Name | Total Lines | Lines of Code | Total Coverage | Code Coverage |
---|---|---|---|---|
rcov/ruby/1.8/gems/rspec-mocks-2.5.0/lib/rspec/mocks/message_expectation.rb | 351 | 281 | 32.76%
|
20.28%
|
Code reported as executed by Ruby looks like this...and this: this line is also marked as covered.Lines considered as run by rcov, but not reported by Ruby, look like this,and this: these lines were inferred by rcov (using simple heuristics).Finally, here's a line marked as not executed.
1 module RSpec |
2 module Mocks |
3 |
4 class BaseExpectation |
5 attr_reader :sym |
6 attr_writer :expected_received_count, :method_block, :expected_from |
7 protected :expected_received_count=, :method_block=, :expected_from= |
8 attr_accessor :error_generator |
9 protected :error_generator, :error_generator= |
10 |
11 def initialize(error_generator, expectation_ordering, expected_from, sym, method_block, expected_received_count=1, opts={}, &implementation) |
12 @error_generator = error_generator |
13 @error_generator.opts = opts |
14 @expected_from = expected_from |
15 @sym = sym |
16 @method_block = method_block |
17 @return_block = nil |
18 @actual_received_count = 0 |
19 @expected_received_count = expected_received_count |
20 @args_expectation = ArgumentExpectation.new(ArgumentMatchers::AnyArgsMatcher.new) |
21 @consecutive = false |
22 @exception_to_raise = nil |
23 @symbol_to_throw = nil |
24 @order_group = expectation_ordering |
25 @at_least = nil |
26 @at_most = nil |
27 @exactly = nil |
28 @args_to_yield = [] |
29 @failed_fast = nil |
30 @args_to_yield_were_cloned = false |
31 @return_block = implementation |
32 @eval_context = nil |
33 end |
34 |
35 def build_child(expected_from, method_block, expected_received_count, opts={}) |
36 child = clone |
37 child.expected_from = expected_from |
38 child.method_block = method_block |
39 child.expected_received_count = expected_received_count |
40 child.clear_actual_received_count! |
41 new_gen = error_generator.clone |
42 new_gen.opts = opts |
43 child.error_generator = new_gen |
44 child.clone_args_to_yield(*@args_to_yield) |
45 child |
46 end |
47 |
48 def expected_args |
49 @args_expectation.args |
50 end |
51 |
52 def and_return(*values, &return_block) |
53 Kernel::raise AmbiguousReturnError unless @method_block.nil? |
54 case values.size |
55 when 0 then value = nil |
56 when 1 then value = values[0] |
57 else |
58 value = values |
59 @consecutive = true |
60 @expected_received_count = values.size if !ignoring_args? && |
61 @expected_received_count < values.size |
62 end |
63 @return_block = block_given? ? return_block : lambda { value } |
64 end |
65 |
66 # :call-seq: |
67 # and_raise() |
68 # and_raise(Exception) #any exception class |
69 # and_raise(exception) #any exception object |
70 # |
71 # == Warning |
72 # |
73 # When you pass an exception class, the MessageExpectation will |
74 # raise an instance of it, creating it with +new+. If the exception |
75 # class initializer requires any parameters, you must pass in an |
76 # instance and not the class. |
77 def and_raise(exception=Exception) |
78 @exception_to_raise = exception |
79 end |
80 |
81 def and_throw(symbol) |
82 @symbol_to_throw = symbol |
83 end |
84 |
85 def and_yield(*args, &block) |
86 if @args_to_yield_were_cloned |
87 @args_to_yield.clear |
88 @args_to_yield_were_cloned = false |
89 end |
90 |
91 if block |
92 @eval_context = Object.new |
93 @eval_context.extend RSpec::Mocks::InstanceExec |
94 yield @eval_context |
95 end |
96 |
97 @args_to_yield << args |
98 self |
99 end |
100 |
101 def matches?(sym, *args) |
102 @sym == sym and @args_expectation.args_match?(*args) |
103 end |
104 |
105 def invoke(*args, &block) |
106 if @expected_received_count == 0 |
107 @failed_fast = true |
108 @actual_received_count += 1 |
109 @error_generator.raise_expectation_error(@sym, @expected_received_count, @actual_received_count, *args) |
110 end |
111 |
112 @order_group.handle_order_constraint self |
113 |
114 begin |
115 Kernel::raise @exception_to_raise unless @exception_to_raise.nil? |
116 Kernel::throw @symbol_to_throw unless @symbol_to_throw.nil? |
117 |
118 default_return_val = if !@method_block.nil? |
119 invoke_method_block(*args, &block) |
120 elsif !@args_to_yield.empty? || @eval_context |
121 invoke_with_yield(&block) |
122 else |
123 nil |
124 end |
125 |
126 if @consecutive |
127 invoke_consecutive_return_block(*args, &block) |
128 elsif @return_block |
129 invoke_return_block(*args, &block) |
130 else |
131 default_return_val |
132 end |
133 ensure |
134 @actual_received_count += 1 |
135 end |
136 end |
137 |
138 def called_max_times? |
139 @expected_received_count != :any && @expected_received_count > 0 && |
140 @actual_received_count >= @expected_received_count |
141 end |
142 |
143 protected |
144 |
145 def invoke_method_block(*args, &block) |
146 begin |
147 @method_block.call(*args, &block) |
148 rescue => detail |
149 @error_generator.raise_block_failed_error(@sym, detail.message) |
150 end |
151 end |
152 |
153 def invoke_with_yield(&block) |
154 if block.nil? |
155 @error_generator.raise_missing_block_error @args_to_yield |
156 end |
157 value = nil |
158 @args_to_yield.each do |args_to_yield_this_time| |
159 if block.arity > -1 && args_to_yield_this_time.length != block.arity |
160 @error_generator.raise_wrong_arity_error args_to_yield_this_time, block.arity |
161 end |
162 value = eval_block(*args_to_yield_this_time, &block) |
163 end |
164 value |
165 end |
166 |
167 def eval_block(*args, &block) |
168 if @eval_context |
169 @eval_context.instance_exec(*args, &block) |
170 else |
171 block.call(*args) |
172 end |
173 end |
174 |
175 def invoke_consecutive_return_block(*args, &block) |
176 value = invoke_return_block(*args, &block) |
177 index = [@actual_received_count, value.size-1].min |
178 value[index] |
179 end |
180 |
181 def invoke_return_block(*args, &block) |
182 args << block unless block.nil? |
183 # Ruby 1.9 - when we set @return_block to return values |
184 # regardless of arguments, any arguments will result in |
185 # a "wrong number of arguments" error |
186 @return_block.arity == 0 ? @return_block.call : @return_block.call(*args) |
187 end |
188 |
189 def clone_args_to_yield(*args) |
190 @args_to_yield = args.clone |
191 @args_to_yield_were_cloned = true |
192 end |
193 |
194 def failed_fast? |
195 @failed_fast |
196 end |
197 end |
198 |
199 class MessageExpectation < BaseExpectation |
200 |
201 def matches_name_but_not_args(sym, *args) |
202 @sym == sym and not @args_expectation.args_match?(*args) |
203 end |
204 |
205 def verify_messages_received |
206 return if expected_messages_received? || failed_fast? |
207 |
208 generate_error |
209 rescue RSpec::Mocks::MockExpectationError => error |
210 error.backtrace.insert(0, @expected_from) |
211 Kernel::raise error |
212 end |
213 |
214 def expected_messages_received? |
215 ignoring_args? || matches_exact_count? || |
216 matches_at_least_count? || matches_at_most_count? |
217 end |
218 |
219 def ignoring_args? |
220 @expected_received_count == :any |
221 end |
222 |
223 def matches_at_least_count? |
224 @at_least && @actual_received_count >= @expected_received_count |
225 end |
226 |
227 def matches_at_most_count? |
228 @at_most && @actual_received_count <= @expected_received_count |
229 end |
230 |
231 def matches_exact_count? |
232 @expected_received_count == @actual_received_count |
233 end |
234 |
235 def similar_messages |
236 @similar_messages ||= [] |
237 end |
238 |
239 def advise(*args) |
240 similar_messages << args |
241 end |
242 |
243 def generate_error |
244 if similar_messages.empty? |
245 @error_generator.raise_expectation_error(@sym, @expected_received_count, @actual_received_count, *@args_expectation.args) |
246 else |
247 @error_generator.raise_similar_message_args_error(self, *@similar_messages) |
248 end |
249 end |
250 |
251 def with(*args, &block) |
252 @return_block = block if block_given? |
253 @args_expectation = ArgumentExpectation.new(*args, &block) |
254 self |
255 end |
256 |
257 def exactly(n) |
258 set_expected_received_count :exactly, n |
259 self |
260 end |
261 |
262 def at_least(n) |
263 set_expected_received_count :at_least, n |
264 self |
265 end |
266 |
267 def at_most(n) |
268 set_expected_received_count :at_most, n |
269 self |
270 end |
271 |
272 def times(&block) |
273 @method_block = block if block |
274 self |
275 end |
276 |
277 def any_number_of_times(&block) |
278 @method_block = block if block |
279 @expected_received_count = :any |
280 self |
281 end |
282 |
283 def never |
284 @expected_received_count = 0 |
285 self |
286 end |
287 |
288 def once(&block) |
289 @method_block = block if block |
290 set_expected_received_count :exactly, 1 |
291 self |
292 end |
293 |
294 def twice(&block) |
295 @method_block = block if block |
296 set_expected_received_count :exactly, 2 |
297 self |
298 end |
299 |
300 def ordered(&block) |
301 @method_block = block if block |
302 @order_group.register(self) |
303 @ordered = true |
304 self |
305 end |
306 |
307 def negative_expectation_for?(sym) |
308 return false |
309 end |
310 |
311 def actual_received_count_matters? |
312 @at_least || @at_most || @exactly |
313 end |
314 |
315 def increase_actual_received_count! |
316 @actual_received_count += 1 |
317 end |
318 |
319 protected |
320 def set_expected_received_count(relativity, n) |
321 @at_least = (relativity == :at_least) |
322 @at_most = (relativity == :at_most) |
323 @exactly = (relativity == :exactly) |
324 @expected_received_count = case n |
325 when Numeric |
326 n |
327 when :once |
328 1 |
329 when :twice |
330 2 |
331 end |
332 end |
333 |
334 def clear_actual_received_count! |
335 @actual_received_count = 0 |
336 end |
337 |
338 end |
339 |
340 class NegativeMessageExpectation < MessageExpectation |
341 def initialize(message, expectation_ordering, expected_from, sym, method_block) |
342 super(message, expectation_ordering, expected_from, sym, method_block, 0) |
343 end |
344 |
345 def negative_expectation_for?(sym) |
346 return @sym == sym |
347 end |
348 end |
349 |
350 end |
351 end |
Generated on Fri Apr 22 17:22:41 -0700 2011 with rcov 0.9.8