Permalink
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!).

- Closes #38.
  • Loading branch information...
1 parent 4a27f1f commit 9fca9ea26ff304db73fdc18bdfa110ee91b0c7f4 @myronmarston myronmarston committed with dchelimsky Oct 22, 2010
Showing with 11 additions and 5 deletions.
  1. +3 −5 lib/rspec/matchers/matcher.rb
  2. +8 −0 spec/rspec/matchers/matcher_spec.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
@@ -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 9fca9ea

Please sign in to comment.