PageRenderTime 50ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/test/rexml/test_core.rb

https://github.com/nazy/ruby
Ruby | 1398 lines | 1228 code | 112 blank | 58 comment | 3 complexity | ee6e428b4064786a244ab2226077432a MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, AGPL-3.0, 0BSD, Unlicense
  1. # coding: binary
  2. require "rexml_test_utils"
  3. require "rexml/document"
  4. require "rexml/parseexception"
  5. require "rexml/output"
  6. require "rexml/source"
  7. require "rexml/formatters/pretty"
  8. require "rexml/undefinednamespaceexception"
  9. require "listener"
  10. class Tester < Test::Unit::TestCase
  11. include REXMLTestUtils
  12. include REXML
  13. def setup
  14. @xsa_source = <<-EOL
  15. <?xml version="1.0"?>
  16. <?xsl stylesheet="blah.xsl"?>
  17. <!-- The first line tests the XMLDecl, the second tests PI.
  18. The next line tests DocType. This line tests comments. -->
  19. <!DOCTYPE xsa PUBLIC
  20. "-//LM Garshol//DTD XML Software Autoupdate 1.0//EN//XML"
  21. "http://www.garshol.priv.no/download/xsa/xsa.dtd">
  22. <xsa>
  23. <vendor id="blah">
  24. <name>Lars Marius Garshol</name>
  25. <email>larsga@garshol.priv.no</email>
  26. <url>http://www.stud.ifi.uio.no/~lmariusg/</url>
  27. </vendor>
  28. </xsa>
  29. EOL
  30. end
  31. def test_bad_markup
  32. [
  33. "<pkg='version'> foo </pkg>",
  34. '<0/>',
  35. '<a>&</a>',
  36. '<a>&a</a>',
  37. # '<a>&a;</a>', # FIXME
  38. '<a a="<"/>',
  39. '<a 3="<"/>',
  40. '<a a="1" a="2"/>',
  41. '<a><!-- -- --></a>',
  42. '<a><!-- ---></a>',
  43. '<a>&#x00;</a>',
  44. '<a>&#0;</a>',
  45. "<a a='&#0;' />",
  46. "<a>\f</a>",
  47. "<a a='\f' />",
  48. "<a>\000</a>",
  49. # FIXME '<a' + [65535].pack('U') + ' />',
  50. '<a>&#xfffe;</a>',
  51. '<a>&#65535;</a>',
  52. # FIXME '<a' + [0x0371].pack('U') + ' />',
  53. # FIXME '<a a' + [0x0371].pack('U') + '="" />',
  54. ].each do |src|
  55. assert_raise( ParseException, %Q{Parse #{src.inspect} should have failed!} ) do
  56. Document.new(src)
  57. end
  58. end
  59. end
  60. def test_attribute
  61. # Testing constructors
  62. #a = Attribute.new "hello", "dolly"
  63. #b = Attribute.new a
  64. #d = Document.new( "<a hello='dolly' href='blah'/>" )
  65. #c = d[0].attributes.get_attribute( "hello" )
  66. #assert_equal a, b
  67. #for attr in [ a, b, c]
  68. # assert_equal "hello", attr.name
  69. # assert_equal "dolly", attr.value
  70. #end
  71. # This because of a reported bug in attribute handling in 1.0a8
  72. source = '<a att="A">blah</a>'
  73. doc = Document.new source
  74. doc.elements.each do |a|
  75. a.attributes['att'] << 'B'
  76. assert_equal "AB", a.attributes['att']
  77. a.attributes['att'] = 'C'
  78. assert_equal "C", a.attributes['att']
  79. end
  80. # Bryan Murphy <murphybryanp@yahoo.com>
  81. text = "this is a {target[@name='test']/@value} test"
  82. source = <<-EOL
  83. <?xml version="1.0"?>
  84. <doc search="#{text}"/>
  85. EOL
  86. xml = Document.new source
  87. value = xml.root.attributes["search"]
  88. assert_equal text, value.to_s
  89. e = Element.new "test"
  90. e.add_attributes({ "name1" => "test1", "name4" => "test4" })
  91. e.add_attributes([["name3","test3"], ["name2","test2"]])
  92. assert_equal "test1", e.attributes["name1"]
  93. assert_equal "test2", e.attributes["name2"]
  94. assert_equal "test3", e.attributes["name3"]
  95. assert_equal "test4", e.attributes["name4"]
  96. # ensure that the attributes come out in sorted order
  97. assert_equal %w(<test
  98. name1='test1'
  99. name2='test2'
  100. name3='test3'
  101. name4='test4'/>).join(' '), e.to_s
  102. end
  103. def test_cdata
  104. test = "The quick brown fox jumped
  105. & < & < \" '
  106. over the lazy dog."
  107. source = "<a><![CDATA[#{test}]]></a>"
  108. d = REXML::Document.new( source )
  109. # Test constructors
  110. cdata = d[0][0]
  111. assert_equal test, cdata.value
  112. end
  113. def test_comment
  114. string = "This is a new comment!"
  115. source = "<!--#{string}-->"
  116. comment = Comment.new string
  117. REXML::Formatters::Default.new.write( comment, out = "" )
  118. assert_equal(source, out)
  119. comment2 = Comment.new comment
  120. assert_equal(comment, comment2)
  121. assert_raise(ParseException) {
  122. REXML::Document.new("<d><!- foo --></d>")
  123. }
  124. assert_raise(ParseException) {
  125. REXML::Document.new("<d><!-- foo -></d>")
  126. }
  127. end
  128. def test_whitespace
  129. doc = Document.new "<root-element><first-element/></root-element>"
  130. assert_equal 1, doc.root.size
  131. assert_equal 1, doc.root.elements.size
  132. doc = Document.new "<root-element>
  133. <first-element/>
  134. </root-element>"
  135. assert_equal 3, doc.root.size
  136. assert_equal 1, doc.root.elements.size
  137. text = " This is text
  138. with a lot of whitespace "
  139. source = "<a>#{text}<b>#{text}</b><c>#{text}</c>#{text}</a>"
  140. doc = Document.new( source, {
  141. :respect_whitespace => %w{ a c }
  142. } )
  143. assert_equal text, doc.elements["//c"].text
  144. string = ""
  145. doc.root.each { |n| string << n.to_s if n.kind_of? Text }
  146. assert_equal text+text, string
  147. string =" lots of blank
  148. space"
  149. doc.root.add_element("d").add_element("c").text = string
  150. doc.root.add_element("e").text = string
  151. assert_equal string, doc.elements["/a/d/c"].text
  152. assert string != doc.elements["/a/e"].text, "Text wasn't properly compressed"
  153. doc = Document.new source, { :respect_whitespace => :all }
  154. doc.root.add_element("d").text = string
  155. assert_equal text, doc.root.text
  156. nxt = ""
  157. doc.root.each { |n| nxt << n.to_s if n.kind_of? Text }
  158. assert_equal text+text, nxt
  159. assert_equal text, doc.root.elements["b"].text
  160. assert_equal text, doc.root.elements["c"].text
  161. assert_equal string, doc.root.elements["d"].text
  162. end
  163. # This isn't complete. We need to check declarations and comments
  164. def test_doctype
  165. string = "something"
  166. correct = "<!DOCTYPE something>"
  167. doc = DocType.new(string)
  168. assert_equal(string, doc.name)
  169. doc.write(out="")
  170. assert_equal(correct, out)
  171. doc2 = DocType.new(doc)
  172. assert_equal(doc.name, doc2.name)
  173. assert_equal(doc.external_id, doc2.external_id)
  174. correct = '<!DOCTYPE xsa PUBLIC "-//LM Garshol//DTD XML Software Autoupdate 1.0//EN//XML" "http://www.garshol.priv.no/download/xsa/xsa.dtd">'
  175. one_line_source = '<!DOCTYPE xsa PUBLIC "-//LM Garshol//DTD XML Software Autoupdate 1.0//EN//XML" "http://www.garshol.priv.no/download/xsa/xsa.dtd"><a/>'
  176. doc = Document.new( one_line_source )
  177. doc = doc[0]
  178. assert(doc)
  179. doc.write(test="")
  180. assert_equal(correct, test)
  181. multi_line_source = '<!DOCTYPE xsa PUBLIC
  182. "-//LM Garshol//DTD XML Software Autoupdate 1.0//EN//XML"
  183. "http://www.garshol.priv.no/download/xsa/xsa.dtd">
  184. <a/>'
  185. d = Document.new( multi_line_source )
  186. doc = d[0]
  187. assert(doc)
  188. doc.write(test="")
  189. assert_equal(correct, test)
  190. odd_space_source = ' <!DOCTYPE
  191. xsa PUBLIC "-//LM Garshol//DTD XML Software Autoupdate 1.0//EN//XML"
  192. "http://www.garshol.priv.no/download/xsa/xsa.dtd"> <a/>'
  193. d = Document.new( odd_space_source )
  194. dt = d.doctype
  195. dt.write(test="")
  196. assert_equal(correct, test)
  197. # OK, the BIG doctype test, numba wun
  198. docin = File.new(fixture_path("doctype_test.xml"))
  199. doc = Document.new(docin)
  200. doc.write(test="")
  201. assert_equal(31, doc.doctype.size)
  202. # Here's a little ditty from Tobias...
  203. src = <<-EOL
  204. <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
  205. "http://www.w3.org/TR/SVG/DTD/svg10.dtd"
  206. [
  207. <!-- <!ENTITY % fast-slow "0 0 .5 1">-->
  208. <!--<!ENTITY % slow-fast ".5 0 1 1">-->
  209. <!ENTITY hover_ani
  210. '<animateTransform attributeName="transform"
  211. type="scale" restart="whenNotActive" values="1;0.96"
  212. dur="0.5s" calcMode="spline" keySplines="0 0 .5 1"
  213. fill="freeze" begin="mouseover"/>
  214. <animateTransform attributeName="transform"
  215. type="scale" restart="whenNotActive" values="0.96;1"
  216. dur="0.5s" calcMode="spline" keySplines=".5 0 1 1"
  217. fill="freeze" begin="mouseover+0.5s"/>'
  218. >
  219. ]
  220. > <a/>
  221. EOL
  222. end
  223. def test_document
  224. # Testing cloning
  225. source = "<element/>"
  226. doc = Document.new source
  227. doc2 = Document.new doc
  228. # Testing Root
  229. assert_equal doc.root.name.to_s, "element"
  230. # Testing String source
  231. source = @xsa_source
  232. doc = Document.new source
  233. assert_instance_of XMLDecl, doc.xml_decl
  234. assert_instance_of DocType, doc.doctype
  235. assert_equal doc.version, "1.0"
  236. source = File.new(fixture_path("dash.xml"))
  237. doc = Document.new source
  238. assert_equal "content-2", doc.elements["//content-2"].name
  239. end
  240. def test_instruction
  241. target = "use"
  242. content = "ruby"
  243. source = "<?#{target} #{content}?>"
  244. instruction = Instruction.new target, content
  245. instruction2 = Instruction.new instruction
  246. assert_equal(instruction, instruction2)
  247. REXML::Formatters::Default.new.write( instruction, out = "" )
  248. assert_equal(source, out)
  249. d = Document.new( source )
  250. instruction2 = d[0]
  251. assert_equal(instruction.to_s, instruction2.to_s)
  252. assert_raise(ParseException) {
  253. REXML::Document.new("<d><?foo bar></d>")
  254. }
  255. end
  256. def test_parent
  257. parent = Parent.new
  258. begin
  259. parent << "Something"
  260. rescue Exception
  261. parent << Comment.new("Some comment")
  262. assert parent.size == 1, "size of parent should be 1"
  263. else
  264. assert_fail "should have gotten an exception trying to add a "+ "String to a Parent"
  265. end
  266. source = "<a><one/><three/><five/></a>"
  267. doc = Document.new source
  268. three = doc.root.elements["three"]
  269. doc.root.insert_before( three, Element.new("two") )
  270. nxt = doc.root.elements["one"]
  271. string = ""
  272. while nxt
  273. string << nxt.name
  274. nxt = nxt.next_sibling
  275. end
  276. assert_equal "onetwothreefive", string
  277. doc.root.insert_after( three, Element.new("four") )
  278. string = ""
  279. doc.root.each { |element| string << element.name }
  280. assert_equal "onetwothreefourfive", string
  281. string = ""
  282. nxt = doc.root.elements["five"]
  283. while nxt
  284. string << nxt.name
  285. nxt = nxt.previous_sibling
  286. end
  287. assert_equal "fivefourthreetwoone", string
  288. doc.insert_after "//two", Element.new("two-and-half")
  289. string = doc.root.elements.collect {|x| x.name}.join
  290. assert_equal "onetwotwo-and-halfthreefourfive", string
  291. doc.elements["/a/five"].insert_before "../four", Element.new("three-and-half")
  292. string = doc.root.elements.collect {|x| x.name}.join
  293. assert_equal "onetwotwo-and-halfthreethree-and-halffourfive", string
  294. doc.elements["/a/five"].previous_sibling = Element.new("four-and-half")
  295. string = doc.root.elements.collect {|x| x.name}.join
  296. assert_equal "onetwotwo-and-halfthreethree-and-halffourfour-and-halffive", string
  297. doc.elements["/a/one"].next_sibling = Element.new("one-and-half")
  298. string = doc.root.elements.collect {|x| x.name}.join
  299. assert_equal "oneone-and-halftwotwo-and-halfthreethree-and-halffourfour-and-halffive", string
  300. doc = Document.new "<a><one/><three/></a>"
  301. doc.root[1,0] = Element.new "two"
  302. string = ""
  303. doc.root.each { |el| string << el.name }
  304. assert_equal "onetwothree", string
  305. end
  306. # The Source classes are tested extensively throughout the test suite
  307. def test_source
  308. # Testing string source
  309. source = @xsa_source
  310. doc = Document.new source
  311. assert_equal doc.root.name.to_s, "xsa"
  312. # Testing IO source
  313. doc = Document.new File.new(fixture_path("project.xml"))
  314. assert_equal doc.root.name.to_s, "Project"
  315. end
  316. def test_text
  317. f = REXML::Formatters::Default.new
  318. string = "Some text"
  319. text = Text.new(string)
  320. assert_equal(string, text.to_s)
  321. text2 = Text.new(text)
  322. assert_equal(text, text2)
  323. #testing substitution
  324. string = "0 < ( 1 & 1 )"
  325. correct = "0 &lt; ( 1 &amp; 1 )"
  326. text = Text.new(string, true)
  327. f.write(text,out="")
  328. assert_equal(correct, out)
  329. string = "Cats &amp; dogs"
  330. text = Text.new(string, false, nil, true)
  331. assert_equal(string, text.to_s)
  332. string2 = "<a>#{string}</a>"
  333. doc = Document.new( string2, {
  334. :raw => %w{ a b }
  335. } )
  336. f.write(doc,out="")
  337. assert_equal(string2, out)
  338. b = doc.root.add_element( "b" )
  339. b.text = string
  340. assert_equal(string, b.get_text.to_s)
  341. c = doc.root.add_element("c")
  342. c.text = string
  343. assert_equal("Cats &amp;amp; dogs", c.get_text.to_s)
  344. # test all
  345. string = "<a>&amp;<b>&lt;</b><c>&gt;<d>&quot;</d></c></a>"
  346. doc = Document.new(string, { :raw => :all })
  347. assert_equal( "&amp;", doc.elements["/a"][0].to_s )
  348. assert_equal( "&", doc.elements["/a"].text )
  349. assert_equal( "&lt;", doc.elements["/a/b"][0].to_s )
  350. assert_equal( "<", doc.elements["/a/b"].text )
  351. assert_equal( "&gt;", doc.elements["/a/c"][0].to_s )
  352. assert_equal( ">", doc.elements["/a/c"].text )
  353. assert_equal( '&quot;', doc.elements["//d"][0].to_s )
  354. assert_equal( '"', doc.elements["//d"].text )
  355. # test some other stuff
  356. doc = Document.new('<a><b/></a>')
  357. doc.root.text = 'Sean'
  358. assert_equal( '<a><b/>Sean</a>', doc.to_s )
  359. doc.root.text = 'Elliott'
  360. assert_equal( '<a><b/>Elliott</a>', doc.to_s )
  361. doc.root.add_element( 'c' )
  362. assert_equal( '<a><b/>Elliott<c/></a>', doc.to_s )
  363. doc.root.text = 'Russell'
  364. assert_equal( '<a><b/>Russell<c/></a>', doc.to_s )
  365. doc.root.text = nil
  366. assert_equal( '<a><b/><c/></a>', doc.to_s )
  367. end
  368. def test_xmldecl
  369. source = "<?xml version='1.0'?>"
  370. # test args
  371. # test no args
  372. decl2 = XMLDecl.new
  373. assert_equal source, decl2.to_s
  374. # test XMLDecl
  375. decl2 = XMLDecl.new "1.0"
  376. assert_equal source, decl2.to_s
  377. end
  378. def each_test( element, xpath, num_children )
  379. count = 0
  380. element.each_element( xpath ) { |child|
  381. count += 1
  382. yield child if block_given?
  383. }
  384. assert_equal num_children, count
  385. end
  386. # This is the biggest test, as the number of permutations of xpath are
  387. # enormous.
  388. def test_element_access
  389. # Testing each_element
  390. doc = Document.new File.new(fixture_path("project.xml"))
  391. each_test( doc, "/", 1 ) { |child|
  392. assert_equal doc.name, child.name
  393. }
  394. each_test(doc, ".", 1) { |child| assert_equal doc, child }
  395. each_test(doc.root, "..", 1) { |child| assert_equal doc, child }
  396. each_test(doc.root, "*", 5)
  397. each_test(doc, "Project/Datasets", 1) { |child|
  398. assert_equal "Datasets", child.name
  399. }
  400. each_test(doc, "Project/Datasets/link", 2 )
  401. each_test(doc.root, "/Project/Description", 1) {|child|
  402. assert_equal "Description", child.name
  403. }
  404. each_test(doc.root, "./Description",1 ) { |child|
  405. assert_equal "Description",child.name
  406. }
  407. each_test(doc.root, "../Project",1 ) { |child|
  408. assert_equal doc.root, child
  409. }
  410. #each_test(doc,".../link",2) {|child| assert_equal "link",child.name.to_s}
  411. # test get_element
  412. first = doc.elements[ "Project" ]
  413. assert_equal doc.root, first
  414. second = doc.elements[ "Project" ].elements[1]
  415. third = doc.elements[ "Project/Creator" ]
  416. assert_equal second, third
  417. fourth = doc.elements[ "Project/Datasets/link[@idref='18']" ]
  418. assert_equal "Test data 1", fourth.attributes["name"]
  419. # Testing each_predicate
  420. each_test( doc, "Project/Datasets/link[@idref='18']", 1 ) { |child|
  421. assert_equal "Test data 1", child.attributes["name"]
  422. }
  423. # testing next/previous_element
  424. creator = doc.elements["//Creator"]
  425. lm = creator.next_element
  426. assert_equal "LastModifier", lm.name
  427. assert_equal "Creator", lm.previous_element.name
  428. end
  429. def test_child
  430. sean = Element.new "Sean"
  431. rubbell = Element.new "Rubbell"
  432. elliott = sean.add_element "Elliott"
  433. sean << rubbell
  434. assert_equal elliott, rubbell.previous_sibling
  435. assert_equal rubbell, elliott.next_sibling
  436. russell = Element.new "Russell"
  437. rubbell.replace_with russell
  438. assert_equal elliott, russell.previous_sibling
  439. assert_equal russell, elliott.next_sibling
  440. assert_nil russell.document
  441. assert_equal sean, russell.root
  442. end
  443. # Most of this class is tested elsewhere. Here are the methods which
  444. # aren't used in any other class
  445. def test_element
  446. sean = Element.new "Sean"
  447. string = "1) He's a great guy!"
  448. sean.text = string
  449. russell = Element.new "Russell"
  450. sean << russell
  451. russell.attributes["email"] = "ser@germane-software.com"
  452. assert_equal russell.attributes["email"], "ser@germane-software.com"
  453. russell.attributes["webpage"] = "http://www.germane-software.com/~ser"
  454. assert sean.has_text?, "element should have text"
  455. assert_equal sean.text, string
  456. assert sean.has_elements?, "element should have one element"
  457. string = "2) What a stud!"
  458. sean.add_text string
  459. sean.text = "3) Super programmer!"
  460. sean.text = nil
  461. assert sean.has_text?, "element should still have text"
  462. assert_equal sean.text, string
  463. russell.delete_attribute "email"
  464. assert_nil russell.attributes["email"]
  465. russell.attributes.delete "webpage"
  466. assert !russell.has_attributes?, "element should have no attributes"
  467. end
  468. def test_no_format
  469. source = "<a><b><c>blah</c><d/></b></a>"
  470. out = ""
  471. doc = Document.new( source )
  472. doc.write(out)
  473. assert_equal(source, out)
  474. end
  475. def test_namespace
  476. source = <<-EOF
  477. <x xmlns:foo="http://www.bar.com/schema">
  478. </x>
  479. EOF
  480. doc = Document.new(source)
  481. assert_equal("http://www.bar.com/schema", doc.root.namespace( "foo" ))
  482. source = <<-EOF
  483. <!-- bar namespace is "someuri" -->
  484. <foo:bar xmlns="default" xmlns:foo="someuri">
  485. <!-- a namespace is "default" -->
  486. <a/>
  487. <!-- foo:b namespace is "someuri" -->
  488. <foo:b>
  489. <!-- c namespace is "default" -->
  490. <c/>
  491. </foo:b>
  492. <!-- d namespace is "notdefault" -->
  493. <d xmlns="notdefault">
  494. <!-- e namespace is "notdefault" -->
  495. <e/>
  496. <f xmlns="">
  497. <g/>
  498. </f>
  499. </d>
  500. </foo:bar>
  501. EOF
  502. doc = Document.new source
  503. assert_equal "someuri", doc.root.namespace
  504. assert_equal "default", doc.root.elements[1].namespace
  505. assert_equal "someuri", doc.root.elements[2].namespace
  506. assert_equal "notdefault", doc.root.elements[ 3 ].namespace
  507. # Testing namespaces in attributes
  508. source = <<-EOF
  509. <a xmlns:b="uri">
  510. <b b:a="x" a="y"/>
  511. <c xmlns="foo">
  512. </c>
  513. </a>
  514. EOF
  515. doc = Document.new source
  516. b = doc.root.elements["b"]
  517. assert_equal "x", b.attributes["b:a"]
  518. assert_equal "y", b.attributes["a"]
  519. doc = Document.new
  520. doc.add_element "sean:blah"
  521. doc.root.text = "Some text"
  522. out = ""
  523. doc.write(out)
  524. assert_equal "<sean:blah>Some text</sean:blah>", out
  525. end
  526. def test_add_namespace
  527. e = Element.new 'a'
  528. e.add_namespace 'someuri'
  529. e.add_namespace 'foo', 'otheruri'
  530. e.add_namespace 'xmlns:bar', 'thirduri'
  531. assert_equal 'someuri', e.attributes['xmlns']
  532. assert_equal 'otheruri', e.attributes['xmlns:foo']
  533. assert_equal 'thirduri', e.attributes['xmlns:bar']
  534. end
  535. def test_big_documentation
  536. f = File.new(fixture_path("documentation.xml"))
  537. d = Document.new f
  538. assert_equal "Sean Russell", d.elements["documentation/head/author"].text.tr("\n\t", " ").squeeze(" ")
  539. out = ""
  540. d.write out
  541. end
  542. def test_tutorial
  543. doc = Document.new File.new(fixture_path("tutorial.xml"))
  544. out = ""
  545. doc.write out
  546. end
  547. def test_stream
  548. c = Listener.new
  549. Document.parse_stream( File.new(fixture_path("documentation.xml")), c )
  550. assert(c.ts, "Stream parsing apparantly didn't parse the whole file")
  551. assert(c.te, "Stream parsing dropped end tag for documentation")
  552. Document.parse_stream("<a.b> <c/> </a.b>", c)
  553. Document.parse_stream("<a>&lt;&gt;&amp;</a>", c)
  554. assert_equal('<>&', c.normalize)
  555. end
  556. def test_line
  557. doc = Document.new File.new(fixture_path("bad.xml"))
  558. assert_fail "There should have been an error"
  559. rescue Exception
  560. # We should get here
  561. er = $!
  562. assert($!.line == 5, "Should have been an error on line 5, "+
  563. "but was reported as being on line #{$!.line}" )
  564. end
  565. def test_substitution
  566. val = "a'b\"c"
  567. el = Element.new("a")
  568. el.attributes["x"] = val
  569. REXML::Formatters::Default.new.write(el, out="")
  570. nel = Document.new( out)
  571. assert_equal( val, nel.root.attributes["x"] )
  572. end
  573. def test_exception
  574. source = SourceFactory.create_from "<a/>"
  575. p = ParseException.new( "dummy message", source )
  576. s = p.to_s
  577. begin
  578. raise "dummy"
  579. rescue Exception
  580. p.continued_exception = $!
  581. end
  582. s = p.to_s
  583. end
  584. def test_bad_content
  585. in_gt = '<root-el>content>content</root-el>'
  586. in_lt = '<root-el>content<content</root-el>'
  587. # This is OK
  588. tree_gt = Document.new in_gt
  589. assert_equal "content>content", tree_gt.elements[1].text
  590. # This isn't
  591. begin
  592. tree_lt = Document.new in_lt
  593. assert_fail "Should have gotten a parse error"
  594. rescue ParseException
  595. end
  596. end
  597. def test_iso_8859_1_output_function
  598. out = ""
  599. output = Output.new( out )
  600. koln_iso_8859_1 = "K\xF6ln"
  601. koln_utf8 = "K\xc3\xb6ln"
  602. source = Source.new( koln_iso_8859_1, 'iso-8859-1' )
  603. results = source.scan(/.*/)[0]
  604. koln_utf8.force_encoding('UTF-8') if koln_utf8.respond_to?(:force_encoding)
  605. assert_equal koln_utf8, results
  606. output << results
  607. if koln_iso_8859_1.respond_to?(:force_encoding)
  608. koln_iso_8859_1.force_encoding('ISO-8859-1')
  609. end
  610. assert_equal koln_iso_8859_1, out
  611. end
  612. def test_attributes_each
  613. doc = Document.new("<a xmlns:a='foo'><b x='1' y='2' z='3' a:x='4'/></a>")
  614. count = 0
  615. doc.root.elements[1].attributes.each {|k,v| count += 1 }
  616. assert_equal 4, count
  617. end
  618. def test_delete_namespace
  619. doc = Document.new "<a xmlns='1' xmlns:x='2'/>"
  620. doc.root.delete_namespace
  621. doc.root.delete_namespace 'x'
  622. assert_equal "<a/>", doc.to_s
  623. end
  624. def test_each_element_with_attribute
  625. doc = Document.new "<a><b id='1'/><c id='2'/><d id='1'/><e/></a>"
  626. arry = []
  627. block = proc { |e|
  628. assert arry.include?(e.name)
  629. arry.delete e.name
  630. }
  631. # Yields b, c, d
  632. arry = %w{b c d}
  633. doc.root.each_element_with_attribute( 'id', &block )
  634. assert_equal 0, arry.size
  635. # Yields b, d
  636. arry = %w{b d}
  637. doc.root.each_element_with_attribute( 'id', '1', &block )
  638. assert_equal 0, arry.size
  639. # Yields b
  640. arry = ['b']
  641. doc.root.each_element_with_attribute( 'id', '1', 1, &block )
  642. assert_equal 0, arry.size
  643. # Yields d
  644. arry = ['d']
  645. doc.root.each_element_with_attribute( 'id', '1', 0, 'd', &block )
  646. assert_equal 0, arry.size
  647. end
  648. def test_each_element_with_text
  649. doc = Document.new '<a><b>b</b><c>b</c><d>d</d><e/></a>'
  650. arry = []
  651. block = proc { |e|
  652. assert arry.include?(e.name)
  653. arry.delete e.name
  654. }
  655. # Yields b, c, d
  656. arry = %w{b c d}
  657. doc.root.each_element_with_text(&block)
  658. assert_equal 0, arry.size
  659. # Yields b, d
  660. arry = %w{b c}
  661. doc.root.each_element_with_text( 'b', &block )
  662. assert_equal 0, arry.size
  663. # Yields b
  664. arry = ['b']
  665. doc.root.each_element_with_text( 'b', 1, &block )
  666. assert_equal 0, arry.size
  667. # Yields d
  668. arry = ['d']
  669. doc.root.each_element_with_text( nil, 0, 'd', &block )
  670. assert_equal 0, arry.size
  671. end
  672. def test_element_parse_stream
  673. s = Source.new( "<a>some text</a>" )
  674. l = Listener.new
  675. class << l
  676. def tag_start name, attributes
  677. raise "Didn't find proper tag name" unless 'a'==name
  678. end
  679. end
  680. Document::parse_stream(s, l)
  681. end
  682. def test_deep_clone
  683. a = Document.new( '<?xml version="1"?><a x="y"><b>text</b>text<c><d><e>text</e></d></c></a>' )
  684. b = a.deep_clone
  685. assert_equal a.to_s, b.to_s
  686. a = Document.new( '<a>some &lt; text <b> more &gt; text </b> &gt; </a>' )
  687. b = a.deep_clone
  688. assert_equal a.to_s, b.to_s
  689. c = Document.new( b.to_s )
  690. assert_equal a.to_s, c.to_s
  691. end
  692. def test_whitespace_before_root
  693. a = <<EOL
  694. <?xml version='1.0'?>
  695. <blo>
  696. <wak>
  697. </wak>
  698. </blo>
  699. EOL
  700. d = Document.new(a)
  701. b = ""
  702. d.write( b )
  703. assert_equal a,b
  704. end
  705. def test_entities
  706. a = Document.new( '<a>&#101;&#x65;&#252;</a>' )
  707. assert_equal('ee端'.force_encoding("UTF-8"), a.root.text)
  708. end
  709. def test_element_decl
  710. element_decl = Source.new("<!DOCTYPE foo [
  711. <!ELEMENT bar (#PCDATA)>
  712. ]>")
  713. doc = Document.new( element_decl )
  714. d = doc[0]
  715. assert_equal("<!ELEMENT bar (#PCDATA)>", d.to_s.split(/\n/)[1].strip)
  716. end
  717. def test_attlist_decl
  718. doc = Document.new <<-EOL
  719. <!DOCTYPE blah [
  720. <!ATTLIST blah
  721. xmlns CDATA "foo">
  722. <!ATTLIST a
  723. bar CDATA "gobble"
  724. xmlns:one CDATA "two"
  725. >
  726. ]>
  727. <a xmlns:three='xxx' three='yyy'><one:b/><three:c/></a>
  728. EOL
  729. assert_equal 'gobble', doc.root.attributes['bar']
  730. assert_equal 'xxx', doc.root.elements[2].namespace
  731. assert_equal 'two', doc.root.elements[1].namespace
  732. assert_equal 'foo', doc.root.namespace
  733. doc = Document.new <<-EOL
  734. <?xml version="1.0"?>
  735. <!DOCTYPE schema SYSTEM "XMLSchema.dtd" [
  736. <!ENTITY % p ''>
  737. <!ENTITY % s ''>
  738. <!ATTLIST schema
  739. xmlns:svg CDATA #FIXED "http://www.w3.org/2000/svg"
  740. xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink"
  741. xmlns:xml CDATA #FIXED "http://www.w3.org/XML/1998/namespace"
  742. >]>
  743. <schema/>
  744. EOL
  745. prefixes = doc.root.prefixes.sort
  746. correct = ['svg', 'xlink', 'xml']
  747. assert_equal correct, prefixes
  748. end
  749. def test_attlist_write
  750. file=File.new(fixture_path("foo.xml"))
  751. doc=Document.new file
  752. root = doc.root
  753. out = ''
  754. doc.write(out)
  755. end
  756. def test_more_namespaces
  757. assert_raise( REXML::UndefinedNamespaceException,
  758. %Q{Should have gotten an Undefined Namespace error} ) {
  759. doc1 = Document.new("<r><p><n:c/></p></r>")
  760. }
  761. doc2 = Document.new("<r xmlns:n='1'><p><n:c/></p></r>")
  762. es = XPath.match(doc2, '//c')
  763. assert_equal 0, es.size
  764. es = XPath.match(doc2, '//n:c')
  765. assert_equal 1, es.size
  766. doc2.root.add_namespace('m', '2')
  767. doc2.root.add_element("m:o")
  768. es = XPath.match(doc2, './/o')
  769. assert_equal 0, es.size
  770. es = XPath.match(doc2, '//n:c')
  771. assert_equal 1, es.size
  772. end
  773. def test_ticket_51
  774. doc = REXML::Document.new <<-EOL
  775. <test xmlns='1' xmlns:x='1'>
  776. <a>X</a>
  777. <x:a>Y</x:a>
  778. <b xmlns='2'>
  779. <a>Z</a>
  780. </b>
  781. </test>
  782. EOL
  783. # The most common case. People not caring about the namespaces much.
  784. assert_equal( "XY", XPath.match( doc, "/test/a/text()" ).join )
  785. assert_equal( "XY", XPath.match( doc, "/test/x:a/text()" ).join )
  786. # Surprising? I don't think so, if you believe my definition of the "common case"
  787. assert_equal( "XYZ", XPath.match( doc, "//a/text()" ).join )
  788. # These are the uncommon cases. Namespaces are actually important, so we define our own
  789. # mappings, and pass them in.
  790. assert_equal( "XY", XPath.match( doc, "/f:test/f:a/text()", { "f" => "1" } ).join )
  791. # The namespaces are defined, and override the original mappings
  792. assert_equal( "", XPath.match( doc, "/test/a/text()", { "f" => "1" } ).join )
  793. assert_equal( "", XPath.match( doc, "/x:test/x:a/text()", { "f" => "1" } ).join )
  794. assert_equal( "", XPath.match( doc, "//a/text()", { "f" => "1" } ).join )
  795. end
  796. def test_processing_instruction
  797. d = Document.new("<a><?foo bar?><?foo2 bar2?><b><?foo3 bar3?></b><?foo4 bar4?></a>")
  798. assert_equal 4, XPath.match(d, '//processing-instruction()' ).size
  799. match = XPath.match(d, "//processing-instruction('foo3')" )
  800. assert_equal 1, match.size
  801. assert_equal 'bar3', match[0].content
  802. end
  803. def test_oses_with_bad_EOLs
  804. d = Document.new("\n\n\n<?xml version='1.0'?>\n\n\n<a/>\n\n")
  805. end
  806. # Contributed (with patch to fix bug) by Kouhei
  807. def test_ignore_whitespace
  808. source = "<a> <b/> abc <![CDATA[def]]> </a>"
  809. context_all = {:ignore_whitespace_nodes => :all}
  810. context_a = {:ignore_whitespace_nodes => %(a)}
  811. context_b = {:ignore_whitespace_nodes => %(b)}
  812. tests = [[[" abc ", "def"], context_all],
  813. [[" abc ", "def"], context_a],
  814. [[" ", " abc ", "def", " "], context_b]]
  815. tests.each do |test|
  816. assert_equal(test[0], Document.new(source, test[1]).root.texts.collect{|x|
  817. x.to_s})
  818. end
  819. end
  820. def test_0xD_in_preface
  821. doc = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\x0D<opml version=\"1.0\">\x0D</opml>"
  822. doc = Document.new doc
  823. end
  824. def test_hyphens_in_doctype
  825. doc = REXML::Document.new <<-EOQ
  826. <?xml version="1.0"?>
  827. <!DOCTYPE a-b-c>
  828. <a-b-c>
  829. <a/>
  830. </a-b-c>
  831. EOQ
  832. assert_equal('a-b-c', doc.doctype.name)
  833. end
  834. def test_accents
  835. docs = [
  836. %Q{<?xml version="1.0" encoding="ISO-8859-1"?>
  837. <gnuPod>
  838. <files>
  839. <file id="57" artist="Coralie Cl\357\277\275ent" />
  840. </files>
  841. </gnuPod>},
  842. '<?xml version="1.0" encoding="ISO-8859-1"?>
  843. <gnuPod>
  844. <files>
  845. <file id="71" album="Astrakan Caf" />
  846. </files>
  847. </gnuPod>',
  848. %Q{<?xml version="1.0" encoding="ISO-8859-1"?>
  849. <gnuPod>
  850. <files>
  851. <file id="71" album="Astrakan Caf\357\277\275eria" />
  852. </files>
  853. </gnuPod>},
  854. %Q{<?xml version="1.0" encoding="ISO-8859-1"?>
  855. <gnuPod>
  856. <files>
  857. <file id="71" album="Astrakan Caf\357\277\275" />
  858. </files>
  859. </gnuPod>} ]
  860. docs.each_with_index { |d,i|
  861. begin
  862. REXML::Document.new(d)
  863. rescue
  864. puts "#{i} => #{docs[i]}"
  865. raise
  866. end
  867. }
  868. end
  869. def test_replace_text
  870. e = REXML::Element.new( "a" )
  871. e.add_text( "foo" )
  872. assert_equal( "<a>foo</a>", e.to_s )
  873. e[0].value = "bar"
  874. assert_equal( "<a>bar</a>", e.to_s )
  875. e[0].value = "<"
  876. assert_equal( "<a>&lt;</a>", e.to_s )
  877. assert_equal( "<", e[0].value )
  878. end
  879. def test_write_doctype
  880. ## XML Document and Declaration
  881. document = REXML::Document.new
  882. xmldecl = REXML::XMLDecl.new("1.0", "UTF-8")
  883. document.add(xmldecl)
  884. s = ""
  885. document.write(s)
  886. ## XML Doctype
  887. str = '<!DOCTYPE foo "bar">'
  888. source = REXML::Source.new(str)
  889. doctype = REXML::DocType.new(source)
  890. document.add(doctype)
  891. document.write(s)
  892. ## Element
  893. element = REXML::Element.new("hoge")
  894. document.add(element)
  895. document.write(s)
  896. end
  897. def test_write_cdata
  898. src = "<a>A</a>"
  899. doc = REXML::Document.new( src )
  900. out = ""
  901. doc.write( out )
  902. assert_equal( src, out )
  903. src = "<a><![CDATA[A]]></a>"
  904. doc = REXML::Document.new( src )
  905. out = ""
  906. doc.write( out )
  907. assert_equal( src, out )
  908. end
  909. def test_namespace_attributes
  910. source = <<-EOL
  911. <a xmlns:x="1">
  912. <x:b x:n="foo"/>
  913. </a>
  914. EOL
  915. d = REXML::Document.new( source )
  916. assert_equal( 'foo', REXML::XPath.first(d.root, "//x:b/@x:n").value )
  917. assert_equal( nil, REXML::XPath.first(d.root, "//x:b/@x:n", {}))
  918. end
  919. def test_null_element_name
  920. a = REXML::Document.new
  921. assert_raise( RuntimeError ) {
  922. a.add_element( nil )
  923. }
  924. end
  925. def test_text_raw
  926. # From the REXML tutorial
  927. # (http://www.germane-software.com/software/rexml/test/data/tutorial.html)
  928. doc = Document.new <<-EOL
  929. <?xml version="1.0"?>
  930. <!DOCTYPE schema SYSTEM "XMLSchema.dtd" [
  931. <!ENTITY % s 'Sean'>
  932. ]>
  933. <a/>
  934. EOL
  935. a = doc.root
  936. # This makes sure that RAW text nodes don't have their entity strings
  937. # replaced
  938. t = Text.new "Sean", false, nil, true
  939. a.text = t
  940. assert_equal( "Sean", t.to_s )
  941. assert_equal( "Sean", t.value )
  942. # This makes sure that they do
  943. t = Text.new "Sean", false, nil, false
  944. a.text = t
  945. assert_equal( "&s;", t.to_s )
  946. assert_equal( "Sean", t.value )
  947. t = Text.new "&s;", false, nil, true
  948. a.text = t
  949. assert_equal( "&s;", t.to_s )
  950. assert_equal( "Sean", t.value )
  951. t = Text.new "&s;", false, nil, true
  952. a.text = t
  953. assert_equal( "&s;", t.to_s )
  954. assert_equal( "Sean", t.value )
  955. # Ticket #44
  956. t = REXML::Text.new( "&amp;", false, nil, true )
  957. assert_equal( "&amp;", t.to_s )
  958. t = REXML::Text.new("&amp;", false, false)
  959. assert_equal( "&amp;amp;", t.to_s )
  960. end
  961. def test_to_xpath
  962. doc = REXML::Document.new( %q{<tag1>
  963. <tag2 name="tag2"/>
  964. <tag2 name="tag2"/>
  965. </tag1>})
  966. names = %w{ /tag1/tag2[1] /tag1/tag2[2] }
  967. doc.root.elements.each_with_index {|el, i|
  968. assert_equal( names[i], el.xpath )
  969. }
  970. end
  971. def test_transitive
  972. doc = REXML::Document.new( "<a/>")
  973. s = ""
  974. doc.write( s, 0, true )
  975. end
  976. # This is issue #40
  977. def test_replace_with
  978. old = '<doc>old<foo/>old</doc>'
  979. d = REXML::Document.new(old).root
  980. new = REXML::Text.new('new',true,nil,true)
  981. child = d.children[2]
  982. child.replace_with(new)
  983. assert_equal( new, d.children[2] )
  984. end
  985. def test_repeated_writes
  986. require 'iconv'
  987. a = IO.read(fixture_path("iso8859-1.xml"))
  988. f = REXML::Formatters::Pretty.new
  989. xmldoc = REXML::Document.new( a )
  990. a_andre = xmldoc.elements['//image'].attributes['caption']
  991. f.write(xmldoc,b="")
  992. xmldoc = REXML::Document.new(b)
  993. b_andre = xmldoc.elements['//image'].attributes['caption']
  994. assert_equal( a_andre, b_andre )
  995. f.write(xmldoc,c="")
  996. xmldoc = REXML::Document.new(c)
  997. c_andre = xmldoc.elements['//image'].attributes['caption']
  998. assert_equal( b_andre, c_andre )
  999. o = Output.new(d="","UTF-8")
  1000. f.write(xmldoc,o)
  1001. assert_not_equal( c, d )
  1002. end
  1003. def test_ticket_58
  1004. doc = REXML::Document.new
  1005. doc << REXML::XMLDecl.default
  1006. doc << REXML::Element.new("a")
  1007. str = ""
  1008. doc.write(str)
  1009. assert_equal("<a/>", str)
  1010. doc = REXML::Document.new
  1011. doc << REXML::XMLDecl.new("1.0", "UTF-8")
  1012. doc << REXML::Element.new("a")
  1013. str = ""
  1014. doc.write(str)
  1015. assert_equal("<?xml version='1.0' encoding='UTF-8'?><a/>", str)
  1016. end
  1017. # Incomplete tags should generate an error
  1018. def test_ticket_53
  1019. assert_raise( REXML::ParseException ) {
  1020. REXML::Document.new( "<a><b></a>" )
  1021. }
  1022. assert_raise( REXML::ParseException ) {
  1023. REXML::Document.new( "<a><b>" )
  1024. }
  1025. assert_raise( REXML::ParseException ) {
  1026. REXML::Document.new( "<a><b/>" )
  1027. }
  1028. end
  1029. def test_ticket_52
  1030. source = "<!-- this is a single line comment -->"
  1031. d = REXML::Document.new(source)
  1032. d.write(k="")
  1033. assert_equal( source, k )
  1034. source = "<a><!-- Comment --></a>"
  1035. target = "<a>\n <!-- Comment -->\n</a>"
  1036. d = REXML::Document.new(source)
  1037. REXML::Formatters::Pretty.new(4).write(d,k="")
  1038. assert_equal( target, k )
  1039. end
  1040. def test_ticket_76
  1041. src = "<div>at&t"
  1042. assert_raise( ParseException, %Q{"#{src}" is invalid XML} ) {
  1043. REXML::Document.new(src)
  1044. }
  1045. end
  1046. def test_ticket_21
  1047. src = "<foo bar=value/>"
  1048. assert_raise( ParseException, "invalid XML should be caught" ) {
  1049. d = REXML::Document.new(src)
  1050. }
  1051. begin
  1052. d = REXML::Document.new(src)
  1053. rescue
  1054. assert_match( /missing attribute quote/, $!.message )
  1055. end
  1056. end
  1057. def test_ticket_63
  1058. d = REXML::Document.new(File.new(fixture_path("t63-1.xml")))
  1059. end
  1060. def test_ticket_75
  1061. d = REXML::Document.new(File.new(fixture_path("t75.xml")))
  1062. assert_equal("tree", d.root.name)
  1063. end
  1064. def test_ticket_48_part_II
  1065. f = REXML::Formatters::Pretty.new
  1066. #- rexml sanity check (bugs in ruby 1.8.4, ruby 1.8.6)
  1067. xmldoc = Document.new("<test/>")
  1068. xmldoc << XMLDecl.new(XMLDecl::DEFAULT_VERSION, "UTF-8")
  1069. content = ['61c3a927223c3e26'].pack("H*")
  1070. content.force_encoding('UTF-8') if content.respond_to?(:force_encoding)
  1071. #- is some UTF-8 text but just to make sure my editor won't magically convert..
  1072. xmldoc.root.add_attribute('attr', content)
  1073. f.write(xmldoc,out=[])
  1074. xmldoc = REXML::Document.new(out.join)
  1075. sanity1 = xmldoc.root.attributes['attr']
  1076. f.write(xmldoc,out=[])
  1077. xmldoc = REXML::Document.new(out.join)
  1078. sanity2 = xmldoc.root.attributes['attr']
  1079. f.write(xmldoc,out=[])
  1080. assert_equal( sanity1, sanity2 )
  1081. end
  1082. def test_ticket_88
  1083. doc = REXML::Document.new("<?xml version=\"1.0\" encoding=\"shift_jis\"?>")
  1084. assert_equal("<?xml version='1.0' encoding='SHIFT_JIS'?>", doc.to_s)
  1085. doc = REXML::Document.new("<?xml version = \"1.0\" encoding = \"shift_jis\"?>")
  1086. assert_equal("<?xml version='1.0' encoding='SHIFT_JIS'?>", doc.to_s)
  1087. end
  1088. def test_ticket_85
  1089. xml = <<ENDXML
  1090. <foo>
  1091. <bar>
  1092. <bob name='jimmy'/>
  1093. </bar>
  1094. </foo>
  1095. ENDXML
  1096. yml = "<foo>
  1097. <bar>
  1098. <bob name='jimmy'/>
  1099. </bar>
  1100. </foo>"
  1101. zml = "<foo><bar><bob name='jimmy'/></bar></foo>"
  1102. # The pretty printer ignores all whitespace, anyway so output1 == output2
  1103. f = REXML::Formatters::Pretty.new( 2 )
  1104. d = Document.new( xml, :ignore_whitespace_nodes=>:all )
  1105. f.write( d, output1="" )
  1106. d = Document.new( xml )
  1107. f.write( d, output2="" )
  1108. # Output directives should override whitespace directives.
  1109. assert_equal( output1, output2 )
  1110. # The base case.
  1111. d = Document.new(yml)
  1112. f.write( d, output3="" )
  1113. assert_equal( output3.strip, output2.strip )
  1114. d = Document.new(yml)
  1115. f.write( d, output4="" )
  1116. assert_equal( output3.strip, output4.strip )
  1117. end
  1118. def test_ticket_91
  1119. source="<root>
  1120. <bah something='1' somethingelse='bah'>
  1121. <something>great</something>
  1122. </bah>
  1123. </root>"
  1124. expected="<root>
  1125. <bah something='1' somethingelse='bah'>
  1126. <something>great</something>
  1127. </bah>
  1128. <bah/>
  1129. </root>"
  1130. d = Document.new( source )
  1131. d.root.add_element( "bah" )
  1132. p=REXML::Formatters::Pretty.new(2)
  1133. p.compact = true # Don't add whitespace to text nodes unless necessary
  1134. p.write(d,out="")
  1135. assert_equal( expected, out )
  1136. end
  1137. def test_ticket_95
  1138. testd = REXML::Document.new "<a><b><c/><c/><c/></b></a>"
  1139. testd.write(out1="")
  1140. testd.elements["//c[2]"].xpath
  1141. testd.write(out2="")
  1142. assert_equal(out1,out2)
  1143. end
  1144. def test_ticket_102
  1145. doc = REXML::Document.new '<doc xmlns="ns"><item name="foo"/></doc>'
  1146. assert_equal( "foo", doc.root.elements["item"].attribute("name","ns").to_s )
  1147. assert_equal( "item", doc.root.elements["item[@name='foo']"].name )
  1148. end
  1149. def test_ticket_14
  1150. # Per .2.5 Node Tests of XPath spec
  1151. assert_raise( REXML::UndefinedNamespaceException,
  1152. %Q{Should have gotten an Undefined Namespace error} ) {
  1153. d = Document.new("<a><n:b/></a>")
  1154. }
  1155. end
  1156. # 5.7 Text Nodes
  1157. # Character data is grouped into text nodes. As much character data as
  1158. # possible is grouped into each text node: a text node never has an
  1159. # immediately following or preceding sibling that is a text node. The
  1160. # string-value of a text node is the character data. A text node always has
  1161. # at least one character of data.
  1162. def test_ticket_105
  1163. d = Document.new("<a/>")
  1164. d.root.add_text( "a" )
  1165. d.root.add_text( "b" )
  1166. assert_equal( 1, d.root.children.size )
  1167. end
  1168. # phantom namespace same as default namespace
  1169. def test_ticket_121
  1170. doc = REXML::Document.new(
  1171. '<doc xmlns="ns" xmlns:phantom="ns"><item name="foo">text</item></doc>'
  1172. )
  1173. assert_equal 'text', doc.text( "/doc/item[@name='foo']" )
  1174. assert_equal "name='foo'",
  1175. doc.root.elements["item"].attribute("name", "ns").inspect
  1176. assert_equal "<item name='foo'>text</item>",
  1177. doc.root.elements["item[@name='foo']"].to_s
  1178. end
  1179. def test_ticket_135
  1180. bean_element = REXML::Element.new("bean")
  1181. textToAdd = "(&#38;(|(memberof=CN=somegroupabcdefgh,OU=OUsucks,DC=hookemhorns,DC=com)(mail=*someco.com))(acct=%u)(!(extraparameter:2.2.222.222222.2.2.222:=2)))"
  1182. bean_element.add_element("prop", {"key"=> "filter"}).add_text(textToAdd)
  1183. doc = REXML::Document.new
  1184. doc.add_element(bean_element)
  1185. REXML::Formatters::Pretty.new(3).write( doc, out = "" )
  1186. assert_equal "<bean>\n <prop key='filter'>\n (&amp;#38;(|(memberof=CN=somegroupabcdefgh,OU=OUsucks,DC=hookemhorns,DC=com)(mail=*someco.com))(acct=%u)(!(extraparameter:2.2.222.222222.2.2.222:=2)))\n </prop>\n</bean>", out
  1187. end
  1188. def test_ticket_138
  1189. doc = REXML::Document.new(
  1190. '<svg xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" ' +
  1191. 'inkscape:version="0.44" version="1.0"/>'
  1192. )
  1193. expected = {
  1194. "inkscape" => attribute("xmlns:inkscape",
  1195. "http://www.inkscape.org/namespaces/inkscape"),
  1196. "version" => {
  1197. "inkscape" => attribute("inkscape:version", "0.44"),
  1198. "" => attribute("version", "1.0"),
  1199. },
  1200. }
  1201. assert_equal(expected, doc.root.attributes)
  1202. assert_equal(expected, REXML::Document.new(doc.root.to_s).root.attributes)
  1203. end
  1204. def test_empty_doc
  1205. assert(REXML::Document.new('').children.empty?)
  1206. end
  1207. private
  1208. def attribute(name, value)
  1209. REXML::Attribute.new(name, value)
  1210. end
  1211. end