Pulling attribute conditions up from have_selector to have_xpath
This commit is contained in:
parent
1625e3e9ba
commit
29c40bd73c
|
@ -18,6 +18,7 @@ module Webrat
|
||||||
|
|
||||||
def tag_inspect
|
def tag_inspect
|
||||||
options = @options.dup
|
options = @options.dup
|
||||||
|
count = options.delete(:count)
|
||||||
content = options.delete(:content)
|
content = options.delete(:content)
|
||||||
|
|
||||||
html = "<#{@expected}"
|
html = "<#{@expected}"
|
||||||
|
@ -35,29 +36,7 @@ module Webrat
|
||||||
end
|
end
|
||||||
|
|
||||||
def query
|
def query
|
||||||
options = @options.dup
|
Nokogiri::CSS::Parser.parse(@expected.to_s).map { |ast| ast.to_xpath }.first
|
||||||
selector = @expected.to_s
|
|
||||||
|
|
||||||
options.each do |key, value|
|
|
||||||
next if [:content, :count].include?(key)
|
|
||||||
selector << "[#{key}='#{value}']"
|
|
||||||
end
|
|
||||||
|
|
||||||
Nokogiri::CSS::Parser.parse(selector).map { |ast| ast.to_xpath }.first
|
|
||||||
end
|
|
||||||
|
|
||||||
def xpath_escape(string)
|
|
||||||
if string.include?("'") && string.include?('"')
|
|
||||||
parts = string.split("'").map do |part|
|
|
||||||
"'#{part}'"
|
|
||||||
end
|
|
||||||
|
|
||||||
"concat(" + parts.join(", \"'\", ") + ")"
|
|
||||||
elsif string.include?("'")
|
|
||||||
"\"#{string}\""
|
|
||||||
else
|
|
||||||
"'#{string}'"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -37,6 +37,21 @@ module Webrat
|
||||||
@query = query
|
@query = query
|
||||||
end
|
end
|
||||||
|
|
||||||
|
attribute_conditions = []
|
||||||
|
|
||||||
|
@options.each do |key, value|
|
||||||
|
next if [:content, :count].include?(key)
|
||||||
|
attribute_conditions << "@#{key} = #{xpath_escape(value)}"
|
||||||
|
end
|
||||||
|
|
||||||
|
if attribute_conditions.any?
|
||||||
|
@query.first << "[#{attribute_conditions.join(' and ')}]"
|
||||||
|
end
|
||||||
|
|
||||||
|
if @options[:content]
|
||||||
|
@query.first << "[contains(., #{xpath_escape(@options[:content])})]"
|
||||||
|
end
|
||||||
|
|
||||||
@document = Webrat.rexml_document(stringlike)
|
@document = Webrat.rexml_document(stringlike)
|
||||||
|
|
||||||
@query.map do |q|
|
@query.map do |q|
|
||||||
|
@ -55,8 +70,19 @@ module Webrat
|
||||||
@query = query
|
@query = query
|
||||||
end
|
end
|
||||||
|
|
||||||
|
attribute_conditions = []
|
||||||
|
|
||||||
|
@options.each do |key, value|
|
||||||
|
next if [:content, :count].include?(key)
|
||||||
|
attribute_conditions << "@#{key} = #{xpath_escape(value)}"
|
||||||
|
end
|
||||||
|
|
||||||
|
if attribute_conditions.any?
|
||||||
|
@query.first << "[#{attribute_conditions.join(' and ')}]"
|
||||||
|
end
|
||||||
|
|
||||||
if @options[:content]
|
if @options[:content]
|
||||||
query << "[contains(., #{xpath_escape(@options[:content])})]"
|
@query.first << "[contains(., #{xpath_escape(@options[:content])})]"
|
||||||
end
|
end
|
||||||
|
|
||||||
@document = Webrat::XML.document(stringlike)
|
@document = Webrat::XML.document(stringlike)
|
||||||
|
@ -77,7 +103,24 @@ module Webrat
|
||||||
# String:: The failure message to be displayed in negative matches.
|
# String:: The failure message to be displayed in negative matches.
|
||||||
def negative_failure_message
|
def negative_failure_message
|
||||||
"expected following text to not match xpath #{@expected}:\n#{@document}"
|
"expected following text to not match xpath #{@expected}:\n#{@document}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def xpath_escape(string)
|
||||||
|
if string.include?("'") && string.include?('"')
|
||||||
|
parts = string.split("'").map do |part|
|
||||||
|
"'#{part}'"
|
||||||
|
end
|
||||||
|
|
||||||
|
"concat(" + parts.join(", \"'\", ") + ")"
|
||||||
|
elsif string.include?("'")
|
||||||
|
"\"#{string}\""
|
||||||
|
else
|
||||||
|
"'#{string}'"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Matches HTML content against an XPath query
|
# Matches HTML content against an XPath query
|
||||||
|
|
|
@ -22,6 +22,34 @@ describe "have_xpath" do
|
||||||
@body.should have_xpath("//div")
|
@body.should have_xpath("//div")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "should be able to match an XPATH with attributes" do
|
||||||
|
@body.should have_xpath("//div", :class => "inner")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should be able to match an XPATH with content" do
|
||||||
|
@body.should have_xpath("//div", :content => "hello, world!")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should not match an XPATH without content" do
|
||||||
|
@body.should_not have_xpath("//div", :content => "not present")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should be able to match an XPATH with content and class" do
|
||||||
|
@body.should have_xpath("//div", :class => "inner", :content => "hello, world!")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should not match an XPATH with content and wrong class" do
|
||||||
|
@body.should_not have_xpath("//div", :class => "outer", :content => "hello, world!")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should not match an XPATH with wrong content and class" do
|
||||||
|
@body.should_not have_xpath("//div", :class => "inner", :content => "wrong")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should not match an XPATH with wrong content and wrong class" do
|
||||||
|
@body.should_not have_xpath("//div", :class => "outer", :content => "wrong")
|
||||||
|
end
|
||||||
|
|
||||||
it "should not match a XPATH that does not exist" do
|
it "should not match a XPATH that does not exist" do
|
||||||
@body.should_not have_xpath("//p")
|
@body.should_not have_xpath("//p")
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue