rspec-mocks 3.0.4 → 3.12.6

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.
Files changed (49) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data/.document +1 -1
  4. data/.yardopts +1 -1
  5. data/Changelog.md +512 -2
  6. data/{License.txt → LICENSE.md} +5 -4
  7. data/README.md +113 -30
  8. data/lib/rspec/mocks/any_instance/chain.rb +5 -3
  9. data/lib/rspec/mocks/any_instance/error_generator.rb +31 -0
  10. data/lib/rspec/mocks/any_instance/expect_chain_chain.rb +1 -5
  11. data/lib/rspec/mocks/any_instance/expectation_chain.rb +9 -8
  12. data/lib/rspec/mocks/any_instance/message_chains.rb +7 -8
  13. data/lib/rspec/mocks/any_instance/proxy.rb +14 -5
  14. data/lib/rspec/mocks/any_instance/recorder.rb +61 -31
  15. data/lib/rspec/mocks/any_instance/stub_chain.rb +15 -11
  16. data/lib/rspec/mocks/any_instance/stub_chain_chain.rb +1 -5
  17. data/lib/rspec/mocks/any_instance.rb +1 -0
  18. data/lib/rspec/mocks/argument_list_matcher.rb +55 -10
  19. data/lib/rspec/mocks/argument_matchers.rb +88 -30
  20. data/lib/rspec/mocks/configuration.rb +61 -13
  21. data/lib/rspec/mocks/error_generator.rb +250 -107
  22. data/lib/rspec/mocks/example_methods.rb +151 -28
  23. data/lib/rspec/mocks/instance_method_stasher.rb +17 -6
  24. data/lib/rspec/mocks/matchers/have_received.rb +50 -20
  25. data/lib/rspec/mocks/matchers/receive.rb +39 -11
  26. data/lib/rspec/mocks/matchers/receive_message_chain.rb +22 -7
  27. data/lib/rspec/mocks/matchers/receive_messages.rb +12 -7
  28. data/lib/rspec/mocks/message_chain.rb +3 -7
  29. data/lib/rspec/mocks/message_expectation.rb +466 -307
  30. data/lib/rspec/mocks/method_double.rb +88 -29
  31. data/lib/rspec/mocks/method_reference.rb +85 -25
  32. data/lib/rspec/mocks/minitest_integration.rb +68 -0
  33. data/lib/rspec/mocks/mutate_const.rb +50 -109
  34. data/lib/rspec/mocks/object_reference.rb +89 -32
  35. data/lib/rspec/mocks/order_group.rb +4 -5
  36. data/lib/rspec/mocks/proxy.rb +156 -60
  37. data/lib/rspec/mocks/space.rb +52 -35
  38. data/lib/rspec/mocks/standalone.rb +1 -1
  39. data/lib/rspec/mocks/syntax.rb +26 -30
  40. data/lib/rspec/mocks/targets.rb +55 -28
  41. data/lib/rspec/mocks/test_double.rb +43 -7
  42. data/lib/rspec/mocks/verifying_double.rb +27 -33
  43. data/lib/rspec/mocks/{verifying_message_expecation.rb → verifying_message_expectation.rb} +11 -16
  44. data/lib/rspec/mocks/verifying_proxy.rb +77 -26
  45. data/lib/rspec/mocks/version.rb +1 -1
  46. data/lib/rspec/mocks.rb +8 -1
  47. data.tar.gz.sig +0 -0
  48. metadata +80 -43
  49. metadata.gz.sig +0 -0
@@ -2,29 +2,45 @@ module RSpec
2
2
  module Mocks
3
3
  # @private
4
4
  class Proxy
5
+ # @private
5
6
  SpecificMessage = Struct.new(:object, :message, :args) do
6
7
  def ==(expectation)
7
8
  expectation.orig_object == object && expectation.matches?(message, *args)
8
9
  end
9
10
  end
10
11
 
12
+ unless defined?(Mutex)
13
+ Support.require_rspec_support 'mutex'
14
+ Mutex = Support::Mutex
15
+ end
16
+
11
17
  # @private
12
- def ensure_implemented(*args)
18
+ def ensure_implemented(*_args)
13
19
  # noop for basic proxies, see VerifyingProxy for behaviour.
14
20
  end
15
21
 
16
22
  # @private
17
- def initialize(object, order_group, name=nil, options={})
23
+ def initialize(object, order_group, options={})
24
+ ensure_can_be_proxied!(object)
25
+
18
26
  @object = object
19
27
  @order_group = order_group
20
- @name = name
21
- @error_generator = ErrorGenerator.new(object, name)
28
+ @error_generator = ErrorGenerator.new(object)
22
29
  @messages_received = []
30
+ @messages_received_mutex = Mutex.new
23
31
  @options = options
24
32
  @null_object = false
25
33
  @method_doubles = Hash.new { |h, k| h[k] = MethodDouble.new(@object, k, self) }
26
34
  end
27
35
 
36
+ # @private
37
+ def ensure_can_be_proxied!(object)
38
+ return unless object.is_a?(Symbol)
39
+
40
+ msg = "Cannot proxy frozen objects. Symbols such as #{object} cannot be mocked or stubbed."
41
+ raise ArgumentError, msg
42
+ end
43
+
28
44
  # @private
29
45
  attr_reader :object
30
46
 
@@ -42,12 +58,14 @@ module RSpec
42
58
  end
43
59
 
44
60
  # @private
45
- def original_method_handle_for(message)
61
+ def original_method_handle_for(_message)
46
62
  nil
47
63
  end
48
64
 
65
+ DEFAULT_MESSAGE_EXPECTATION_OPTS = {}.freeze
66
+
49
67
  # @private
50
- def add_message_expectation(method_name, opts={}, &block)
68
+ def add_message_expectation(method_name, opts=DEFAULT_MESSAGE_EXPECTATION_OPTS, &block)
51
69
  location = opts.fetch(:expected_from) { CallerFilter.first_non_rspec_line }
52
70
  meth_double = method_double_for(method_name)
53
71
 
@@ -88,21 +106,30 @@ module RSpec
88
106
  @error_generator.raise_expectation_on_unstubbed_method(expected_method_name)
89
107
  end
90
108
 
91
- @messages_received.each do |(actual_method_name, args, _)|
92
- if expectation.matches?(actual_method_name, *args)
93
- expectation.invoke(nil)
94
- block.call(*args) if block
109
+ @messages_received_mutex.synchronize do
110
+ @messages_received.each do |(actual_method_name, args, received_block)|
111
+ next unless expectation.matches?(actual_method_name, *args)
112
+
113
+ expectation.safe_invoke(nil)
114
+ block.call(*args, &received_block) if block
95
115
  end
96
116
  end
97
-
98
117
  end
99
118
 
100
119
  # @private
101
120
  def check_for_unexpected_arguments(expectation)
102
- @messages_received.each do |(method_name, args, _)|
103
- if expectation.matches_name_but_not_args(method_name, *args)
104
- raise_unexpected_message_args_error(expectation, *args)
121
+ @messages_received_mutex.synchronize do
122
+ return if @messages_received.empty?
123
+
124
+ return if @messages_received.any? { |method_name, args, _| expectation.matches?(method_name, *args) }
125
+
126
+ name_but_not_args, others = @messages_received.partition do |(method_name, args, _)|
127
+ expectation.matches_name_but_not_args(method_name, *args)
105
128
  end
129
+
130
+ return if name_but_not_args.empty? && !others.empty?
131
+
132
+ expectation.raise_unexpected_message_args_error(name_but_not_args.map { |args| args[1] })
106
133
  end
107
134
  end
108
135
 
@@ -129,29 +156,43 @@ module RSpec
129
156
 
130
157
  # @private
131
158
  def verify
132
- @method_doubles.each_value {|d| d.verify}
159
+ @method_doubles.each_value { |d| d.verify }
133
160
  end
134
161
 
135
162
  # @private
136
163
  def reset
137
- @messages_received.clear
164
+ @messages_received_mutex.synchronize do
165
+ @messages_received.clear
166
+ end
138
167
  end
139
168
 
140
169
  # @private
141
170
  def received_message?(method_name, *args, &block)
142
- @messages_received.any? {|array| array == [method_name, args, block]}
171
+ @messages_received_mutex.synchronize do
172
+ @messages_received.any? { |array| array == [method_name, args, block] }
173
+ end
174
+ end
175
+
176
+ # @private
177
+ def messages_arg_list
178
+ @messages_received_mutex.synchronize do
179
+ @messages_received.map { |_, args, _| args }
180
+ end
143
181
  end
144
182
 
145
183
  # @private
146
184
  def has_negative_expectation?(message)
147
- method_double_for(message).expectations.detect {|expectation| expectation.negative_expectation_for?(message)}
185
+ method_double_for(message).expectations.find { |expectation| expectation.negative_expectation_for?(message) }
148
186
  end
149
187
 
150
188
  # @private
151
189
  def record_message_received(message, *args, &block)
152
190
  @order_group.invoked SpecificMessage.new(object, message, args)
153
- @messages_received << [message, args, block]
191
+ @messages_received_mutex.synchronize do
192
+ @messages_received << [message, args, block]
193
+ end
154
194
  end
195
+ ruby2_keywords :record_message_received if respond_to?(:ruby2_keywords, true)
155
196
 
156
197
  # @private
157
198
  def message_received(message, *args, &block)
@@ -162,57 +203,67 @@ module RSpec
162
203
 
163
204
  if (stub && expectation && expectation.called_max_times?) || (stub && !expectation)
164
205
  expectation.increase_actual_received_count! if expectation && expectation.actual_received_count_matters?
165
- if expectation = find_almost_matching_expectation(message, *args)
206
+ if (expectation = find_almost_matching_expectation(message, *args))
166
207
  expectation.advise(*args) unless expectation.expected_messages_received?
167
208
  end
168
209
  stub.invoke(nil, *args, &block)
169
210
  elsif expectation
211
+ expectation.unadvise(messages_arg_list)
170
212
  expectation.invoke(stub, *args, &block)
171
- elsif expectation = find_almost_matching_expectation(message, *args)
213
+ elsif (expectation = find_almost_matching_expectation(message, *args))
172
214
  expectation.advise(*args) if null_object? unless expectation.expected_messages_received?
173
- raise_unexpected_message_args_error(expectation, *args) unless (has_negative_expectation?(message) or null_object?)
174
- elsif stub = find_almost_matching_stub(message, *args)
215
+
216
+ if null_object? || !has_negative_expectation?(message)
217
+ expectation.raise_unexpected_message_args_error([args])
218
+ end
219
+ elsif (stub = find_almost_matching_stub(message, *args))
175
220
  stub.advise(*args)
176
- raise_missing_default_stub_error(stub, *args)
221
+ raise_missing_default_stub_error(stub, [args])
177
222
  elsif Class === @object
178
223
  @object.superclass.__send__(message, *args, &block)
179
224
  else
180
225
  @object.__send__(:method_missing, message, *args, &block)
181
226
  end
182
227
  end
228
+ ruby2_keywords :message_received if respond_to?(:ruby2_keywords, true)
183
229
 
184
230
  # @private
185
- def raise_unexpected_message_error(method_name, *args)
186
- @error_generator.raise_unexpected_message_error method_name, *args
231
+ def raise_unexpected_message_error(method_name, args)
232
+ @error_generator.raise_unexpected_message_error method_name, args
187
233
  end
188
234
 
189
235
  # @private
190
- def raise_unexpected_message_args_error(expectation, *args)
191
- @error_generator.raise_unexpected_message_args_error(expectation, *args)
236
+ def raise_missing_default_stub_error(expectation, args_for_multiple_calls)
237
+ @error_generator.raise_missing_default_stub_error(expectation, args_for_multiple_calls)
192
238
  end
193
239
 
194
240
  # @private
195
- def raise_missing_default_stub_error(expectation, *args)
196
- @error_generator.raise_missing_default_stub_error(expectation, *args)
197
- end
198
-
199
- # @private
200
- def visibility_for(method_name)
241
+ def visibility_for(_method_name)
201
242
  # This is the default (for test doubles). Subclasses override this.
202
243
  :public
203
244
  end
204
245
 
205
246
  if Support::RubyFeatures.module_prepends_supported?
247
+ def self.prepended_modules_of(klass)
248
+ ancestors = klass.ancestors
249
+
250
+ # `|| 0` is necessary for Ruby 2.0, where the singleton class
251
+ # is only in the ancestor list when there are prepended modules.
252
+ singleton_index = ancestors.index(klass) || 0
253
+
254
+ ancestors[0, singleton_index]
255
+ end
256
+
206
257
  def prepended_modules_of_singleton_class
207
- @prepended_modules_of_singleton_class ||= begin
208
- singleton_class = @object.singleton_class
209
- singleton_class.ancestors.take_while do |mod|
210
- !(Class === mod || @object.equal?(mod))
211
- end
212
- end
258
+ @prepended_modules_of_singleton_class ||= RSpec::Mocks::Proxy.prepended_modules_of(@object.singleton_class)
213
259
  end
214
260
  end
215
261
 
262
+ # @private
263
+ def method_double_if_exists_for_message(message)
264
+ method_double_for(message) if @method_doubles.key?(message.to_sym)
265
+ end
266
+
216
267
  private
217
268
 
218
269
  def method_double_for(message)
@@ -224,12 +275,14 @@ module RSpec
224
275
  expectation.matches?(method_name, *args)
225
276
  end
226
277
  end
278
+ ruby2_keywords :find_matching_expectation if respond_to?(:ruby2_keywords, true)
227
279
 
228
280
  def find_almost_matching_expectation(method_name, *args)
229
281
  find_best_matching_expectation_for(method_name) do |expectation|
230
282
  expectation.matches_name_but_not_args(method_name, *args)
231
283
  end
232
284
  end
285
+ ruby2_keywords :find_almost_matching_expectation if respond_to?(:ruby2_keywords, true)
233
286
 
234
287
  def find_best_matching_expectation_for(method_name)
235
288
  first_match = nil
@@ -244,12 +297,14 @@ module RSpec
244
297
  end
245
298
 
246
299
  def find_matching_method_stub(method_name, *args)
247
- method_double_for(method_name).stubs.find {|stub| stub.matches?(method_name, *args)}
300
+ method_double_for(method_name).stubs.find { |stub| stub.matches?(method_name, *args) }
248
301
  end
302
+ ruby2_keywords :find_matching_method_stub if respond_to?(:ruby2_keywords, true)
249
303
 
250
304
  def find_almost_matching_stub(method_name, *args)
251
- method_double_for(method_name).stubs.find {|stub| stub.matches_name_but_not_args(method_name, *args)}
305
+ method_double_for(method_name).stubs.find { |stub| stub.matches_name_but_not_args(method_name, *args) }
252
306
  end
307
+ ruby2_keywords :find_almost_matching_stub if respond_to?(:ruby2_keywords, true)
253
308
  end
254
309
 
255
310
  # @private
@@ -295,7 +350,7 @@ module RSpec
295
350
  end
296
351
 
297
352
  def reset
298
- @method_doubles.each_value {|d| d.reset}
353
+ @method_doubles.each_value { |d| d.reset }
299
354
  super
300
355
  end
301
356
 
@@ -305,6 +360,7 @@ module RSpec
305
360
  end
306
361
  super
307
362
  end
363
+ ruby2_keywords :message_received if respond_to?(:ruby2_keywords, true)
308
364
 
309
365
  private
310
366
 
@@ -356,27 +412,43 @@ module RSpec
356
412
 
357
413
  return super unless unbound_method
358
414
  unbound_method.bind(object)
415
+ # :nocov:
416
+ rescue TypeError
417
+ if RUBY_VERSION == '1.8.7'
418
+ # In MRI 1.8.7, a singleton method on a class cannot be rebound to its subclass
419
+ if unbound_method && unbound_method.owner.ancestors.first != unbound_method.owner
420
+ # This is a singleton method; we can't do anything with it
421
+ # But we can work around this using a different implementation
422
+ double = method_double_from_ancestor_for(message)
423
+ return object.method(double.method_stasher.stashed_method_name)
424
+ end
425
+ end
426
+ raise
427
+ # :nocov:
359
428
  end
360
429
 
361
430
  protected
362
431
 
363
432
  def original_unbound_method_handle_from_ancestor_for(message)
364
- method_double = @method_doubles.fetch(message) do
433
+ double = method_double_from_ancestor_for(message)
434
+ double && double.original_method.unbind
435
+ end
436
+
437
+ def method_double_from_ancestor_for(message)
438
+ @method_doubles.fetch(message) do
365
439
  # The fact that there is no method double for this message indicates
366
440
  # that it has not been redefined by rspec-mocks. We need to continue
367
441
  # looking up the ancestor chain.
368
442
  return superclass_proxy &&
369
- superclass_proxy.original_unbound_method_handle_from_ancestor_for(message)
443
+ superclass_proxy.method_double_from_ancestor_for(message)
370
444
  end
371
-
372
- method_double.original_method.unbind
373
445
  end
374
446
 
375
447
  def superclass_proxy
376
448
  return @superclass_proxy if defined?(@superclass_proxy)
377
449
 
378
450
  if (superclass = object.superclass)
379
- @superclass_proxy = @source_space.proxy_for(superclass)
451
+ @superclass_proxy = @source_space.superclass_proxy_for(superclass)
380
452
  else
381
453
  @superclass_proxy = nil
382
454
  end
@@ -391,33 +463,57 @@ module RSpec
391
463
  # @private
392
464
  class ProxyForNil < PartialDoubleProxy
393
465
  def initialize(order_group)
394
- @warn_about_expectations = true
466
+ set_expectation_behavior
395
467
  super(nil, order_group)
396
468
  end
397
469
 
470
+ attr_accessor :disallow_expectations
398
471
  attr_accessor :warn_about_expectations
399
- alias warn_about_expectations? warn_about_expectations
400
472
 
401
473
  def add_message_expectation(method_name, opts={}, &block)
402
- warn(method_name) if warn_about_expectations?
403
- super
404
- end
405
-
406
- def add_negative_message_expectation(location, method_name, &implementation)
407
- warn(method_name) if warn_about_expectations?
474
+ warn_or_raise!(method_name)
408
475
  super
409
476
  end
410
477
 
411
478
  def add_stub(method_name, opts={}, &implementation)
412
- warn(method_name) if warn_about_expectations?
479
+ warn_or_raise!(method_name)
413
480
  super
414
481
  end
415
482
 
416
483
  private
417
484
 
418
- def warn method_name
419
- source = CallerFilter.first_non_rspec_line
420
- Kernel.warn("An expectation of :#{method_name} was set on nil. Called from #{source}. Use allow_message_expectations_on_nil to disable warnings.")
485
+ def set_expectation_behavior
486
+ case RSpec::Mocks.configuration.allow_message_expectations_on_nil
487
+ when false
488
+ @warn_about_expectations = false
489
+ @disallow_expectations = true
490
+ when true
491
+ @warn_about_expectations = false
492
+ @disallow_expectations = false
493
+ else
494
+ @warn_about_expectations = true
495
+ @disallow_expectations = false
496
+ end
497
+ end
498
+
499
+ def warn_or_raise!(method_name)
500
+ # This method intentionally swallows the message when
501
+ # neither disallow_expectations nor warn_about_expectations
502
+ # are set to true.
503
+ if disallow_expectations
504
+ raise_error(method_name)
505
+ elsif warn_about_expectations
506
+ warn(method_name)
507
+ end
508
+ end
509
+
510
+ def warn(method_name)
511
+ warning_msg = @error_generator.expectation_on_nil_message(method_name)
512
+ RSpec.warning(warning_msg)
513
+ end
514
+
515
+ def raise_error(method_name)
516
+ @error_generator.raise_expectation_on_nil_error(method_name)
421
517
  end
422
518
  end
423
519
  end
@@ -1,3 +1,5 @@
1
+ RSpec::Support.require_rspec_support 'reentrant_mutex'
2
+
1
3
  module RSpec
2
4
  module Mocks
3
5
  # @private
@@ -5,23 +7,23 @@ module RSpec
5
7
  # the scope of an example. Called "root" because it serves
6
8
  # as the root of the space stack.
7
9
  class RootSpace
8
- def proxy_for(*args)
10
+ def proxy_for(*_args)
9
11
  raise_lifecycle_message
10
12
  end
11
13
 
12
- def any_instance_recorder_for(*args)
14
+ def any_instance_recorder_for(*_args)
13
15
  raise_lifecycle_message
14
16
  end
15
17
 
16
- def any_instance_proxy_for(*args)
18
+ def any_instance_proxy_for(*_args)
17
19
  raise_lifecycle_message
18
20
  end
19
21
 
20
- def register_constant_mutator(mutator)
22
+ def register_constant_mutator(_mutator)
21
23
  raise_lifecycle_message
22
24
  end
23
25
 
24
- def any_instance_recorders_from_ancestry_of(object)
26
+ def any_instance_recorders_from_ancestry_of(_object)
25
27
  raise_lifecycle_message
26
28
  end
27
29
 
@@ -31,10 +33,14 @@ module RSpec
31
33
  def verify_all
32
34
  end
33
35
 
34
- def registered?(object)
36
+ def registered?(_object)
35
37
  false
36
38
  end
37
39
 
40
+ def superclass_proxy_for(*_args)
41
+ raise_lifecycle_message
42
+ end
43
+
38
44
  def new_scope
39
45
  Space.new
40
46
  end
@@ -43,7 +49,7 @@ module RSpec
43
49
 
44
50
  def raise_lifecycle_message
45
51
  raise OutsideOfExampleError,
46
- "The use of doubles or partial doubles from rspec-mocks outside of the per-test lifecycle is not supported."
52
+ "The use of doubles or partial doubles from rspec-mocks outside of the per-test lifecycle is not supported."
47
53
  end
48
54
  end
49
55
 
@@ -71,9 +77,9 @@ module RSpec
71
77
 
72
78
  def reset_all
73
79
  proxies.each_value { |proxy| proxy.reset }
74
- @constant_mutators.reverse.each { |mut| mut.idempotently_reset }
75
80
  any_instance_recorders.each_value { |recorder| recorder.stop_all_observation! }
76
81
  any_instance_recorders.clear
82
+ @constant_mutators.reverse.each { |mut| mut.idempotently_reset }
77
83
  end
78
84
 
79
85
  def register_constant_mutator(mutator)
@@ -84,7 +90,7 @@ module RSpec
84
90
  @constant_mutators.find { |m| m.full_constant_name == name }
85
91
  end
86
92
 
87
- def any_instance_recorder_for(klass, only_return_existing = false)
93
+ def any_instance_recorder_for(klass, only_return_existing=false)
88
94
  any_instance_mutex.synchronize do
89
95
  id = klass.__id__
90
96
  any_instance_recorders.fetch(id) do
@@ -109,10 +115,17 @@ module RSpec
109
115
  end
110
116
  end
111
117
 
118
+ def superclass_proxy_for(klass)
119
+ proxy_mutex.synchronize do
120
+ id = id_for(klass)
121
+ proxies.fetch(id) { superclass_proxy_not_found_for(id, klass) }
122
+ end
123
+ end
124
+
112
125
  alias ensure_registered proxy_for
113
126
 
114
127
  def registered?(object)
115
- proxies.has_key?(id_for object)
128
+ proxies.key?(id_for object)
116
129
  end
117
130
 
118
131
  def any_instance_recorders_from_ancestry_of(object)
@@ -131,36 +144,40 @@ module RSpec
131
144
 
132
145
  private
133
146
 
134
- # We don't want to depend on the stdlib ourselves, but if the user is
135
- # using threads then a Mutex will be available to us. If not, we don't
136
- # need to synchronize anyway.
137
147
  def new_mutex
138
- defined?(::Mutex) ? ::Mutex.new : FakeMutex
139
- end
140
-
141
- # @private
142
- module FakeMutex
143
- def self.synchronize
144
- yield
145
- end
148
+ Support::ReentrantMutex.new
146
149
  end
147
150
 
148
151
  def proxy_not_found_for(id, object)
149
152
  proxies[id] = case object
150
- when NilClass then ProxyForNil.new(@expectation_ordering)
151
- when TestDouble then object.__build_mock_proxy_unless_expired(@expectation_ordering)
152
- when Class
153
- if RSpec::Mocks.configuration.verify_partial_doubles?
154
- VerifyingPartialClassDoubleProxy.new(self, object, @expectation_ordering)
155
- else
156
- PartialClassDoubleProxy.new(self, object, @expectation_ordering)
157
- end
158
- else
159
- if RSpec::Mocks.configuration.verify_partial_doubles?
160
- VerifyingPartialDoubleProxy.new(object, @expectation_ordering)
161
- else
162
- PartialDoubleProxy.new(object, @expectation_ordering)
163
- end
153
+ when NilClass then ProxyForNil.new(@expectation_ordering)
154
+ when TestDouble then object.__build_mock_proxy_unless_expired(@expectation_ordering)
155
+ when Class
156
+ class_proxy_with_callback_verification_strategy(object, CallbackInvocationStrategy.new)
157
+ else
158
+ if RSpec::Mocks.configuration.verify_partial_doubles?
159
+ VerifyingPartialDoubleProxy.new(object, @expectation_ordering)
160
+ else
161
+ PartialDoubleProxy.new(object, @expectation_ordering)
162
+ end
163
+ end
164
+ end
165
+
166
+ def superclass_proxy_not_found_for(id, object)
167
+ raise "superclass_proxy_not_found_for called with something that is not a class" unless Class === object
168
+ proxies[id] = class_proxy_with_callback_verification_strategy(object, NoCallbackInvocationStrategy.new)
169
+ end
170
+
171
+ def class_proxy_with_callback_verification_strategy(object, strategy)
172
+ if RSpec::Mocks.configuration.verify_partial_doubles?
173
+ VerifyingPartialClassDoubleProxy.new(
174
+ self,
175
+ object,
176
+ @expectation_ordering,
177
+ strategy
178
+ )
179
+ else
180
+ PartialClassDoubleProxy.new(self, object, @expectation_ordering)
164
181
  end
165
182
  end
166
183
 
@@ -1,3 +1,3 @@
1
1
  require 'rspec/mocks'
2
- include RSpec::Mocks::ExampleMethods
2
+ extend RSpec::Mocks::ExampleMethods
3
3
  RSpec::Mocks.setup