Skip to content

Commit

Permalink
add tests, fixes according to review comments
Browse files Browse the repository at this point in the history
  • Loading branch information
abotalov committed Mar 4, 2013
1 parent 3783237 commit f3f8f9c
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 24 deletions.
24 changes: 13 additions & 11 deletions lib/capybara/helpers.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# encoding: UTF-8

module Capybara

# @api private
module Helpers
class << self
##
Expand Down Expand Up @@ -48,36 +50,36 @@ def inject_asset_host(html)
end
end

# @api private
module CountHelpers
class << self
def matches_count?(count, options={})
case
when options[:between]
options[:between] === count
when options[:count]
options[:count].to_i == count
Integer(options[:count]) == count
when options[:maximum]
options[:maximum].to_i >= count
Integer(options[:maximum]) >= count
when options[:minimum]
options[:minimum].to_i <= count
Integer(options[:minimum]) <= count
else
count > 0
end
end

def failure_message(description, options={})
message_prototype = "expected to find #{description} COUNT"
message = if options[:count]
message_prototype.sub(/COUNT/, "#{options[:count]} #{declension('time', 'times', options[:count])}")
message = "expected to find #{description}"
if options[:count]
message << " #{options[:count]} #{declension('time', 'times', options[:count])}"
elsif options[:between]
message_prototype.sub(/COUNT/, "between #{options[:between].first} and #{options[:between].last} times")
message << " between #{options[:between].first} and #{options[:between].last} times"
elsif options[:maximum]
message_prototype.sub(/COUNT/, "at most #{options[:maximum]} #{declension('time', 'times', options[:maximum])}")
message << " at most #{options[:maximum]} #{declension('time', 'times', options[:maximum])}"
elsif options[:minimum]
message_prototype.sub(/COUNT/, "at least #{options[:minimum]} #{declension('time', 'times', options[:minimum])}")
else
"expected to find #{description}"
message << " at least #{options[:minimum]} #{declension('time', 'times', options[:minimum])}"
end
message
end

def declension(singular, plural, count)
Expand Down
6 changes: 3 additions & 3 deletions lib/capybara/node/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,12 @@ def reload
# until a certain amount of time passes. The amount of time defaults to
# {Capybara.default_wait_time} and can be overriden through the `seconds`
# argument. This time is compared with the system time to see how much
# time has passed. If the return value of {Time.now} is stubbed out,
# time has passed. If the return value of `Time.now` is stubbed out,
# Capybara will raise `Capybara::FrozenInTime`.
#
# @param [Integer] seconds Number of seconds to retry this block
# @param [Integer] seconds Number of seconds to retry this block
# @return [Object] The result of the given block
# @raise [Capybara::FrozenInTime] If the return value of {Time.now} appears stuck
# @raise [Capybara::FrozenInTime] If the return value of `Time.now` appears stuck
#
def synchronize(seconds=Capybara.default_wait_time)
start_time = Time.now
Expand Down
19 changes: 10 additions & 9 deletions lib/capybara/node/matchers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def has_no_selector?(*args)
#
# page.assert_selector('li', :text => 'Horse', :visible => true)
#
# {assert_selector} can also accept XPath expressions generated by the
# `assert_selector` can also accept XPath expressions generated by the
# XPath gem:
#
# page.assert_selector(:xpath, XPath.descendant(:p))
Expand Down Expand Up @@ -204,14 +204,15 @@ def has_no_css?(path, options={})
#
# This will check if the text occurs from 2 to 4 times.
#
# @param type [:all, :visible] Whether to check for only visible or all text
# @param content [String, Regexp] The text/regexp to check for
# @param options a customizable set of options
# @option options [Integer] :count (nil) Number of times the text should occur
# @option options [Integer] :minimum (nil) Minimum number of times the text should occur
# @option options [Integer] :maximum (nil) Maximum number of times the text should occur
# @option options [Range] :between (nil) Range of times that should contain number of times text occurs
# @return [Boolean] Whether it exists
# @overload has_text?([type], text, [options])
# @param [:all, :visible] type Whether to check for only visible or all text
# @param [String, Regexp] text The text/regexp to check for
# @param [Hash] options additional options
# @option options [Integer] :count (nil) Number of times the text should occur
# @option options [Integer] :minimum (nil) Minimum number of times the text should occur
# @option options [Integer] :maximum (nil) Maximum number of times the text should occur
# @option options [Range] :between (nil) Range of times that should contain number of times text occurs
# @return [Boolean] Whether it exists
#
def has_text?(*args)
synchronize do
Expand Down
45 changes: 44 additions & 1 deletion spec/rspec/matchers_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,28 @@

it "fails if matched node count does not equal expected count" do
expect do
"<h1>Text</h1>".should have_css('h1', :count => 2)
"<h1>Text</h1>".should have_css('h1', count: 2)
end.to raise_error("expected to find css \"h1\" 2 times, found 1 match: \"Text\"")
end

it "fails if matched node count is less than expected minimum count" do
expect do
"<h1>Text</h1>".should have_css('p', minimum: 1)
end.to raise_error("expected to find css \"p\" at least 1 time but there were no matches")
end

it "fails if matched node count is more than expected maximum count" do
expect do
"<h1>Text</h1><h1>Text</h1><h1>Text</h1>".should have_css('h1', maximum: 2)
end.to raise_error('expected to find css "h1" at most 2 times, found 3 matches: "Text", "Text", "Text"')
end

it "fails if matched node count does not belong to expected range" do
expect do
"<h1>Text</h1>".should have_css('h1', between: 2..3)
end.to raise_error("expected to find css \"h1\" between 2 and 3 times, found 1 match: \"Text\"")
end

end

context "with should_not" do
Expand Down Expand Up @@ -330,6 +349,30 @@
"<h1>Text</h1>".should have_text(:cast_me)
end.to raise_error(/expected to find text "cast_me" in "Text"/)
end

it "fails if matched text count does not equal to expected count" do
expect do
"<h1>Text</h1>".should have_text('Text', count: 2)
end.to raise_error(/expected to find text "Text" 2 times in "Text"/)
end

it "fails if matched text count is less than expected minimum count" do
expect do
"<h1>Text</h1>".should have_text('Lorem', minimum: 1)
end.to raise_error(/expected to find text "Lorem" at least 1 time in "Text"/)
end

it "fails if matched text count is more than expected maximum count" do
expect do
"<h1>Text TextText</h1>".should have_text('Text', maximum: 2)
end.to raise_error(/expected to find text "Text" at most 2 times in "Text TextText"/)
end

it "fails if matched text count does not belong to expected range" do
expect do
"<h1>Text</h1>".should have_text('Text', between: 2..3)
end.to raise_error(/expected to find text "Text" between 2 and 3 times in "Text"/)
end
end

context "with should_not" do
Expand Down

0 comments on commit f3f8f9c

Please sign in to comment.