Make "should contain" matcher work with inner text instead of HTML
This commit is contained in:
parent
b23dcfb213
commit
7b3e6fa118
@ -3,12 +3,31 @@ module Webrat
|
|||||||
|
|
||||||
class HasContent
|
class HasContent
|
||||||
def initialize(content)
|
def initialize(content)
|
||||||
|
# Require nokogiri and fall back on rexml
|
||||||
|
begin
|
||||||
|
require "nokogiri"
|
||||||
|
require "webrat/nokogiri"
|
||||||
|
rescue LoadError => e
|
||||||
|
if require "rexml/document"
|
||||||
|
require "webrat/vendor/nokogiri/css"
|
||||||
|
warn("Standard REXML library is slow. Please consider installing nokogiri.\nUse \"sudo gem install nokogiri\"")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
@content = content
|
@content = content
|
||||||
end
|
end
|
||||||
|
|
||||||
def matches?(element)
|
def matches?(stringlike)
|
||||||
element = element.body.to_s if element.respond_to?(:body)
|
if defined?(Nokogiri::XML)
|
||||||
@element = element
|
matches_nokogiri?(stringlike)
|
||||||
|
else
|
||||||
|
matches_rexml?(stringlike)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def matches_rexml?(stringlike)
|
||||||
|
@document = rexml_document(stringlike)
|
||||||
|
@element = @document.inner_text
|
||||||
|
|
||||||
case @content
|
case @content
|
||||||
when String
|
when String
|
||||||
@ -18,16 +37,63 @@ module Webrat
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def matches_nokogiri?(stringlike)
|
||||||
|
@document = nokogiri_document(stringlike)
|
||||||
|
@element = @document.inner_text
|
||||||
|
|
||||||
|
case @content
|
||||||
|
when String
|
||||||
|
@element.include?(@content)
|
||||||
|
when Regexp
|
||||||
|
@element.match(@content)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def rexml_document(stringlike)
|
||||||
|
stringlike = stringlike.body.to_s if stringlike.respond_to?(:body)
|
||||||
|
|
||||||
|
case stringlike
|
||||||
|
when REXML::Document
|
||||||
|
stringlike.root
|
||||||
|
when REXML::Node
|
||||||
|
stringlike
|
||||||
|
when StringIO, String
|
||||||
|
begin
|
||||||
|
REXML::Document.new(stringlike.to_s).root
|
||||||
|
rescue REXML::ParseException => e
|
||||||
|
if e.message.include?("second root element")
|
||||||
|
REXML::Document.new("<fake-root-element>#{stringlike}</fake-root-element>").root
|
||||||
|
else
|
||||||
|
raise e
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def nokogiri_document(stringlike)
|
||||||
|
return stringlike.dom if stringlike.respond_to?(:dom)
|
||||||
|
stringlike = stringlike.body.to_s if stringlike.respond_to?(:body)
|
||||||
|
|
||||||
|
case stringlike
|
||||||
|
when Nokogiri::HTML::Document, Nokogiri::XML::NodeSet
|
||||||
|
stringlike
|
||||||
|
when StringIO
|
||||||
|
Nokogiri::HTML(stringlike.string)
|
||||||
|
else
|
||||||
|
Nokogiri::HTML(stringlike.to_s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# ==== Returns
|
# ==== Returns
|
||||||
# String:: The failure message.
|
# String:: The failure message.
|
||||||
def failure_message
|
def failure_message
|
||||||
"expected the following element's content to #{content_message}:\n#{@element.inner_text}"
|
"expected the following element's content to #{content_message}:\n#{@element}"
|
||||||
end
|
end
|
||||||
|
|
||||||
# ==== Returns
|
# ==== Returns
|
||||||
# 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 the following element's content to not #{content_message}:\n#{@element.inner_text}"
|
"expected the following element's content to not #{content_message}:\n#{@element}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def content_message
|
def content_message
|
||||||
|
@ -58,31 +58,23 @@ describe Webrat::Matchers do
|
|||||||
include Webrat::Matchers
|
include Webrat::Matchers
|
||||||
|
|
||||||
before(:each) do
|
before(:each) do
|
||||||
@element = stub(:element)
|
@body = <<-EOF
|
||||||
@element.stub!(:inner_text).and_return <<-EOF
|
|
||||||
<div id='main'>
|
<div id='main'>
|
||||||
<div class='inner'>hello, world!</div>
|
<div class='inner'>hello, world!</div>
|
||||||
</div>
|
</div>
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
@element.stub!(:include?)
|
|
||||||
@element.stub!(:match)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#matches?" do
|
describe "#matches?" do
|
||||||
it "should call element#include? when the argument is a string" do
|
it "should call element#include? when the argument is a string" do
|
||||||
@element.should_receive(:include?)
|
@body.should contain("hello, world!")
|
||||||
|
|
||||||
Webrat::Matchers::HasContent.new("hello, world!").matches?(@element)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should call element#match when the argument is a regular expression" do
|
it "should call element#match when the argument is a regular expression" do
|
||||||
@element.should_receive(:match)
|
@body.should contain(/hello, world/)
|
||||||
|
|
||||||
Webrat::Matchers::HasContent.new(/hello, world/).matches?(@element)
|
|
||||||
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!")
|
||||||
@ -100,9 +92,9 @@ describe Webrat::Matchers do
|
|||||||
|
|
||||||
it "should include the element's inner content" do
|
it "should include the element's inner content" 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(@element.inner_text)
|
hc.failure_message.should include("hello, world!")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user