Permalink
Browse files

Align respond_to? and method_missing in Matchers generated by DSL.

- Fixes #103.
  • Loading branch information...
1 parent 04e55a8 commit d7db5d0b1f668c4d206434b0a333d8d9b3a77179 @dchelimsky dchelimsky committed Jan 6, 2012
Showing with 39 additions and 13 deletions.
  1. +14 −10 lib/rspec/matchers/matcher.rb
  2. +24 −3 spec/rspec/matchers/dsl_spec.rb
  3. +1 −0 spec/rspec/matchers/method_missing_spec.rb
@@ -171,7 +171,7 @@ def description(&block)
def diffable
@diffable = true
end
-
+
# Convenience for defining methods on this matcher to create a fluent
# interface. The trick about fluent interfaces is that each method must
# return self in order to chain methods together. `chain` handles that
@@ -196,7 +196,7 @@ def chain(method, &block)
self
end
end
-
+
# @api private
# Used internally by objects returns by +should+ and +should_not+.
def diffable?
@@ -212,15 +212,11 @@ def does_not_match?(actual)
!matches?(actual)
end
- private
-
- def include(*args)
- singleton_class.__send__(:include, *args)
+ def respond_to?(method, include_private=false)
+ $matcher_execution_context.respond_to?(method, include_private) || super
end
- def define_method(name, &block)
- singleton_class.__send__(:define_method, name, &block)
- end
+ private
def method_missing(method, *args, &block)
if $matcher_execution_context.respond_to?(method)
@@ -229,7 +225,15 @@ def method_missing(method, *args, &block)
super(method, *args, &block)
end
end
-
+
+ def include(*args)
+ singleton_class.__send__(:include, *args)
+ end
+
+ def define_method(name, &block)
+ singleton_class.__send__(:define_method, name, &block)
+ end
+
def making_declared_methods_public
# Our home-grown instance_exec in ruby 1.8.6 results in any methods
# declared in the block eval'd by instance_exec in the block to which we
@@ -1,8 +1,29 @@
require 'spec_helper'
-module RSpec
- module Matchers
- module DSL
+describe "a matcher defined using the matcher DSL" do
+ def question?
+ :answer
+ end
+
+ it "has access to methods available in the scope of the example" do
+ RSpec::Matchers::define(:ignore) {}
+ ignore.question?.should eq(:answer)
+ end
+
+ it "raises when method is missing from local scope as well as matcher" do
+ RSpec::Matchers::define(:ignore) {}
+ expect { ignore.i_dont_exist }.to raise_error(NameError)
+ end
+
+ describe "#respond_to?" do
+ it "returns true for methods in example scope" do
+ RSpec::Matchers::define(:ignore) {}
+ ignore.should respond_to(:question?)
+ end
+
+ it "returns false for methods not defined in matcher or example scope" do
+ RSpec::Matchers::define(:ignore) {}
+ ignore.should_not respond_to(:i_dont_exist)
end
end
end
@@ -8,6 +8,7 @@
describe "RSpec::Matchers method_missing hook" do
subject { self }
+
it_behaves_like "a well-behaved method_missing hook"
context 'when invoked in a Test::Unit::TestCase' do

0 comments on commit d7db5d0

Please sign in to comment.