mirror of
https://github.com/teamcapybara/capybara.git
synced 2022-11-09 12:08:07 -05:00
Refactor and document
This commit is contained in:
parent
e5809138e1
commit
415e2db70d
4 changed files with 109 additions and 83 deletions
|
@ -4,90 +4,117 @@ module Capybara
|
|||
|
||||
# @api private
|
||||
module Helpers
|
||||
class << self
|
||||
##
|
||||
#
|
||||
# Normalizes whitespace space by stripping leading and trailing
|
||||
# whitespace and replacing sequences of whitespace characters
|
||||
# with a single space.
|
||||
#
|
||||
# @param [String] text Text to normalize
|
||||
# @return [String] Normalized text
|
||||
#
|
||||
def normalize_whitespace(text)
|
||||
text.to_s.gsub(/[[:space:]]+/, ' ').strip
|
||||
end
|
||||
extend self
|
||||
|
||||
##
|
||||
#
|
||||
# Escapes any characters that would have special meaning in a regexp
|
||||
# if text is not a regexp
|
||||
#
|
||||
# @param [String] text Text to escape
|
||||
# @return [String] Escaped text
|
||||
#
|
||||
def to_regexp(text)
|
||||
text.is_a?(Regexp) ? text : Regexp.new(Regexp.escape(normalize_whitespace(text)))
|
||||
end
|
||||
##
|
||||
#
|
||||
# Normalizes whitespace space by stripping leading and trailing
|
||||
# whitespace and replacing sequences of whitespace characters
|
||||
# with a single space.
|
||||
#
|
||||
# @param [String] text Text to normalize
|
||||
# @return [String] Normalized text
|
||||
#
|
||||
def normalize_whitespace(text)
|
||||
text.to_s.gsub(/[[:space:]]+/, ' ').strip
|
||||
end
|
||||
|
||||
##
|
||||
#
|
||||
# Injects a `<base>` tag into the given HTML code, pointing to
|
||||
# `Capybara.asset_host`.
|
||||
#
|
||||
# @param [String] html HTML code to inject into
|
||||
# @param [String] The modified HTML code
|
||||
#
|
||||
def inject_asset_host(html)
|
||||
if Capybara.asset_host
|
||||
if Nokogiri::HTML(html).css("base").empty? and match = html.match(/<head[^<]*?>/)
|
||||
html.clone.insert match.end(0), "<base href='#{Capybara.asset_host}' />"
|
||||
end
|
||||
else
|
||||
html
|
||||
##
|
||||
#
|
||||
# Escapes any characters that would have special meaning in a regexp
|
||||
# if text is not a regexp
|
||||
#
|
||||
# @param [String] text Text to escape
|
||||
# @return [String] Escaped text
|
||||
#
|
||||
def to_regexp(text)
|
||||
text.is_a?(Regexp) ? text : Regexp.new(Regexp.escape(normalize_whitespace(text)))
|
||||
end
|
||||
|
||||
##
|
||||
#
|
||||
# Injects a `<base>` tag into the given HTML code, pointing to
|
||||
# `Capybara.asset_host`.
|
||||
#
|
||||
# @param [String] html HTML code to inject into
|
||||
# @param [String] The modified HTML code
|
||||
#
|
||||
def inject_asset_host(html)
|
||||
if Capybara.asset_host
|
||||
if Nokogiri::HTML(html).css("base").empty? and match = html.match(/<head[^<]*?>/)
|
||||
html.clone.insert match.end(0), "<base href='#{Capybara.asset_host}' />"
|
||||
end
|
||||
else
|
||||
html
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# @api private
|
||||
module CountHelpers
|
||||
class << self
|
||||
def matches_count?(count, options={})
|
||||
case
|
||||
when options[:between]
|
||||
options[:between] === count
|
||||
when options[:count]
|
||||
Integer(options[:count]) == count
|
||||
when options[:maximum]
|
||||
Integer(options[:maximum]) >= count
|
||||
when options[:minimum]
|
||||
Integer(options[:minimum]) <= count
|
||||
else
|
||||
count > 0
|
||||
end
|
||||
##
|
||||
#
|
||||
# Checks if the given count matches the given count options. By default,
|
||||
# when no options are given, count should be larger than zero.
|
||||
#
|
||||
# @param [Integer] count The actual number. Should be coercible via Integer()
|
||||
# @option [Range] between Count must be within the given range
|
||||
# @option [Integer] count Count must be exactly this
|
||||
# @option [Integer] maximum Count must be smaller than or equal to this value
|
||||
# @option [Integer] minimum Count must be larger than or equal to this value
|
||||
#
|
||||
def matches_count?(count, options={})
|
||||
case
|
||||
when options[:between]
|
||||
options[:between] === count
|
||||
when options[:count]
|
||||
Integer(options[:count]) == count
|
||||
when options[:maximum]
|
||||
Integer(options[:maximum]) >= count
|
||||
when options[:minimum]
|
||||
Integer(options[:minimum]) <= count
|
||||
else
|
||||
count > 0
|
||||
end
|
||||
end
|
||||
|
||||
def failure_message(description, options={})
|
||||
message = "expected to find #{description}"
|
||||
if options[:count]
|
||||
message << " #{options[:count]} #{declension('time', 'times', options[:count])}"
|
||||
elsif options[:between]
|
||||
message << " between #{options[:between].first} and #{options[:between].last} times"
|
||||
elsif options[:maximum]
|
||||
message << " at most #{options[:maximum]} #{declension('time', 'times', options[:maximum])}"
|
||||
elsif options[:minimum]
|
||||
message << " at least #{options[:minimum]} #{declension('time', 'times', options[:minimum])}"
|
||||
end
|
||||
message
|
||||
##
|
||||
#
|
||||
# Generates a failure message given a description of the query and count
|
||||
# options.
|
||||
#
|
||||
# @param [String] description Description of a query
|
||||
# @option [Range] between Count should have been within the given range
|
||||
# @option [Integer] count Count should have been exactly this
|
||||
# @option [Integer] maximum Count should have been smaller than or equal to this value
|
||||
# @option [Integer] minimum Count should have been larger than or equal to this value
|
||||
#
|
||||
def failure_message(description, options={})
|
||||
message = "expected to find #{description}"
|
||||
if options[:count]
|
||||
message << " #{options[:count]} #{declension('time', 'times', options[:count])}"
|
||||
elsif options[:between]
|
||||
message << " between #{options[:between].first} and #{options[:between].last} times"
|
||||
elsif options[:maximum]
|
||||
message << " at most #{options[:maximum]} #{declension('time', 'times', options[:maximum])}"
|
||||
elsif options[:minimum]
|
||||
message << " at least #{options[:minimum]} #{declension('time', 'times', options[:minimum])}"
|
||||
end
|
||||
message
|
||||
end
|
||||
|
||||
def declension(singular, plural, count)
|
||||
if count == 1
|
||||
singular
|
||||
else
|
||||
plural
|
||||
end
|
||||
##
|
||||
#
|
||||
# A poor man's `pluralize`. Given two declensions, one singular and one
|
||||
# plural, as well as a count, this will pick the correct declension. This
|
||||
# way we can generate gramatically correct error message.
|
||||
#
|
||||
# @param [String] singular The singular form of the word
|
||||
# @param [String] plural The plural form of the word
|
||||
# @param [Integer] count The number of items
|
||||
#
|
||||
def declension(singular, plural, count)
|
||||
if count == 1
|
||||
singular
|
||||
else
|
||||
plural
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -458,15 +458,14 @@ module Capybara
|
|||
self.eql?(other) or (other.respond_to?(:base) and base == other.base)
|
||||
end
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
def text_found?(*args)
|
||||
type = args.shift if args.first.is_a?(Symbol) or args.first.nil?
|
||||
content = args.shift
|
||||
options = (args.first.is_a?(Hash))? args.first : {}
|
||||
content, options = args
|
||||
count = Capybara::Helpers.normalize_whitespace(text(type)).scan(Capybara::Helpers.to_regexp(content)).count
|
||||
|
||||
Capybara::CountHelpers.matches_count?(count, options)
|
||||
|
||||
Capybara::Helpers.matches_count?(count, options || {})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -32,13 +32,13 @@ module Capybara
|
|||
def_delegators :@result, :each, :[], :at, :size, :count, :length, :first, :last, :empty?
|
||||
|
||||
def matches_count?
|
||||
Capybara::CountHelpers.matches_count?(@result.size, @query.options)
|
||||
Capybara::Helpers.matches_count?(@result.size, @query.options)
|
||||
end
|
||||
|
||||
def failure_message
|
||||
message = Capybara::CountHelpers.failure_message(@query.description, @query.options)
|
||||
message = Capybara::Helpers.failure_message(@query.description, @query.options)
|
||||
if count > 0
|
||||
message << ", found #{count} #{Capybara::CountHelpers.declension("match", "matches", count)}: " << @result.map(&:text).map(&:inspect).join(", ")
|
||||
message << ", found #{count} #{Capybara::Helpers.declension("match", "matches", count)}: " << @result.map(&:text).map(&:inspect).join(", ")
|
||||
else
|
||||
message << " but there were no matches"
|
||||
end
|
||||
|
|
|
@ -52,7 +52,7 @@ module Capybara
|
|||
end
|
||||
|
||||
def failure_message_for_should
|
||||
message = Capybara::CountHelpers.failure_message(description, options)
|
||||
message = Capybara::Helpers.failure_message(description, options)
|
||||
message << " in #{format(@actual.text(type))}"
|
||||
message
|
||||
end
|
||||
|
|
Loading…
Add table
Reference in a new issue