PageRenderTime 28ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/test/rexml/test_functions.rb

http://github.com/ruby/ruby
Ruby | 225 lines | 183 code | 30 blank | 12 comment | 0 complexity | 53535ce0d2275093975a3277bed58d61 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, AGPL-3.0
  1. # frozen_string_literal: false
  2. require "test/unit/testcase"
  3. require "rexml/document"
  4. module REXMLTests
  5. class FunctionsTester < Test::Unit::TestCase
  6. include REXML
  7. def test_functions
  8. # trivial text() test
  9. # confuse-a-function
  10. source = "<a>more <b id='1'/><b id='2'>dumb</b><b id='3'/><c/> text</a>"
  11. doc = Document.new source
  12. res = ""
  13. XPath::each(doc.root, "text()") {|val| res << val.to_s}
  14. assert_equal "more text", res
  15. res = XPath::first(doc.root, "b[last()]")
  16. assert_equal '3', res.attributes['id']
  17. res = XPath::first(doc.root, "b[position()=2]")
  18. assert_equal '2', res.attributes['id']
  19. res = XPath::first(doc.root, "*[name()='c']")
  20. assert_equal "c", res.name
  21. end
  22. # Contributed by Mike Stok
  23. def test_starts_with
  24. source = <<-EOF
  25. <foo>
  26. <a href="mailto:a@b.c">a@b.c</a>
  27. <a href="http://www.foo.com">http://www.foo.com</a>
  28. </foo>
  29. EOF
  30. doc = Document.new source
  31. mailtos = doc.elements.to_a("//a[starts-with(@href, 'mailto:')]")
  32. assert_equal 1, mailtos.size
  33. assert_equal "mailto:a@b.c", mailtos[0].attributes['href']
  34. ailtos = doc.elements.to_a("//a[starts-with(@href, 'ailto:')]")
  35. assert_equal 0, ailtos.size
  36. end
  37. def test_string_length
  38. doc = Document.new <<-EOF
  39. <AAA>
  40. <Q/>
  41. <SSSS/>
  42. <BB/>
  43. <CCC/>
  44. <DDDDDDDD/>
  45. <EEEE/>
  46. </AAA>
  47. EOF
  48. assert doc, "create doc"
  49. set = doc.elements.to_a("//*[string-length(name()) = 3]")
  50. assert_equal 2, set.size, "nodes with names length = 3"
  51. set = doc.elements.to_a("//*[string-length(name()) < 3]")
  52. assert_equal 2, set.size, "nodes with names length < 3"
  53. set = doc.elements.to_a("//*[string-length(name()) > 3]")
  54. assert_equal 3, set.size, "nodes with names length > 3"
  55. end
  56. # Test provided by Mike Stok
  57. def test_contains
  58. source = <<-EOF
  59. <foo>
  60. <a href="mailto:a@b.c">a@b.c</a>
  61. <a href="http://www.foo.com">http://www.foo.com</a>
  62. </foo>
  63. EOF
  64. doc = Document.new source
  65. [['o', 2], ['foo', 1], ['bar', 0]].each { |test|
  66. search, expected = test
  67. set = doc.elements.to_a("//a[contains(@href, '#{search}')]")
  68. assert_equal expected, set.size
  69. }
  70. end
  71. # Mike Stok and Sean Russell
  72. def test_substring
  73. # examples from http://www.w3.org/TR/xpath#function-substring
  74. doc = Document.new('<test string="12345" />')
  75. #puts XPath.first(d, 'node()[0 + 1]')
  76. #d = Document.new("<a b='1'/>")
  77. #puts XPath.first(d, 'a[0 mod 0]')
  78. [ [1.5, 2.6, '234'],
  79. [0, 3, '12'],
  80. [0, '0 div 0', ''],
  81. [1, '0 div 0', ''],
  82. ['-42', '1 div 0', '12345'],
  83. ['-1 div 0', '1 div 0', '']
  84. ].each { |start, length, expected|
  85. set = doc.elements.to_a("//test[substring(@string, #{start}, #{length}) = '#{expected}']")
  86. assert_equal 1, set.size, "#{start}, #{length}, '#{expected}'"
  87. }
  88. end
  89. def test_substring_angrez
  90. testString = REXML::Functions::substring_after("helloworld","hello")
  91. assert_equal( 'world', testString )
  92. end
  93. def test_translate
  94. source = <<-EOF
  95. <doc>
  96. <case name='w3c one' result='BAr' /> <!-- w3c -->
  97. <case name='w3c two' result='AAA' /> <!-- w3c -->
  98. <case name='alchemy' result="gold" /> <!-- mike -->
  99. <case name='vbxml one' result='A Space Odyssey' />
  100. <case name='vbxml two' result='AbCdEf' />
  101. </doc>
  102. EOF
  103. doc = Document.new(source)
  104. [ ['bar', 'abc', 'ABC', 'w3c one'],
  105. ['--aaa--','abc-','ABC', 'w3c two'],
  106. ['lead', 'dear language', 'doll groover', 'alchemy'],
  107. ['A Space Odissei', 'i', 'y', 'vbxml one'],
  108. ['abcdefg', 'aceg', 'ACE', 'vbxml two'],
  109. ].each { |arg1, arg2, arg3, name|
  110. translate = "translate('#{arg1}', '#{arg2}', '#{arg3}')"
  111. set = doc.elements.to_a("//case[@result = #{translate}]")
  112. assert_equal 1, set.size, translate
  113. assert_equal name, set[0].attributes['name']
  114. }
  115. end
  116. def test_name
  117. d = REXML::Document.new("<a xmlns:x='foo'><b/><x:b/></a>")
  118. assert_equal 1, d.root.elements.to_a('*[name() = "b"]').size
  119. assert_equal 1, d.elements.to_a('//*[name() = "x:b"]').size
  120. end
  121. def test_local_name
  122. d = REXML::Document.new("<a xmlns:x='foo'><b/><x:b/></a>")
  123. assert_equal 2, d.root.elements.to_a('*[local_name() = "b"]').size
  124. assert_equal 2, d.elements.to_a('//*[local_name() = "b"]').size
  125. end
  126. def test_substring2
  127. doc = Document.new('<test string="12345" />')
  128. assert_equal(1,doc.elements.to_a("//test[substring(@string,2)='2345']").size)
  129. end
  130. # Submitted by Kouhei
  131. def test_floor_ceiling_round
  132. source = "<a><b id='1'/><b id='2'/><b id='3'/></a>"
  133. doc = REXML::Document.new(source)
  134. id_1 = doc.elements["/a/b[@id='1']"]
  135. id_2 = doc.elements["/a/b[@id='2']"]
  136. id_3 = doc.elements["/a/b[@id='3']"]
  137. good = {
  138. "floor" => [[], [id_1], [id_2], [id_3]],
  139. "ceiling" => [[id_1], [id_2], [id_3], []],
  140. "round" => [[id_1], [id_2], [id_3], []]
  141. }
  142. good.each do |key, value|
  143. (0..3).each do |i|
  144. xpath = "//b[number(@id) = #{key}(#{i+0.5})]"
  145. assert_equal(value[i], REXML::XPath.match(doc, xpath))
  146. end
  147. end
  148. good["round"] = [[], [id_1], [id_2], [id_3]]
  149. good.each do |key, value|
  150. (0..3).each do |i|
  151. xpath = "//b[number(@id) = #{key}(#{i+0.4})]"
  152. assert_equal(value[i], REXML::XPath.match(doc, xpath))
  153. end
  154. end
  155. end
  156. # Submitted by Kou
  157. def test_lang
  158. d = Document.new(<<-XML)
  159. <a xml:lang="en">
  160. <b xml:lang="ja">
  161. <c xml:lang="fr"/>
  162. <d/>
  163. <e xml:lang="ja-JP"/>
  164. <f xml:lang="en-US"/>
  165. </b>
  166. </a>
  167. XML
  168. assert_equal(1, d.elements.to_a("//*[lang('fr')]").size)
  169. assert_equal(3, d.elements.to_a("//*[lang('ja')]").size)
  170. assert_equal(2, d.elements.to_a("//*[lang('en')]").size)
  171. assert_equal(1, d.elements.to_a("//*[lang('en-us')]").size)
  172. d = Document.new(<<-XML)
  173. <root>
  174. <para xml:lang="en"/>
  175. <div xml:lang="en"><para/></div>
  176. <para xml:lang="EN"/>
  177. <para xml:lang="en-us"/>
  178. </root>
  179. XML
  180. assert_equal(5, d.elements.to_a("//*[lang('en')]").size)
  181. end
  182. def test_ticket_60
  183. document = REXML::Document.new("<a><b>A</b><b>1</b></a>")
  184. assert_equal( "A", REXML::XPath.first(document, '//b[.="A"]').text )
  185. assert_equal( "1", REXML::XPath.first(document, '//b[.="1"]').text )
  186. end
  187. def test_normalize_space
  188. source = "<a><!--COMMENT A--><b><!-- COMMENT A --></b></a>"
  189. doc = REXML::Document.new(source)
  190. predicate = "string(.)=normalize_space('\nCOMMENT \n A \n\n ')"
  191. m = REXML::XPath.match(doc, "//comment()[#{predicate}]")
  192. assert_equal( [REXML::Comment.new("COMMENT A")], m )
  193. end
  194. end
  195. end