Rspec Steps C0 Coverage Information - RCov

rcov/ruby/1.8/gems/rspec-mocks-2.5.0/lib/rspec/mocks/message_expectation.rb

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%

Key

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.

Coverage Details

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