changelog shortlog tags changeset manifest revisions annotate raw

vendor/plugins/rspec/lib/spec/mocks/message_expectation.rb

changeset 15: 64acf98d15f4
author: moriq@moriq.com
date: Mon Mar 10 10:12:58 2008 +0900 (16 years ago)
permissions: -rw-r--r--
description: add plugins rspec
1module Spec
2 module Mocks
3
4 class BaseExpectation
5 attr_reader :sym
6
7 def initialize(error_generator, expectation_ordering, expected_from, sym, method_block, expected_received_count=1, opts={})
8 @error_generator = error_generator
9 @error_generator.opts = opts
10 @expected_from = expected_from
11 @sym = sym
12 @method_block = method_block
13 @return_block = nil
14 @actual_received_count = 0
15 @expected_received_count = expected_received_count
16 @args_expectation = ArgumentExpectation.new([AnyArgsConstraint.new])
17 @consecutive = false
18 @exception_to_raise = nil
19 @symbol_to_throw = nil
20 @order_group = expectation_ordering
21 @at_least = nil
22 @at_most = nil
23 @args_to_yield = []
24 end
25
26 def expected_args
27 @args_expectation.args
28 end
29
30 def and_return(*values, &return_block)
31 Kernel::raise AmbiguousReturnError unless @method_block.nil?
32 case values.size
33 when 0 then value = nil
34 when 1 then value = values[0]
35 else
36 value = values
37 @consecutive = true
38 @expected_received_count = values.size if !ignoring_args? &&
39 @expected_received_count < values.size
40 end
41 @return_block = block_given? ? return_block : lambda { value }
42 # Ruby 1.9 - see where this is used below
43 @ignore_args = !block_given?
44 end
45
46 # :call-seq:
47 # and_raise()
48 # and_raise(Exception) #any exception class
49 # and_raise(exception) #any exception object
50 #
51 # == Warning
52 #
53 # When you pass an exception class, the MessageExpectation will
54 # raise an instance of it, creating it with +new+. If the exception
55 # class initializer requires any parameters, you must pass in an
56 # instance and not the class.
57 def and_raise(exception=Exception)
58 @exception_to_raise = exception
59 end
60
61 def and_throw(symbol)
62 @symbol_to_throw = symbol
63 end
64
65 def and_yield(*args)
66 @args_to_yield << args
67 self
68 end
69
70 def matches(sym, args)
71 @sym == sym and @args_expectation.check_args(args)
72 end
73
74 def invoke(args, block)
75 @order_group.handle_order_constraint self
76
77 begin
78 Kernel::raise @exception_to_raise unless @exception_to_raise.nil?
79 Kernel::throw @symbol_to_throw unless @symbol_to_throw.nil?
80
81 if !@method_block.nil?
82 default_return_val = invoke_method_block(args)
83 elsif @args_to_yield.size > 0
84 default_return_val = invoke_with_yield(block)
85 else
86 default_return_val = nil
87 end
88
89 if @consecutive
90 return invoke_consecutive_return_block(args, block)
91 elsif @return_block
92 return invoke_return_block(args, block)
93 else
94 return default_return_val
95 end
96 ensure
97 @actual_received_count += 1
98 end
99 end
100
101 protected
102
103 def invoke_method_block(args)
104 begin
105 @method_block.call(*args)
106 rescue => detail
107 @error_generator.raise_block_failed_error @sym, detail.message
108 end
109 end
110
111 def invoke_with_yield(block)
112 if block.nil?
113 @error_generator.raise_missing_block_error @args_to_yield
114 end
115 @args_to_yield.each do |args_to_yield_this_time|
116 if block.arity > -1 && args_to_yield_this_time.length != block.arity
117 @error_generator.raise_wrong_arity_error args_to_yield_this_time, block.arity
118 end
119 block.call(*args_to_yield_this_time)
120 end
121 end
122
123 def invoke_consecutive_return_block(args, block)
124 args << block unless block.nil?
125 value = @return_block.call(*args)
126
127 index = [@actual_received_count, value.size-1].min
128 value[index]
129 end
130
131 def invoke_return_block(args, block)
132 args << block unless block.nil?
133 # Ruby 1.9 - when we set @return_block to return values
134 # regardless of arguments, any arguments will result in
135 # a "wrong number of arguments" error
136 if @ignore_args
137 @return_block.call()
138 else
139 @return_block.call(*args)
140 end
141 end
142 end
143
144 class MessageExpectation < BaseExpectation
145
146 def matches_name_but_not_args(sym, args)
147 @sym == sym and not @args_expectation.check_args(args)
148 end
149
150 def verify_messages_received
151 return if ignoring_args? || matches_exact_count? ||
152 matches_at_least_count? || matches_at_most_count?
153
154 generate_error
155 rescue Spec::Mocks::MockExpectationError => error
156 error.backtrace.insert(0, @expected_from)
157 Kernel::raise error
158 end
159
160 def ignoring_args?
161 @expected_received_count == :any
162 end
163
164 def matches_at_least_count?
165 @at_least && @actual_received_count >= @expected_received_count
166 end
167
168 def matches_at_most_count?
169 @at_most && @actual_received_count <= @expected_received_count
170 end
171
172 def matches_exact_count?
173 @expected_received_count == @actual_received_count
174 end
175
176 def generate_error
177 @error_generator.raise_expectation_error(@sym, @expected_received_count, @actual_received_count, *@args_expectation.args)
178 end
179
180 def with(*args, &block)
181 @method_block = block if block
182 @args_expectation = ArgumentExpectation.new(args)
183 self
184 end
185
186 def exactly(n)
187 set_expected_received_count :exactly, n
188 self
189 end
190
191 def at_least(n)
192 set_expected_received_count :at_least, n
193 self
194 end
195
196 def at_most(n)
197 set_expected_received_count :at_most, n
198 self
199 end
200
201 def times(&block)
202 @method_block = block if block
203 self
204 end
205
206 def any_number_of_times(&block)
207 @method_block = block if block
208 @expected_received_count = :any
209 self
210 end
211
212 def never
213 @expected_received_count = 0
214 self
215 end
216
217 def once(&block)
218 @method_block = block if block
219 @expected_received_count = 1
220 self
221 end
222
223 def twice(&block)
224 @method_block = block if block
225 @expected_received_count = 2
226 self
227 end
228
229 def ordered(&block)
230 @method_block = block if block
231 @order_group.register(self)
232 @ordered = true
233 self
234 end
235
236 def negative_expectation_for?(sym)
237 return false
238 end
239
240 protected
241 def set_expected_received_count(relativity, n)
242 @at_least = (relativity == :at_least)
243 @at_most = (relativity == :at_most)
244 @expected_received_count = case n
245 when Numeric
246 n
247 when :once
248 1
249 when :twice
250 2
251 end
252 end
253
254 end
255
256 class NegativeMessageExpectation < MessageExpectation
257 def initialize(message, expectation_ordering, expected_from, sym, method_block)
258 super(message, expectation_ordering, expected_from, sym, method_block, 0)
259 end
260
261 def negative_expectation_for?(sym)
262 return @sym == sym
263 end
264 end
265
266 end
267end