Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add support for a DSL-defined matcher to define match logic for should

and should_not.
  • Loading branch information...
commit cd5c8cf419d5026f03b9ff87a08e4e6b69ec64d1 1 parent 7624c93
@myronmarston myronmarston authored
View
28 features/matchers/define_matcher.feature
@@ -256,3 +256,31 @@ Feature: define matcher
When I run "rspec scoped_matcher_spec.rb"
Then the output should contain "3 examples, 0 failures"
+
+ Scenario: matcher with separate logic for should and should_not
+ Given a file named "matcher_with_separate_should_not_logic_spec.rb" with:
+ """
+ RSpec::Matchers.define :contain do |*expected|
+ match_for_should do |actual|
+ expected.all? { |e| actual.include?(e) }
+ end
+
+ match_for_should_not do |actual|
+ expected.none? { |e| actual.include?(e) }
+ end
+ end
+
+ describe [1, 2, 3] do
+ it { should contain(1, 2) }
+ it { should_not contain(4, 5, 6) }
+
+ # deliberate failures
+ it { should contain(1, 4) }
+ it { should_not contain(1, 4) }
+ end
+ """
+ When I run "rspec matcher_with_separate_should_not_logic_spec.rb"
+ Then the output should contain all of these:
+ | 4 examples, 2 failures |
+ | expected [1, 2, 3] to contain 1 and 4 |
+ | expected [1, 2, 3] not to contain 1 and 4 |
View
14 lib/rspec/matchers/matcher.rb
@@ -41,10 +41,24 @@ def matches?(actual)
end
end
+ # Used internally by +should_not+
+ def does_not_match?(actual)
+ @actual = actual
+ @match_for_should_not_block ?
+ instance_exec(actual, &@match_for_should_not_block) :
+ !matches?(actual)
+ end
+
# See RSpec::Matchers
def match(&block)
@match_block = block
end
+ alias match_for_should match
+
+ # See RSpec::Matchers
+ def match_for_should_not(&block)
+ @match_for_should_not_block = block
+ end
# See RSpec::Matchers
def match_unless_raises(exception=Exception, &block)
View
29 spec/rspec/matchers/matcher_spec.rb
@@ -29,6 +29,35 @@ module Matchers
end
end
+ context "with separate match logic for should and should not" do
+ let(:matcher) do
+ RSpec::Matchers::Matcher.new(:to_be_composed_of, 7, 11) do |a, b|
+ match_for_should do |actual|
+ actual == a * b
+ end
+
+ match_for_should_not do |actual|
+ actual == a + b
+ end
+ end
+ end
+
+ it "invokes the match_for_should block for #matches?" do
+ matcher.matches?(77).should be_true
+ matcher.matches?(18).should be_false
+ end
+
+ it "invokes the match_for_should_not block for #does_not_match?" do
+ matcher.does_not_match?(77).should be_false
+ matcher.does_not_match?(18).should be_true
+ end
+
+ it "provides a default failure message for #should_not" do
+ matcher.does_not_match?(77)
+ matcher.failure_message_for_should_not.should == "expected 77 not to to be composed of 7 and 11"
+ end
+ end
+
it "is not diffable by default" do
matcher = RSpec::Matchers::Matcher.new(:name) {}
matcher.should_not be_diffable
Please sign in to comment.
Something went wrong with that request. Please try again.