Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add description generation for any Has matcher

  • Loading branch information...
commit a7b702d759de587ec169041b52eb557125aace26 1 parent e14e87f
@Mange Mange authored dchelimsky committed
View
26 lib/rspec/matchers/has.rb
@@ -1,35 +1,39 @@
module RSpec
module Matchers
-
class Has
-
def initialize(expected, *args)
@expected, @args = expected, args
end
-
+
def matches?(actual)
actual.__send__(predicate(@expected), *@args)
end
-
+
def failure_message_for_should
"expected ##{predicate(@expected)}(#{@args[0].inspect}) to return true, got false"
end
-
+
def failure_message_for_should_not
"expected ##{predicate(@expected)}(#{@args[0].inspect}) to return false, got true"
end
-
+
def description
- "have key #{@args[0].inspect}"
+ [method_description(@expected), args_description(@args)].compact.join(' ')
end
-
+
private
-
def predicate(sym)
"#{sym.to_s.sub("have_","has_")}?".to_sym
end
-
+
+ def method_description(method)
+ method.to_s.gsub('_', ' ')
+ end
+
+ def args_description(args)
+ return nil if args.empty?
+ args.map { |arg| arg.inspect }.join(', ')
+ end
end
-
end
end
View
66 spec/rspec/matchers/description_generation_spec.rb
@@ -9,42 +9,42 @@
"this".should == "this"
RSpec::Matchers.generated_description.should == "should == \"this\""
end
-
+
it "should not == expected" do
"this".should_not == "that"
RSpec::Matchers.generated_description.should == "should not == \"that\""
end
-
+
it "should be empty (arbitrary predicate)" do
[].should be_empty
RSpec::Matchers.generated_description.should == "should be empty"
end
-
+
it "should not be empty (arbitrary predicate)" do
[1].should_not be_empty
RSpec::Matchers.generated_description.should == "should not be empty"
end
-
+
it "should be true" do
true.should be_true
RSpec::Matchers.generated_description.should == "should be true"
end
-
+
it "should be false" do
false.should be_false
RSpec::Matchers.generated_description.should == "should be false"
end
-
+
it "should be nil" do
nil.should be_nil
RSpec::Matchers.generated_description.should == "should be nil"
end
-
+
it "should be > n" do
5.should be > 3
RSpec::Matchers.generated_description.should == "should be > 3"
end
-
+
it "should be predicate arg1, arg2 and arg3" do
5.0.should be_between(0,10)
RSpec::Matchers.generated_description.should == "should be between 0 and 10"
@@ -55,42 +55,58 @@
expected.should equal(expected)
RSpec::Matchers.generated_description.should == "should equal \"expected\""
end
-
+
it "should_not equal" do
5.should_not equal(37)
RSpec::Matchers.generated_description.should == "should not equal 37"
end
-
+
it "should eql" do
"string".should eql("string")
RSpec::Matchers.generated_description.should == "should eql \"string\""
end
-
+
it "should not eql" do
"a".should_not eql(:a)
RSpec::Matchers.generated_description.should == "should not eql :a"
end
-
+
it "should have_key" do
{:a => "a"}.should have_key(:a)
RSpec::Matchers.generated_description.should == "should have key :a"
end
-
+
+ it "should have_some_method" do
+ object = Object.new
+ def object.has_eyes_closed?; true; end
+
+ object.should have_eyes_closed
+ RSpec::Matchers.generated_description.should == 'should have eyes closed'
+ end
+
+ it "should have_some_method(args*)" do
+ object = Object.new
+ def object.has_taste_for?(*args); true; end
+
+ object.should have_taste_for("blood", "victory")
+ RSpec::Matchers.generated_description.should == 'should have taste for "blood", "victory"'
+ end
+
it "should have n items" do
team.should have(3).players
RSpec::Matchers.generated_description.should == "should have 3 players"
end
-
+
it "should have at least n items" do
team.should have_at_least(2).players
RSpec::Matchers.generated_description.should == "should have at least 2 players"
end
-
+
it "should have at most n items" do
team.should have_at_most(4).players
RSpec::Matchers.generated_description.should == "should have at most 4 players"
end
-
+
it "should include" do
[1,2,3].should include(3)
RSpec::Matchers.generated_description.should == "should include 3"
@@ -100,42 +116,42 @@
[1,2,3].should =~ [1,2,3]
RSpec::Matchers.generated_description.should == "should contain exactly 1, 2 and 3"
end
-
+
it "should match" do
"this string".should match(/this string/)
RSpec::Matchers.generated_description.should == "should match /this string/"
end
-
+
it "should raise_error" do
lambda { raise }.should raise_error
RSpec::Matchers.generated_description.should == "should raise Exception"
end
-
+
it "should raise_error with type" do
lambda { raise }.should raise_error(RuntimeError)
RSpec::Matchers.generated_description.should == "should raise RuntimeError"
end
-
+
it "should raise_error with type and message" do
lambda { raise "there was an error" }.should raise_error(RuntimeError, "there was an error")
RSpec::Matchers.generated_description.should == "should raise RuntimeError with \"there was an error\""
end
-
+
it "should respond_to" do
[].should respond_to(:insert)
RSpec::Matchers.generated_description.should == "should respond to #insert"
end
-
+
it "should throw symbol" do
lambda { throw :what_a_mess }.should throw_symbol
RSpec::Matchers.generated_description.should == "should throw a Symbol"
end
-
+
it "should throw symbol (with named symbol)" do
lambda { throw :what_a_mess }.should throw_symbol(:what_a_mess)
RSpec::Matchers.generated_description.should == "should throw :what_a_mess"
end
-
+
def team
Class.new do
def players
@@ -152,7 +168,7 @@ def matches?(ignore); true; end
def failure_message; ""; end
end.new
end
-
+
it "provides a helpful message when used in a string-less example block" do
5.should matcher
RSpec::Matchers.generated_description.should =~ /When you call.*description method/m
View
4 spec/rspec/matchers/has_spec.rb
@@ -26,7 +26,7 @@ def has_foo?
Object.new.should have_key(:a)
}.should raise_error(NoMethodError)
end
-
+
it "reraises an exception thrown in #has_sym?(*args)" do
o = Object.new
def o.has_sym?(*args)
@@ -60,7 +60,7 @@ def has_foo?
Object.new.should have_key(:a)
}.should raise_error(NoMethodError)
end
-
+
it "reraises an exception thrown in #has_sym?(*args)" do
o = Object.new
def o.has_sym?(*args)
View
42 spec/rspec/matchers/have_spec.rb
@@ -50,7 +50,7 @@ def create_collection_owner_with(n)
owner.should have(4).items_in_collection_with_size_method
}.should fail_with("expected 4 items_in_collection_with_size_method, got 3")
end
-
+
it "fails if target has a collection of items with > n members" do
owner = create_collection_owner_with(3)
lambda {
@@ -63,7 +63,7 @@ def create_collection_owner_with(n)
end
describe 'should have(1).item when ActiveSupport::Inflector is defined' do
-
+
it 'pluralizes the collection name' do
owner = create_collection_owner_with(1)
owner.should have(1).item
@@ -78,7 +78,7 @@ def create_collection_owner_with(n)
end
end
-
+
after(:each) do
unless @active_support_was_defined
Object.__send__ :remove_const, :ActiveSupport
@@ -87,7 +87,7 @@ def create_collection_owner_with(n)
end
describe 'should have(1).item when Inflector is defined' do
-
+
before(:each) do
if defined?(Inflector)
@inflector_was_defined = true
@@ -100,7 +100,7 @@ def self.pluralize(string)
end
end
end
-
+
it 'pluralizes the collection name' do
owner = create_collection_owner_with(1)
owner.should have(1).item
@@ -133,7 +133,7 @@ def items
owner.should_not have(4).items_in_collection_with_length_method
owner.should_not have(4).items_in_collection_with_size_method
end
-
+
it "passes if target has a collection of items with > n members" do
owner = create_collection_owner_with(3)
owner.should_not have(2).items_in_collection_with_length_method
@@ -174,7 +174,7 @@ def items
owner.should have_exactly(4).items_in_collection_with_size_method
}.should fail_with("expected 4 items_in_collection_with_size_method, got 3")
end
-
+
it "fails if target has a collection of items with > n members" do
owner = create_collection_owner_with(3)
lambda {
@@ -193,7 +193,7 @@ def items
owner.should have_at_least(3).items_in_collection_with_length_method
owner.should have_at_least(3).items_in_collection_with_size_method
end
-
+
it "passes if target has a collection of items with > n members" do
owner = create_collection_owner_with(3)
owner.should have_at_least(2).items_in_collection_with_length_method
@@ -209,17 +209,17 @@ def items
owner.should have_at_least(4).items_in_collection_with_size_method
}.should fail_with("expected at least 4 items_in_collection_with_size_method, got 3")
end
-
+
it "provides educational negative failure messages" do
#given
owner = create_collection_owner_with(3)
length_matcher = have_at_least(3).items_in_collection_with_length_method
size_matcher = have_at_least(3).items_in_collection_with_size_method
-
+
#when
length_matcher.matches?(owner)
size_matcher.matches?(owner)
-
+
#then
length_matcher.failure_message_for_should_not.should == <<-EOF
Isn't life confusing enough?
@@ -255,7 +255,7 @@ def items
owner.should have_at_most(2).items_in_collection_with_size_method
}.should fail_with("expected at most 2 items_in_collection_with_size_method, got 3")
end
-
+
it "passes if target has a collection of items with < n members" do
owner = create_collection_owner_with(3)
owner.should have_at_most(4).items_in_collection_with_length_method
@@ -267,11 +267,11 @@ def items
owner = create_collection_owner_with(3)
length_matcher = have_at_most(3).items_in_collection_with_length_method
size_matcher = have_at_most(3).items_in_collection_with_size_method
-
+
#when
length_matcher.matches?(owner)
size_matcher.matches?(owner)
-
+
#then
length_matcher.failure_message_for_should_not.should == <<-EOF
Isn't life confusing enough?
@@ -280,7 +280,7 @@ def items
We recommend that you use this instead:
should have_at_least(4).items_in_collection_with_length_method
EOF
-
+
size_matcher.failure_message_for_should_not.should == <<-EOF
Isn't life confusing enough?
Instead of having to figure out the meaning of this:
@@ -338,7 +338,7 @@ def items
def @collection.floozles; [1,2] end
def @collection.send(*args); raise "DOH! Library developers shouldn't use #send!" end
end
-
+
it "works in the straightforward case" do
lambda {
@collection.should have(2).floozles
@@ -374,24 +374,24 @@ def @collection.send(*args); raise "DOH! Library developers shouldn't use #send!
@a_method_which_have_defines = described_class.instance_methods.first
@a_method_which_object_defines = Object.instance_methods.first
end
-
+
it "is true for a method which Have defines" do
@have.should respond_to(@a_method_which_have_defines)
end
-
+
it "is true for a method that it's superclass (Object) defines" do
@have.should respond_to(@a_method_which_object_defines)
end
-
+
it "is false for a method which neither Object nor nor Have defines" do
@have.should_not respond_to(:foo_bar_baz)
end
-
+
it "is false if the owner doesn't respond to the method" do
have = described_class.new(99)
have.should_not respond_to(:problems)
end
-
+
it "is true if the owner responds to the method" do
have = described_class.new(:a_symbol)
have.should respond_to(:to_sym)

0 comments on commit a7b702d

Please sign in to comment.
Something went wrong with that request. Please try again.