Permalink
Browse files

move include matcher to a class and start to extract a base matcher c…

…lass
  • Loading branch information...
1 parent 14142dc commit fc64e47728356724f9e15f6bd37b1d9169533ab0 @dchelimsky dchelimsky committed Oct 17, 2011
@@ -16,7 +16,7 @@ def self.handle_matcher(actual, matcher, message=nil, &block)
matcher.failure_message
if matcher.respond_to?(:diffable?) && matcher.diffable?
- ::RSpec::Expectations.fail_with message, matcher.expected.first, matcher.actual
+ ::RSpec::Expectations.fail_with message, matcher.expected, matcher.actual
else
::RSpec::Expectations.fail_with message
end
View
@@ -195,11 +195,32 @@ def eq(expected)
def eql(expected)
Eql.new(expected)
end
+
+ # :call-seq:
+ # should include(expected)
+ # should_not include(expected)
+ #
+ # Passes if actual includes expected. This works for
+ # collections and Strings. You can also pass in multiple args
+ # and it will only pass if all args are found in collection.
+ #
+ # == Examples
+ #
+ # [1,2,3].should include(3)
+ # [1,2,3].should include(2,3) #would pass
+ # [1,2,3].should include(2,3,4) #would fail
+ # [1,2,3].should_not include(4)
+ # "spread".should include("read")
+ # "spread".should_not include("red")
+ def include(*expected)
+ Include.new(*expected)
+ end
end
end
require 'rspec/matchers/extensions/instance_eval_with_args'
require 'rspec/matchers/pretty'
+require 'rspec/matchers/base_matcher'
require 'rspec/matchers/matcher'
require 'rspec/matchers/operator_matcher'
require 'rspec/matchers/be'
@@ -0,0 +1,36 @@
+module RSpec
+ module Matchers
+ class BaseMatcher
+ include RSpec::Matchers::Pretty
+
+ attr_reader :actual, :expected
+
+ def initialize(expected)
+ @expected = expected
+ end
+
+ def failure_message_for_should
+ "expected #{actual.inspect} to #{name_to_sentence}#{expected_to_sentence}"
+ end
+
+ def failure_message_for_should_not
+ "expected #{actual.inspect} not to #{name_to_sentence}#{expected_to_sentence}"
+ end
+
+
+ # from matcher.rb
+ def name_to_sentence
+ split_words(name)
+ end
+
+ def expected_to_sentence
+ to_sentence(@expected)
+ end
+
+ def name
+ defined?(@name) ? @name : self.class.name.split("::").last.downcase
+ end
+
+ end
+ end
+end
View
@@ -1,15 +1,7 @@
module RSpec
module Matchers
- class Eq
+ class Eq < BaseMatcher
attr_reader :actual
- def initialize(expected)
- @expected = expected
- end
-
- def expected
- [@expected]
- end
-
def matches?(actual)
@actual = actual
@actual == @expected
View
@@ -1,15 +1,7 @@
module RSpec
module Matchers
- class Eql
+ class Eql < BaseMatcher
attr_reader :actual
- def initialize(expected)
- @expected = expected
- end
-
- def expected
- [@expected]
- end
-
def matches?(actual)
@actual = actual
@actual.eql?(@expected)
@@ -1,53 +1,54 @@
module RSpec
module Matchers
- # :call-seq:
- # should include(expected)
- # should_not include(expected)
+ # Used _internally_ as a base class for matchers that ship with
+ # rspec-expectations.
#
- # Passes if actual includes expected. This works for
- # collections and Strings. You can also pass in multiple args
- # and it will only pass if all args are found in collection.
+ # == Warning
#
- # == Examples
- #
- # [1,2,3].should include(3)
- # [1,2,3].should include(2,3) #would pass
- # [1,2,3].should include(2,3,4) #would fail
- # [1,2,3].should_not include(4)
- # "spread".should include("read")
- # "spread".should_not include("red")
- def include(*expected)
- Matcher.new :include, *expected do |*_expected|
+ # This class is for internal use, and subject to change without notice. We
+ # strongly recommend that you do not base your custom matchers on this
+ # class. If/when this changes, we will announce it and remove this warning.
+ class Include < BaseMatcher
+ def initialize(*expected)
+ super(expected)
+ end
- diffable
+ def matches?(actual)
+ @actual = actual
+ perform_match(:all?, :all?, actual, expected)
+ end
- match_for_should do |actual|
- perform_match(:all?, :all?, actual, _expected)
- end
+ def does_not_match?(actual)
+ @actual = actual
+ perform_match(:none?, :any?, actual, expected)
+ end
- match_for_should_not do |actual|
- perform_match(:none?, :any?, actual, _expected)
- end
+ def diffable?
+ false
+ end
- def perform_match(predicate, hash_predicate, actual, _expected)
- _expected.send(predicate) do |expected|
- if comparing_hash_values?(actual, expected)
- expected.send(hash_predicate) {|k,v| actual[k] == v}
- elsif comparing_hash_keys?(actual, expected)
- actual.has_key?(expected)
- else
- actual.include?(expected)
- end
+ def description
+ "include#{expected_to_sentence}"
+ end
+
+ def perform_match(predicate, hash_predicate, actual, expected)
+ expected.send(predicate) do |expected|
+ if comparing_hash_values?(actual, expected)
+ expected.send(hash_predicate) {|k,v| actual[k] == v}
+ elsif comparing_hash_keys?(actual, expected)
+ actual.has_key?(expected)
+ else
+ actual.include?(expected)
end
end
+ end
- def comparing_hash_keys?(actual, expected)
- actual.is_a?(Hash) && !expected.is_a?(Hash)
- end
+ def comparing_hash_keys?(actual, expected)
+ actual.is_a?(Hash) && !expected.is_a?(Hash)
+ end
- def comparing_hash_values?(actual, expected)
- actual.is_a?(Hash) && expected.is_a?(Hash)
- end
+ def comparing_hash_values?(actual, expected)
+ actual.is_a?(Hash) && expected.is_a?(Hash)
end
end
end
@@ -76,7 +76,7 @@ module Expectations
:diffable? => true,
:failure_message_for_should => "message",
:matches? => false,
- :expected => [1],
+ :expected => 1,
:actual => 2
)
actual = Object.new
@@ -39,6 +39,10 @@
end
describe "should include(with, multiple, args)" do
+ it "has a description" do
+ matcher = include("a")
+ matcher.description.should eq("include \"a\"")
+ end
context "for a string target" do
it "passes if target includes all items" do
"a string".should include("str", "a")

0 comments on commit fc64e47

Please sign in to comment.