diff options
Diffstat (limited to 'test/rexml/functions/test_base.rb')
-rw-r--r-- | test/rexml/functions/test_base.rb | 261 |
1 files changed, 261 insertions, 0 deletions
diff --git a/test/rexml/functions/test_base.rb b/test/rexml/functions/test_base.rb new file mode 100644 index 0000000000..74dc1a31de --- /dev/null +++ b/test/rexml/functions/test_base.rb @@ -0,0 +1,261 @@ +# frozen_string_literal: false +require "test/unit/testcase" + +require "rexml/document" + +# TODO: Split me +module REXMLTests + class FunctionsTester < Test::Unit::TestCase + include REXML + + def setup + super + REXML::Functions.context = nil + end + + def test_functions + # trivial text() test + # confuse-a-function + source = "<a>more <b id='1'/><b id='2'>dumb</b><b id='3'/><c/> text</a>" + 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 + + # Contributed by Mike Stok + def test_starts_with + source = <<-EOF + <foo> + <a href="mailto:[email protected]">[email protected]</a> + <a href="http://www.foo.com">http://www.foo.com</a> + </foo> + EOF + doc = Document.new source + mailtos = doc.elements.to_a("//a[starts-with(@href, 'mailto:')]") + assert_equal 1, mailtos.size + assert_equal "mailto:[email protected]", mailtos[0].attributes['href'] + + ailtos = doc.elements.to_a("//a[starts-with(@href, 'ailto:')]") + assert_equal 0, ailtos.size + end + + def test_string_length + doc = Document.new <<-EOF + <AAA> + <Q/> + <SSSS/> + <BB/> + <CCC/> + <DDDDDDDD/> + <EEEE/> + </AAA> + 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 + <foo> + <a href="mailto:[email protected]">[email protected]</a> + <a href="http://www.foo.com">http://www.foo.com</a> + </foo> + EOF + doc = Document.new source + + [['o', 2], ['foo', 1], ['bar', 0]].each { |test| + search, expected = test + 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('<test string="12345" />') + + #puts XPath.first(d, 'node()[0 + 1]') + #d = Document.new("<a b='1'/>") + #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_substring_angrez + testString = REXML::Functions::substring_after("helloworld","hello") + assert_equal( 'world', testString ) + end + + def test_translate + source = <<-EOF + <doc> + <case name='w3c one' result='BAr' /> <!-- w3c --> + <case name='w3c two' result='AAA' /> <!-- w3c --> + <case name='alchemy' result="gold" /> <!-- mike --> + <case name='vbxml one' result='A Space Odyssey' /> + <case name='vbxml two' result='AbCdEf' /> + </doc> + 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_name + d = REXML::Document.new("<a xmlns:x='foo'><b/><x:b/></a>") + 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("<a xmlns:x='foo'><b/><x:b/></a>") + 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_substring2 + doc = Document.new('<test string="12345" />') + assert_equal(1,doc.elements.to_a("//test[substring(@string,2)='2345']").size) + end + + # Submitted by Kouhei + def test_floor_ceiling_round + source = "<a><b id='1'/><b id='2'/><b id='3'/></a>" + doc = REXML::Document.new(source) + + id_1 = doc.elements["/a/b[@id='1']"] + id_2 = doc.elements["/a/b[@id='2']"] + id_3 = doc.elements["/a/b[@id='3']"] + + good = { + "floor" => [[], [id_1], [id_2], [id_3]], + "ceiling" => [[id_1], [id_2], [id_3], []], + "round" => [[id_1], [id_2], [id_3], []] + } + good.each do |key, value| + (0..3).each do |i| + xpath = "//b[number(@id) = #{key}(#{i+0.5})]" + assert_equal(value[i], REXML::XPath.match(doc, xpath)) + end + end + + good["round"] = [[], [id_1], [id_2], [id_3]] + good.each do |key, value| + (0..3).each do |i| + xpath = "//b[number(@id) = #{key}(#{i+0.4})]" + assert_equal(value[i], REXML::XPath.match(doc, xpath)) + end + end + end + + # Submitted by Kou + def test_lang + d = Document.new(<<-XML) + <a xml:lang="en"> + <b xml:lang="ja"> + <c xml:lang="fr"/> + <d/> + <e xml:lang="ja-JP"/> + <f xml:lang="en-US"/> + </b> + </a> + XML + + assert_equal(1, d.elements.to_a("//*[lang('fr')]").size) + assert_equal(3, d.elements.to_a("//*[lang('ja')]").size) + assert_equal(2, d.elements.to_a("//*[lang('en')]").size) + assert_equal(1, d.elements.to_a("//*[lang('en-us')]").size) + + d = Document.new(<<-XML) + <root> + <para xml:lang="en"/> + <div xml:lang="en"><para/></div> + <para xml:lang="EN"/> + <para xml:lang="en-us"/> + </root> + XML + + assert_equal(5, d.elements.to_a("//*[lang('en')]").size) + end + + def test_ticket_60 + document = REXML::Document.new("<a><b>A</b><b>1</b></a>") + assert_equal( "A", REXML::XPath.first(document, '//b[.="A"]').text ) + assert_equal( "1", REXML::XPath.first(document, '//b[.="1"]').text ) + end + + def test_normalize_space + source = "<a><!--COMMENT A--><b><!-- COMMENT A --></b></a>" + doc = REXML::Document.new(source) + predicate = "string(.)=normalize_space('\nCOMMENT \n A \n\n ')" + m = REXML::XPath.match(doc, "//comment()[#{predicate}]") + assert_equal( [REXML::Comment.new("COMMENT A")], m ) + end + + def test_string_nil_without_context + doc = REXML::Document.new(<<-XML) + <?xml version="1.0" encoding="UTF-8"?> + <root> + <foo bar="baz"/> + <foo bar=""/> + </root> + XML + + assert_equal([doc.root.elements[2]], + REXML::XPath.match(doc, + "//foo[@bar=$n]", + nil, + {"n" => nil})) + end + + def test_unregistered_method + doc = Document.new("<root/>") + assert_nil(XPath::first(doc.root, "to_s()")) + end + + def test_nonexistent_function + doc = Document.new("<root><nonexistent/></root>") + # TODO: Maybe, this is not XPath spec behavior. + # This behavior must be reconsidered. + assert_equal(doc.root.elements[1], + XPath::first(doc.root, "nonexistent()")) + end + end +end |