Permalink
Browse files

Fixed the include matcher.

- Make it properly fail for the should_not case when given multiple values.
- Reorganized specs and added missing coverage.
- Added include matcher cuke.
  • Loading branch information...
1 parent cd5c8cf commit ca24fa3ed6b0b79a2eec7dc220b2ec55725913ec @myronmarston myronmarston committed Oct 7, 2010
Showing with 465 additions and 70 deletions.
  1. +136 −0 features/matchers/include.feature
  2. +11 −5 lib/rspec/matchers/include.rb
  3. +318 −65 spec/rspec/matchers/include_spec.rb
@@ -0,0 +1,136 @@
+Feature: include matcher
+
+ rspec-expectations provides an include matcher for testing if an object includes
+ one or more expected objects. This works on any object that responds to #include?
+ (such as a string or array):
+
+ "a string".should include("a")
+ "a string".should include("str")
+ "a string".should include("str", "g")
+ "a string".should_not include("foo")
+
+ [1, 2].should include(1)
+ [1, 2].should include(1, 2)
+ [1, 2].should_not include(17)
+
+ The matcher also provides flexible handling for hashes:
+
+ {:a => 1, :b => 2}.should include(:a)
+ {:a => 1, :b => 2}.should include(:a, :b)
+ {:a => 1, :b => 2}.should include(:a => 1)
+ {:a => 1, :b => 2}.should include(:b => 2, :a => 1)
+ {:a => 1, :b => 2}.should_not include(:c)
+ {:a => 1, :b => 2}.should_not include(:a => 2)
+ {:a => 1, :b => 2}.should_not include(:c => 3)
+
+ Scenario: array usage
+ Given a file named "array_include_matcher_spec.rb" with:
+ """
+ describe [1, 3, 7] do
+ it { should include(1) }
+ it { should include(3) }
+ it { should include(7) }
+ it { should include(1, 7) }
+ it { should include(1, 3, 7) }
+ it { should_not include(17) }
+ it { should_not include(43, 100) }
+
+ # deliberate failures
+ it { should include(4) }
+ it { should_not include(1) }
+ it { should_not include(3) }
+ it { should_not include(7) }
+ it { should_not include(1, 3, 7) }
+
+ # both of these should fail since it includes 1 but not 9
+ it { should include(1, 9) }
+ it { should_not include(1, 9) }
+ end
+ """
+ When I run "rspec array_include_matcher_spec.rb"
+ Then the output should contain all of these:
+ | 14 examples, 7 failures |
+ | expected [1, 3, 7] to include 4 |
+ | expected [1, 3, 7] not to include 1 |
+ | expected [1, 3, 7] not to include 3 |
+ | expected [1, 3, 7] not to include 7 |
+ | expected [1, 3, 7] not to include 1, 3, and 7 |
+ | expected [1, 3, 7] to include 1 and 9 |
+ | expected [1, 3, 7] not to include 1 and 9 |
+
+ Scenario: string usage
+ Given a file named "string_include_matcher_spec.rb" with:
+ """
+ describe "a string" do
+ it { should include("str") }
+ it { should include("a", "str", "ng") }
+ it { should_not include("foo") }
+ it { should_not include("foo", "bar") }
+
+ # deliberate failures
+ it { should include("foo") }
+ it { should_not include("str") }
+ it { should include("str", "foo") }
+ it { should_not include("str", "foo") }
+ end
+ """
+ When I run "rspec string_include_matcher_spec.rb"
+ Then the output should contain all of these:
+ | 8 examples, 4 failures |
+ | expected "a string" to include "foo" |
+ | expected "a string" not to include "str" |
+ | expected "a string" to include "str" and "foo" |
+ | expected "a string" not to include "str" and "foo" |
+
+ Scenario: hash usage
+ Given a file named "hash_include_matcher_spec.rb" with:
+ """
+ describe Hash do
+ subject { { :a => 7, :b => 5 } }
+
+ it { should include(:a) }
+ it { should include(:b, :a) }
+ it { should include(:a => 7) }
+ it { should include(:b => 5, :a => 7) }
+ it { should_not include(:c) }
+ it { should_not include(:c, :d) }
+ it { should_not include(:d => 2) }
+ it { should_not include(:a => 5) }
+ it { should_not include(:b => 7, :a => 5) }
+
+ # deliberate failures
+ it { should_not include(:a) }
+ it { should_not include(:b, :a) }
+ it { should_not include(:a => 7) }
+ it { should_not include(:a => 7, :b => 5) }
+ it { should include(:c) }
+ it { should include(:c, :d) }
+ it { should include(:d => 2) }
+ it { should include(:a => 5) }
+ it { should include(:a => 5, :b => 7) }
+
+ # Mixed cases--the hash includes one but not the other.
+ # All 4 of these cases should fail.
+ it { should include(:a, :d) }
+ it { should_not include(:a, :d) }
+ it { should include(:a => 7, :d => 3) }
+ it { should_not include(:a => 7, :d => 3) }
+ end
+ """
+ When I run "rspec hash_include_matcher_spec.rb"
+ Then the output should contain all of these:
+ | 22 examples, 13 failures |
+ | expected {:a=>7, :b=>5} not to include :a |
+ | expected {:a=>7, :b=>5} not to include :b and :a |
+ | expected {:a=>7, :b=>5} not to include {:a=>7} |
+ | expected {:a=>7, :b=>5} not to include {:a=>7, :b=>5} |
+ | expected {:a=>7, :b=>5} to include :c |
+ | expected {:a=>7, :b=>5} to include :c and :d |
+ | expected {:a=>7, :b=>5} to include {:d=>2} |
+ | expected {:a=>7, :b=>5} to include {:a=>5} |
+ | expected {:a=>7, :b=>5} to include {:a=>5, :b=>7} |
+ | expected {:a=>7, :b=>5} to include :a and :d |
+ | expected {:a=>7, :b=>5} not to include :a and :d |
+ | expected {:a=>7, :b=>5} to include {:a=>7, :d=>3} |
+ | expected {:a=>7, :b=>5} not to include {:a=>7, :d=>3} |
+
@@ -18,10 +18,18 @@ module Matchers
# "spread".should_not include("red")
def include(*expected)
Matcher.new :include, *expected do |*_expected|
- match do |actual|
- _expected.all? do |expected|
+ match_for_should do |actual|
+ perform_match(:all?, :all?, actual, _expected)
+ end
+
+ match_for_should_not do |actual|
+ perform_match(:none?, :any?, actual, _expected)
+ end
+
+ def perform_match(predicate, hash_predicate, actual, _expected)
+ _expected.send(predicate) do |expected|
if comparing_hash_values?(actual, expected)
- expected.all? {|k,v| actual[k] == v}
+ expected.send(hash_predicate) {|k,v| actual[k] == v}
elsif comparing_hash_keys?(actual, expected)
actual.has_key?(expected)
else
@@ -37,9 +45,7 @@ def comparing_hash_keys?(actual, expected) # :nodoc:
def comparing_hash_values?(actual, expected) # :nodoc:
actual.is_a?(Hash) && expected.is_a?(Hash)
end
-
end
-
end
end
end
Oops, something went wrong. Retry.

0 comments on commit ca24fa3

Please sign in to comment.