Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: rspec/rspec-expectations
...
head fork: rspec/rspec-expectations
Checking mergeability… Don’t worry, you can still create the pull request.
  • 7 commits
  • 5 files changed
  • 0 commit comments
  • 2 contributors
View
49 features/built_in_matchers/include.feature
@@ -123,3 +123,52 @@ Feature: include matcher
"""
When I run `rspec hash_include_matcher_spec.rb`
Then the output should contain "13 failure"
+
+ Scenario: fuzzy usage with matchers
+ Given a file named "fuzzy_include_matcher_spec.rb" with:
+ """
+ require 'ostruct'
+
+ class User < OpenStruct
+ def inspect
+ name
+ end
+ end
+
+ RSpec::Matchers.define :a_user_named do |expected|
+ match do |actual|
+ actual.is_a?(User) && (actual.name == expected)
+ end
+ description do
+ "a user named '#{expected}'"
+ end
+ end
+
+ describe "Collection of users" do
+ subject do
+ [User.new(:name => "Joe"),
+ User.new(:name => "Fred"),
+ User.new(:name => "John"),
+ User.new(:name => "Luke"),
+ User.new(:name => "David")]
+ end
+
+ it { should include( a_user_named "Joe" ) }
+ it { should include( a_user_named "Luke" ) }
+ it { should_not include( a_user_named "Richard" ) }
+ it { should_not include( a_user_named "Hayley" ) }
+
+ # deliberate failures
+ it { should include( a_user_named "Richard" ) }
+ it { should_not include( a_user_named "Fred" ) }
+ it { should include( a_user_named "Sarah" ) }
+ it { should_not include( a_user_named "Luke" ) }
+ end
+ """
+ When I run `rspec fuzzy_include_matcher_spec.rb`
+ Then the output should contain all of these:
+ | 8 examples, 4 failures |
+ | expected [Joe, Fred, John, Luke, David] to include a user named 'Richard' |
+ | expected [Joe, Fred, John, Luke, David] not to include a user named 'Fred' |
+ | expected [Joe, Fred, John, Luke, David] to include a user named 'Sarah' |
+ | expected [Joe, Fred, John, Luke, David] not to include a user named 'Luke' |
View
6 lib/rspec/matchers/built_in/include.rb
@@ -34,6 +34,8 @@ def perform_match(predicate, hash_predicate, actuals, expecteds)
}
elsif comparing_hash_keys?(actuals, expected)
actuals.has_key?(expected)
+ elsif comparing_with_matcher?(actual, expected)
+ actual.any? { |value| expected.matches?(value) }
else
actuals.include?(expected)
end
@@ -47,6 +49,10 @@ def comparing_hash_keys?(actual, expected)
def comparing_hash_values?(actual, expected)
actual.is_a?(Hash) && expected.is_a?(Hash)
end
+
+ def comparing_with_matcher?(actual, expected)
+ actual.is_a?(Array) && expected.respond_to?(:matches?)
+ end
end
end
end
View
6 lib/rspec/matchers/pretty.rb
@@ -7,7 +7,7 @@ def split_words(sym)
def to_sentence(words)
return "" unless words
- words = Array(words).map{|w| w.inspect}
+ words = Array(words).map { |w| to_word(w) }
case words.length
when 0
""
@@ -34,6 +34,10 @@ def _pretty_print(array)
result
end
+ def to_word(item)
+ item.respond_to?(:description) ? item.description : item.inspect
+ end
+
def name_to_sentence
split_words(name)
end
View
30 spec/rspec/matchers/include_matcher_integration_spec.rb
@@ -0,0 +1,30 @@
+require 'spec_helper'
+
+module RSpec
+ module Matchers
+ describe "include() interaction with built-in matchers" do
+ it "works with be_within(delta).of(expected)" do
+ expect([10, 20, 30]).to include( be_within(5).of(24) )
+ expect([10, 20, 30]).not_to include( be_within(3).of(24) )
+ end
+
+ it "works with be_instance_of(klass)" do
+ expect(["foo", 123, {:foo => "bar"}]).to include( be_instance_of(Hash) )
+ expect(["foo", 123, {:foo => "bar"}]).not_to include( be_instance_of(Range) )
+ end
+
+ it "works with be_kind_of(klass)" do
+ class StringSubclass < String; end
+ class NotHashSubclass; end
+
+ expect([StringSubclass.new("baz")]).to include( be_kind_of(String) )
+ expect([NotHashSubclass.new]).not_to include( be_kind_of(Hash) )
+ end
+
+ it "works with be_[some predicate]" do
+ expect([stub("actual", :happy? => true)]).to include( be_happy )
+ expect([stub("actual", :happy? => false)]).not_to include( be_happy )
+ end
+ end
+ end
+end
View
38 spec/rspec/matchers/include_spec.rb
@@ -386,3 +386,41 @@ def array.send; :sent; end
end
end
end
+
+RSpec::Matchers.define :string_containing_string do |expected|
+ match do |actual|
+ actual.include?(expected)
+ end
+
+ description do
+ "a string containing '#{expected}'"
+ end
+end
+
+describe "expect(...).to include(matcher)" do
+ context 'for an array target' do
+ it "passes if target includes an object that satisfies the matcher" do
+ expect(['foo', 'bar', 'baz']).to include(string_containing_string("ar"))
+ end
+
+ it "fails if target doesn't include object that satisfies the matcher" do
+ expect {
+ expect(['foo', 'bar', 'baz']).to include(string_containing_string("abc"))
+ }.to fail_matching(%Q|expected #{['foo', 'bar', 'baz'].inspect} to include a string containing 'abc'|)
+ end
+ end
+end
+
+describe "expect(...).to include(multiple, matcher, arguments)" do
+ context 'for an array target' do
+ it "passes if target includes items satisfying all matchers" do
+ expect(['foo', 'bar', 'baz']).to include(string_containing_string("ar"), string_containing_string('oo'))
+ end
+
+ it "fails if target does not include an item satisfying any one of the items" do
+ expect {
+ expect(['foo', 'bar', 'baz']).to include(string_containing_string("ar"), string_containing_string("abc"))
+ }.to fail_matching(%Q|expected #{['foo', 'bar', 'baz'].inspect} to include a string containing 'ar' and a string containing 'abc'|)
+ end
+ end
+end

No commit comments for this range

Something went wrong with that request. Please try again.