Skip to content
Browse files

Fix matcher chaining to prevent name collisions.

Previously, #chain used #define_method on the class to define an instance method on all instances.  We want it to define the method on only this instance, so we need to delegate to the singleton class instead (which the recently added #define_method does for us!).
  • Loading branch information...
1 parent 32e3f9f commit 9c2971a8cbe4be660bf21b4078acfa0ec22ee10e @myronmarston myronmarston committed with dchelimsky
Showing with 11 additions and 5 deletions.
  1. +3 −5 lib/rspec/matchers/matcher.rb
  2. +8 −0 spec/rspec/matchers/matcher_spec.rb
View
8 lib/rspec/matchers/matcher.rb
@@ -97,11 +97,9 @@ def diffable
# See RSpec::Matchers
def chain(method, &block)
- self.class.class_eval do
- define_method method do |*args|
- block.call(*args)
- self
- end
+ define_method method do |*args|
+ block.call(*args)
+ self
end
end
View
8 spec/rspec/matchers/matcher_spec.rb
@@ -334,6 +334,14 @@ def assert_equal(a,b)
matcher.expecting('value').matches?('other value').should be_false
end
+ it "prevents name collisions on chainable methods from different matchers" do
+ m1 = RSpec::Matchers::Matcher.new(:m1) { chain(:foo) { raise "foo in m1" } }
+ m2 = RSpec::Matchers::Matcher.new(:m2) { chain(:foo) { raise "foo in m2" } }
+
+ expect { m1.foo }.to raise_error("foo in m1")
+ expect { m2.foo }.to raise_error("foo in m2")
+ end
+
context "defined using the dsl" do
def a_method_in_the_example
"method defined in the example"

0 comments on commit 9c2971a

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