Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Make Matchers::Have recognize #count in collection objects.

- Closes #91.
  • Loading branch information...
commit a715f88dfaaca299d93519561c4221a1650ec54a 1 parent a541a75
@mjbellantoni mjbellantoni authored dchelimsky committed
View
20 lib/rspec/matchers/have.rb
@@ -24,21 +24,28 @@ def matches?(collection_owner)
collection = collection_owner.__send__(@collection_name, *@args, &@block)
elsif (@plural_collection_name && collection_owner.respond_to?(@plural_collection_name))
collection = collection_owner.__send__(@plural_collection_name, *@args, &@block)
- elsif (collection_owner.respond_to?(:length) || collection_owner.respond_to?(:size))
+ elsif (collection_owner.respond_to?(:length) || collection_owner.respond_to?(:size) || collection_owner.respond_to?(:count))
collection = collection_owner
else
collection_owner.__send__(@collection_name, *@args, &@block)
end
- @actual = collection.size if collection.respond_to?(:size)
- @actual = collection.length if collection.respond_to?(:length)
- raise not_a_collection if @actual.nil?
+ @actual = case
+ when collection.respond_to?(:size)
+ collection.size
+ when collection.respond_to?(:length)
+ collection.length
+ when collection.respond_to?(:count)
+ collection.count
+ else
+ raise not_a_collection
+ end
return @actual >= @expected if @relativity == :at_least
return @actual <= @expected if @relativity == :at_most
return @actual == @expected
end
def not_a_collection
- "expected #{@collection_name} to be a collection but it does not respond to #length or #size"
+ "expected #{@collection_name} to be a collection but it does not respond to #length, #size or #count"
end
def failure_message_for_should
@@ -121,6 +128,9 @@ def relative_expectation
# # Passes if [1,2,3].length == 3
# [1,2,3].should have(3).items #"items" is pure sugar
#
+ # # Passes if ['a', 'b', 'c'].count == 3
+ # [1,2,3].should have(3).items #"items" is pure sugar
+ #
# # Passes if "this string".length == 11
# "this string".should have(11).characters #"characters" is pure sugar
def have(n)
View
54 spec/rspec/matchers/have_spec.rb
@@ -23,6 +23,7 @@ def create_collection_owner_with(n)
(1..n).each do |number|
owner.add_to_collection_with_length_method(number)
owner.add_to_collection_with_size_method(number)
+ owner.add_to_collection_with_count_method(number)
end
owner
end
@@ -33,18 +34,21 @@ def create_collection_owner_with(n)
owner = create_collection_owner_with(3)
owner.should have(3).items_in_collection_with_length_method
owner.should have(3).items_in_collection_with_size_method
+ owner.should have(3).items_in_collection_with_count_method
end
it "converts :no to 0" do
owner = create_collection_owner_with(0)
owner.should have(:no).items_in_collection_with_length_method
owner.should have(:no).items_in_collection_with_size_method
+ owner.should have(:no).items_in_collection_with_count_method
end
it "converts a String argument to Integer" do
owner = create_collection_owner_with(3)
owner.should have('3').items_in_collection_with_length_method
owner.should have('3').items_in_collection_with_size_method
+ owner.should have('3').items_in_collection_with_count_method
end
it "fails if target has a collection of items with < n members" do
@@ -55,6 +59,9 @@ def create_collection_owner_with(n)
lambda {
owner.should have(4).items_in_collection_with_size_method
}.should fail_with("expected 4 items_in_collection_with_size_method, got 3")
+ lambda {
+ owner.should have(4).items_in_collection_with_count_method
+ }.should fail_with("expected 4 items_in_collection_with_count_method, got 3")
end
it "fails if target has a collection of items with > n members" do
@@ -65,6 +72,9 @@ def create_collection_owner_with(n)
lambda {
owner.should have(2).items_in_collection_with_size_method
}.should fail_with("expected 2 items_in_collection_with_size_method, got 3")
+ lambda {
+ owner.should have(2).items_in_collection_with_count_method
+ }.should fail_with("expected 2 items_in_collection_with_count_method, got 3")
end
end
@@ -128,7 +138,7 @@ def items
end.new
lambda do
owner.should have(3).items
- end.should raise_error("expected items to be a collection but it does not respond to #length or #size")
+ end.should raise_error("expected items to be a collection but it does not respond to #length, #size or #count")
end
end
@@ -138,12 +148,14 @@ def items
owner = create_collection_owner_with(3)
owner.should_not have(4).items_in_collection_with_length_method
owner.should_not have(4).items_in_collection_with_size_method
+ owner.should_not have(4).items_in_collection_with_count_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
owner.should_not have(2).items_in_collection_with_size_method
+ owner.should_not have(2).items_in_collection_with_count_method
end
it "fails if target has a collection of items with n members" do
@@ -154,6 +166,9 @@ def items
lambda {
owner.should_not have(3).items_in_collection_with_size_method
}.should fail_with("expected target not to have 3 items_in_collection_with_size_method, got 3")
+ lambda {
+ owner.should_not have(3).items_in_collection_with_count_method
+ }.should fail_with("expected target not to have 3 items_in_collection_with_count_method, got 3")
end
end
@@ -163,12 +178,14 @@ def items
owner = create_collection_owner_with(3)
owner.should have_exactly(3).items_in_collection_with_length_method
owner.should have_exactly(3).items_in_collection_with_size_method
+ owner.should have_exactly(3).items_in_collection_with_count_method
end
it "converts :no to 0" do
owner = create_collection_owner_with(0)
owner.should have_exactly(:no).items_in_collection_with_length_method
owner.should have_exactly(:no).items_in_collection_with_size_method
+ owner.should have_exactly(:no).items_in_collection_with_count_method
end
it "fails if target has a collection of items with < n members" do
@@ -179,6 +196,9 @@ def items
lambda {
owner.should have_exactly(4).items_in_collection_with_size_method
}.should fail_with("expected 4 items_in_collection_with_size_method, got 3")
+ lambda {
+ owner.should have_exactly(4).items_in_collection_with_count_method
+ }.should fail_with("expected 4 items_in_collection_with_count_method, got 3")
end
it "fails if target has a collection of items with > n members" do
@@ -189,6 +209,9 @@ def items
lambda {
owner.should have_exactly(2).items_in_collection_with_size_method
}.should fail_with("expected 2 items_in_collection_with_size_method, got 3")
+ lambda {
+ owner.should have_exactly(2).items_in_collection_with_count_method
+ }.should fail_with("expected 2 items_in_collection_with_count_method, got 3")
end
end
@@ -198,12 +221,14 @@ def items
owner = create_collection_owner_with(3)
owner.should have_at_least(3).items_in_collection_with_length_method
owner.should have_at_least(3).items_in_collection_with_size_method
+ owner.should have_at_least(3).items_in_collection_with_count_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
owner.should have_at_least(2).items_in_collection_with_size_method
+ owner.should have_at_least(2).items_in_collection_with_count_method
end
it "fails if target has a collection of items with < n members" do
@@ -214,6 +239,9 @@ def items
lambda {
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")
+ lambda {
+ owner.should have_at_least(4).items_in_collection_with_count_method
+ }.should fail_with("expected at least 4 items_in_collection_with_count_method, got 3")
end
it "provides educational negative failure messages" do
@@ -221,10 +249,12 @@ def items
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
+ count_matcher = have_at_least(3).items_in_collection_with_count_method
#when
length_matcher.matches?(owner)
size_matcher.matches?(owner)
+ count_matcher.matches?(owner)
#then
length_matcher.failure_message_for_should_not.should eq <<-EOF
@@ -242,6 +272,13 @@ def items
We recommend that you use this instead:
should have_at_most(2).items_in_collection_with_size_method
EOF
+ count_matcher.failure_message_for_should_not.should eq <<-EOF
+Isn't life confusing enough?
+Instead of having to figure out the meaning of this:
+ should_not have_at_least(3).items_in_collection_with_count_method
+We recommend that you use this instead:
+ should have_at_most(2).items_in_collection_with_count_method
+EOF
end
end
@@ -250,6 +287,7 @@ def items
owner = create_collection_owner_with(3)
owner.should have_at_most(3).items_in_collection_with_length_method
owner.should have_at_most(3).items_in_collection_with_size_method
+ owner.should have_at_most(3).items_in_collection_with_count_method
end
it "fails if target has a collection of items with > n members" do
@@ -260,12 +298,16 @@ def items
lambda {
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")
+ lambda {
+ owner.should have_at_most(2).items_in_collection_with_count_method
+ }.should fail_with("expected at most 2 items_in_collection_with_count_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
owner.should have_at_most(4).items_in_collection_with_size_method
+ owner.should have_at_most(4).items_in_collection_with_count_method
end
it "provides educational negative failure messages" do
@@ -273,10 +315,12 @@ 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
+ count_matcher = have_at_most(3).items_in_collection_with_count_method
#when
length_matcher.matches?(owner)
size_matcher.matches?(owner)
+ count_matcher.matches?(owner)
#then
length_matcher.failure_message_for_should_not.should eq <<-EOF
@@ -294,6 +338,14 @@ def items
We recommend that you use this instead:
should have_at_least(4).items_in_collection_with_size_method
EOF
+
+ count_matcher.failure_message_for_should_not.should eq <<-EOF
+Isn't life confusing enough?
+Instead of having to figure out the meaning of this:
+ should_not have_at_most(3).items_in_collection_with_count_method
+We recommend that you use this instead:
+ should have_at_least(4).items_in_collection_with_count_method
+EOF
end
end
View
31 spec/support/classes.rb
@@ -7,34 +7,45 @@ def initialize; @list = []; end
def size; @list.size; end
def push(item); @list.push(item); end
end
-
+
class CollectionWithLengthMethod
def initialize; @list = []; end
def length; @list.size; end
def push(item); @list.push(item); end
end
+ class CollectionWithCountMethod
+ def initialize; @list = []; end
+ def count; @list.count; end
+ def push(item); @list.push(item); end
+ end
+
class CollectionOwner
- attr_reader :items_in_collection_with_size_method, :items_in_collection_with_length_method
-
+ attr_reader :items_in_collection_with_size_method, :items_in_collection_with_length_method, :items_in_collection_with_count_method
+
def initialize
@items_in_collection_with_size_method = CollectionWithSizeMethod.new
@items_in_collection_with_length_method = CollectionWithLengthMethod.new
+ @items_in_collection_with_count_method = CollectionWithCountMethod.new
end
-
+
def add_to_collection_with_size_method(item)
@items_in_collection_with_size_method.push(item)
end
-
- def add_to_collection_with_length_method(item)
- @items_in_collection_with_length_method.push(item)
- end
-
+
+ def add_to_collection_with_length_method(item)
+ @items_in_collection_with_length_method.push(item)
+ end
+
+ def add_to_collection_with_count_method(item)
+ @items_in_collection_with_count_method.push(item)
+ end
+
def items_for(arg)
return [1, 2, 3] if arg == 'a'
[1]
end
-
+
def items
@items_in_collection_with_size_method
end
Please sign in to comment.
Something went wrong with that request. Please try again.