rspec-mocks 3.0.0.beta1 → 3.0.0.beta2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
-
|