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.
|
# HaveSelector:: A new have selector matcher.
|
||||||
# ---
|
# ---
|
||||||
# @api public
|
# @api public
|
||||||
def have_selector(expected)
|
def have_selector(expected, &block)
|
||||||
HaveSelector.new(expected)
|
HaveSelector.new(expected, &block)
|
||||||
end
|
end
|
||||||
alias_method :match_selector, :have_selector
|
alias_method :match_selector, :have_selector
|
||||||
|
|
||||||
|
@ -49,8 +49,8 @@ module Webrat
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def have_tag(name, attributes = {})
|
def have_tag(name, attributes = {}, &block)
|
||||||
HaveTag.new([name, attributes])
|
HaveTag.new([name, attributes], &block)
|
||||||
end
|
end
|
||||||
alias_method :match_tag, :have_tag
|
alias_method :match_tag, :have_tag
|
||||||
|
|
||||||
|
@ -16,17 +16,31 @@ module Webrat
|
|||||||
end
|
end
|
||||||
|
|
||||||
def matches_rexml?(stringlike)
|
def matches_rexml?(stringlike)
|
||||||
|
@query = query
|
||||||
|
|
||||||
@document = rexml_document(stringlike)
|
@document = rexml_document(stringlike)
|
||||||
|
|
||||||
query.all? do |q|
|
matched = @query.map do |q|
|
||||||
matched = REXML::XPath.match(@document, q)
|
if @document.is_a?(Array)
|
||||||
matched.any? && (!block_given? || matched.all?(&@block))
|
@document.map { |d| REXML::XPath.match(d, q) }
|
||||||
end
|
else
|
||||||
|
REXML::XPath.match(@document, q)
|
||||||
|
end
|
||||||
|
end.flatten.compact
|
||||||
|
|
||||||
|
matched.any? && (!@block || @block.call(matched))
|
||||||
end
|
end
|
||||||
|
|
||||||
def matches_nokogiri?(stringlike)
|
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 = Webrat.nokogiri_document(stringlike)
|
||||||
@document.xpath(*query).any?
|
matched = @document.xpath(*@query)
|
||||||
|
matched.any? && (!@block || @block.call(matched))
|
||||||
end
|
end
|
||||||
|
|
||||||
def rexml_document(stringlike)
|
def rexml_document(stringlike)
|
||||||
@ -35,9 +49,10 @@ module Webrat
|
|||||||
case stringlike
|
case stringlike
|
||||||
when REXML::Document
|
when REXML::Document
|
||||||
stringlike.root
|
stringlike.root
|
||||||
when REXML::Node
|
when REXML::Node, Array
|
||||||
|
@query = query.map { |q| q.gsub(%r'//', './') }
|
||||||
stringlike
|
stringlike
|
||||||
when StringIO, String
|
else
|
||||||
begin
|
begin
|
||||||
REXML::Document.new(stringlike.to_s).root
|
REXML::Document.new(stringlike.to_s).root
|
||||||
rescue REXML::ParseException => e
|
rescue REXML::ParseException => e
|
||||||
@ -76,8 +91,8 @@ module Webrat
|
|||||||
# HaveXpath:: A new have xpath matcher.
|
# HaveXpath:: A new have xpath matcher.
|
||||||
# ---
|
# ---
|
||||||
# @api public
|
# @api public
|
||||||
def have_xpath(expected)
|
def have_xpath(expected, &block)
|
||||||
HaveXpath.new(expected)
|
HaveXpath.new(expected, &block)
|
||||||
end
|
end
|
||||||
alias_method :match_xpath, :have_xpath
|
alias_method :match_xpath, :have_xpath
|
||||||
|
|
||||||
|
@ -5,9 +5,11 @@ module Webrat
|
|||||||
def self.nokogiri_document(stringlike) #:nodoc:
|
def self.nokogiri_document(stringlike) #:nodoc:
|
||||||
return stringlike.dom if stringlike.respond_to?(:dom)
|
return stringlike.dom if stringlike.respond_to?(:dom)
|
||||||
|
|
||||||
if stringlike === Nokogiri::HTML::Document || stringlike === Nokogiri::XML::NodeSet
|
if Nokogiri::HTML::Document === stringlike
|
||||||
stringlike
|
stringlike
|
||||||
elsif stringlike === StringIO
|
elsif Nokogiri::XML::NodeSet === stringlike
|
||||||
|
stringlike
|
||||||
|
elsif StringIO === stringlike
|
||||||
Nokogiri::HTML(stringlike.string)
|
Nokogiri::HTML(stringlike.string)
|
||||||
elsif stringlike.respond_to?(:body)
|
elsif stringlike.respond_to?(:body)
|
||||||
Nokogiri::HTML(stringlike.body.to_s)
|
Nokogiri::HTML(stringlike.body.to_s)
|
||||||
|
@ -8,10 +8,50 @@ describe Webrat::Matchers do
|
|||||||
@body = <<-EOF
|
@body = <<-EOF
|
||||||
<div id='main'>
|
<div id='main'>
|
||||||
<div class='inner'>hello, world!</div>
|
<div class='inner'>hello, world!</div>
|
||||||
|
<ul>
|
||||||
|
<li>First</li>
|
||||||
|
<li>Second</li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
EOF
|
EOF
|
||||||
end
|
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
|
describe "#have_selector" do
|
||||||
|
|
||||||
it "should be able to match a CSS selector" do
|
it "should be able to match a CSS selector" do
|
||||||
@ -23,12 +63,22 @@ describe Webrat::Matchers do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "should be able to loop over all the matched elements" do
|
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
|
end
|
||||||
|
|
||||||
it "should not match of any of the matchers in the block fail" do
|
it "should not match of any of the matchers in the block fail" do
|
||||||
lambda {
|
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)
|
}.should raise_error(Spec::Expectations::ExpectationNotMetError)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -52,11 +102,38 @@ describe Webrat::Matchers do
|
|||||||
@body.should have_tag("div", :class => "inner")
|
@body.should have_tag("div", :class => "inner")
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
describe Webrat::Matchers::HasContent do
|
describe Webrat::Matchers::HasContent do
|
||||||
include Webrat::Matchers
|
include Webrat::Matchers
|
||||||
|
|
||||||
before(:each) do
|
before(:each) do
|
||||||
@body = <<-EOF
|
@body = <<-EOF
|
||||||
<div id='main'>
|
<div id='main'>
|
||||||
@ -66,26 +143,26 @@ describe Webrat::Matchers do
|
|||||||
end
|
end
|
||||||
|
|
||||||
describe "#matches?" do
|
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!")
|
@body.should contain("hello, world!")
|
||||||
end
|
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/)
|
@body.should contain(/hello, world/)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#failure_message" do
|
describe "#failure_message" do
|
||||||
it "should include the content string" do
|
it "should include the content string" do
|
||||||
hc = Webrat::Matchers::HasContent.new("hello, world!")
|
hc = Webrat::Matchers::HasContent.new("hello, world!")
|
||||||
hc.matches?(@element)
|
hc.matches?(@body)
|
||||||
|
|
||||||
hc.failure_message.should include("\"hello, world!\"")
|
hc.failure_message.should include("\"hello, world!\"")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should include the content regular expresson" do
|
it "should include the content regular expresson" do
|
||||||
hc = Webrat::Matchers::HasContent.new(/hello,\sworld!/)
|
hc = Webrat::Matchers::HasContent.new(/hello,\sworld!/)
|
||||||
hc.matches?(@element)
|
hc.matches?(@body)
|
||||||
|
|
||||||
hc.failure_message.should include("/hello,\\sworld!/")
|
hc.failure_message.should include("/hello,\\sworld!/")
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user