# frozen_string_literal: false
require_relative "../rexml_test_utils"
require "rexml/document"
module REXMLTests
class TestXPathBase < Test::Unit::TestCase
include REXMLTestUtils
include REXML
SOURCE = <<-EOF
EOF
JENI_TENNISON = <<-EOJT
EOJT
def setup
@@doc = Document.new(SOURCE) unless defined? @@doc
@@jeni = Document.new( JENI_TENNISON ) unless defined? @@jeni
end
def each_test( element, xpath )
count = 0
XPath::each( element, xpath ) { |child|
count += 1
yield child if block_given?
}
count
end
def test_descendant
doc = Document.new("")
p = XPath.match( doc, "//c" )
assert_equal( 2, p.size )
p = XPath.first( @@doc, "//p" )
assert_equal "p", p.name
c = each_test( @@doc, "//c" ) { |child| assert_equal "c", child.name }
assert_equal 5, c
c = each_test( @@doc.root, "b//c" ) { |child|
assert_equal "c", child.name
}
assert_equal 2, c
doc = Document.new( "" )
# //para[1] : all descendants which are the first para child of their parent
assert_equal( 4, XPath.match( doc, "//z[1]" ).size )
# /descendant::para[1] : the first descendant para element
assert_equal( 1, XPath.match( doc, "/descendant::z[1]" ).size )
end
def test_root
source = ""
doc = Document.new( source )
assert_equal doc, doc.root_node
assert_equal "a", XPath::first( doc, "/" ).elements[1].name
end
def test_abbreviated_simple_child
assert_equal "a", XPath::first(@@doc, "a").name
end
def test_child
c = XPath::first( @@doc, "a/b/c" )
assert_equal "c", c.name
assert_equal "3", XPath::first(@@doc, "a/b/c").attributes["id"]
end
def test_root_child
assert_equal "a", XPath::first(@@doc, "/a").name
c = XPath::first( @@doc, "a/b/c" )
assert_equal "a", XPath::first(c, "/a").name
end
def test_root_children
c = XPath::first( @@doc, "a/b/c" )
assert_equal "2", XPath::first(c, "/a/b").attributes["id"]
end
def test_abbreviated_step
c = XPath::first( @@doc, "a/b/c" )
assert_equal("c", c.name)
assert_equal("a", XPath::first(@@doc.root, ".").name)
assert_equal("b", XPath::first(c, "..").name)
assert_equal("a", XPath::first(@@doc, "a/b/..").name)
doc = File.open(fixture_path("project.xml")) do |f|
REXML::Document.new(f)
end
c = each_test(doc.root, "./Description" ) { |child|
assert_equal("Description",child.name)
}
assert_equal 1, c
end
# Things that aren't tested elsewhere
def test_predicates
assert_equal "12", XPath::first(@@doc, "a/e/f[3]").attributes["id"]
assert_equal "13", XPath::first(@@doc, "a/e/f[3]/g").attributes["id"]
assert_equal "14", XPath::first(@@doc, "a/e/f[@a='d'][2]").attributes["id"]
assert_equal "14", XPath::first(@@doc, "a/e/f[@a='d'][@id='14']").attributes["id"]
assert_equal "a", XPath::first( @@doc, "*[name()='a' and @id='1']" ).name
c=each_test( @@doc, "//*[name()='f' and @a='d']") { |i|
assert_equal "f", i.name
}
assert_equal 2, c
c=each_test( @@doc, "//*[name()='m' or @a='d']") { |i|
assert ["m","f"].include?(i.name)
}
assert_equal 3, c
assert_equal "b", XPath::first( @@doc, "//b[@x]" ).name
end
def test_node_type
doc = Document.new "text"
#res = XPath::first(doc.root, "text()")
#assert_equal "text", res.to_s
#res = XPath::first(doc, "*")
#assert_equal "a", res.name
assert_equal( :processing_instruction,
XPath::first(doc.root, "processing-instruction()").node_type)
assert_equal( :comment, XPath::first(doc.root, "comment()").node_type)
end
def test_functions
# trivial text() test
# confuse-a-function
source = "more dumb text"
doc = Document.new source
res = ""
#XPath::each(doc.root, "text()") {|val| res << val.to_s}
#assert_equal "more text", res
#res = XPath::first(doc.root, "b[last()]")
#assert_equal '3', res.attributes['id']
res = XPath::first(doc.root, "b[position()=2]")
assert_equal '2', res.attributes['id']
res = XPath::first(doc.root, "*[name()='c']")
assert_equal "c", res.name
end
def no_test_ancestor
doc = REXML::Document.new(File.new(fixture_path("testsrc.xml")))
doc.elements.each("//item") { |el| print el.name
if el.attributes['x']
puts " -- "+el.attributes['x']
else
puts
end
}
doc.elements.each("//item/ancestor::") { |el| print el.name
if el.attributes['x']
puts " -- "+el.attributes['x']
else
puts
end
}
end
# Here are some XPath tests that were originally submitted by ...
# The code has changed some, but the logic and the source documents are the
# same.
# This method reads a document from a file, and then a series of xpaths,
# also from a file. It then checks each xpath against the source file.
def test_more
xmlsource = fixture_path("testsrc.xml")
xpathtests = fixture_path("xp.tst")
doc = File.open(xmlsource) {|f| REXML::Document.new(f) }
#results = ""
results = REXML::Document.new
results.add_element "test-results"
File.foreach(xpathtests) do |line|
line.strip!
begin
doc.root
#puts "#"*80
#print "\nDoing #{line} " ; $stdout.flush
doc.elements.each(line) do |el|
#print "." ; $stdout.flush
results.root << el.clone
#results << el.to_s
end
#ObjectSpace.garbage_collect
GC::start
rescue Exception => z
#puts "\n'#{line}' failed"
fail("Error on line #{line}:\n#{z.message}\n"+z.backtrace[0,10].join("\n"))
#results.root.add_element( "error", {"path"=>line}).text = z.message+"\n"+z.backtrace[0,10].join("\n")
#results << ""+z.message+""
end
end
end
def test_axe_descendant
assert_equal "f", XPath::first( @@doc, "descendant::f").name
end
def test_axe_parent
q = XPath.first( @@doc, "a/d/c/parent::*/q" )
assert_equal 19, q.attributes["id"].to_i
end
def test_abbreviated_attribute
assert_equal 'a', XPath::first( @@doc, "a[@id='1']" ).name
c = XPath::first( @@doc, "a/b/c[@id='4']" )
assert_equal 'c', c.name
assert_equal '4', c.attributes['id']
result = XPath::first( @@doc, "descendant::f[@a='c']")
assert_equal "11", result.attributes['id']
assert_equal "11", XPath::first(@@doc, "a/e/f[@a='c']").attributes["id"]
assert_equal "11", XPath::first(@@doc, "a/e/*[@a='c']").attributes["id"]
end
def test_axe_self
c = XPath::first( @@doc, "a/b/c" )
assert c
assert_equal "c", c.name
assert_equal "c", XPath::first( c, "self::node()" ).name
end
def test_axe_ancestor
doc = REXML::Document.new "
"
d = XPath.first( doc, "//d" )
assert_equal "d", d.name
b = each_test( d, "ancestor::b" ) { |el|
assert((1..2) === el.attributes['id'].to_i,
"Expected #{el.attributes['id']} to be either 1 or 2"
)
}
assert_equal 2, b
end
def test_axe_child
m = XPath.first( @@doc, "a/child::m" )
assert_equal 15, m.attributes['id'].to_i
end
def test_axe_attribute
a = XPath.first( @@doc, "a/attribute::id" )
assert_equal "1", a.value
a = XPath.first( @@doc, "a/e/f[@id='14']/attribute::a" )
assert_equal "d", a.value
end
def test_axe_sibling
doc = Document.new ""
first_f = XPath.first( doc, "a/e/f" )
assert first_f
assert_equal '10', first_f.attributes['id']
next_f = XPath.first( doc, "a/e/f/following-sibling::node()" )
assert_equal '11', next_f.attributes['id']
b = XPath.first( doc, "a/e/preceding-sibling::node()" )
assert_equal 'b', b.name
end
def test_lang
doc = File.open(fixture_path("lang0.xml")) {|f| Document.new(f) }
#puts IO.read( "test/lang.xml" )
#puts XPath.match( doc, "//language/*" ).size
c = each_test( doc, "//language/*" ) { |element|
#puts "#{element.name}: #{element.text}"
}
assert_equal 4, c
end
def test_namespaces_1
source = <<-EOF
this bar
that bar
EOF
doc = Document.new source
XPath.each( doc, "//bar" ) {
fail "'bar' should match nothing in this case"
}
namespace = {"t"=>"this"}
results = XPath.first( doc, "//t:bar", namespace )
assert_equal "this bar", results.text
end
def test_namespaces_2
source = <<-EOF
this bar
that bar
EOF
doc = Document.new source
res = XPath::first(doc, "//*[local_name()='bar']")
assert res, "looking for //*[name()='bar']"
assert_equal 'this', res.namespace
res = XPath::first(doc.root, "*[namespace_uri()='that']")
assert_equal 'that bar', res.text
end
def test_complex
next_f = XPath.first( @@doc, "a/e/f[@id='11']/following-sibling::*" )
assert_equal 12, next_f.attributes['id'].to_i
prev_f = XPath.first( @@doc, "a/e/f[@id='11']/preceding-sibling::*" )
assert_equal 10, prev_f.attributes['id'].to_i
c = each_test( @@doc, "descendant-or-self::*[@x='y']" )
assert_equal 2, c
end
def test_grouping
t = XPath.first( @@doc, "a/d/*[name()='d' and (name()='f' or name()='q')]" )
assert_nil t
t = XPath.first( @@doc, "a/d/*[(name()='d' and name()='f') or name()='q']" )
assert_equal 'q', t.name
end
def test_preceding
d = Document.new ""
start = XPath.first( d, "/a/b[@id='1']" )
assert_equal 'b', start.name
c = XPath.first( start, "preceding::c" )
assert_equal '2', c.attributes['id']
c1, c0 = XPath.match( d, "/a/b/c[@id='2']/preceding::node()" )
assert_equal '1', c1.attributes['id']
assert_equal '0', c0.attributes['id']
c2, c1, c0, b, b2, b0 = XPath.match( start, "preceding::node()" )
assert_equal 'c', c2.name
assert_equal 'c', c1.name
assert_equal 'c', c0.name
assert_equal 'b', b.name
assert_equal 'b', b2.name
assert_equal 'b', b0.name
assert_equal '2', c2.attributes['id']
assert_equal '1', c1.attributes['id']
assert_equal '0', c0.attributes['id']
assert b.attributes.empty?
assert_equal '2', b2.attributes['id']
assert_equal '0', b0.attributes['id']
d = REXML::Document.new("")
matches = REXML::XPath.match(d, "/a/d/preceding::node()")
assert_equal("c", matches[0].name)
assert_equal("b", matches[1].name)
s = ""
d = REXML::Document.new(s)
c = REXML::XPath.match( d, "//c[@id = '5']")
cs = REXML::XPath.match( c, "preceding::c" )
assert_equal( 4, cs.length )
end
def test_following
d = Document.new ""
start = XPath.first( d, "/a/b[@id='0']" )
assert_equal 'b', start.name
c = XPath.first( start, "following::c" )
assert_equal '1', c.attributes['id']
s = ""
d = Document.new(s)
c = XPath.first(d, '/a/b/c')
assert_equal 'c', c.name
res = XPath.match( c, 'following::*' )
assert_equal 6, res.size
res = XPath.match( c, 'following::i' )
assert_equal 2, res.size
end
# The following three paths were provided by
# Jeni Tennison
# a consultant who is also an XSL and XPath expert
#def test_child_cubed
# els = @@jeni.elements.to_a("*****")
# assert_equal 3, els.size
#end
#def test_div_2
# results = doc.elements.to_a("/ div 2")
#end
#def test_nested_predicates
# puts @@jeni.root.elements[1].elements[1].name
# results = @@jeni.root.elements[1].elements[1].elements.to_a("../following-sibling::*[*[name() = name(current())]]")
# puts results
#end
# Contributed by Mike Stok
def test_starts_with
source = <<-EOF
a@b.c
http://www.foo.com
EOF
doc = Document.new source
mailtos = doc.elements.to_a("//a[starts-with(@href, 'mailto:')]")
assert_equal 1, mailtos.size
assert_equal "mailto:a@b.c", mailtos[0].attributes['href']
ailtos = doc.elements.to_a("//a[starts-with(@href, 'ailto:')]")
assert_equal 0, ailtos.size
end
def test_toms_text_node
file = "ABCDEF"
doc = Document.new(file)
assert_equal 'A', XPath.first(doc[0], 'text()').to_s
assert_equal 'AF', XPath.match(doc[0], 'text()').collect { |n|
n.to_s
}.join('')
assert_equal 'B', XPath.first(doc[0], 'b/text()').to_s
assert_equal 'D', XPath.first(doc[0], '//d/text()').to_s
assert_equal 'ABCDEF', XPath.match(doc[0], '//text()').collect {|n|
n.to_s
}.join('')
end
def test_string_length
doc = Document.new <<-EOF
EOF
assert doc, "create doc"
set = doc.elements.to_a("//*[string-length(name()) = 3]")
assert_equal 2, set.size, "nodes with names length = 3"
set = doc.elements.to_a("//*[string-length(name()) < 3]")
assert_equal 2, set.size, "nodes with names length < 3"
set = doc.elements.to_a("//*[string-length(name()) > 3]")
assert_equal 3, set.size, "nodes with names length > 3"
end
# Test provided by Mike Stok
def test_contains
source = <<-EOF
a@b.c
http://www.foo.com
EOF
doc = Document.new source
[
#['o', 2],
['foo', 1], ['bar', 0]].each { |search, expected|
set = doc.elements.to_a("//a[contains(@href, '#{search}')]")
assert_equal expected, set.size
}
end
# Mike Stok and Sean Russell
def test_substring
# examples from http://www.w3.org/TR/xpath#function-substring
doc = Document.new('')
Document.new("")
#puts XPath.first(d, 'node()[0 + 1]')
#d = Document.new("")
#puts XPath.first(d, 'a[0 mod 0]')
[ [1.5, 2.6, '234'],
[0, 3, '12'],
[0, '0 div 0', ''],
[1, '0 div 0', ''],
['-42', '1 div 0', '12345'],
['-1 div 0', '1 div 0', '']
].each { |start, length, expected|
set = doc.elements.to_a("//test[substring(@string, #{start}, #{length}) = '#{expected}']")
assert_equal 1, set.size, "#{start}, #{length}, '#{expected}'"
}
end
def test_translate
source = <<-EOF
EOF
doc = Document.new(source)
[ ['bar', 'abc', 'ABC', 'w3c one'],
['--aaa--','abc-','ABC', 'w3c two'],
['lead', 'dear language', 'doll groover', 'alchemy'],
['A Space Odissei', 'i', 'y', 'vbxml one'],
['abcdefg', 'aceg', 'ACE', 'vbxml two'],
].each { |arg1, arg2, arg3, name|
translate = "translate('#{arg1}', '#{arg2}', '#{arg3}')"
set = doc.elements.to_a("//case[@result = #{translate}]")
assert_equal 1, set.size, translate
assert_equal name, set[0].attributes['name']
}
end
def test_math
d = Document.new( '' )
assert XPath.first( d.root, 'node()[1]' )
assert_equal 'b', XPath.first( d.root, 'node()[1]' ).name
assert XPath.first( d.root, 'node()[0 + 1]' )
assert_equal 'b', XPath.first( d.root, './node()[0 + 1]' ).name
assert XPath.first( d.root, 'node()[1 + 1]' )
assert_equal 'c', XPath.first( d.root, './node()[1 + 1]' ).name
assert XPath.first( d.root, 'node()[4 div 2]' )
assert_equal 'c', XPath.first( d.root, './node()[4 div 2]' ).name
assert XPath.first( d.root, 'node()[2 - 1]' )
assert_equal 'b', XPath.first( d.root, './node()[2 - 1]' ).name
assert XPath.first( d.root, 'node()[5 mod 2]' )
assert_equal 'b', XPath.first( d.root, './node()[5 mod 2]' ).name
assert XPath.first( d.root, 'node()[8 mod 3]' )
assert_equal 'c', XPath.first( d.root, './node()[8 mod 3]' ).name
assert XPath.first( d.root, 'node()[1 * 2]' )
assert_equal 'c', XPath.first( d.root, './node()[1 * 2]' ).name
assert XPath.first( d.root, 'node()[2 + -1]' )
assert_equal 'b', XPath.first( d.root, './node()[2 + -1]' ).name
end
def test_name
assert_raise( UndefinedNamespaceException, "x should be undefined" ) {
REXML::Document.new("")
}
d = REXML::Document.new("")
assert_equal 1, d.root.elements.to_a('*[name() = "b"]').size
assert_equal 1, d.elements.to_a('//*[name() = "x:b"]').size
end
def test_local_name
d = REXML::Document.new("")
assert_equal 2, d.root.elements.to_a('*[local_name() = "b"]').size
assert_equal 2, d.elements.to_a('//*[local_name() = "b"]').size
end
def test_comparisons
source = ""
doc = REXML::Document.new(source)
# NOTE TO SER: check that number() is required
assert_equal 2, REXML::XPath.match(doc, "//b[number(@id) > 1]").size
assert_equal 3, REXML::XPath.match(doc, "//b[number(@id) >= 1]").size
assert_equal 1, REXML::XPath.match(doc, "//b[number(@id) <= 1]").size
assert_equal 1, REXML::XPath.match(doc, "//b[number(@id) = (1 * 1)]").size
assert_equal 1, REXML::XPath.match(doc, "//b[number(@id) = (1 mod 2)]").size
assert_equal 1, REXML::XPath.match(doc, "//b[number(@id) = (4 div 2)]").size
end
# Contributed by Kouhei
def test_substring_before
doc = Document.new("")
assert_equal("a", doc.root.elements.to_a("*[name()=substring-before('abc', 'b')]")[0].name)
assert_equal("c", doc.root.elements.to_a("*[name()=substring-after('abc', 'b')]")[0].name)
end
def test_spaces
doc = Document.new("
")
match = lambda do |xpath|
REXML::XPath.match(doc, xpath).collect(&:to_s)
end
assert_equal([""],
match.call("//*[local-name()='c' and @id='b']"))
assert_equal([""],
match.call("//*[ local-name()='c' and @id='b' ]"))
assert_equal([""],
match.call("//*[ local-name() = 'c' and @id = 'b' ]"))
assert_equal(["", ""],
match.call('/a/c[@id]'))
assert_equal(["", ""],
match.call('/a/c[(@id)]'))
assert_equal(["", ""],
match.call('/a/c[ @id ]'))
assert_equal(["", ""],
match.call('/a/c[ (@id) ]'))
assert_equal(["", ""],
match.call('/a/c[( @id )]'))
assert_equal(["", ""],
match.call('/a/c[ ( @id ) ]'))
assert_equal(["", ""],
match.call('/a/c [ ( @id ) ] '))
assert_equal(["", ""],
match.call(' / a / c [ ( @id ) ] '))
assert_equal(["", ""],
match.call('/ a / child:: c [( @id )] /'))
end
def test_text_nodes
# source = "
#
#test
#"
source = "test"
d = REXML::Document.new( source )
r = REXML::XPath.match( d, %q{/root/child[text()="test"]} )
assert_equal( 1, r.size )
assert_equal( "child", r[0].name )
assert_equal( "test", r[0].text )
end
def test_auto_string_value
source = "Introduction"
d = REXML::Document.new( source )
#r = REXML::XPath.match( d, %q{/root[title="Introduction"]} )
#assert_equal( 1, r.size )
source = "test"
d = REXML::Document.new( source )
r = REXML::XPath.match( d, %q{/a[c='test']} )
assert_equal( 1, r.size )
r = REXML::XPath.match( d, %q{a[c='test']} )
assert_equal( 1, r.size )
r = d.elements["/a[c='test']"]
assert_not_nil( r )
r = d.elements["a[c='test']"]
assert_not_nil( r )
r = d.elements["a[c='xtest']"]
assert_nil( r )
r = REXML::XPath.match( d, %q{a[c='xtest']} )
assert_equal( 0, r.size )
end
def test_ordering
source = <<-XML
XML
d = REXML::Document.new( source )
r = REXML::XPath.match( d, %q{/a/*/*[1]} )
assert_equal(["1"],
r.collect {|element| element.attribute("id").value})
end
def test_descendant_or_self_ordering
source = "
"
d = REXML::Document.new( source )
cs = XPath.match( d, "/descendant-or-self::c" )
assert_equal( 4, cs.length )
1.upto(4) {|x| assert_equal( x.to_s, cs[x-1].attributes['id'] ) }
end
def test_and
d = Document.new %q{}
assert_equal( nil, d.root.elements["route[@run='0']"] )
assert_equal( nil, d.root.elements["route[@run='0' and @title='HNO']"] )
end
def test_numbers
d = Document.new %q{}
xp1 = "/a[ @x = 0 ]"
xp2 = "/a[ @x = '0' ]"
xp3 = "/a[ (@x + 1) = 1 ]"
xp4 = "/a[ @y = 0 ]"
xp5 = "/a[ (@z + 1) = 5 ]"
xp6 = "/a[ (@w + 1) = 5 ]"
xp7 = "/a[ (@v + 1) = 1 ]"
xp8 = "/a[ @n = 0 ]"
assert_equal( 1, XPath.match( d, xp1 ).length )
assert_equal( 1, XPath.match( d, xp2 ).length )
assert_equal( 1, XPath.match( d, xp3 ).length )
assert_equal( 0, XPath.match( d, xp4 ).length )
assert_equal( 0, XPath.match( d, xp5 ).length )
assert_equal( 0, XPath.match( d, xp6 ).length )
assert_equal( 0, XPath.match( d, xp7 ).length )
assert_equal( 0, XPath.match( d, xp8 ).length )
end
def test_tobis_preceding
doc_string = '
'
doc = Document.new(doc_string)
# e = REXML::XPath.first(doc,'/a/c/e')
e = doc.root.get_elements('/a/c/e')[0]
assert_equal( 1, e.get_elements('preceding-sibling::*').length )
assert_equal( 2, XPath.match(e, 'preceding::*').length )
end
def test_filtering
#doc=Document.new("")
#assert_equal( 3, XPath.match( doc, '/a/b/*[1]' ).length )
#assert_equal( 2, XPath.match( doc, '/a/b/following-sibling::*[1]' ).length )
end
# Submitted by Alex
def test_union
data = %Q{
a
b
}
rd = REXML::Document.new( data )
#union = rd.get_elements("/div/span | /div/em")
#assert_equal(2, union.length, "/div/span | /div/em" )
union = rd.get_elements('//*[name()="em" or name()="strong"]')
assert_equal(2, union.length, 'name() and "or" failed')
union = rd.get_elements('//em|//strong')
assert_equal(2, union.length,
'Both tag types are returned by XPath union operator')
end
def test_union2
src = <<-EOL
a
b
EOL
rd = REXML::Document.new( src )
union = rd.get_elements('//em|//strong')
assert_equal(2, union.length,
'Both tag types are returned by XPath union operator')
end
def test_a_star_star_one
string = <<-EOL
EOL
d = REXML::Document.new( string )
cs = XPath.match( d, '/a/*/*[1]' )
assert_equal(["c1"], cs.collect(&:name))
end
def test_sum
d = Document.new(<<-XML)
1
2
3
1
2
XML
assert_equal([6], XPath::match(d, "sum(/a/b)"))
assert_equal([9], XPath::match(d, "sum(//b | //d)"))
assert_equal([3], XPath::match(d, "sum(/a/e/@*)"))
end
def test_xpath_namespace
d = REXML::Document.new("xa")
x = d.root
num = 0
x.each_element('tada') { num += 1 }
assert_equal(1, num)
end
def test_ticket_39
doc = REXML::Document.new( <<-EOL )
true
-
Item 1
-
Item 2
Thu, 13 Oct 2005 19:59:00 +0000
-
Item 3
EOL
root_node = XPath.first(doc, "rss")
assert_not_nil root_node
channel_node = XPath.first(root_node, "channel")
assert_not_nil channel_node
items = XPath.match(channel_node, "*")
assert_equal 4, items.size
items = XPath.match(channel_node, "item")
assert_equal 3, items.size # fails
end
def test_ticket_42
source = ""
doc = Document.new(source)
bElem = Element.new('b')
doc.root.add_element(bElem)
doc.elements.each('//b[name(..) = "a"]') { |x|
assert_equal x,bElem
}
end
def test_ticket_56
namespaces = {'h' => 'http://www.w3.org/1999/xhtml'}
finaldoc = REXML::Document.new(File.read(fixture_path('google.2.xml')))
column_headers = []
REXML::XPath.each(finaldoc, '//h:form[@action="ModifyCampaign"]//h:th',
namespaces) do |el|
node = REXML::XPath.first(el, 'h:a/text()', namespaces)
column_headers << (node ? node.value : nil)
end
column_headers.map! { |h| h.to_s.strip.chomp }
expected = ["", "", "Current Status", "Current Budget",
"Clicks", "Impr.", "CTR", "Avg. CPC", "Cost", "Conv. Rate",
"Cost/Conv."]
assert_equal( expected, column_headers )
end
def test_ticket_70
string = <
Text1, text,
text
Text2, text,
text
EOF
doc = Document.new string
assert_equal( 1, XPath.match( doc, "//someelement[contains(@attribute,'1.10')]" ).length )
end
def test_ticket_43
#url = http://news.search.yahoo.com/news/rss?p=market&ei=UTF-8&fl=0&x=wrt
sum = File.open(fixture_path("yahoo.xml")) do |f|
Document.new(f).elements.to_a("//item").size
end
assert_equal( 10, sum )
text = File.open(fixture_path("yahoo.xml")) do |f|
Document.new(f).elements.to_a(%Q{//title[contains(text(), "'")]}).collect{|e| e.text}.join
end
assert_equal( "Broward labor market's a solid performer (Miami Herald)", text )
end
def test_ticket_57
data = "zzz"
r = Document.new(data)
assert_equal(Text, REXML::XPath.first(r,"a:x/a:y[@p='p' and @q='q']/a:z/text()").class)
assert_equal("zzz", REXML::XPath.first(r,"a:x/a:y[@p='p' and @q='q']/a:z/text()").to_s)
end
def test_ticket_59
data = "
"
d = Document.new(data)
res = d.elements.to_a( "//c" ).collect {|e| e.attributes['id'].to_i}
assert_equal((1..12).to_a, res)
end
def ticket_61_fixture(doc, xpath)
matches = []
doc.elements.each(xpath) do |element|
matches << element
assert_equal('Add', element.text)
assert_equal('ButtonText', element.attributes['class'])
end
assert_equal(1, matches.length)
end
def test_ticket_61_text
doc = File.open(fixture_path("ticket_61.xml")) do |file|
REXML::Document.new file
end
ticket_61_fixture( doc, "//div[text()='Add' and @class='ButtonText']" )
end
def test_ticket_61_contains
doc = File.open(fixture_path("ticket_61.xml")) do |file|
REXML::Document.new file
end
ticket_61_fixture( doc, "//div[contains(.,'Add') and @class='ButtonText']" )
end
def test_namespaces_0
d = Document.new(%q{})
assert_equal( 1, XPath.match( d, "//x:a" ).size )
assert_equal( 1, XPath.match( d, "//x:*" ).size )
end
def test_ticket_71
doc = Document.new(%Q{})
el = doc.root.elements[1]
assert_equal( "element", el.name )
el2 = XPath.first( doc.root, "element[@ns:attrname='foo']", { 'ns' => "xyz" } )
assert_equal( el, el2 )
end
def test_ticket_78
doc = <<-EOT
123
123a
EOT
seq = %w{BEGIN 123 END BEGIN 123a END}
xmlDoc = Document.new(doc)
["//element[tag='123']/tag", "//element[tag='123a']/tag"].each do |query|
assert_equal( "BEGIN", seq.shift )
XPath.each(xmlDoc, query) { |element|
assert_equal( seq.shift, element.text )
}
assert_equal( "END", seq.shift )
end
end
def test_ticket_79
source = "test3"
d = REXML::Document.new( source )
r = REXML::XPath.match( d, %q{/a/b[c='test']} )
assert_equal(1, r.size())
r = REXML::XPath.match( d, %q{/a/b[c='3']} )
assert_equal(1, r.size())
end
def test_or_and
doc = "
test
A link.
"
xmldoc = REXML::Document.new(doc)
xpath = "descendant::node()[(local-name()='link' or local-name()='a') and @rel='sub']"
hrefs = []
xmldoc.elements.each(xpath) do |element|
hrefs << element.attributes["href"]
end
assert_equal(["/"], hrefs, "Bug #3842 [ruby-core:32447]")
end
end
end