Move failure message generatio to result class

This commit is contained in:
Jonas Nicklas and Nicklas Ramhöj 2012-06-08 16:47:01 +02:00
parent ad833a1e13
commit 66b6aed8b2
8 changed files with 92 additions and 86 deletions

View File

@ -305,6 +305,7 @@ module Capybara
autoload :Session, 'capybara/session' autoload :Session, 'capybara/session'
autoload :Selector, 'capybara/selector' autoload :Selector, 'capybara/selector'
autoload :Query, 'capybara/query' autoload :Query, 'capybara/query'
autoload :Result, 'capybara/result'
autoload :VERSION, 'capybara/version' autoload :VERSION, 'capybara/version'
module Node module Node

View File

@ -24,13 +24,7 @@ module Capybara
# @raise [Capybara::ElementNotFound] If the element can't be found before time expires # @raise [Capybara::ElementNotFound] If the element can't be found before time expires
# #
def find(*args) def find(*args)
query = query(*args) synchronize { all(*args).find! }
query.find = true
synchronize do
results = resolve(query)
query.verify!(results)
results.first
end
end end
## ##
@ -115,7 +109,13 @@ module Capybara
# @return [Array[Capybara::Element]] The found elements # @return [Array[Capybara::Element]] The found elements
# #
def all(*args) def all(*args)
resolve(query(*args)) query = Capybara::Query.new(*args)
elements = synchronize do
base.find(query.xpath).map do |node|
Capybara::Node::Element.new(session, node, self, query)
end
end
Capybara::Result.new(elements, query)
end end
## ##
@ -132,18 +132,6 @@ module Capybara
def first(*args) def first(*args)
all(*args).first all(*args).first
end end
def query(*args)
Capybara::Query.new(self, *args)
end
def resolve(query)
synchronize do
base.find(query.xpath).map do |node|
Capybara::Node::Element.new(session, node, self, query)
end.select { |node| query.matches_filters?(node) }
end
end
end end
end end
end end

View File

@ -33,15 +33,19 @@ module Capybara
# @return [Boolean] If the expression exists # @return [Boolean] If the expression exists
# #
def has_selector?(*args) def has_selector?(*args)
synchronize do assert_selector!(*args)
results = all(*args)
query(*args).matches_count?(results) or raise Capybara::ExpectationNotMet
results
end
rescue Capybara::ExpectationNotMet rescue Capybara::ExpectationNotMet
return false return false
end end
def assert_selector!(*args)
synchronize do
result = all(*args)
result.matches_count? or raise Capybara::ExpectationNotMet, result.failure_message
end
return true
end
## ##
# #
# Checks if a given selector is not on the page or current node. # Checks if a given selector is not on the page or current node.
@ -51,15 +55,19 @@ module Capybara
# @return [Boolean] # @return [Boolean]
# #
def has_no_selector?(*args) def has_no_selector?(*args)
synchronize do assert_no_selector!(*args)
results = all(*args)
query(*args).matches_count?(results) and raise Capybara::ExpectationNotMet
results
end
rescue Capybara::ExpectationNotMet rescue Capybara::ExpectationNotMet
return false return false
end end
def assert_no_selector!(*args)
synchronize do
result = all(*args)
result.matches_count? and raise Capybara::ExpectationNotMet, result.negative_failure_message
end
return true
end
## ##
# #
# Checks if a given XPath expression is on the page or current node. # Checks if a given XPath expression is on the page or current node.
@ -162,6 +170,7 @@ module Capybara
normalize_whitespace(text).include?(normalized_content) or normalize_whitespace(text).include?(normalized_content) or
raise ExpectationNotMet raise ExpectationNotMet
end end
return true
rescue Capybara::ExpectationNotMet rescue Capybara::ExpectationNotMet
return false return false
end end
@ -185,6 +194,7 @@ module Capybara
!normalize_whitespace(text).include?(normalized_content) or !normalize_whitespace(text).include?(normalized_content) or
raise ExpectationNotMet raise ExpectationNotMet
end end
return true
rescue Capybara::ExpectationNotMet rescue Capybara::ExpectationNotMet
return false return false
end end

View File

@ -122,10 +122,12 @@ module Capybara
yield # simple nodes don't need to wait yield # simple nodes don't need to wait
end end
def resolve(query) def all(*args)
native.xpath(query.xpath).map do |node| query = Capybara::Query.new(*args)
elements = native.xpath(query.xpath).map do |node|
self.class.new(node) self.class.new(node)
end.select { |node| query.matches_filters?(node) } end
Capybara::Result.new(elements, query)
end end
end end
end end

View File

@ -1,9 +1,8 @@
module Capybara module Capybara
class Query class Query
attr_accessor :node, :selector, :locator, :options, :xpath, :find, :negative attr_accessor :selector, :locator, :options, :xpath, :find, :negative
def initialize(node, *args) def initialize(*args)
@node = node
@options = if args.last.is_a?(Hash) then args.pop.dup else {} end @options = if args.last.is_a?(Hash) then args.pop.dup else {} end
unless options.has_key?(:visible) unless options.has_key?(:visible)
@options[:visible] = Capybara.ignore_hidden_elements @options[:visible] = Capybara.ignore_hidden_elements
@ -21,18 +20,6 @@ module Capybara
@xpath = @selector.call(@locator).to_s @xpath = @selector.call(@locator).to_s
end end
def failure_message
if find
"Unable to find #{description}"
else
"expected #{description} to return something"
end
end
def negative_failure_message
"expected #{description} not to return anything"
end
def name; selector.name; end def name; selector.name; end
def label; selector.label or selector.name; end def label; selector.label or selector.name; end
@ -54,34 +41,20 @@ module Capybara
true true
end end
def verify!(results) def matches_count?(count)
if find and results.length != 1
raise Capybara::ElementNotFound, failure_message
end
end
def error(results)
if negative
negative_failure_message
else
failure_message
end
end
def matches_count?(nodes)
case case
when nodes.empty? when count.zero?
false false
when options[:between] when options[:between]
options[:between] === nodes.size options[:between] === count
when options[:count] when options[:count]
options[:count].to_i == nodes.size options[:count].to_i == count
when options[:maximum] when options[:maximum]
options[:maximum].to_i >= nodes.size options[:maximum].to_i >= count
when options[:minimum] when options[:minimum]
options[:minimum].to_i <= nodes.size options[:minimum].to_i <= count
else else
nodes.size > 0 count > 0
end end
end end
end end

44
lib/capybara/result.rb Normal file
View File

@ -0,0 +1,44 @@
module Capybara
class Result
include Enumerable
def initialize(elements, query)
@unfiltered_elements = elements
@filtered_elements = elements.select { |node| query.matches_filters?(node) }
@query = query
end
def each(&block)
@filtered_elements.each(&block)
end
def first
@filtered_elements.first
end
def matches_count?
@query.matches_count?(@filtered_elements.size)
end
def find!
raise Capybara::ElementNotFound, failure_message(true) if @filtered_elements.count != 1
@filtered_elements.first
end
def failure_message(find=false)
if find
"Unable to find #{@query.description}"
else
"expected #{@query.description} to return something"
end
end
def negative_failure_message
"expected #{@query.description} not to return anything"
end
def empty?
@filtered_elements.empty?
end
end
end

View File

@ -6,24 +6,11 @@ module Capybara
end end
def matches?(actual) def matches?(actual)
@actual = wrap(actual) wrap(actual).assert_selector!(*@args)
@actual.has_selector?(*@args)
end end
def does_not_match?(actual) def does_not_match?(actual)
@actual = wrap(actual) wrap(actual).assert_no_selector!(*@args)
@actual.has_no_selector?(*@args)
end
def failure_message_for_should
results = @actual.resolve(query)
query.error(results)
end
def failure_message_for_should_not
results = @actual.resolve(query)
query.negative = true
query.error(results)
end end
def description def description
@ -39,7 +26,7 @@ module Capybara
end end
def query def query
@query ||= @actual.query(*@args) @query ||= Capybara::Query.new(*@args)
end end
end end

View File

@ -34,7 +34,8 @@ module Capybara
:has_no_button?, :has_field?, :has_no_field?, :has_checked_field?, :has_no_button?, :has_field?, :has_no_field?, :has_checked_field?,
:has_unchecked_field?, :has_no_table?, :has_table?, :unselect, :has_unchecked_field?, :has_no_table?, :has_table?, :unselect,
:has_select?, :has_no_select?, :has_selector?, :has_no_selector?, :has_select?, :has_no_select?, :has_selector?, :has_no_selector?,
:click_on, :has_no_checked_field?, :has_no_unchecked_field?, :query :click_on, :has_no_checked_field?, :has_no_unchecked_field?, :query,
:assert_selector!, :assert_no_selector!
] ]
SESSION_METHODS = [ SESSION_METHODS = [
:body, :html, :current_url, :current_host, :evaluate_script, :source, :body, :html, :current_url, :current_host, :evaluate_script, :source,