Restore support for nested have_xpath, etc. with blocks
This commit is contained in:
parent
055bd568f5
commit
0aad32d38a
@ -30,8 +30,8 @@ module Webrat
|
||||
# HaveSelector:: A new have selector matcher.
|
||||
# ---
|
||||
# @api public
|
||||
def have_selector(expected)
|
||||
HaveSelector.new(expected)
|
||||
def have_selector(expected, &block)
|
||||
HaveSelector.new(expected, &block)
|
||||
end
|
||||
alias_method :match_selector, :have_selector
|
||||
|
||||
|
@ -49,8 +49,8 @@ module Webrat
|
||||
|
||||
end
|
||||
|
||||
def have_tag(name, attributes = {})
|
||||
HaveTag.new([name, attributes])
|
||||
def have_tag(name, attributes = {}, &block)
|
||||
HaveTag.new([name, attributes], &block)
|
||||
end
|
||||
alias_method :match_tag, :have_tag
|
||||
|
||||
|
@ -16,17 +16,31 @@ module Webrat
|
||||
end
|
||||
|
||||
def matches_rexml?(stringlike)
|
||||
@query = query
|
||||
|
||||
@document = rexml_document(stringlike)
|
||||
|
||||
query.all? do |q|
|
||||
matched = REXML::XPath.match(@document, q)
|
||||
matched.any? && (!block_given? || matched.all?(&@block))
|
||||
matched = @query.map do |q|
|
||||
if @document.is_a?(Array)
|
||||
@document.map { |d| REXML::XPath.match(d, q) }
|
||||
else
|
||||
REXML::XPath.match(@document, q)
|
||||
end
|
||||
end.flatten.compact
|
||||
|
||||
matched.any? && (!@block || @block.call(matched))
|
||||
end
|
||||
|
||||
def matches_nokogiri?(stringlike)
|
||||
if Nokogiri::XML::NodeSet === stringlike
|
||||
@query = query.map { |q| q.gsub(%r'//', './') }
|
||||
else
|
||||
@query = query
|
||||
end
|
||||
|
||||
@document = Webrat.nokogiri_document(stringlike)
|
||||
@document.xpath(*query).any?
|
||||
matched = @document.xpath(*@query)
|
||||
matched.any? && (!@block || @block.call(matched))
|
||||
end
|
||||
|
||||
def rexml_document(stringlike)
|
||||
@ -35,9 +49,10 @@ module Webrat
|
||||
case stringlike
|
||||
when REXML::Document
|
||||
stringlike.root
|
||||
when REXML::Node
|
||||
when REXML::Node, Array
|
||||
@query = query.map { |q| q.gsub(%r'//', './') }
|
||||
stringlike
|
||||
when StringIO, String
|
||||
else
|
||||
begin
|
||||
REXML::Document.new(stringlike.to_s).root
|
||||
rescue REXML::ParseException => e
|
||||
@ -76,8 +91,8 @@ module Webrat
|
||||
# HaveXpath:: A new have xpath matcher.
|
||||
# ---
|
||||
# @api public
|
||||
def have_xpath(expected)
|
||||
HaveXpath.new(expected)
|
||||
def have_xpath(expected, &block)
|
||||
HaveXpath.new(expected, &block)
|
||||
end
|
||||
alias_method :match_xpath, :have_xpath
|
||||
|
||||
|
@ -5,9 +5,11 @@ module Webrat
|
||||
def self.nokogiri_document(stringlike) #:nodoc:
|
||||
return stringlike.dom if stringlike.respond_to?(:dom)
|
||||
|
||||
if stringlike === Nokogiri::HTML::Document || stringlike === Nokogiri::XML::NodeSet
|
||||
if Nokogiri::HTML::Document === stringlike
|
||||
stringlike
|
||||
elsif stringlike === StringIO
|
||||
elsif Nokogiri::XML::NodeSet === stringlike
|
||||
stringlike
|
||||
elsif StringIO === stringlike
|
||||
Nokogiri::HTML(stringlike.string)
|
||||
elsif stringlike.respond_to?(:body)
|
||||
Nokogiri::HTML(stringlike.body.to_s)
|
||||
|
@ -8,10 +8,50 @@ describe Webrat::Matchers do
|
||||
@body = <<-EOF
|
||||
<div id='main'>
|
||||
<div class='inner'>hello, world!</div>
|
||||
<ul>
|
||||
<li>First</li>
|
||||
<li>Second</li>
|
||||
</ul>
|
||||
</div>
|
||||
EOF
|
||||
end
|
||||
|
||||
describe "#have_xpath" do
|
||||
|
||||
it "should be able to match an XPATH" do
|
||||
@body.should have_xpath("//div")
|
||||
end
|
||||
|
||||
it "should not match a XPATH that does not exist" do
|
||||
@body.should_not have_xpath("//p")
|
||||
end
|
||||
|
||||
it "should be able to loop over all the matched elements" do
|
||||
@body.should have_xpath("//div") { |node| node.first.name.should == "div" }
|
||||
end
|
||||
|
||||
it "should not match of any of the matchers in the block fail" do
|
||||
lambda {
|
||||
@body.should have_xpath("//div") { |node| node.first.name.should == "p" }
|
||||
}.should raise_error(Spec::Expectations::ExpectationNotMetError)
|
||||
end
|
||||
|
||||
it "should be able to use #have_xpath in the block" do
|
||||
@body.should have_xpath("//div[@id='main']") { |node| node.should have_xpath("./div[@class='inner']") }
|
||||
end
|
||||
|
||||
it "should convert absolute paths to relative in the block" do
|
||||
@body.should have_xpath("//div[@id='main']") { |node| node.should have_xpath("//div[@class='inner']") }
|
||||
end
|
||||
|
||||
it "should not match any parent tags in the block" do
|
||||
lambda {
|
||||
@body.should have_xpath("//div[@class='inner']") { |node| node.should have_xpath("//div[@id='main']") }
|
||||
}.should raise_error(Spec::Expectations::ExpectationNotMetError)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "#have_selector" do
|
||||
|
||||
it "should be able to match a CSS selector" do
|
||||
@ -23,12 +63,22 @@ describe Webrat::Matchers do
|
||||
end
|
||||
|
||||
it "should be able to loop over all the matched elements" do
|
||||
@body.should have_selector("div") { |node| node.name.should == "div" }
|
||||
@body.should have_selector("div") { |node| node.first.name.should == "div" }
|
||||
end
|
||||
|
||||
it "should not match of any of the matchers in the block fail" do
|
||||
lambda {
|
||||
@body.should_not have_selector("div") { |node| node.name.should == "p" }
|
||||
@body.should have_selector("div") { |node| node.first.name.should == "p" }
|
||||
}.should raise_error(Spec::Expectations::ExpectationNotMetError)
|
||||
end
|
||||
|
||||
it "should be able to use #have_selector in the block" do
|
||||
@body.should have_selector("#main") { |node| node.should have_selector(".inner") }
|
||||
end
|
||||
|
||||
it "should not match any parent tags in the block" do
|
||||
lambda {
|
||||
@body.should have_selector(".inner") { |node| node.should have_selector("#main") }
|
||||
}.should raise_error(Spec::Expectations::ExpectationNotMetError)
|
||||
end
|
||||
|
||||
@ -52,6 +102,33 @@ describe Webrat::Matchers do
|
||||
@body.should have_tag("div", :class => "inner")
|
||||
end
|
||||
|
||||
it "should be able to loop over all the matched elements" do
|
||||
@body.should have_tag("div") { |node| node.first.name.should == "div" }
|
||||
end
|
||||
|
||||
it "should not match of any of the matchers in the block fail" do
|
||||
lambda {
|
||||
@body.should have_tag("div") { |node| node.first.name.should == "p" }
|
||||
}.should raise_error(Spec::Expectations::ExpectationNotMetError)
|
||||
end
|
||||
|
||||
it "should be able to use #have_tag in the block" do
|
||||
@body.should have_tag("div", :id => "main") { |node| node.should have_tag("div", :class => "inner") }
|
||||
end
|
||||
|
||||
it "should not match any parent tags in the block" do
|
||||
lambda {
|
||||
@body.should have_tag("div", :class => "inner") { |node| node.should have_tag("div", :id => "main") }
|
||||
}.should raise_error(Spec::Expectations::ExpectationNotMetError)
|
||||
end
|
||||
|
||||
it "should work with items that have multiple child nodes" do
|
||||
@body.should have_tag("ul") { |n|
|
||||
n.should have_tag("li", :content => "First")
|
||||
n.should have_tag("li", :content => "Second")
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe Webrat::Matchers::HasContent do
|
||||
@ -66,11 +143,11 @@ describe Webrat::Matchers do
|
||||
end
|
||||
|
||||
describe "#matches?" do
|
||||
it "should call element#include? when the argument is a string" do
|
||||
it "should call element#contains? when the argument is a string" do
|
||||
@body.should contain("hello, world!")
|
||||
end
|
||||
|
||||
it "should call element#match when the argument is a regular expression" do
|
||||
it "should call element#matches? when the argument is a regular expression" do
|
||||
@body.should contain(/hello, world/)
|
||||
end
|
||||
end
|
||||
@ -78,14 +155,14 @@ describe Webrat::Matchers do
|
||||
describe "#failure_message" do
|
||||
it "should include the content string" do
|
||||
hc = Webrat::Matchers::HasContent.new("hello, world!")
|
||||
hc.matches?(@element)
|
||||
hc.matches?(@body)
|
||||
|
||||
hc.failure_message.should include("\"hello, world!\"")
|
||||
end
|
||||
|
||||
it "should include the content regular expresson" do
|
||||
hc = Webrat::Matchers::HasContent.new(/hello,\sworld!/)
|
||||
hc.matches?(@element)
|
||||
hc.matches?(@body)
|
||||
|
||||
hc.failure_message.should include("/hello,\\sworld!/")
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user