Skip to content

Commit

Permalink
Adding :count option to have_tag
Browse files Browse the repository at this point in the history
  • Loading branch information
brynary committed Feb 16, 2009
1 parent 932fdab commit 17a8bc7
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 17 deletions.
16 changes: 15 additions & 1 deletion lib/webrat/core/matchers/have_tag.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,19 @@ def negative_failure_message
"expected following output to omit a #{tag_inspect}:\n#{@document}"
end

def matches?(stringlike, &block)
@block ||= block
matched = matches(stringlike)

options = @expected.last.dup

if options[:count]
matched.size == options[:count] && (!@block || @block.call(matched))
else
matched.any? && (!@block || @block.call(matched))
end
end

def tag_inspect
options = @expected.last.dup
content = options.delete(:content)
Expand All @@ -38,7 +51,7 @@ def query
selector = @expected.first.to_s

options.each do |key, value|
next if key == :content
next if [:content, :count].include?(key)
selector << "[#{key}='#{value}']"
end

Expand All @@ -56,6 +69,7 @@ def query
elsif options[:content]
q << "[contains(., '#{options[:content]}')]"
end

q
end
end
Expand Down
21 changes: 11 additions & 10 deletions lib/webrat/core/matchers/have_xpath.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,19 @@ def initialize(expected, &block)

def matches?(stringlike, &block)
@block ||= block

matched = matches(stringlike)
matched.any? && (!@block || @block.call(matched))
end

def matches(stringlike)
if Webrat.configuration.parse_with_nokogiri?
matches_nokogiri?(stringlike)
nokogiri_matches(stringlike)
else
matches_rexml?(stringlike)
rexml_matches(stringlike)
end
end

def matches_rexml?(stringlike)
def rexml_matches(stringlike)
if REXML::Node === stringlike || Array === stringlike
@query = query.map { |q| q.gsub(%r'//', './') }
else
Expand All @@ -29,27 +33,24 @@ def matches_rexml?(stringlike)

@document = Webrat.rexml_document(stringlike)

matched = @query.map do |q|
@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)
def nokogiri_matches(stringlike)
if Nokogiri::XML::NodeSet === stringlike
@query = query.map { |q| q.gsub(%r'//', './') }
else
@query = query
end

@document = Webrat::XML.document(stringlike)
matched = @document.xpath(*@query)
matched.any? && (!@block || @block.call(matched))
@document.xpath(*@query)
end

def query
Expand Down
22 changes: 16 additions & 6 deletions spec/public/matchers_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -178,19 +178,29 @@
end

it "should be able to specify the content of the tag" do
@body.should have_tag("div", :content => "hello, world!")
@body.should have_tag("div", :content => "hello, world!")
end

it "should be able to specify the content of the tag with double quotes in it" do
@body.should have_tag("h2", :content => 'Welcome "Bryan"')
@body.should have_tag("h2", :content => 'Welcome "Bryan"')
end

it "should be able to specify the content of the tag with single quotes in it" do
@body.should have_tag("h3", :content => "Welcome 'Bryan'")
@body.should have_tag("h3", :content => "Welcome 'Bryan'")
end

it "should be able to specify the content of the tag with both kinds of quotes" do
@body.should have_tag("h4", :content => "Welcome 'Bryan\"")
@body.should have_tag("h4", :content => "Welcome 'Bryan\"")
end

it "should be able to specify the number of occurences of the tag" do
@body.should have_tag("li", :count => 2)
end

it "should not match if the count is wrong" do
lambda {
@body.should have_tag("li", :count => 3)
}.should raise_error(Spec::Expectations::ExpectationNotMetError)
end

it "should be able to specify the attributes of the tag" do
Expand Down Expand Up @@ -226,10 +236,10 @@
end

it "should work with items that have multiple child nodes" do
@body.should have_tag("ul") { |n|
@body.should have_tag("ul") do |n|
n.should have_tag("li", :content => "First")
n.should have_tag("li", :content => "Second")
}
end
end

describe "asserts for tags," do
Expand Down

0 comments on commit 17a8bc7

Please sign in to comment.