Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Matchers::Have should check for Enumerable#count #91

Closed
wants to merge 1 commit into from

2 participants

Matthew Bellantoni David Chelimsky
Matthew Bellantoni

The Matchers::Have expectation checks for the existence of #length and #size, but not #count. Since #count is the only method provided by the module Enumerable, it seems like it should support #count as well.

I've made this change and the code is here:

mjbellantoni/rspec-expectations@51f953f

David Chelimsky dchelimsky referenced this pull request from a commit
David Chelimsky dchelimsky changelog
- #91.
d8edde0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
20 lib/rspec/matchers/have.rb
View
@@ -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)
54 spec/rspec/matchers/have_spec.rb
View
@@ -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
21 spec/support/classes.rb
View
@@ -13,22 +13,33 @@ 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'
Something went wrong with that request. Please try again.