rspec-mocks 2.13.1 → 2.14.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- data/Changelog.md +45 -4
- data/README.md +1 -1
- data/features/argument_matchers/README.md +2 -2
- data/features/argument_matchers/explicit.feature +2 -3
- data/features/argument_matchers/general_matchers.feature +2 -2
- data/features/argument_matchers/type_matchers.feature +3 -4
- data/features/message_expectations/README.md +2 -2
- data/features/message_expectations/any_instance.feature +2 -2
- data/features/message_expectations/block_local_expectations.feature.pending +3 -3
- data/features/message_expectations/expect_message_using_expect.feature +103 -0
- data/features/message_expectations/expect_message_using_should_receive.feature +118 -0
- data/features/message_expectations/receive_counts.feature +1 -1
- data/features/method_stubs/README.md +1 -1
- data/features/method_stubs/any_instance.feature +11 -11
- data/features/method_stubs/as_null_object.feature +1 -1
- data/features/method_stubs/stub_implementation.feature +2 -2
- data/features/outside_rspec/configuration.feature +0 -20
- data/features/spies/spy_partial_mock_method.feature +34 -0
- data/features/spies/spy_pure_mock_method.feature +76 -0
- data/features/spies/spy_unstubbed_method.feature +18 -0
- data/features/step_definitions/additional_cli_steps.rb +7 -0
- data/features/test_frameworks/test_unit.feature +43 -0
- data/lib/rspec/mocks.rb +9 -34
- data/lib/rspec/mocks/any_instance/chain.rb +8 -2
- data/lib/rspec/mocks/any_instance/expectation_chain.rb +19 -16
- data/lib/rspec/mocks/any_instance/recorder.rb +6 -3
- data/lib/rspec/mocks/any_instance/stub_chain.rb +11 -11
- data/lib/rspec/mocks/any_instance/stub_chain_chain.rb +8 -10
- data/lib/rspec/mocks/argument_list_matcher.rb +7 -3
- data/lib/rspec/mocks/configuration.rb +28 -1
- data/lib/rspec/mocks/deprecation.rb +18 -0
- data/lib/rspec/mocks/error_generator.rb +60 -8
- data/lib/rspec/mocks/errors.rb +1 -1
- data/lib/rspec/mocks/example_methods.rb +39 -3
- data/lib/rspec/mocks/extensions/marshal.rb +4 -10
- data/lib/rspec/mocks/framework.rb +16 -4
- data/lib/rspec/mocks/instance_method_stasher.rb +3 -0
- data/lib/rspec/mocks/matchers/have_received.rb +93 -0
- data/lib/rspec/mocks/matchers/receive.rb +92 -0
- data/lib/rspec/mocks/message_expectation.rb +66 -129
- data/lib/rspec/mocks/method_double.rb +50 -43
- data/lib/rspec/mocks/mutate_const.rb +8 -20
- data/lib/rspec/mocks/proxy.rb +41 -25
- data/lib/rspec/mocks/proxy_for_nil.rb +36 -0
- data/lib/rspec/mocks/space.rb +64 -11
- data/lib/rspec/mocks/stub_chain.rb +51 -0
- data/lib/rspec/mocks/syntax.rb +329 -0
- data/lib/rspec/mocks/targets.rb +69 -0
- data/lib/rspec/mocks/test_double.rb +25 -4
- data/lib/rspec/mocks/version.rb +1 -1
- data/lib/spec/mocks.rb +1 -3
- data/spec/rspec/mocks/and_call_original_spec.rb +8 -0
- data/spec/rspec/mocks/and_yield_spec.rb +6 -6
- data/spec/rspec/mocks/any_instance_spec.rb +43 -31
- data/spec/rspec/mocks/any_number_of_times_spec.rb +6 -0
- data/spec/rspec/mocks/argument_expectation_spec.rb +12 -14
- data/spec/rspec/mocks/at_least_spec.rb +46 -37
- data/spec/rspec/mocks/at_most_spec.rb +12 -12
- data/spec/rspec/mocks/block_return_value_spec.rb +18 -1
- data/spec/rspec/mocks/bug_report_10260_spec.rb +1 -1
- data/spec/rspec/mocks/bug_report_10263_spec.rb +1 -1
- data/spec/rspec/mocks/bug_report_11545_spec.rb +4 -4
- data/spec/rspec/mocks/bug_report_600_spec.rb +1 -1
- data/spec/rspec/mocks/bug_report_7611_spec.rb +1 -1
- data/spec/rspec/mocks/configuration_spec.rb +124 -0
- data/spec/rspec/mocks/double_spec.rb +13 -1
- data/spec/rspec/mocks/failing_argument_matchers_spec.rb +17 -1
- data/spec/rspec/mocks/hash_excluding_matcher_spec.rb +13 -13
- data/spec/rspec/mocks/matchers/have_received_spec.rb +266 -0
- data/spec/rspec/mocks/matchers/receive_spec.rb +318 -0
- data/spec/rspec/mocks/methods_spec.rb +27 -0
- data/spec/rspec/mocks/mock_ordering_spec.rb +4 -4
- data/spec/rspec/mocks/mock_space_spec.rb +94 -39
- data/spec/rspec/mocks/mock_spec.rb +65 -50
- data/spec/rspec/mocks/multiple_return_value_spec.rb +10 -10
- data/spec/rspec/mocks/mutate_const_spec.rb +21 -1
- data/spec/rspec/mocks/nil_expectation_warning_spec.rb +10 -4
- data/spec/rspec/mocks/null_object_mock_spec.rb +11 -2
- data/spec/rspec/mocks/once_counts_spec.rb +5 -5
- data/spec/rspec/mocks/options_hash_spec.rb +4 -4
- data/spec/rspec/mocks/partial_mock_spec.rb +20 -11
- data/spec/rspec/mocks/partial_mock_using_mocks_directly_spec.rb +7 -7
- data/spec/rspec/mocks/passing_argument_matchers_spec.rb +2 -2
- data/spec/rspec/mocks/precise_counts_spec.rb +6 -6
- data/spec/rspec/mocks/serialization_spec.rb +1 -22
- data/spec/rspec/mocks/stash_spec.rb +4 -12
- data/spec/rspec/mocks/stub_implementation_spec.rb +3 -3
- data/spec/rspec/mocks/stub_spec.rb +44 -20
- data/spec/rspec/mocks/stubbed_message_expectations_spec.rb +6 -6
- data/spec/rspec/mocks/twice_counts_spec.rb +6 -6
- data/spec/rspec/mocks_spec.rb +1 -3
- data/spec/spec_helper.rb +25 -1
- metadata +86 -81
- data/features/message_expectations/expect_message.feature +0 -94
- data/lib/rspec/mocks/any_instance.rb +0 -81
- data/lib/rspec/mocks/extensions/psych.rb +0 -23
- data/lib/rspec/mocks/methods.rb +0 -155
- data/lib/rspec/mocks/serialization.rb +0 -34
- data/spec/rspec/mocks/combining_implementation_instructions_spec.rb +0 -197
@@ -0,0 +1,51 @@
|
|
1
|
+
module RSpec
|
2
|
+
module Mocks
|
3
|
+
# @private
|
4
|
+
class StubChain
|
5
|
+
def self.stub_chain_on(object, *chain, &blk)
|
6
|
+
new(object, *chain, &blk).stub_chain
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_reader :object, :chain, :block
|
10
|
+
|
11
|
+
def initialize(object, *chain, &blk)
|
12
|
+
@object = object
|
13
|
+
@chain, @block = format_chain(*chain, &blk)
|
14
|
+
end
|
15
|
+
|
16
|
+
def stub_chain
|
17
|
+
if chain.length > 1
|
18
|
+
if matching_stub = find_matching_stub
|
19
|
+
chain.shift
|
20
|
+
matching_stub.invoke(nil).stub_chain(*chain, &block)
|
21
|
+
else
|
22
|
+
next_in_chain = Mock.new
|
23
|
+
object.stub(chain.shift) { next_in_chain }
|
24
|
+
StubChain.stub_chain_on(next_in_chain, *chain, &block)
|
25
|
+
end
|
26
|
+
else
|
27
|
+
object.stub(chain.shift, &block)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def format_chain(*chain, &blk)
|
34
|
+
if Hash === chain.last
|
35
|
+
hash = chain.pop
|
36
|
+
hash.each do |k,v|
|
37
|
+
chain << k
|
38
|
+
blk = lambda { v }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
return chain.join('.').split('.'), blk
|
42
|
+
end
|
43
|
+
|
44
|
+
def find_matching_stub
|
45
|
+
::RSpec::Mocks.proxy_for(object).
|
46
|
+
__send__(:find_matching_method_stub, chain.first.to_sym)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
@@ -0,0 +1,329 @@
|
|
1
|
+
module RSpec
|
2
|
+
module Mocks
|
3
|
+
# @api private
|
4
|
+
# Provides methods for enabling and disabling the available syntaxes
|
5
|
+
# provided by rspec-mocks.
|
6
|
+
module Syntax
|
7
|
+
|
8
|
+
# @api private
|
9
|
+
# Enables the should syntax (`dbl.stub`, `dbl.should_receive`, etc).
|
10
|
+
def self.enable_should(syntax_host = default_should_syntax_host)
|
11
|
+
return if should_enabled?(syntax_host)
|
12
|
+
|
13
|
+
syntax_host.class_eval do
|
14
|
+
def should_receive(message, opts={}, &block)
|
15
|
+
proxy = ::RSpec::Mocks.proxy_for(self)
|
16
|
+
proxy.add_message_expectation(opts[:expected_from] || caller(1)[0], message.to_sym, opts, &block)
|
17
|
+
end
|
18
|
+
|
19
|
+
def should_not_receive(message, &block)
|
20
|
+
proxy = ::RSpec::Mocks.proxy_for(self)
|
21
|
+
proxy.add_negative_message_expectation(caller(1)[0], message.to_sym, &block)
|
22
|
+
end
|
23
|
+
|
24
|
+
def stub(message_or_hash, opts={}, &block)
|
25
|
+
if ::Hash === message_or_hash
|
26
|
+
message_or_hash.each {|message, value| stub(message).and_return value }
|
27
|
+
else
|
28
|
+
::RSpec::Mocks.proxy_for(self).add_stub(caller(1)[0], message_or_hash.to_sym, opts, &block)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def unstub(message)
|
33
|
+
::RSpec::Mocks.space.proxy_for(self).remove_stub(message)
|
34
|
+
end
|
35
|
+
|
36
|
+
def stub!(message_or_hash, opts={}, &block)
|
37
|
+
::RSpec.deprecate "stub!", :replacement => "stub"
|
38
|
+
stub(message_or_hash, opts={}, &block)
|
39
|
+
end
|
40
|
+
|
41
|
+
def unstub!(message)
|
42
|
+
::RSpec.deprecate "unstub!", :replacement => "unstub"
|
43
|
+
unstub(message)
|
44
|
+
end
|
45
|
+
|
46
|
+
def stub_chain(*chain, &blk)
|
47
|
+
::RSpec::Mocks::StubChain.stub_chain_on(self, *chain, &blk)
|
48
|
+
end
|
49
|
+
|
50
|
+
def as_null_object
|
51
|
+
@_null_object = true
|
52
|
+
::RSpec::Mocks.proxy_for(self).as_null_object
|
53
|
+
end
|
54
|
+
|
55
|
+
def null_object?
|
56
|
+
defined?(@_null_object)
|
57
|
+
end
|
58
|
+
|
59
|
+
def received_message?(message, *args, &block)
|
60
|
+
::RSpec::Mocks.proxy_for(self).received_message?(message, *args, &block)
|
61
|
+
end
|
62
|
+
|
63
|
+
unless Class.respond_to? :any_instance
|
64
|
+
Class.class_eval do
|
65
|
+
def any_instance
|
66
|
+
::RSpec::Mocks.any_instance_recorder_for(self)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# @api private
|
74
|
+
# Disables the should syntax (`dbl.stub`, `dbl.should_receive`, etc).
|
75
|
+
def self.disable_should(syntax_host = default_should_syntax_host)
|
76
|
+
return unless should_enabled?(syntax_host)
|
77
|
+
|
78
|
+
syntax_host.class_eval do
|
79
|
+
undef should_receive
|
80
|
+
undef should_not_receive
|
81
|
+
undef stub
|
82
|
+
undef unstub
|
83
|
+
undef stub!
|
84
|
+
undef unstub!
|
85
|
+
undef stub_chain
|
86
|
+
undef as_null_object
|
87
|
+
undef null_object?
|
88
|
+
undef received_message?
|
89
|
+
end
|
90
|
+
|
91
|
+
Class.class_eval do
|
92
|
+
undef any_instance
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# @api private
|
97
|
+
# Enables the expect syntax (`expect(dbl).to receive`, `allow(dbl).to receive`, etc).
|
98
|
+
def self.enable_expect(syntax_host = ::RSpec::Mocks::ExampleMethods)
|
99
|
+
return if expect_enabled?(syntax_host)
|
100
|
+
|
101
|
+
syntax_host.class_eval do
|
102
|
+
def receive(method_name, &block)
|
103
|
+
Matchers::Receive.new(method_name, block)
|
104
|
+
end
|
105
|
+
|
106
|
+
def allow(target)
|
107
|
+
AllowanceTarget.new(target)
|
108
|
+
end
|
109
|
+
|
110
|
+
def expect_any_instance_of(klass)
|
111
|
+
AnyInstanceExpectationTarget.new(klass)
|
112
|
+
end
|
113
|
+
|
114
|
+
def allow_any_instance_of(klass)
|
115
|
+
AnyInstanceAllowanceTarget.new(klass)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
RSpec::Mocks::ExampleMethods::ExpectHost.class_eval do
|
120
|
+
def expect(target)
|
121
|
+
ExpectationTarget.new(target)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
# @api private
|
127
|
+
# Disables the expect syntax (`expect(dbl).to receive`, `allow(dbl).to receive`, etc).
|
128
|
+
def self.disable_expect(syntax_host = ::RSpec::Mocks::ExampleMethods)
|
129
|
+
return unless expect_enabled?(syntax_host)
|
130
|
+
|
131
|
+
syntax_host.class_eval do
|
132
|
+
undef receive
|
133
|
+
undef allow
|
134
|
+
undef expect_any_instance_of
|
135
|
+
undef allow_any_instance_of
|
136
|
+
end
|
137
|
+
|
138
|
+
RSpec::Mocks::ExampleMethods::ExpectHost.class_eval do
|
139
|
+
undef expect
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
# @api private
|
144
|
+
# Indicates whether or not the should syntax is enabled.
|
145
|
+
def self.should_enabled?(syntax_host = default_should_syntax_host)
|
146
|
+
syntax_host.method_defined?(:should_receive)
|
147
|
+
end
|
148
|
+
|
149
|
+
# @api private
|
150
|
+
# Indicates whether or not the expect syntax is enabled.
|
151
|
+
def self.expect_enabled?(syntax_host = ::RSpec::Mocks::ExampleMethods)
|
152
|
+
syntax_host.method_defined?(:allow)
|
153
|
+
end
|
154
|
+
|
155
|
+
# @api private
|
156
|
+
# Determines where the methods like `should_receive`, and `stub` are added.
|
157
|
+
def self.default_should_syntax_host
|
158
|
+
# On 1.8.7, Object.ancestors.last == Kernel but
|
159
|
+
# things blow up if we include `RSpec::Mocks::Methods`
|
160
|
+
# into Kernel...not sure why.
|
161
|
+
return Object unless defined?(::BasicObject)
|
162
|
+
|
163
|
+
# MacRuby has BasicObject but it's not the root class.
|
164
|
+
return Object unless Object.ancestors.last == ::BasicObject
|
165
|
+
|
166
|
+
::BasicObject
|
167
|
+
end
|
168
|
+
|
169
|
+
# @method should_receive
|
170
|
+
# Sets an expectation that this object should receive a message before
|
171
|
+
# the end of the example.
|
172
|
+
#
|
173
|
+
# @example
|
174
|
+
#
|
175
|
+
# logger = double('logger')
|
176
|
+
# thing_that_logs = ThingThatLogs.new(logger)
|
177
|
+
# logger.should_receive(:log)
|
178
|
+
# thing_that_logs.do_something_that_logs_a_message
|
179
|
+
#
|
180
|
+
# @note This is only available when you have enabled the `should` syntax.
|
181
|
+
|
182
|
+
# @method should_not_receive
|
183
|
+
# Sets and expectation that this object should _not_ receive a message
|
184
|
+
# during this example.
|
185
|
+
|
186
|
+
# @method stub
|
187
|
+
# Tells the object to respond to the message with the specified value.
|
188
|
+
#
|
189
|
+
# @example
|
190
|
+
#
|
191
|
+
# counter.stub(:count).and_return(37)
|
192
|
+
# counter.stub(:count => 37)
|
193
|
+
# counter.stub(:count) { 37 }
|
194
|
+
#
|
195
|
+
# @note This is only available when you have enabled the `should` syntax.
|
196
|
+
|
197
|
+
# @method unstub
|
198
|
+
# Removes a stub. On a double, the object will no longer respond to
|
199
|
+
# `message`. On a real object, the original method (if it exists) is
|
200
|
+
# restored.
|
201
|
+
#
|
202
|
+
# This is rarely used, but can be useful when a stub is set up during a
|
203
|
+
# shared `before` hook for the common case, but you want to replace it
|
204
|
+
# for a special case.
|
205
|
+
#
|
206
|
+
# @note This is only available when you have enabled the `should` syntax.
|
207
|
+
|
208
|
+
# @method stub_chain
|
209
|
+
# @overload stub_chain(method1, method2)
|
210
|
+
# @overload stub_chain("method1.method2")
|
211
|
+
# @overload stub_chain(method1, method_to_value_hash)
|
212
|
+
#
|
213
|
+
# Stubs a chain of methods.
|
214
|
+
#
|
215
|
+
# ## Warning:
|
216
|
+
#
|
217
|
+
# Chains can be arbitrarily long, which makes it quite painless to
|
218
|
+
# violate the Law of Demeter in violent ways, so you should consider any
|
219
|
+
# use of `stub_chain` a code smell. Even though not all code smells
|
220
|
+
# indicate real problems (think fluent interfaces), `stub_chain` still
|
221
|
+
# results in brittle examples. For example, if you write
|
222
|
+
# `foo.stub_chain(:bar, :baz => 37)` in a spec and then the
|
223
|
+
# implementation calls `foo.baz.bar`, the stub will not work.
|
224
|
+
#
|
225
|
+
# @example
|
226
|
+
#
|
227
|
+
# double.stub_chain("foo.bar") { :baz }
|
228
|
+
# double.stub_chain(:foo, :bar => :baz)
|
229
|
+
# double.stub_chain(:foo, :bar) { :baz }
|
230
|
+
#
|
231
|
+
# # Given any of ^^ these three forms ^^:
|
232
|
+
# double.foo.bar # => :baz
|
233
|
+
#
|
234
|
+
# # Common use in Rails/ActiveRecord:
|
235
|
+
# Article.stub_chain("recent.published") { [Article.new] }
|
236
|
+
#
|
237
|
+
# @note This is only available when you have enabled the `should` syntax.
|
238
|
+
|
239
|
+
# @method as_null_object
|
240
|
+
# Tells the object to respond to all messages. If specific stub values
|
241
|
+
# are declared, they'll work as expected. If not, the receiver is
|
242
|
+
# returned.
|
243
|
+
#
|
244
|
+
# @note This is only available when you have enabled the `should` syntax.
|
245
|
+
|
246
|
+
# @method null_object?
|
247
|
+
# Returns true if this object has received `as_null_object`
|
248
|
+
#
|
249
|
+
# @note This is only available when you have enabled the `should` syntax.
|
250
|
+
|
251
|
+
# @method any_instance
|
252
|
+
# Used to set stubs and message expectations on any instance of a given
|
253
|
+
# class. Returns a [Recorder](Recorder), which records messages like
|
254
|
+
# `stub` and `should_receive` for later playback on instances of the
|
255
|
+
# class.
|
256
|
+
#
|
257
|
+
# @example
|
258
|
+
#
|
259
|
+
# Car.any_instance.should_receive(:go)
|
260
|
+
# race = Race.new
|
261
|
+
# race.cars << Car.new
|
262
|
+
# race.go # assuming this delegates to all of its cars
|
263
|
+
# # this example would pass
|
264
|
+
#
|
265
|
+
# Account.any_instance.stub(:balance) { Money.new(:USD, 25) }
|
266
|
+
# Account.new.balance # => Money.new(:USD, 25))
|
267
|
+
#
|
268
|
+
# @return [Recorder]
|
269
|
+
#
|
270
|
+
# @note This is only available when you have enabled the `should` syntax.
|
271
|
+
|
272
|
+
# @method expect
|
273
|
+
# Used to wrap an object in preparation for setting a mock expectation
|
274
|
+
# on it.
|
275
|
+
#
|
276
|
+
# @example
|
277
|
+
#
|
278
|
+
# expect(obj).to receive(:foo).with(5).and_return(:return_value)
|
279
|
+
#
|
280
|
+
# @note This method is usually provided by rspec-expectations, unless
|
281
|
+
# you are using rspec-mocks w/o rspec-expectations, in which case it
|
282
|
+
# is only made available if you enable the `expect` syntax.
|
283
|
+
|
284
|
+
# @method allow
|
285
|
+
# Used to wrap an object in preparation for stubbing a method
|
286
|
+
# on it.
|
287
|
+
#
|
288
|
+
# @example
|
289
|
+
#
|
290
|
+
# allow(dbl).to receive(:foo).with(5).and_return(:return_value)
|
291
|
+
#
|
292
|
+
# @note This is only available when you have enabled the `expect` syntax.
|
293
|
+
|
294
|
+
# @method expect_any_instance_of
|
295
|
+
# Used to wrap a class in preparation for setting a mock expectation
|
296
|
+
# on instances of it.
|
297
|
+
#
|
298
|
+
# @example
|
299
|
+
#
|
300
|
+
# expect_any_instance_of(MyClass).to receive(:foo)
|
301
|
+
#
|
302
|
+
# @note This is only available when you have enabled the `expect` syntax.
|
303
|
+
|
304
|
+
# @method allow_any_instance_of
|
305
|
+
# Used to wrap a class in preparation for stubbing a method
|
306
|
+
# on instances of it.
|
307
|
+
#
|
308
|
+
# @example
|
309
|
+
#
|
310
|
+
# allow_any_instance_of(MyClass).to receive(:foo)
|
311
|
+
#
|
312
|
+
# @note This is only available when you have enabled the `expect` syntax.
|
313
|
+
|
314
|
+
# @method receive
|
315
|
+
# Used to specify a message that you expect or allow an object
|
316
|
+
# to receive. The object returned by `receive` supports the same
|
317
|
+
# fluent interface that `should_receive` and `stub` have always
|
318
|
+
# supported, allowing you to constrain the arguments or number of
|
319
|
+
# times, and configure how the object should respond to the message.
|
320
|
+
#
|
321
|
+
# @example
|
322
|
+
#
|
323
|
+
# expect(obj).to receive(:hello).with("world").exactly(3).times
|
324
|
+
#
|
325
|
+
# @note This is only available when you have enabled the `expect` syntax.
|
326
|
+
end
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module RSpec
|
2
|
+
module Mocks
|
3
|
+
UnsupportedMatcherError = Class.new(StandardError)
|
4
|
+
NegationUnsupportedError = Class.new(StandardError)
|
5
|
+
|
6
|
+
class TargetBase
|
7
|
+
def initialize(target)
|
8
|
+
@target = target
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.delegate_to(matcher_method, options = {})
|
12
|
+
method_name = options.fetch(:from) { :to }
|
13
|
+
class_eval(<<-RUBY)
|
14
|
+
def #{method_name}(matcher, &block)
|
15
|
+
unless Matchers::Receive === matcher
|
16
|
+
raise UnsupportedMatcherError, "only the `receive` matcher is supported " +
|
17
|
+
"with `\#{expression}(...).\#{#{method_name.inspect}}`, but you have provided: \#{matcher}"
|
18
|
+
end
|
19
|
+
|
20
|
+
matcher.__send__(#{matcher_method.inspect}, @target, &block)
|
21
|
+
end
|
22
|
+
RUBY
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.disallow_negation(method)
|
26
|
+
define_method method do |*args|
|
27
|
+
raise NegationUnsupportedError,
|
28
|
+
"`#{expression}(...).#{method} receive` is not supported since it " +
|
29
|
+
"doesn't really make sense. What would it even mean?"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def expression
|
36
|
+
self.class::EXPRESSION
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class AllowanceTarget < TargetBase
|
41
|
+
EXPRESSION = :allow
|
42
|
+
delegate_to :setup_allowance
|
43
|
+
disallow_negation :not_to
|
44
|
+
disallow_negation :to_not
|
45
|
+
end
|
46
|
+
|
47
|
+
class ExpectationTarget < TargetBase
|
48
|
+
EXPRESSION = :expect
|
49
|
+
delegate_to :setup_expectation
|
50
|
+
delegate_to :setup_negative_expectation, :from => :not_to
|
51
|
+
delegate_to :setup_negative_expectation, :from => :to_not
|
52
|
+
end
|
53
|
+
|
54
|
+
class AnyInstanceAllowanceTarget < TargetBase
|
55
|
+
EXPRESSION = :expect_any_instance_of
|
56
|
+
delegate_to :setup_any_instance_allowance
|
57
|
+
disallow_negation :not_to
|
58
|
+
disallow_negation :to_not
|
59
|
+
end
|
60
|
+
|
61
|
+
class AnyInstanceExpectationTarget < TargetBase
|
62
|
+
EXPRESSION = :expect_any_instance_of
|
63
|
+
delegate_to :setup_any_instance_expectation
|
64
|
+
delegate_to :setup_any_instance_negative_expectation, :from => :not_to
|
65
|
+
delegate_to :setup_any_instance_negative_expectation, :from => :to_not
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|