rspec-mocks 3.13.8 → 4.0.0.beta1

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.
@@ -5,93 +5,36 @@ module RSpec
5
5
  def initialize(object, method)
6
6
  @object = object
7
7
  @method = method
8
+ # We don't want to create singleton class if it doesn't exist,
9
+ # so we don't use `object.singleton_class`.
8
10
  @klass = (class << object; self; end)
9
11
 
10
12
  @original_method = nil
11
- @method_is_stashed = false
12
13
  end
13
14
 
14
15
  attr_reader :original_method
15
16
 
16
- if RUBY_VERSION.to_f < 1.9
17
- # @private
18
- def method_is_stashed?
19
- @method_is_stashed
20
- end
21
-
22
- # @private
23
- def stash
24
- return if !method_defined_directly_on_klass? || @method_is_stashed
25
-
26
- @klass.__send__(:alias_method, stashed_method_name, @method)
27
- @method_is_stashed = true
28
- end
29
-
30
- # @private
31
- def stashed_method_name
32
- "obfuscated_by_rspec_mocks__#{@method}"
33
- end
34
-
35
- # @private
36
- def restore
37
- return unless @method_is_stashed
38
-
39
- if @klass.__send__(:method_defined?, @method)
40
- @klass.__send__(:undef_method, @method)
41
- end
42
- @klass.__send__(:alias_method, @method, stashed_method_name)
43
- @klass.__send__(:remove_method, stashed_method_name)
44
- @method_is_stashed = false
45
- end
46
- else
47
-
48
- # @private
49
- def method_is_stashed?
50
- !!@original_method
51
- end
52
-
53
- # @private
54
- def stash
55
- return unless method_defined_directly_on_klass?
56
- @original_method ||= ::RSpec::Support.method_handle_for(@object, @method)
57
- @klass.__send__(:undef_method, @method)
58
- end
17
+ # @private
18
+ def method_is_stashed?
19
+ !!@original_method
20
+ end
59
21
 
60
- # @private
61
- def restore
62
- return unless @original_method
22
+ # @private
23
+ def stash
24
+ return unless method_defined_directly_on_klass?
25
+ @original_method ||= ::RSpec::Support.method_handle_for(@object, @method)
26
+ @klass.undef_method(@method)
27
+ end
63
28
 
64
- if @klass.__send__(:method_defined?, @method)
65
- @klass.__send__(:undef_method, @method)
66
- end
29
+ # @private
30
+ def restore
31
+ return unless @original_method
67
32
 
68
- handle_restoration_failures do
69
- @klass.__send__(:define_method, @method, @original_method)
70
- end
33
+ @klass.undef_method(@method) if @klass.method_defined?(@method)
71
34
 
72
- @original_method = nil
73
- end
74
- end
35
+ @klass.define_method(@method, @original_method)
75
36
 
76
- if RUBY_DESCRIPTION.include?('2.0.0p247') || RUBY_DESCRIPTION.include?('2.0.0p195')
77
- # ruby 2.0.0-p247 and 2.0.0-p195 both have a bug that we can't work around :(.
78
- # https://bugs.ruby-lang.org/issues/8686
79
- def handle_restoration_failures
80
- yield
81
- rescue TypeError
82
- RSpec.warn_with(
83
- "RSpec failed to properly restore a partial double (#{@object.inspect}) " \
84
- "to its original state due to a known bug in MRI 2.0.0-p195 & p247 " \
85
- "(https://bugs.ruby-lang.org/issues/8686). This object may remain " \
86
- "screwed up for the rest of this process. Please upgrade to 2.0.0-p353 or above.",
87
- :call_site => nil, :use_spec_location_as_call_site => true
88
- )
89
- end
90
- else
91
- def handle_restoration_failures
92
- # No known reasons for restoration to fail on other rubies.
93
- yield
94
- end
37
+ @original_method = nil
95
38
  end
96
39
 
97
40
  private
@@ -109,37 +52,17 @@ module RSpec
109
52
  def method_owned_by_klass?
110
53
  owner = @klass.instance_method(@method).owner
111
54
 
112
- # On Ruby 2.0.0+ the owner of a method on a class which has been
55
+ # The owner of a method on a class which has been
113
56
  # `prepend`ed may actually be an instance, e.g.
114
57
  # `#<MyClass:0x007fbb94e3cd10>`, rather than the expected `MyClass`.
115
58
  owner = owner.class unless Module === owner
116
59
 
117
- # On some 1.9s (e.g. rubinius) aliased methods
118
- # can report the wrong owner. Example:
119
- # class MyClass
120
- # class << self
121
- # alias alternate_new new
122
- # end
123
- # end
124
- #
125
- # MyClass.owner(:alternate_new) returns `Class` when incorrect,
126
- # but we need to consider the owner to be `MyClass` because
127
- # it is not actually available on `Class` but is on `MyClass`.
128
- # Hence, we verify that the owner actually has the method defined.
129
- # If the given owner does not have the method defined, we assume
130
- # that the method is actually owned by @klass.
131
- #
132
- # On 1.8, aliased methods can also report the wrong owner. Example:
133
- # module M
134
- # def a; end
135
- # module_function :a
136
- # alias b a
137
- # module_function :b
138
- # end
139
- # The owner of M.b is the raw Module object, instead of the expected
140
- # singleton class of the module
141
- return true if RUBY_VERSION < '1.9' && owner == @object
142
- owner == @klass || !(method_defined_on_klass?(owner))
60
+ owner == @klass ||
61
+ # When `extend self` is used, and not under `allow_any_instance_of`
62
+ # nor `expect_any_instance_of`.
63
+ (owner.singleton_class == @klass &&
64
+ !Mocks.space.any_instance_recorder_for(owner, true)) ||
65
+ !(method_defined_on_klass?(owner))
143
66
  end
144
67
  end
145
68
  end
@@ -1,4 +1,4 @@
1
- RSpec::Support.require_rspec_support 'mutex'
1
+ RSpec::Support.require_rspec_support 'reentrant_mutex'
2
2
 
3
3
  module RSpec
4
4
  module Mocks
@@ -415,7 +415,6 @@ module RSpec
415
415
  attr_reader :orig_object
416
416
  attr_writer :expected_received_count, :expected_from, :argument_list_matcher
417
417
  protected :expected_received_count=, :expected_from=, :error_generator=, :implementation=
418
-
419
418
  # @private
420
419
  attr_reader :type
421
420
 
@@ -849,7 +848,7 @@ module RSpec
849
848
 
850
849
  def cannot_modify_further_error
851
850
  CannotModifyFurtherError.new "This method has already been configured " \
852
- "to call the original implementation, and cannot be modified further."
851
+ "to call the original implementation, and cannot be modified further."
853
852
  end
854
853
  end
855
854
  end
@@ -2,9 +2,6 @@ module RSpec
2
2
  module Mocks
3
3
  # @private
4
4
  class MethodDouble
5
- # @private TODO: drop in favor of FrozenError in ruby 2.5+
6
- FROZEN_ERROR_MSG = /can't modify frozen/
7
-
8
5
  # @private
9
6
  attr_reader :method_name, :object, :expectations, :stubs, :method_stasher
10
7
 
@@ -24,8 +21,7 @@ module RSpec
24
21
  def original_implementation_callable
25
22
  # If original method is not present, uses the `method_missing`
26
23
  # handler of the object. This accounts for cases where the user has not
27
- # correctly defined `respond_to?`, and also 1.8 which does not provide
28
- # method handles for missing methods even if `respond_to?` is correct.
24
+ # correctly defined `respond_to?`.
29
25
  @original_implementation_callable ||= original_method || method_missing_block
30
26
  end
31
27
 
@@ -54,6 +50,8 @@ module RSpec
54
50
 
55
51
  # @private
56
52
  def object_singleton_class
53
+ # We can't use @object.singleton_class because this method
54
+ # creates a new singleton class if the object doesn't have one.
57
55
  class << @object; self; end
58
56
  end
59
57
 
@@ -70,8 +68,19 @@ module RSpec
70
68
 
71
69
  save_original_implementation_callable!
72
70
  definition_target.class_exec(self, method_name, @original_visibility || visibility) do |method_double, method_name, visibility|
73
- define_method(method_name) do |*args, &block|
74
- method_double.proxy_method_invoked(self, *args, &block)
71
+ if RUBY_VERSION.to_f > 3 && method_name == :respond_to?
72
+ define_method(method_name) do |*args, &block|
73
+ # This is a work around for a respond_to? check within kernel_inspect
74
+ if caller_locations[0].label == "Kernel#inspect"
75
+ super(*args, &block)
76
+ else
77
+ method_double.proxy_method_invoked(self, *args, &block)
78
+ end
79
+ end
80
+ else
81
+ define_method(method_name) do |*args, &block|
82
+ method_double.proxy_method_invoked(self, *args, &block)
83
+ end
75
84
  end
76
85
  # This can't be `if respond_to?(:ruby2_keywords, true)`,
77
86
  # see https://github.com/rspec/rspec-mocks/pull/1385#issuecomment-755340298
@@ -80,14 +89,8 @@ module RSpec
80
89
  end
81
90
 
82
91
  @method_is_proxied = true
83
- rescue RuntimeError, TypeError => e
84
- # TODO: drop in favor of FrozenError in ruby 2.5+
85
- # RuntimeError (and FrozenError) for ruby 2.x
86
- # TypeError for ruby 1.x
87
- if (defined?(FrozenError) && e.is_a?(FrozenError)) || FROZEN_ERROR_MSG === e.message
88
- raise ArgumentError, "Cannot proxy frozen objects, rspec-mocks relies on proxies for method stubbing and expectations."
89
- end
90
- raise
92
+ rescue FrozenError
93
+ raise ArgumentError, "Cannot proxy frozen objects, rspec-mocks relies on proxies for method stubbing and expectations."
91
94
  end
92
95
 
93
96
  # The implementation of the proxied method. Subclasses may override this
@@ -104,18 +107,15 @@ module RSpec
104
107
  return unless @method_is_proxied
105
108
 
106
109
  remove_method_from_definition_target
107
- @method_stasher.restore if @method_stasher.method_is_stashed?
108
- restore_original_visibility
109
110
 
110
- @method_is_proxied = false
111
- rescue RuntimeError, TypeError => e
112
- # TODO: drop in favor of FrozenError in ruby 2.5+
113
- # RuntimeError (and FrozenError) for ruby 2.x
114
- # TypeError for ruby 1.x
115
- if (defined?(FrozenError) && e.is_a?(FrozenError)) || FROZEN_ERROR_MSG === e.message
116
- return show_frozen_warning
111
+ if @method_stasher.method_is_stashed?
112
+ @method_stasher.restore
113
+ restore_original_visibility
117
114
  end
118
- raise
115
+
116
+ @method_is_proxied = false
117
+ rescue FrozenError
118
+ return show_frozen_warning
119
119
  end
120
120
 
121
121
  # @private
@@ -131,10 +131,7 @@ module RSpec
131
131
 
132
132
  # @private
133
133
  def restore_original_visibility
134
- return unless @original_visibility &&
135
- MethodReference.method_defined_at_any_visibility?(object_singleton_class, @method_name)
136
-
137
- object_singleton_class.__send__(@original_visibility, method_name)
134
+ method_owner.__send__(@original_visibility, @method_name)
138
135
  end
139
136
 
140
137
  # @private
@@ -234,7 +231,9 @@ module RSpec
234
231
  RSpec::Mocks.error_generator.raise_method_not_stubbed_error(method_name)
235
232
  end
236
233
 
237
- # In Ruby 2.0.0 and above prepend will alter the method lookup chain.
234
+ private
235
+
236
+ # Prepend alters the method lookup chain.
238
237
  # We use an object's singleton class to define method doubles upon,
239
238
  # however if the object has had its singleton class (as opposed to
240
239
  # its actual class) prepended too then the the method lookup chain
@@ -244,54 +243,44 @@ module RSpec
244
243
  # This code works around that by providing a mock definition target
245
244
  # that is either the singleton class, or if necessary, a prepended module
246
245
  # of our own.
247
- #
248
- if Support::RubyFeatures.module_prepends_supported?
249
-
250
- private
251
-
252
- # We subclass `Module` in order to be able to easily detect our prepended module.
253
- RSpecPrependedModule = Class.new(Module)
254
246
 
255
- def definition_target
256
- @definition_target ||= usable_rspec_prepended_module || object_singleton_class
257
- end
258
-
259
- def usable_rspec_prepended_module
260
- @proxy.prepended_modules_of_singleton_class.each do |mod|
261
- # If we have one of our modules prepended before one of the user's
262
- # modules that defines the method, use that, since our module's
263
- # definition will take precedence.
264
- return mod if RSpecPrependedModule === mod
265
-
266
- # If we hit a user module with the method defined first,
267
- # we must create a new prepend module, even if one exists later,
268
- # because ours will only take precedence if it comes first.
269
- return new_rspec_prepended_module if mod.method_defined?(method_name)
270
- end
247
+ # We subclass `Module` in order to be able to easily detect our prepended module.
248
+ RSpecPrependedModule = Class.new(Module)
271
249
 
272
- nil
273
- end
250
+ def definition_target
251
+ @definition_target ||= usable_rspec_prepended_module || object_singleton_class
252
+ end
274
253
 
275
- def new_rspec_prepended_module
276
- RSpecPrependedModule.new.tap do |mod|
277
- object_singleton_class.__send__ :prepend, mod
278
- end
254
+ def usable_rspec_prepended_module
255
+ @proxy.prepended_modules_of_singleton_class.each do |mod|
256
+ # If we have one of our modules prepended before one of the user's
257
+ # modules that defines the method, use that, since our module's
258
+ # definition will take precedence.
259
+ return mod if RSpecPrependedModule === mod
260
+
261
+ # If we hit a user module with the method defined first,
262
+ # we must create a new prepend module, even if one exists later,
263
+ # because ours will only take precedence if it comes first.
264
+ return new_rspec_prepended_module if mod.method_defined?(method_name)
279
265
  end
280
266
 
281
- else
282
-
283
- private
267
+ nil
268
+ end
284
269
 
285
- def definition_target
286
- object_singleton_class
270
+ def new_rspec_prepended_module
271
+ RSpecPrependedModule.new.tap do |mod|
272
+ @object.singleton_class.prepend mod
287
273
  end
288
-
289
274
  end
290
275
 
291
- private
276
+ def method_owner
277
+ @method_owner ||=
278
+ # We do this because object.method might be overridden.
279
+ ::RSpec::Support.method_handle_for(object, @method_name).owner
280
+ end
292
281
 
293
282
  def remove_method_from_definition_target
294
- definition_target.__send__(:remove_method, @method_name)
283
+ definition_target.remove_method(@method_name)
295
284
  rescue NameError
296
285
  # This can happen when the method has been monkeyed with by
297
286
  # something outside RSpec. This happens, for example, when
@@ -301,10 +290,11 @@ module RSpec
301
290
  # Note: we could avoid rescuing this by checking
302
291
  # `definition_target.instance_method(@method_name).owner == definition_target`,
303
292
  # saving us from the cost of the expensive exception, but this error is
304
- # extremely rare (it was discovered on 2014-12-30, only happens on
305
- # RUBY_VERSION < 2.0 and our spec suite only hits this condition once),
306
- # so we'd rather avoid the cost of that check for every method double,
307
- # and risk the rare situation where this exception will get raised.
293
+ # extremely rare so we'd rather avoid the cost of that check for every
294
+ # method double, and risk the rare situation where this exception will
295
+ # get raised. This was originally discovered in the core library of older
296
+ # unsupported Rubies, (< 3.0) but could happen in code under test
297
+ # during meta-programming.
308
298
  RSpec.warn_with(
309
299
  "WARNING: RSpec could not fully restore #{@object.inspect}." \
310
300
  "#{@method_name}, possibly because the method has been redefined " \
@@ -1,5 +1,3 @@
1
- RSpec::Support.require_rspec_support 'comparable_version'
2
-
3
1
  module RSpec
4
2
  module Mocks
5
3
  # Represents a method on an object that may or may not be defined.
@@ -94,7 +92,7 @@ module RSpec
94
92
  proxy = RSpec::Mocks.space.proxy_for(object)
95
93
  respond_to = proxy.method_double_if_exists_for_message(:respond_to?)
96
94
 
97
- visible = respond_to && respond_to.original_method.call(method_name) ||
95
+ visible = (respond_to && respond_to.original_method.call(method_name)) ||
98
96
  object.respond_to?(method_name)
99
97
 
100
98
  return :public if visible
@@ -124,20 +122,8 @@ module RSpec
124
122
  # definition of "implemented". However, it's the best we can do.
125
123
  alias method_defined? method_implemented?
126
124
 
127
- # works around the fact that repeated calls for method parameters will
128
- # falsely return empty arrays on JRuby in certain circumstances, this
129
- # is necessary here because we can't dup/clone UnboundMethods.
130
- #
131
- # This is necessary due to a bug in JRuby prior to 1.7.5 fixed in:
132
- # https://github.com/jruby/jruby/commit/99a0613fe29935150d76a9a1ee4cf2b4f63f4a27
133
- if RUBY_PLATFORM == 'java' && RSpec::Support::ComparableVersion.new(JRUBY_VERSION) < '1.7.5'
134
- def find_method(mod)
135
- mod.dup.instance_method(@method_name)
136
- end
137
- else
138
- def find_method(mod)
139
- mod.instance_method(@method_name)
140
- end
125
+ def find_method(mod)
126
+ mod.instance_method(@method_name)
141
127
  end
142
128
 
143
129
  def visibility_from(mod)
@@ -162,6 +148,8 @@ module RSpec
162
148
  end
163
149
 
164
150
  def method_defined?(object)
151
+ # We don't want to create singleton class if it doesn't exist,
152
+ # so we don't use `object.singleton_class`.
165
153
  (class << object; self; end).method_defined?(@method_name)
166
154
  end
167
155
 
@@ -192,16 +180,10 @@ module RSpec
192
180
  uses_class_new?(klass)
193
181
  end
194
182
 
195
- if RUBY_VERSION.to_i >= 3
196
- CLASS_NEW = ::Class.instance_method(:new)
183
+ CLASS_NEW = ::Class.instance_method(:new)
197
184
 
198
- def self.uses_class_new?(klass)
199
- ::RSpec::Support.method_handle_for(klass, :new) == CLASS_NEW.bind(klass)
200
- end
201
- else # Ruby 2's Method#== is too strict
202
- def self.uses_class_new?(klass)
203
- ::RSpec::Support.method_handle_for(klass, :new).owner == ::Class
204
- end
185
+ def self.uses_class_new?(klass)
186
+ ::RSpec::Support.method_handle_for(klass, :new) == CLASS_NEW.bind(klass)
205
187
  end
206
188
 
207
189
  def with_signature
@@ -28,7 +28,7 @@ module RSpec
28
28
  end
29
29
  end
30
30
 
31
- Minitest::Test.send(:include, RSpec::Mocks::MinitestIntegration)
31
+ Minitest::Test.__send__(:include, RSpec::Mocks::MinitestIntegration)
32
32
 
33
33
  if defined?(::Minitest::Expectation)
34
34
  if defined?(::RSpec::Expectations) && ::Minitest::Expectation.method_defined?(:to)
@@ -248,7 +248,6 @@ module RSpec
248
248
  end
249
249
 
250
250
  if Array === @transfer_nested_constants
251
- @transfer_nested_constants = @transfer_nested_constants.map(&:to_s) if RUBY_VERSION == '1.8.7'
252
251
  undefined_constants = @transfer_nested_constants - constants_defined_on(@original_value)
253
252
 
254
253
  if undefined_constants.any?
@@ -27,14 +27,8 @@ module RSpec
27
27
  end
28
28
  end
29
29
 
30
- if Module.new.name.nil?
31
- def self.anonymous_module?(mod)
32
- !name_of(mod)
33
- end
34
- else # 1.8.7
35
- def self.anonymous_module?(mod)
36
- name_of(mod) == ""
37
- end
30
+ def self.anonymous_module?(mod)
31
+ !name_of(mod)
38
32
  end
39
33
  private_class_method :anonymous_module?
40
34
 
@@ -1,5 +1,3 @@
1
- RSpec::Support.require_rspec_support 'reentrant_mutex'
2
-
3
1
  module RSpec
4
2
  module Mocks
5
3
  # @private
@@ -7,7 +5,6 @@ module RSpec
7
5
  def initialize
8
6
  @expectations = []
9
7
  @invocation_order = []
10
- @invocation_order_mutex = Support::Mutex.new
11
8
  @index = 0
12
9
  end
13
10
 
@@ -17,9 +14,7 @@ module RSpec
17
14
  end
18
15
 
19
16
  def invoked(message)
20
- @invocation_order_mutex.synchronize do
21
- @invocation_order << message
22
- end
17
+ @invocation_order << message
23
18
  end
24
19
 
25
20
  # @private
@@ -52,9 +47,7 @@ module RSpec
52
47
 
53
48
  def clear
54
49
  @index = 0
55
- @invocation_order_mutex.synchronize do
56
- @invocation_order.clear
57
- end
50
+ @invocation_order.clear
58
51
  @expectations.clear
59
52
  end
60
53
 
@@ -73,15 +66,11 @@ module RSpec
73
66
  end
74
67
 
75
68
  def invoked_expectations
76
- @invocation_order_mutex.synchronize do
77
- @expectations.select { |e| e.ordered? && @invocation_order.include?(e) }
78
- end
69
+ @expectations.select { |e| e.ordered? && @invocation_order.include?(e) }
79
70
  end
80
71
 
81
72
  def expected_invocations
82
- @invocation_order_mutex.synchronize do
83
- @invocation_order.map { |invocation| expectation_for(invocation) }.compact
84
- end
73
+ @invocation_order.map { |invocation| expectation_for(invocation) }.compact
85
74
  end
86
75
 
87
76
  def expectation_for(message)
@@ -1,4 +1,4 @@
1
- RSpec::Support.require_rspec_support 'mutex'
1
+ RSpec::Support.require_rspec_support "reentrant_mutex"
2
2
 
3
3
  module RSpec
4
4
  module Mocks
@@ -240,20 +240,14 @@ module RSpec
240
240
  :public
241
241
  end
242
242
 
243
- if Support::RubyFeatures.module_prepends_supported?
244
- def self.prepended_modules_of(klass)
245
- ancestors = klass.ancestors
246
-
247
- # `|| 0` is necessary for Ruby 2.0, where the singleton class
248
- # is only in the ancestor list when there are prepended modules.
249
- singleton_index = ancestors.index(klass) || 0
250
-
251
- ancestors[0, singleton_index]
252
- end
243
+ def self.prepended_modules_of(klass)
244
+ ancestors = klass.ancestors
245
+ singleton_index = ancestors.index(klass)
246
+ ancestors[0, singleton_index]
247
+ end
253
248
 
254
- def prepended_modules_of_singleton_class
255
- @prepended_modules_of_singleton_class ||= RSpec::Mocks::Proxy.prepended_modules_of(@object.singleton_class)
256
- end
249
+ def prepended_modules_of_singleton_class
250
+ @prepended_modules_of_singleton_class ||= RSpec::Mocks::Proxy.prepended_modules_of(@object.singleton_class)
257
251
  end
258
252
 
259
253
  # @private
@@ -409,19 +403,6 @@ module RSpec
409
403
 
410
404
  return super unless unbound_method
411
405
  unbound_method.bind(object)
412
- # :nocov:
413
- rescue TypeError
414
- if RUBY_VERSION == '1.8.7'
415
- # In MRI 1.8.7, a singleton method on a class cannot be rebound to its subclass
416
- if unbound_method && unbound_method.owner.ancestors.first != unbound_method.owner
417
- # This is a singleton method; we can't do anything with it
418
- # But we can work around this using a different implementation
419
- double = method_double_from_ancestor_for(message)
420
- return object.method(double.method_stasher.stashed_method_name)
421
- end
422
- end
423
- raise
424
- # :nocov:
425
406
  end
426
407
 
427
408
  protected
@@ -137,6 +137,8 @@ module RSpec
137
137
 
138
138
  # We access the ancestors through the singleton class, to avoid calling
139
139
  # `class` in case `class` has been stubbed.
140
+ # We can't use `object.singleton_class` here, as this method creates
141
+ # a new singleton class for the object if the object doesn't have one.
140
142
  (class << object; ancestors; end).map do |klass|
141
143
  any_instance_recorders[klass.__id__]
142
144
  end.compact
@@ -185,23 +187,8 @@ module RSpec
185
187
  any_instance_recorders[id] = AnyInstance::Recorder.new(klass)
186
188
  end
187
189
 
188
- if defined?(::BasicObject) && !::BasicObject.method_defined?(:__id__) # for 1.9.2
189
- require 'securerandom'
190
-
191
- def id_for(object)
192
- id = object.__id__
193
-
194
- return id if object.equal?(::ObjectSpace._id2ref(id))
195
- # this suggests that object.__id__ is proxying through to some wrapped object
196
-
197
- object.instance_exec do
198
- @__id_for_rspec_mocks_space ||= ::SecureRandom.uuid
199
- end
200
- end
201
- else
202
- def id_for(object)
203
- object.__id__
204
- end
190
+ def id_for(object)
191
+ object.__id__
205
192
  end
206
193
  end
207
194
 
@@ -1,3 +1,5 @@
1
1
  require 'rspec/mocks'
2
+
2
3
  extend RSpec::Mocks::ExampleMethods
4
+
3
5
  RSpec::Mocks.setup
@@ -87,21 +87,23 @@ module RSpec
87
87
  end
88
88
  end
89
89
 
90
+ visibility = proxy.visibility_for(message)
91
+
90
92
  # Defined private and protected methods will still trigger `method_missing`
91
93
  # when called publicly. We want ruby's method visibility error to get raised,
92
94
  # so we simply delegate to `super` in that case.
95
+ # return super if visibility == :private || visibility == :protected
93
96
  # ...well, we would delegate to `super`, but there's a JRuby
94
97
  # bug, so we raise our own visibility error instead:
95
98
  # https://github.com/jruby/jruby/issues/1398
96
- visibility = proxy.visibility_for(message)
99
+ # Only works without this workaround with JRuby 9.2
97
100
  if visibility == :private || visibility == :protected
98
101
  ErrorGenerator.new(self).raise_non_public_error(
99
102
  message, visibility
100
103
  )
101
104
  end
102
105
 
103
- # Required wrapping doubles in an Array on Ruby 1.9.2
104
- raise NoMethodError if [:to_a, :to_ary].include? message
106
+ raise NoMethodError if message == :to_ary || message == :to_a
105
107
  proxy.raise_unexpected_message_error(message, args)
106
108
  end
107
109