Permalink
Browse files

Allow modules to be included in custom matchers.

Closes rspec-core #344.
  • Loading branch information...
1 parent 268f8c0 commit a832e96fa1653c26318417c2fcb2799a01e4bea0 @myronmarston myronmarston committed Mar 10, 2011
@@ -309,3 +309,32 @@ Feature: define matcher
| 4 examples, 2 failures |
| expected 9 to be a multiple of 2 |
| expected 9 not to be a multiple of 3 |
+
+ Scenario: include a module with helper methods in the matcher
+ Given a file named "include_module_spec.rb" with:
+ """
+ module MatcherHelpers
+ def is_multiple?(actual, expected)
+ actual % expected == 0
+ end
+ end
+
+ RSpec::Matchers.define :be_a_multiple_of do |expected|
+ include MatcherHelpers
+ match { |actual| is_multiple?(actual, expected) }
+ end
+
+ describe 9 do
+ it { should be_a_multiple_of(3) }
+ it { should_not be_a_multiple_of(4) }
+
+ # deliberate failures
+ it { should be_a_multiple_of(2) }
+ it { should_not be_a_multiple_of(3) }
+ end
+ """
+ When I run "rspec include_module_spec.rb"
+ Then the output should contain all of these:
+ | 4 examples, 2 failures |
+ | expected 9 to be a multiple of 2 |
+ | expected 9 not to be a multiple of 3 |
@@ -51,6 +51,10 @@ def does_not_match?(actual)
!matches?(actual)
end
+ def include(*args)
+ singleton_class.__send__(:include, *args)
+ end
+
def define_method(name, &block) # :nodoc:
singleton_class.__send__(:define_method, name, &block)
end
@@ -1,10 +1,56 @@
require 'spec_helper'
class UnexpectedError < StandardError; end
+module MatcherHelperModule
+ def self.included(base)
+ base.module_eval do
+ def included_method; end
+ end
+ end
+
+ def self.extended(base)
+ base.instance_eval do
+ def extended_method; end
+ end
+ end
+
+ def greeting
+ "Hello, World"
+ end
+end
module RSpec
module Matchers
describe Matcher do
+ context "with an included module" do
+ let(:matcher) do
+ RSpec::Matchers::Matcher.new(:be_a_greeting) do
+ include MatcherHelperModule
+ match { |actual| actual == greeting }
+ end
+ end
+
+ it "has access to the module's methods" do
+ matcher.matches?("Hello, World")
+ end
+
+ it "runs the module's included hook" do
+ matcher.should respond_to(:included_method)
+ end
+
+ it "does not run the module's extended hook" do
+ matcher.should_not respond_to(:extended_method)
+ end
+
+ it 'allows multiple modules to be included at once' do
+ m = RSpec::Matchers::Matcher.new(:multiple_modules) do
+ include Enumerable, Comparable
+ end
+ m.should be_a(Enumerable)
+ m.should be_a(Comparable)
+ end
+ end
+
context "without overrides" do
before(:each) do
@matcher = RSpec::Matchers::Matcher.new(:be_a_multiple_of, 3) do |multiple|

0 comments on commit a832e96

Please sign in to comment.