rspec-mocks 3.0.0.beta1 → 3.0.0.beta2
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +1 -1
- data/Changelog.md +95 -3
- data/README.md +27 -13
- data/features/README.md +15 -7
- data/features/argument_matchers/README.md +5 -5
- data/features/argument_matchers/explicit.feature +6 -6
- data/features/argument_matchers/general_matchers.feature +4 -4
- data/features/argument_matchers/type_matchers.feature +2 -2
- data/features/message_expectations/README.md +29 -27
- data/features/message_expectations/call_original.feature +0 -1
- data/features/message_expectations/message_chains_using_expect.feature +49 -0
- data/features/method_stubs/README.md +2 -1
- data/features/method_stubs/{any_instance.feature → allow_any_instance_of.feature} +12 -12
- data/features/method_stubs/{stub_chain.feature → receive_message_chain.feature} +3 -3
- data/features/method_stubs/to_ary.feature +1 -1
- data/features/mutating_constants/stub_defined_constant.feature +0 -1
- data/features/outside_rspec/standalone.feature +1 -1
- data/features/spies/spy_pure_mock_method.feature +1 -1
- data/features/test_frameworks/test_unit.feature +21 -10
- data/features/verifying_doubles/README.md +17 -0
- data/features/verifying_doubles/class_doubles.feature +1 -16
- data/features/verifying_doubles/dynamic_classes.feature +0 -1
- data/features/verifying_doubles/{introduction.feature → instance_doubles.feature} +41 -23
- data/features/verifying_doubles/partial_doubles.feature +2 -2
- data/lib/rspec/mocks.rb +69 -82
- data/lib/rspec/mocks/any_instance/expect_chain_chain.rb +35 -0
- data/lib/rspec/mocks/any_instance/expectation_chain.rb +1 -2
- data/lib/rspec/mocks/any_instance/recorder.rb +52 -18
- data/lib/rspec/mocks/any_instance/stub_chain.rb +1 -1
- data/lib/rspec/mocks/any_instance/stub_chain_chain.rb +4 -0
- data/lib/rspec/mocks/argument_list_matcher.rb +10 -44
- data/lib/rspec/mocks/argument_matchers.rb +132 -163
- data/lib/rspec/mocks/configuration.rb +28 -4
- data/lib/rspec/mocks/error_generator.rb +46 -13
- data/lib/rspec/mocks/example_methods.rb +13 -12
- data/lib/rspec/mocks/extensions/marshal.rb +1 -1
- data/lib/rspec/mocks/framework.rb +3 -4
- data/lib/rspec/mocks/instance_method_stasher.rb +2 -3
- data/lib/rspec/mocks/matchers/have_received.rb +8 -6
- data/lib/rspec/mocks/matchers/receive.rb +28 -20
- data/lib/rspec/mocks/matchers/receive_message_chain.rb +65 -0
- data/lib/rspec/mocks/matchers/receive_messages.rb +3 -2
- data/lib/rspec/mocks/message_chain.rb +91 -0
- data/lib/rspec/mocks/message_expectation.rb +86 -80
- data/lib/rspec/mocks/method_double.rb +2 -11
- data/lib/rspec/mocks/method_reference.rb +82 -23
- data/lib/rspec/mocks/method_signature_verifier.rb +207 -0
- data/lib/rspec/mocks/mutate_const.rb +34 -50
- data/lib/rspec/mocks/object_reference.rb +0 -1
- data/lib/rspec/mocks/proxy.rb +70 -13
- data/lib/rspec/mocks/ruby_features.rb +24 -0
- data/lib/rspec/mocks/space.rb +105 -31
- data/lib/rspec/mocks/standalone.rb +2 -2
- data/lib/rspec/mocks/syntax.rb +43 -8
- data/lib/rspec/mocks/targets.rb +16 -7
- data/lib/rspec/mocks/test_double.rb +41 -15
- data/lib/rspec/mocks/verifying_double.rb +51 -4
- data/lib/rspec/mocks/verifying_message_expecation.rb +12 -12
- data/lib/rspec/mocks/verifying_proxy.rb +32 -19
- data/lib/rspec/mocks/version.rb +1 -1
- data/spec/rspec/mocks/and_call_original_spec.rb +28 -7
- data/spec/rspec/mocks/and_return_spec.rb +23 -0
- data/spec/rspec/mocks/and_yield_spec.rb +1 -2
- data/spec/rspec/mocks/any_instance_spec.rb +33 -17
- data/spec/rspec/mocks/array_including_matcher_spec.rb +6 -6
- data/spec/rspec/mocks/before_all_spec.rb +132 -0
- data/spec/rspec/mocks/block_return_value_spec.rb +12 -1
- data/spec/rspec/mocks/combining_implementation_instructions_spec.rb +9 -11
- data/spec/rspec/mocks/configuration_spec.rb +14 -1
- data/spec/rspec/mocks/double_spec.rb +867 -24
- data/spec/rspec/mocks/example_methods_spec.rb +13 -0
- data/spec/rspec/mocks/extensions/marshal_spec.rb +17 -17
- data/spec/rspec/mocks/failing_argument_matchers_spec.rb +29 -1
- data/spec/rspec/mocks/hash_excluding_matcher_spec.rb +12 -12
- data/spec/rspec/mocks/hash_including_matcher_spec.rb +21 -17
- data/spec/rspec/mocks/instance_method_stasher_spec.rb +2 -3
- data/spec/rspec/mocks/matchers/have_received_spec.rb +7 -0
- data/spec/rspec/mocks/matchers/receive_message_chain_spec.rb +198 -0
- data/spec/rspec/mocks/matchers/receive_messages_spec.rb +2 -2
- data/spec/rspec/mocks/matchers/receive_spec.rb +19 -6
- data/spec/rspec/mocks/method_signature_verifier_spec.rb +272 -0
- data/spec/rspec/mocks/methods_spec.rb +0 -1
- data/spec/rspec/mocks/multiple_return_value_spec.rb +2 -2
- data/spec/rspec/mocks/mutate_const_spec.rb +24 -1
- data/spec/rspec/mocks/nil_expectation_warning_spec.rb +6 -22
- data/spec/rspec/mocks/null_object_mock_spec.rb +13 -7
- data/spec/rspec/mocks/options_hash_spec.rb +3 -3
- data/spec/rspec/mocks/{partial_mock_spec.rb → partial_double_spec.rb} +5 -2
- data/spec/rspec/mocks/{partial_mock_using_mocks_directly_spec.rb → partial_double_using_mocks_directly_spec.rb} +1 -1
- data/spec/rspec/mocks/passing_argument_matchers_spec.rb +18 -0
- data/spec/rspec/mocks/serialization_spec.rb +1 -0
- data/spec/rspec/mocks/space_spec.rb +218 -7
- data/spec/rspec/mocks/stub_chain_spec.rb +6 -0
- data/spec/rspec/mocks/stub_spec.rb +0 -6
- data/spec/rspec/mocks/syntax_spec.rb +19 -0
- data/spec/rspec/mocks/test_double_spec.rb +0 -1
- data/spec/rspec/mocks/verifying_double_spec.rb +281 -18
- data/spec/rspec/mocks/verifying_message_expecation_spec.rb +7 -6
- data/spec/rspec/mocks_spec.rb +168 -42
- data/spec/spec_helper.rb +34 -22
- metadata +94 -63
- metadata.gz.sig +0 -0
- checksums.yaml +0 -15
- checksums.yaml.gz.sig +0 -2
- data/features/outside_rspec/configuration.feature +0 -60
- data/lib/rspec/mocks/arity_calculator.rb +0 -66
- data/lib/rspec/mocks/errors.rb +0 -12
- data/lib/rspec/mocks/mock.rb +0 -7
- data/lib/rspec/mocks/proxy_for_nil.rb +0 -37
- data/lib/rspec/mocks/stub_chain.rb +0 -51
- data/spec/rspec/mocks/argument_expectation_spec.rb +0 -32
- data/spec/rspec/mocks/arity_calculator_spec.rb +0 -95
- data/spec/rspec/mocks/mock_space_spec.rb +0 -113
- data/spec/rspec/mocks/mock_spec.rb +0 -788
data/lib/rspec/mocks/proxy.rb
CHANGED
@@ -14,7 +14,6 @@ module RSpec
|
|
14
14
|
@order_group = order_group
|
15
15
|
@name = name
|
16
16
|
@error_generator = ErrorGenerator.new(object, name)
|
17
|
-
@expectation_ordering = RSpec::Mocks::space.expectation_ordering
|
18
17
|
@messages_received = []
|
19
18
|
@options = options
|
20
19
|
@null_object = false
|
@@ -47,12 +46,12 @@ module RSpec
|
|
47
46
|
meth_double = method_double_for(method_name)
|
48
47
|
|
49
48
|
if null_object? && !block
|
50
|
-
meth_double.add_default_stub(@error_generator, @
|
49
|
+
meth_double.add_default_stub(@error_generator, @order_group, location, opts) do
|
51
50
|
@object
|
52
51
|
end
|
53
52
|
end
|
54
53
|
|
55
|
-
meth_double.add_expectation @error_generator, @
|
54
|
+
meth_double.add_expectation @error_generator, @order_group, location, opts, &block
|
56
55
|
end
|
57
56
|
|
58
57
|
# @private
|
@@ -66,7 +65,7 @@ module RSpec
|
|
66
65
|
|
67
66
|
meth_double.build_expectation(
|
68
67
|
@error_generator,
|
69
|
-
@
|
68
|
+
@order_group
|
70
69
|
)
|
71
70
|
end
|
72
71
|
|
@@ -103,7 +102,7 @@ module RSpec
|
|
103
102
|
|
104
103
|
# @private
|
105
104
|
def add_stub(location, method_name, opts={}, &implementation)
|
106
|
-
method_double_for(method_name).add_stub @error_generator, @
|
105
|
+
method_double_for(method_name).add_stub @error_generator, @order_group, location, opts, &implementation
|
107
106
|
end
|
108
107
|
|
109
108
|
# @private
|
@@ -124,13 +123,10 @@ module RSpec
|
|
124
123
|
# @private
|
125
124
|
def verify
|
126
125
|
@method_doubles.each_value {|d| d.verify}
|
127
|
-
ensure
|
128
|
-
reset
|
129
126
|
end
|
130
127
|
|
131
128
|
# @private
|
132
129
|
def reset
|
133
|
-
@method_doubles.each_value {|d| d.reset}
|
134
130
|
@messages_received.clear
|
135
131
|
end
|
136
132
|
|
@@ -192,7 +188,13 @@ module RSpec
|
|
192
188
|
@error_generator.raise_missing_default_stub_error(expectation, *args)
|
193
189
|
end
|
194
190
|
|
195
|
-
private
|
191
|
+
# @private
|
192
|
+
def visibility_for(method_name)
|
193
|
+
# This is the default (for test doubles). Subclasses override this.
|
194
|
+
:public
|
195
|
+
end
|
196
|
+
|
197
|
+
private
|
196
198
|
|
197
199
|
def method_double_for(message)
|
198
200
|
@method_doubles[message.to_sym]
|
@@ -231,15 +233,25 @@ module RSpec
|
|
231
233
|
end
|
232
234
|
end
|
233
235
|
|
234
|
-
|
236
|
+
# @private
|
237
|
+
class TestDoubleProxy < Proxy
|
238
|
+
def reset
|
239
|
+
@method_doubles.clear
|
240
|
+
object.__disallow_further_usage!
|
241
|
+
super
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
# @private
|
246
|
+
class PartialDoubleProxy < Proxy
|
235
247
|
def method_handle_for(message)
|
236
248
|
if any_instance_class_recorder_observing_method?(@object.class, message)
|
237
|
-
message = ::RSpec::Mocks.
|
249
|
+
message = ::RSpec::Mocks.space.
|
238
250
|
any_instance_recorder_for(@object.class).
|
239
251
|
build_alias_method_name(message)
|
240
252
|
end
|
241
253
|
|
242
|
-
::RSpec::
|
254
|
+
::RSpec::Support.method_handle_for(@object, message)
|
243
255
|
rescue NameError
|
244
256
|
nil
|
245
257
|
end
|
@@ -256,14 +268,59 @@ module RSpec
|
|
256
268
|
super
|
257
269
|
end
|
258
270
|
|
271
|
+
# @private
|
272
|
+
def visibility_for(method_name)
|
273
|
+
# We fall back to :public because by default we allow undefined methods
|
274
|
+
# to be stubbed, and when we do so, we make them public.
|
275
|
+
MethodReference.method_visibility_for(@object, method_name) || :public
|
276
|
+
end
|
277
|
+
|
278
|
+
def reset
|
279
|
+
@method_doubles.each_value {|d| d.reset}
|
280
|
+
super
|
281
|
+
end
|
282
|
+
|
259
283
|
private
|
260
284
|
|
261
285
|
def any_instance_class_recorder_observing_method?(klass, method_name)
|
262
|
-
return true if ::RSpec::Mocks.any_instance_recorder_for(klass).already_observing?(method_name)
|
286
|
+
return true if ::RSpec::Mocks.space.any_instance_recorder_for(klass).already_observing?(method_name)
|
263
287
|
superklass = klass.superclass
|
264
288
|
return false if superklass.nil?
|
265
289
|
any_instance_class_recorder_observing_method?(superklass, method_name)
|
266
290
|
end
|
267
291
|
end
|
292
|
+
|
293
|
+
# @private
|
294
|
+
class ProxyForNil < PartialDoubleProxy
|
295
|
+
def initialize(order_group)
|
296
|
+
@warn_about_expectations = true
|
297
|
+
super(nil, order_group)
|
298
|
+
end
|
299
|
+
|
300
|
+
attr_accessor :warn_about_expectations
|
301
|
+
alias warn_about_expectations? warn_about_expectations
|
302
|
+
|
303
|
+
def add_message_expectation(location, method_name, opts={}, &block)
|
304
|
+
warn(method_name) if warn_about_expectations?
|
305
|
+
super
|
306
|
+
end
|
307
|
+
|
308
|
+
def add_negative_message_expectation(location, method_name, &implementation)
|
309
|
+
warn(method_name) if warn_about_expectations?
|
310
|
+
super
|
311
|
+
end
|
312
|
+
|
313
|
+
def add_stub(location, method_name, opts={}, &implementation)
|
314
|
+
warn(method_name) if warn_about_expectations?
|
315
|
+
super
|
316
|
+
end
|
317
|
+
|
318
|
+
private
|
319
|
+
|
320
|
+
def warn method_name
|
321
|
+
source = CallerFilter.first_non_rspec_line
|
322
|
+
Kernel.warn("An expectation of :#{method_name} was set on nil. Called from #{source}. Use allow_message_expectations_on_nil to disable warnings.")
|
323
|
+
end
|
324
|
+
end
|
268
325
|
end
|
269
326
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module RSpec
|
2
|
+
module Mocks
|
3
|
+
# @api private
|
4
|
+
#
|
5
|
+
# Provides query methods for ruby features that differ among
|
6
|
+
# implementations.
|
7
|
+
module RubyFeatures
|
8
|
+
def optional_and_splat_args_supported?
|
9
|
+
Method.method_defined?(:parameters)
|
10
|
+
end
|
11
|
+
module_function :optional_and_splat_args_supported?
|
12
|
+
|
13
|
+
def kw_args_supported?
|
14
|
+
RUBY_VERSION >= '2.0.0' && RUBY_ENGINE != 'rbx'
|
15
|
+
end
|
16
|
+
module_function :kw_args_supported?
|
17
|
+
|
18
|
+
def required_kw_args_supported?
|
19
|
+
RUBY_VERSION >= '2.1.0' && RUBY_ENGINE != 'rbx'
|
20
|
+
end
|
21
|
+
module_function :required_kw_args_supported?
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/rspec/mocks/space.rb
CHANGED
@@ -1,44 +1,81 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Mocks
|
3
|
+
# @private
|
4
|
+
# Provides a default space implementation for outside
|
5
|
+
# the scope of an example. Called "root" because it serves
|
6
|
+
# as the root of the space stack.
|
7
|
+
class RootSpace
|
8
|
+
def proxy_for(*args)
|
9
|
+
raise_lifecycle_message
|
10
|
+
end
|
11
|
+
|
12
|
+
def any_instance_recorder_for(*args)
|
13
|
+
raise_lifecycle_message
|
14
|
+
end
|
15
|
+
|
16
|
+
def register_constant_mutator(mutator)
|
17
|
+
raise_lifecycle_message
|
18
|
+
end
|
19
|
+
|
20
|
+
def reset_all
|
21
|
+
end
|
22
|
+
|
23
|
+
def verify_all
|
24
|
+
end
|
25
|
+
|
26
|
+
def registered?(object)
|
27
|
+
false
|
28
|
+
end
|
29
|
+
|
30
|
+
def new_scope
|
31
|
+
Space.new
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def raise_lifecycle_message
|
37
|
+
raise OutsideOfExampleError,
|
38
|
+
"The use of doubles or partial doubles from rspec-mocks outside of the per-test lifecycle is not supported."
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
3
42
|
# @api private
|
4
43
|
class Space
|
5
|
-
attr_reader :proxies, :any_instance_recorders
|
44
|
+
attr_reader :proxies, :any_instance_recorders, :expectation_ordering
|
6
45
|
|
7
46
|
def initialize
|
8
47
|
@proxies = {}
|
9
48
|
@any_instance_recorders = {}
|
49
|
+
@constant_mutators = []
|
50
|
+
@expectation_ordering = OrderGroup.new
|
10
51
|
end
|
11
52
|
|
12
|
-
def
|
13
|
-
|
14
|
-
|
15
|
-
end
|
53
|
+
def new_scope
|
54
|
+
NestedSpace.new(self)
|
55
|
+
end
|
16
56
|
|
17
|
-
|
18
|
-
|
19
|
-
|
57
|
+
def verify_all
|
58
|
+
proxies.each_value { |proxy| proxy.verify }
|
59
|
+
any_instance_recorders.each_value { |recorder| recorder.verify }
|
20
60
|
end
|
21
61
|
|
22
62
|
def reset_all
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
object.reset
|
27
|
-
end
|
63
|
+
proxies.each_value { |proxy| proxy.reset }
|
64
|
+
@constant_mutators.reverse.each { |mut| mut.idempotently_reset }
|
65
|
+
end
|
28
66
|
|
29
|
-
|
30
|
-
|
31
|
-
expectation_ordering.clear
|
67
|
+
def register_constant_mutator(mutator)
|
68
|
+
@constant_mutators << mutator
|
32
69
|
end
|
33
70
|
|
34
|
-
def
|
35
|
-
@
|
71
|
+
def constant_mutator_for(name)
|
72
|
+
@constant_mutators.find { |m| m.full_constant_name == name }
|
36
73
|
end
|
37
74
|
|
38
75
|
def any_instance_recorder_for(klass)
|
39
76
|
id = klass.__id__
|
40
77
|
any_instance_recorders.fetch(id) do
|
41
|
-
|
78
|
+
any_instance_recorder_not_found_for(id, klass)
|
42
79
|
end
|
43
80
|
end
|
44
81
|
|
@@ -52,18 +89,7 @@ module RSpec
|
|
52
89
|
|
53
90
|
def proxy_for(object)
|
54
91
|
id = id_for(object)
|
55
|
-
proxies.fetch(id)
|
56
|
-
proxies[id] = case object
|
57
|
-
when NilClass then ProxyForNil.new(expectation_ordering)
|
58
|
-
when TestDouble then object.__build_mock_proxy(expectation_ordering)
|
59
|
-
else
|
60
|
-
if RSpec::Mocks.configuration.verify_partial_doubles?
|
61
|
-
VerifyingPartialMockProxy.new(object, expectation_ordering)
|
62
|
-
else
|
63
|
-
PartialMockProxy.new(object, expectation_ordering)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
92
|
+
proxies.fetch(id) { proxy_not_found_for(id, object) }
|
67
93
|
end
|
68
94
|
|
69
95
|
alias ensure_registered proxy_for
|
@@ -72,6 +98,25 @@ module RSpec
|
|
72
98
|
proxies.has_key?(id_for object)
|
73
99
|
end
|
74
100
|
|
101
|
+
private
|
102
|
+
|
103
|
+
def proxy_not_found_for(id, object)
|
104
|
+
proxies[id] = case object
|
105
|
+
when NilClass then ProxyForNil.new(@expectation_ordering)
|
106
|
+
when TestDouble then object.__build_mock_proxy(@expectation_ordering)
|
107
|
+
else
|
108
|
+
if RSpec::Mocks.configuration.verify_partial_doubles?
|
109
|
+
VerifyingPartialDoubleProxy.new(object, @expectation_ordering)
|
110
|
+
else
|
111
|
+
PartialDoubleProxy.new(object, @expectation_ordering)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def any_instance_recorder_not_found_for(id, klass)
|
117
|
+
any_instance_recorders[id] = AnyInstance::Recorder.new(klass)
|
118
|
+
end
|
119
|
+
|
75
120
|
if defined?(::BasicObject) && !::BasicObject.method_defined?(:__id__) # for 1.9.2
|
76
121
|
require 'securerandom'
|
77
122
|
|
@@ -91,5 +136,34 @@ module RSpec
|
|
91
136
|
end
|
92
137
|
end
|
93
138
|
end
|
139
|
+
|
140
|
+
class NestedSpace < Space
|
141
|
+
def initialize(parent)
|
142
|
+
@parent = parent
|
143
|
+
super()
|
144
|
+
end
|
145
|
+
|
146
|
+
def proxies_of(klass)
|
147
|
+
super + @parent.proxies_of(klass)
|
148
|
+
end
|
149
|
+
|
150
|
+
def constant_mutator_for(name)
|
151
|
+
super || @parent.constant_mutator_for(name)
|
152
|
+
end
|
153
|
+
|
154
|
+
def registered?(object)
|
155
|
+
super || @parent.registered?(object)
|
156
|
+
end
|
157
|
+
|
158
|
+
private
|
159
|
+
|
160
|
+
def proxy_not_found_for(id, object)
|
161
|
+
@parent.proxies[id] || super
|
162
|
+
end
|
163
|
+
|
164
|
+
def any_instance_recorder_not_found_for(id, klass)
|
165
|
+
@parent.any_instance_recorders[id] || super
|
166
|
+
end
|
167
|
+
end
|
94
168
|
end
|
95
169
|
end
|
@@ -1,3 +1,3 @@
|
|
1
1
|
require 'rspec/mocks'
|
2
|
-
|
3
|
-
RSpec::Mocks.setup
|
2
|
+
include RSpec::Mocks::ExampleMethods
|
3
|
+
RSpec::Mocks.setup
|
data/lib/rspec/mocks/syntax.rb
CHANGED
@@ -10,11 +10,11 @@ module RSpec
|
|
10
10
|
end
|
11
11
|
|
12
12
|
# @api private
|
13
|
-
def self.warn_unless_should_configured(method_name)
|
13
|
+
def self.warn_unless_should_configured(method_name ,replacement = "the new `:expect` syntax or explicitly enable `:should`")
|
14
14
|
if @warn_about_should
|
15
15
|
RSpec.deprecate(
|
16
16
|
"Using `#{method_name}` from rspec-mocks' old `:should` syntax without explicitly enabling the syntax",
|
17
|
-
:replacement =>
|
17
|
+
:replacement => replacement
|
18
18
|
)
|
19
19
|
|
20
20
|
@warn_about_should = false
|
@@ -24,7 +24,7 @@ module RSpec
|
|
24
24
|
# @api private
|
25
25
|
# Enables the should syntax (`dbl.stub`, `dbl.should_receive`, etc).
|
26
26
|
def self.enable_should(syntax_host = default_should_syntax_host)
|
27
|
-
@warn_about_should = false
|
27
|
+
@warn_about_should = false if syntax_host == default_should_syntax_host
|
28
28
|
return if should_enabled?(syntax_host)
|
29
29
|
|
30
30
|
syntax_host.class_exec do
|
@@ -51,7 +51,7 @@ module RSpec
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def unstub(message)
|
54
|
-
::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__)
|
54
|
+
::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__, "`allow(...).to_receive(...).and_call_original` or explicitly enable `:should`")
|
55
55
|
::RSpec::Mocks.space.proxy_for(self).remove_stub(message)
|
56
56
|
end
|
57
57
|
|
@@ -63,7 +63,7 @@ module RSpec
|
|
63
63
|
def as_null_object
|
64
64
|
::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__)
|
65
65
|
@_null_object = true
|
66
|
-
::RSpec::Mocks.proxy_for(self).as_null_object
|
66
|
+
::RSpec::Mocks.space.proxy_for(self).as_null_object
|
67
67
|
end
|
68
68
|
|
69
69
|
def null_object?
|
@@ -73,14 +73,14 @@ module RSpec
|
|
73
73
|
|
74
74
|
def received_message?(message, *args, &block)
|
75
75
|
::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__)
|
76
|
-
::RSpec::Mocks.proxy_for(self).received_message?(message, *args, &block)
|
76
|
+
::RSpec::Mocks.space.proxy_for(self).received_message?(message, *args, &block)
|
77
77
|
end
|
78
78
|
|
79
79
|
unless Class.respond_to? :any_instance
|
80
80
|
Class.class_exec do
|
81
81
|
def any_instance
|
82
82
|
::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__)
|
83
|
-
::RSpec::Mocks.any_instance_recorder_for(self)
|
83
|
+
::RSpec::Mocks.space.any_instance_recorder_for(self)
|
84
84
|
end
|
85
85
|
end
|
86
86
|
end
|
@@ -124,6 +124,10 @@ module RSpec
|
|
124
124
|
matcher
|
125
125
|
end
|
126
126
|
|
127
|
+
def receive_message_chain(*messages, &block)
|
128
|
+
Matchers::ReceiveMessageChain.new(messages, &block)
|
129
|
+
end
|
130
|
+
|
127
131
|
def allow(target)
|
128
132
|
AllowanceTarget.new(target)
|
129
133
|
end
|
@@ -152,6 +156,7 @@ module RSpec
|
|
152
156
|
syntax_host.class_exec do
|
153
157
|
undef receive
|
154
158
|
undef receive_messages
|
159
|
+
undef receive_message_chain
|
155
160
|
undef allow
|
156
161
|
undef expect_any_instance_of
|
157
162
|
undef allow_any_instance_of
|
@@ -368,7 +373,37 @@ module RSpec
|
|
368
373
|
# allow(obj).to receive_messages(:speak => "Hello", :meow => "Meow")
|
369
374
|
#
|
370
375
|
# @note This is only available when you have enabled the `expect` syntax.
|
376
|
+
#
|
377
|
+
# @method receive_message_chain
|
378
|
+
# @overload receive_message_chain(method1, method2)
|
379
|
+
# @overload receive_message_chain("method1.method2")
|
380
|
+
# @overload receive_message_chain(method1, method_to_value_hash)
|
381
|
+
#
|
382
|
+
# stubs/mocks a chain of messages on an object or test double.
|
383
|
+
#
|
384
|
+
# ## Warning:
|
385
|
+
#
|
386
|
+
# Chains can be arbitrarily long, which makes it quite painless to
|
387
|
+
# violate the Law of Demeter in violent ways, so you should consider any
|
388
|
+
# use of `receive_message_chain` a code smell. Even though not all code smells
|
389
|
+
# indicate real problems (think fluent interfaces), `receive_message_chain` still
|
390
|
+
# results in brittle examples. For example, if you write
|
391
|
+
# `foo.receive_message_chain(:bar, :baz => 37)` in a spec and then the
|
392
|
+
# implementation calls `foo.baz.bar`, the stub will not work.
|
393
|
+
#
|
394
|
+
# @example
|
395
|
+
#
|
396
|
+
# allow(double).to receive_message_chain("foo.bar") { :baz }
|
397
|
+
# allow(double).to receive_message_chain(:foo, :bar => :baz)
|
398
|
+
# allow(double).to receive_message_chain(:foo, :bar) { :baz }
|
399
|
+
#
|
400
|
+
# # Given any of ^^ these three forms ^^:
|
401
|
+
# double.foo.bar # => :baz
|
402
|
+
#
|
403
|
+
# # Common use in Rails/ActiveRecord:
|
404
|
+
# allow(Article).to receive_message_chain("recent.published") { [Article.new] }
|
405
|
+
#
|
406
|
+
# @note This is only available when you have enabled the `expect` syntax.
|
371
407
|
end
|
372
408
|
end
|
373
409
|
end
|
374
|
-
|