Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Nest StashedInstanceMethod under RSpec::Mocks.

We shouldn't grab any top level real-estate except for the `RSpec` constant itself.
  • Loading branch information...
commit eb931c1318537a4f06c6c00cbfe761d8e1882a60 1 parent b82e1fe
@myronmarston myronmarston authored
View
99 lib/rspec/mocks/stashed_instance_method.rb
@@ -1,60 +1,65 @@
-# @private
-class StashedInstanceMethod
- def initialize(klass, method)
- @klass = klass
- @method = method
+module RSpec
+ module Mocks
+ # @private
+ class StashedInstanceMethod
+ def initialize(klass, method)
+ @klass = klass
+ @method = method
- @method_is_stashed = false
- end
+ @method_is_stashed = false
+ end
- # @private
- def stash
- return if !method_defined_directly_on_klass? || @method_is_stashed
+ # @private
+ def stash
+ return if !method_defined_directly_on_klass? || @method_is_stashed
- @klass.__send__(:alias_method, stashed_method_name, @method)
- @method_is_stashed = true
- end
+ @klass.__send__(:alias_method, stashed_method_name, @method)
+ @method_is_stashed = true
+ end
- private
+ private
- # @private
- def method_defined_directly_on_klass?
- method_defined_on_klass? && method_owned_by_klass?
- end
+ # @private
+ def method_defined_directly_on_klass?
+ method_defined_on_klass? && method_owned_by_klass?
+ end
- # @private
- def method_defined_on_klass?
- @klass.method_defined?(@method) || @klass.private_method_defined?(@method)
- end
+ # @private
+ def method_defined_on_klass?
+ @klass.method_defined?(@method) || @klass.private_method_defined?(@method)
+ end
- if ::UnboundMethod.method_defined?(:owner)
- # @private
- def method_owned_by_klass?
- @klass.instance_method(@method).owner == @klass
- end
- else
- # @private
- def method_owned_by_klass?
- # On 1.8.6, which does not support Method#owner, we have no choice but
- # to assume it's defined on the klass even if it may be defined on
- # a superclass.
- true
- end
- end
+ if ::UnboundMethod.method_defined?(:owner)
+ # @private
+ def method_owned_by_klass?
+ @klass.instance_method(@method).owner == @klass
+ end
+ else
+ # @private
+ def method_owned_by_klass?
+ # On 1.8.6, which does not support Method#owner, we have no choice but
+ # to assume it's defined on the klass even if it may be defined on
+ # a superclass.
+ true
+ end
+ end
- # @private
- def stashed_method_name
- "obfuscated_by_rspec_mocks__#{@method}"
- end
+ # @private
+ def stashed_method_name
+ "obfuscated_by_rspec_mocks__#{@method}"
+ end
- public
+ public
- # @private
- def restore
- return unless @method_is_stashed
+ # @private
+ def restore
+ return unless @method_is_stashed
- @klass.__send__(:alias_method, @method, stashed_method_name)
- @klass.__send__(:remove_method, stashed_method_name)
- @method_is_stashed = false
+ @klass.__send__(:alias_method, @method, stashed_method_name)
+ @klass.__send__(:remove_method, stashed_method_name)
+ @method_is_stashed = false
+ end
+ end
end
end
+
View
101 spec/rspec/mocks/stashed_instance_method_spec.rb
@@ -1,53 +1,58 @@
require 'spec_helper'
-describe StashedInstanceMethod do
- class ExampleClass
- def hello
- :hello_defined_on_class
+module RSpec
+ module Mocks
+ describe StashedInstanceMethod do
+ class ExampleClass
+ def hello
+ :hello_defined_on_class
+ end
+ end
+
+ def singleton_class_for(obj)
+ class << obj; self; end
+ end
+
+ it "stashes the current implementation of an instance method so it can be temporarily replaced" do
+ obj = Object.new
+ def obj.hello; :hello_defined_on_singleton_class; end;
+
+ stashed_method = StashedInstanceMethod.new(singleton_class_for(obj), :hello)
+ stashed_method.stash
+
+ def obj.hello; :overridden_hello; end
+ expect(obj.hello).to eql :overridden_hello
+
+ stashed_method.restore
+ expect(obj.hello).to eql :hello_defined_on_singleton_class
+ end
+
+ it "stashes private instance methods" do
+ obj = Object.new
+ def obj.hello; :hello_defined_on_singleton_class; end;
+ singleton_class_for(obj).__send__(:private, :hello)
+
+ stashed_method = StashedInstanceMethod.new(singleton_class_for(obj), :hello)
+ stashed_method.stash
+
+ def obj.hello; :overridden_hello; end
+ stashed_method.restore
+ expect(obj.send(:hello)).to eql :hello_defined_on_singleton_class
+ end
+
+ it "only stashes methods directly defined on the given class, not its ancestors" do
+ obj = ExampleClass.new
+
+ stashed_method = StashedInstanceMethod.new(singleton_class_for(obj), :hello)
+ stashed_method.stash
+
+ def obj.hello; :overridden_hello; end;
+ expect(obj.hello).to eql :overridden_hello
+
+ stashed_method.restore
+ expect(obj.hello).to eql :overridden_hello
+ end
end
end
-
- def singleton_class_for(obj)
- class << obj; self; end
- end
-
- it "stashes the current implementation of an instance method so it can be temporarily replaced" do
- obj = Object.new
- def obj.hello; :hello_defined_on_singleton_class; end;
-
- stashed_method = StashedInstanceMethod.new(singleton_class_for(obj), :hello)
- stashed_method.stash
-
- def obj.hello; :overridden_hello; end
- expect(obj.hello).to eql :overridden_hello
-
- stashed_method.restore
- expect(obj.hello).to eql :hello_defined_on_singleton_class
- end
-
- it "stashes private instance methods" do
- obj = Object.new
- def obj.hello; :hello_defined_on_singleton_class; end;
- singleton_class_for(obj).__send__(:private, :hello)
-
- stashed_method = StashedInstanceMethod.new(singleton_class_for(obj), :hello)
- stashed_method.stash
-
- def obj.hello; :overridden_hello; end
- stashed_method.restore
- expect(obj.send(:hello)).to eql :hello_defined_on_singleton_class
- end
-
- it "only stashes methods directly defined on the given class, not its ancestors" do
- obj = ExampleClass.new
-
- stashed_method = StashedInstanceMethod.new(singleton_class_for(obj), :hello)
- stashed_method.stash
-
- def obj.hello; :overridden_hello; end;
- expect(obj.hello).to eql :overridden_hello
-
- stashed_method.restore
- expect(obj.hello).to eql :overridden_hello
- end
end
+

1 comment on commit eb931c1

@alindeman
Collaborator

Thanks.

Please sign in to comment.
Something went wrong with that request. Please try again.