rspec-mocks 3.0.0.beta2 → 3.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (145) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/Changelog.md +104 -36
  5. data/README.md +35 -4
  6. data/lib/rspec/mocks.rb +52 -13
  7. data/lib/rspec/mocks/any_instance.rb +10 -0
  8. data/lib/rspec/mocks/any_instance/chain.rb +17 -0
  9. data/lib/rspec/mocks/any_instance/expect_chain_chain.rb +1 -1
  10. data/lib/rspec/mocks/any_instance/expectation_chain.rb +9 -6
  11. data/lib/rspec/mocks/any_instance/message_chains.rb +10 -1
  12. data/lib/rspec/mocks/any_instance/proxy.rb +112 -0
  13. data/lib/rspec/mocks/any_instance/recorder.rb +49 -18
  14. data/lib/rspec/mocks/any_instance/stub_chain.rb +5 -3
  15. data/lib/rspec/mocks/any_instance/stub_chain_chain.rb +1 -1
  16. data/lib/rspec/mocks/argument_list_matcher.rb +5 -3
  17. data/lib/rspec/mocks/argument_matchers.rb +28 -12
  18. data/lib/rspec/mocks/configuration.rb +29 -0
  19. data/lib/rspec/mocks/error_generator.rb +2 -5
  20. data/lib/rspec/mocks/example_methods.rb +122 -13
  21. data/lib/rspec/mocks/instance_method_stasher.rb +26 -2
  22. data/lib/rspec/mocks/marshal_extension.rb +41 -0
  23. data/lib/rspec/mocks/matchers/expectation_customization.rb +20 -0
  24. data/lib/rspec/mocks/matchers/receive.rb +6 -20
  25. data/lib/rspec/mocks/matchers/receive_message_chain.rb +7 -5
  26. data/lib/rspec/mocks/matchers/receive_messages.rb +1 -2
  27. data/lib/rspec/mocks/message_chain.rb +9 -9
  28. data/lib/rspec/mocks/message_expectation.rb +6 -5
  29. data/lib/rspec/mocks/method_double.rb +67 -10
  30. data/lib/rspec/mocks/method_reference.rb +1 -1
  31. data/lib/rspec/mocks/mutate_const.rb +10 -14
  32. data/lib/rspec/mocks/object_reference.rb +7 -4
  33. data/lib/rspec/mocks/proxy.rb +95 -8
  34. data/lib/rspec/mocks/space.rb +58 -9
  35. data/lib/rspec/mocks/syntax.rb +128 -210
  36. data/lib/rspec/mocks/targets.rb +6 -8
  37. data/lib/rspec/mocks/test_double.rb +16 -25
  38. data/lib/rspec/mocks/verifying_double.rb +15 -12
  39. data/lib/rspec/mocks/verifying_message_expecation.rb +3 -3
  40. data/lib/rspec/mocks/verifying_proxy.rb +23 -17
  41. data/lib/rspec/mocks/version.rb +3 -1
  42. metadata +29 -257
  43. metadata.gz.sig +0 -0
  44. data/features/README.md +0 -75
  45. data/features/Scope.md +0 -17
  46. data/features/Upgrade.md +0 -22
  47. data/features/argument_matchers/README.md +0 -27
  48. data/features/argument_matchers/explicit.feature +0 -59
  49. data/features/argument_matchers/general_matchers.feature +0 -85
  50. data/features/argument_matchers/type_matchers.feature +0 -26
  51. data/features/message_expectations/README.md +0 -75
  52. data/features/message_expectations/allow_any_instance_of.feature +0 -26
  53. data/features/message_expectations/any_instance.feature +0 -43
  54. data/features/message_expectations/block_local_expectations.feature.pending +0 -55
  55. data/features/message_expectations/call_original.feature +0 -23
  56. data/features/message_expectations/expect_message_using_expect.feature +0 -107
  57. data/features/message_expectations/expect_message_using_should_receive.feature +0 -118
  58. data/features/message_expectations/message_chains_using_expect.feature +0 -49
  59. data/features/message_expectations/receive_counts.feature +0 -209
  60. data/features/message_expectations/warn_when_expectation_is_set_on_nil.feature +0 -50
  61. data/features/method_stubs/README.md +0 -77
  62. data/features/method_stubs/allow_any_instance_of.feature +0 -136
  63. data/features/method_stubs/as_null_object.feature +0 -40
  64. data/features/method_stubs/receive_message_chain.feature +0 -51
  65. data/features/method_stubs/simple_return_value_with_allow.feature +0 -44
  66. data/features/method_stubs/simple_return_value_with_stub.feature +0 -64
  67. data/features/method_stubs/stub_implementation.feature +0 -48
  68. data/features/method_stubs/to_ary.feature +0 -51
  69. data/features/mutating_constants/README.md +0 -82
  70. data/features/mutating_constants/hiding_defined_constant.feature +0 -64
  71. data/features/mutating_constants/stub_defined_constant.feature +0 -78
  72. data/features/mutating_constants/stub_undefined_constant.feature +0 -50
  73. data/features/outside_rspec/standalone.feature +0 -33
  74. data/features/spies/spy_partial_mock_method.feature +0 -34
  75. data/features/spies/spy_pure_mock_method.feature +0 -76
  76. data/features/spies/spy_unstubbed_method.feature +0 -18
  77. data/features/step_definitions/additional_cli_steps.rb +0 -11
  78. data/features/support/env.rb +0 -22
  79. data/features/support/rubinius.rb +0 -6
  80. data/features/test_frameworks/test_unit.feature +0 -54
  81. data/features/verifying_doubles/README.md +0 -17
  82. data/features/verifying_doubles/class_doubles.feature +0 -73
  83. data/features/verifying_doubles/dynamic_classes.feature +0 -71
  84. data/features/verifying_doubles/instance_doubles.feature +0 -103
  85. data/features/verifying_doubles/object_doubles.feature +0 -65
  86. data/features/verifying_doubles/partial_doubles.feature +0 -34
  87. data/lib/rspec/mocks/extensions/marshal.rb +0 -17
  88. data/lib/rspec/mocks/framework.rb +0 -35
  89. data/lib/rspec/mocks/method_signature_verifier.rb +0 -207
  90. data/lib/rspec/mocks/ruby_features.rb +0 -24
  91. data/spec/rspec/mocks/and_call_original_spec.rb +0 -268
  92. data/spec/rspec/mocks/and_return_spec.rb +0 -23
  93. data/spec/rspec/mocks/and_yield_spec.rb +0 -126
  94. data/spec/rspec/mocks/any_instance/message_chains_spec.rb +0 -41
  95. data/spec/rspec/mocks/any_instance_spec.rb +0 -1045
  96. data/spec/rspec/mocks/array_including_matcher_spec.rb +0 -41
  97. data/spec/rspec/mocks/at_least_spec.rb +0 -123
  98. data/spec/rspec/mocks/at_most_spec.rb +0 -90
  99. data/spec/rspec/mocks/before_all_spec.rb +0 -132
  100. data/spec/rspec/mocks/block_return_value_spec.rb +0 -70
  101. data/spec/rspec/mocks/combining_implementation_instructions_spec.rb +0 -204
  102. data/spec/rspec/mocks/configuration_spec.rb +0 -242
  103. data/spec/rspec/mocks/double_spec.rb +0 -874
  104. data/spec/rspec/mocks/example_methods_spec.rb +0 -13
  105. data/spec/rspec/mocks/extensions/marshal_spec.rb +0 -54
  106. data/spec/rspec/mocks/failing_argument_matchers_spec.rb +0 -184
  107. data/spec/rspec/mocks/hash_excluding_matcher_spec.rb +0 -67
  108. data/spec/rspec/mocks/hash_including_matcher_spec.rb +0 -94
  109. data/spec/rspec/mocks/instance_method_stasher_spec.rb +0 -74
  110. data/spec/rspec/mocks/matchers/have_received_spec.rb +0 -347
  111. data/spec/rspec/mocks/matchers/receive_message_chain_spec.rb +0 -198
  112. data/spec/rspec/mocks/matchers/receive_messages_spec.rb +0 -140
  113. data/spec/rspec/mocks/matchers/receive_spec.rb +0 -418
  114. data/spec/rspec/mocks/method_signature_verifier_spec.rb +0 -272
  115. data/spec/rspec/mocks/methods_spec.rb +0 -26
  116. data/spec/rspec/mocks/mock_expectation_error_spec.rb +0 -22
  117. data/spec/rspec/mocks/mock_ordering_spec.rb +0 -114
  118. data/spec/rspec/mocks/multiple_return_value_spec.rb +0 -132
  119. data/spec/rspec/mocks/mutate_const_spec.rb +0 -542
  120. data/spec/rspec/mocks/nil_expectation_warning_spec.rb +0 -52
  121. data/spec/rspec/mocks/null_object_mock_spec.rb +0 -133
  122. data/spec/rspec/mocks/once_counts_spec.rb +0 -52
  123. data/spec/rspec/mocks/options_hash_spec.rb +0 -35
  124. data/spec/rspec/mocks/order_group_spec.rb +0 -27
  125. data/spec/rspec/mocks/partial_double_spec.rb +0 -308
  126. data/spec/rspec/mocks/partial_double_using_mocks_directly_spec.rb +0 -95
  127. data/spec/rspec/mocks/passing_argument_matchers_spec.rb +0 -145
  128. data/spec/rspec/mocks/precise_counts_spec.rb +0 -68
  129. data/spec/rspec/mocks/record_messages_spec.rb +0 -26
  130. data/spec/rspec/mocks/serialization_spec.rb +0 -90
  131. data/spec/rspec/mocks/space_spec.rb +0 -244
  132. data/spec/rspec/mocks/stash_spec.rb +0 -46
  133. data/spec/rspec/mocks/stub_chain_spec.rb +0 -168
  134. data/spec/rspec/mocks/stub_implementation_spec.rb +0 -81
  135. data/spec/rspec/mocks/stub_spec.rb +0 -327
  136. data/spec/rspec/mocks/stubbed_message_expectations_spec.rb +0 -58
  137. data/spec/rspec/mocks/syntax_agnostic_message_matchers_spec.rb +0 -101
  138. data/spec/rspec/mocks/syntax_spec.rb +0 -19
  139. data/spec/rspec/mocks/test_double_spec.rb +0 -49
  140. data/spec/rspec/mocks/to_ary_spec.rb +0 -54
  141. data/spec/rspec/mocks/twice_counts_spec.rb +0 -66
  142. data/spec/rspec/mocks/verifying_double_spec.rb +0 -590
  143. data/spec/rspec/mocks/verifying_message_expecation_spec.rb +0 -69
  144. data/spec/rspec/mocks_spec.rb +0 -192
  145. data/spec/spec_helper.rb +0 -121
@@ -13,10 +13,18 @@ module RSpec
13
13
  raise_lifecycle_message
14
14
  end
15
15
 
16
+ def any_instance_proxy_for(*args)
17
+ raise_lifecycle_message
18
+ end
19
+
16
20
  def register_constant_mutator(mutator)
17
21
  raise_lifecycle_message
18
22
  end
19
23
 
24
+ def any_instance_recorders_from_ancestry_of(object)
25
+ raise_lifecycle_message
26
+ end
27
+
20
28
  def reset_all
21
29
  end
22
30
 
@@ -39,15 +47,17 @@ module RSpec
39
47
  end
40
48
  end
41
49
 
42
- # @api private
50
+ # @private
43
51
  class Space
44
- attr_reader :proxies, :any_instance_recorders, :expectation_ordering
52
+ attr_reader :proxies, :any_instance_recorders, :proxy_mutex, :any_instance_mutex
45
53
 
46
54
  def initialize
47
55
  @proxies = {}
48
56
  @any_instance_recorders = {}
49
57
  @constant_mutators = []
50
58
  @expectation_ordering = OrderGroup.new
59
+ @proxy_mutex = new_mutex
60
+ @any_instance_mutex = new_mutex
51
61
  end
52
62
 
53
63
  def new_scope
@@ -62,6 +72,8 @@ module RSpec
62
72
  def reset_all
63
73
  proxies.each_value { |proxy| proxy.reset }
64
74
  @constant_mutators.reverse.each { |mut| mut.idempotently_reset }
75
+ any_instance_recorders.each_value { |recorder| recorder.stop_all_observation! }
76
+ any_instance_recorders.clear
65
77
  end
66
78
 
67
79
  def register_constant_mutator(mutator)
@@ -73,14 +85,16 @@ module RSpec
73
85
  end
74
86
 
75
87
  def any_instance_recorder_for(klass)
76
- id = klass.__id__
77
- any_instance_recorders.fetch(id) do
78
- any_instance_recorder_not_found_for(id, klass)
88
+ any_instance_mutex.synchronize do
89
+ id = klass.__id__
90
+ any_instance_recorders.fetch(id) do
91
+ any_instance_recorder_not_found_for(id, klass)
92
+ end
79
93
  end
80
94
  end
81
95
 
82
- def remove_any_instance_recorder_for(klass)
83
- any_instance_recorders.delete(klass.__id__)
96
+ def any_instance_proxy_for(klass)
97
+ AnyInstance::Proxy.new(any_instance_recorder_for(klass), proxies_of(klass))
84
98
  end
85
99
 
86
100
  def proxies_of(klass)
@@ -88,8 +102,10 @@ module RSpec
88
102
  end
89
103
 
90
104
  def proxy_for(object)
91
- id = id_for(object)
92
- proxies.fetch(id) { proxy_not_found_for(id, object) }
105
+ proxy_mutex.synchronize do
106
+ id = id_for(object)
107
+ proxies.fetch(id) { proxy_not_found_for(id, object) }
108
+ end
93
109
  end
94
110
 
95
111
  alias ensure_registered proxy_for
@@ -98,12 +114,44 @@ module RSpec
98
114
  proxies.has_key?(id_for object)
99
115
  end
100
116
 
117
+ def any_instance_recorders_from_ancestry_of(object)
118
+ # Optimization: `any_instance` is a feature we generally
119
+ # recommend not using, so we can often early exit here
120
+ # without doing an O(N) linear search over the number of
121
+ # ancestors in the object's class hierarchy.
122
+ return [] if any_instance_recorders.empty?
123
+
124
+ object.class.ancestors.map do |klass|
125
+ any_instance_recorders[klass.__id__]
126
+ end.compact
127
+ end
128
+
101
129
  private
102
130
 
131
+ # We don't want to depend on the stdlib ourselves, but if the user is
132
+ # using threads then a Mutex will be available to us. If not, we don't
133
+ # need to synchronize anyway.
134
+ def new_mutex
135
+ defined?(::Mutex) ? ::Mutex.new : FakeMutex
136
+ end
137
+
138
+ # @private
139
+ module FakeMutex
140
+ def self.synchronize
141
+ yield
142
+ end
143
+ end
144
+
103
145
  def proxy_not_found_for(id, object)
104
146
  proxies[id] = case object
105
147
  when NilClass then ProxyForNil.new(@expectation_ordering)
106
148
  when TestDouble then object.__build_mock_proxy(@expectation_ordering)
149
+ when Class
150
+ if RSpec::Mocks.configuration.verify_partial_doubles?
151
+ VerifyingPartialClassDoubleProxy.new(self, object, @expectation_ordering)
152
+ else
153
+ PartialClassDoubleProxy.new(self, object, @expectation_ordering)
154
+ end
107
155
  else
108
156
  if RSpec::Mocks.configuration.verify_partial_doubles?
109
157
  VerifyingPartialDoubleProxy.new(object, @expectation_ordering)
@@ -137,6 +185,7 @@ module RSpec
137
185
  end
138
186
  end
139
187
 
188
+ # @private
140
189
  class NestedSpace < Space
141
190
  def initialize(parent)
142
191
  @parent = parent
@@ -4,12 +4,12 @@ module RSpec
4
4
  # Provides methods for enabling and disabling the available syntaxes
5
5
  # provided by rspec-mocks.
6
6
  module Syntax
7
- # @api private
7
+ # @private
8
8
  def self.warn_about_should!
9
9
  @warn_about_should = true
10
10
  end
11
11
 
12
- # @api private
12
+ # @private
13
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(
@@ -30,14 +30,12 @@ module RSpec
30
30
  syntax_host.class_exec do
31
31
  def should_receive(message, opts={}, &block)
32
32
  ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__)
33
- opts[:expected_from] ||= CallerFilter.first_non_rspec_line
34
33
  ::RSpec::Mocks.expect_message(self, message, opts, &block)
35
34
  end
36
35
 
37
36
  def should_not_receive(message, &block)
38
37
  ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__)
39
- opts = {:expected_from => CallerFilter.first_non_rspec_line}
40
- ::RSpec::Mocks.expect_message(self, message, opts, &block).never
38
+ ::RSpec::Mocks.expect_message(self, message, {}, &block).never
41
39
  end
42
40
 
43
41
  def stub(message_or_hash, opts={}, &block)
@@ -45,7 +43,6 @@ module RSpec
45
43
  if ::Hash === message_or_hash
46
44
  message_or_hash.each {|message, value| stub(message).and_return value }
47
45
  else
48
- opts[:expected_from] = CallerFilter.first_non_rspec_line
49
46
  ::RSpec::Mocks.allow_message(self, message_or_hash, opts, &block)
50
47
  end
51
48
  end
@@ -80,7 +77,7 @@ module RSpec
80
77
  Class.class_exec do
81
78
  def any_instance
82
79
  ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__)
83
- ::RSpec::Mocks.space.any_instance_recorder_for(self)
80
+ ::RSpec::Mocks.space.any_instance_proxy_for(self)
84
81
  end
85
82
  end
86
83
  end
@@ -201,209 +198,130 @@ module RSpec
201
198
 
202
199
  ::BasicObject
203
200
  end
204
-
205
- # @method should_receive
206
- # Sets an expectation that this object should receive a message before
207
- # the end of the example.
208
- #
209
- # @example
210
- #
211
- # logger = double('logger')
212
- # thing_that_logs = ThingThatLogs.new(logger)
213
- # logger.should_receive(:log)
214
- # thing_that_logs.do_something_that_logs_a_message
215
- #
216
- # @note This is only available when you have enabled the `should` syntax.
217
-
218
- # @method should_not_receive
219
- # Sets and expectation that this object should _not_ receive a message
220
- # during this example.
221
-
222
- # @method stub
223
- # Tells the object to respond to the message with the specified value.
224
- #
225
- # @example
226
- #
227
- # counter.stub(:count).and_return(37)
228
- # counter.stub(:count => 37)
229
- # counter.stub(:count) { 37 }
230
- #
231
- # @note This is only available when you have enabled the `should` syntax.
232
-
233
- # @method unstub
234
- # Removes a stub. On a double, the object will no longer respond to
235
- # `message`. On a real object, the original method (if it exists) is
236
- # restored.
237
- #
238
- # This is rarely used, but can be useful when a stub is set up during a
239
- # shared `before` hook for the common case, but you want to replace it
240
- # for a special case.
241
- #
242
- # @note This is only available when you have enabled the `should` syntax.
243
-
244
- # @method stub_chain
245
- # @overload stub_chain(method1, method2)
246
- # @overload stub_chain("method1.method2")
247
- # @overload stub_chain(method1, method_to_value_hash)
248
- #
249
- # Stubs a chain of methods.
250
- #
251
- # ## Warning:
252
- #
253
- # Chains can be arbitrarily long, which makes it quite painless to
254
- # violate the Law of Demeter in violent ways, so you should consider any
255
- # use of `stub_chain` a code smell. Even though not all code smells
256
- # indicate real problems (think fluent interfaces), `stub_chain` still
257
- # results in brittle examples. For example, if you write
258
- # `foo.stub_chain(:bar, :baz => 37)` in a spec and then the
259
- # implementation calls `foo.baz.bar`, the stub will not work.
260
- #
261
- # @example
262
- #
263
- # double.stub_chain("foo.bar") { :baz }
264
- # double.stub_chain(:foo, :bar => :baz)
265
- # double.stub_chain(:foo, :bar) { :baz }
266
- #
267
- # # Given any of ^^ these three forms ^^:
268
- # double.foo.bar # => :baz
269
- #
270
- # # Common use in Rails/ActiveRecord:
271
- # Article.stub_chain("recent.published") { [Article.new] }
272
- #
273
- # @note This is only available when you have enabled the `should` syntax.
274
-
275
- # @method as_null_object
276
- # Tells the object to respond to all messages. If specific stub values
277
- # are declared, they'll work as expected. If not, the receiver is
278
- # returned.
279
- #
280
- # @note This is only available when you have enabled the `should` syntax.
281
-
282
- # @method null_object?
283
- # Returns true if this object has received `as_null_object`
284
- #
285
- # @note This is only available when you have enabled the `should` syntax.
286
-
287
- # @method any_instance
288
- # Used to set stubs and message expectations on any instance of a given
289
- # class. Returns a [Recorder](Recorder), which records messages like
290
- # `stub` and `should_receive` for later playback on instances of the
291
- # class.
292
- #
293
- # @example
294
- #
295
- # Car.any_instance.should_receive(:go)
296
- # race = Race.new
297
- # race.cars << Car.new
298
- # race.go # assuming this delegates to all of its cars
299
- # # this example would pass
300
- #
301
- # Account.any_instance.stub(:balance) { Money.new(:USD, 25) }
302
- # Account.new.balance # => Money.new(:USD, 25))
303
- #
304
- # @return [Recorder]
305
- #
306
- # @note This is only available when you have enabled the `should` syntax.
307
-
308
- # @method expect
309
- # Used to wrap an object in preparation for setting a mock expectation
310
- # on it.
311
- #
312
- # @example
313
- #
314
- # expect(obj).to receive(:foo).with(5).and_return(:return_value)
315
- #
316
- # @note This method is usually provided by rspec-expectations, unless
317
- # you are using rspec-mocks w/o rspec-expectations, in which case it
318
- # is only made available if you enable the `expect` syntax.
319
-
320
- # @method allow
321
- # Used to wrap an object in preparation for stubbing a method
322
- # on it.
323
- #
324
- # @example
325
- #
326
- # allow(dbl).to receive(:foo).with(5).and_return(:return_value)
327
- #
328
- # @note This is only available when you have enabled the `expect` syntax.
329
-
330
- # @method expect_any_instance_of
331
- # Used to wrap a class in preparation for setting a mock expectation
332
- # on instances of it.
333
- #
334
- # @example
335
- #
336
- # expect_any_instance_of(MyClass).to receive(:foo)
337
- #
338
- # @note This is only available when you have enabled the `expect` syntax.
339
-
340
- # @method allow_any_instance_of
341
- # Used to wrap a class in preparation for stubbing a method
342
- # on instances of it.
343
- #
344
- # @example
345
- #
346
- # allow_any_instance_of(MyClass).to receive(:foo)
347
- #
348
- # @note This is only available when you have enabled the `expect` syntax.
349
-
350
- # @method receive
351
- # Used to specify a message that you expect or allow an object
352
- # to receive. The object returned by `receive` supports the same
353
- # fluent interface that `should_receive` and `stub` have always
354
- # supported, allowing you to constrain the arguments or number of
355
- # times, and configure how the object should respond to the message.
356
- #
357
- # @example
358
- #
359
- # expect(obj).to receive(:hello).with("world").exactly(3).times
360
- #
361
- # @note This is only available when you have enabled the `expect` syntax.
362
- #
363
- # @method receive_messages
364
- # Shorthand syntax used to setup message(s), and their return value(s),
365
- # that you expect or allow an object to receive. The method takes a hash
366
- # of messages and their respective return values. Unlike with `receive`,
367
- # you cannot apply further customizations using a block or the fluent
368
- # interface.
369
- #
370
- # @example
371
- #
372
- # allow(obj).to receive_messages(:speak => "Hello World")
373
- # allow(obj).to receive_messages(:speak => "Hello", :meow => "Meow")
374
- #
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.
407
201
  end
408
202
  end
409
203
  end
204
+
205
+ # The legacy `:should` syntax adds the following methods directly to
206
+ # `BasicObject` so that they are available off of any object. Note, however,
207
+ # that this syntax does not always play nice with delegate/proxy objects.
208
+ # We recommend you use the non-monkeypatching `:expect` syntax instead.
209
+ # @see Class
210
+ class BasicObject
211
+ # @method should_receive
212
+ # Sets an expectation that this object should receive a message before
213
+ # the end of the example.
214
+ #
215
+ # @example
216
+ #
217
+ # logger = double('logger')
218
+ # thing_that_logs = ThingThatLogs.new(logger)
219
+ # logger.should_receive(:log)
220
+ # thing_that_logs.do_something_that_logs_a_message
221
+ #
222
+ # @note This is only available when you have enabled the `should` syntax.
223
+ # @see RSpec::Mocks::ExampleMethods#expect
224
+
225
+ # @method should_not_receive
226
+ # Sets and expectation that this object should _not_ receive a message
227
+ # during this example.
228
+ # @see RSpec::Mocks::ExampleMethods#expect
229
+
230
+ # @method stub
231
+ # Tells the object to respond to the message with the specified value.
232
+ #
233
+ # @example
234
+ #
235
+ # counter.stub(:count).and_return(37)
236
+ # counter.stub(:count => 37)
237
+ # counter.stub(:count) { 37 }
238
+ #
239
+ # @note This is only available when you have enabled the `should` syntax.
240
+ # @see RSpec::Mocks::ExampleMethods#allow
241
+
242
+ # @method unstub
243
+ # Removes a stub. On a double, the object will no longer respond to
244
+ # `message`. On a real object, the original method (if it exists) is
245
+ # restored.
246
+ #
247
+ # This is rarely used, but can be useful when a stub is set up during a
248
+ # shared `before` hook for the common case, but you want to replace it
249
+ # for a special case.
250
+ #
251
+ # @note This is only available when you have enabled the `should` syntax.
252
+
253
+ # @method stub_chain
254
+ # @overload stub_chain(method1, method2)
255
+ # @overload stub_chain("method1.method2")
256
+ # @overload stub_chain(method1, method_to_value_hash)
257
+ #
258
+ # Stubs a chain of methods.
259
+ #
260
+ # ## Warning:
261
+ #
262
+ # Chains can be arbitrarily long, which makes it quite painless to
263
+ # violate the Law of Demeter in violent ways, so you should consider any
264
+ # use of `stub_chain` a code smell. Even though not all code smells
265
+ # indicate real problems (think fluent interfaces), `stub_chain` still
266
+ # results in brittle examples. For example, if you write
267
+ # `foo.stub_chain(:bar, :baz => 37)` in a spec and then the
268
+ # implementation calls `foo.baz.bar`, the stub will not work.
269
+ #
270
+ # @example
271
+ #
272
+ # double.stub_chain("foo.bar") { :baz }
273
+ # double.stub_chain(:foo, :bar => :baz)
274
+ # double.stub_chain(:foo, :bar) { :baz }
275
+ #
276
+ # # Given any of ^^ these three forms ^^:
277
+ # double.foo.bar # => :baz
278
+ #
279
+ # # Common use in Rails/ActiveRecord:
280
+ # Article.stub_chain("recent.published") { [Article.new] }
281
+ #
282
+ # @note This is only available when you have enabled the `should` syntax.
283
+ # @see RSpec::Mocks::ExampleMethods#receive_message_chain
284
+
285
+ # @method as_null_object
286
+ # Tells the object to respond to all messages. If specific stub values
287
+ # are declared, they'll work as expected. If not, the receiver is
288
+ # returned.
289
+ #
290
+ # @note This is only available when you have enabled the `should` syntax.
291
+
292
+ # @method null_object?
293
+ # Returns true if this object has received `as_null_object`
294
+ #
295
+ # @note This is only available when you have enabled the `should` syntax.
296
+ end
297
+
298
+ # The legacy `:should` syntax adds the `any_instance` to `Class`.
299
+ # We generally recommend you use the newer `:expect` syntax instead,
300
+ # which allows you to stub any instance of a class using
301
+ # `allow_any_instance_of(klass)` or mock any instance using
302
+ # `expect_any_instance_of(klass)`.
303
+ # @see BasicObject
304
+ class Class
305
+ # @method any_instance
306
+ # Used to set stubs and message expectations on any instance of a given
307
+ # class. Returns a [Recorder](Recorder), which records messages like
308
+ # `stub` and `should_receive` for later playback on instances of the
309
+ # class.
310
+ #
311
+ # @example
312
+ #
313
+ # Car.any_instance.should_receive(:go)
314
+ # race = Race.new
315
+ # race.cars << Car.new
316
+ # race.go # assuming this delegates to all of its cars
317
+ # # this example would pass
318
+ #
319
+ # Account.any_instance.stub(:balance) { Money.new(:USD, 25) }
320
+ # Account.new.balance # => Money.new(:USD, 25))
321
+ #
322
+ # @return [Recorder]
323
+ #
324
+ # @note This is only available when you have enabled the `should` syntax.
325
+ # @see RSpec::Mocks::ExampleMethods#expect_any_instance_of
326
+ # @see RSpec::Mocks::ExampleMethods#allow_any_instance_of
327
+ end