rspec-mocks 3.0.4 → 3.12.6

Sign up to get free protection for your applications and to get access to all the features.
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