magic_xml 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +22 -0
- data/Rakefile +52 -0
- data/VERSION +1 -0
- data/doc/classes/Array.html +148 -0
- data/doc/classes/File.html +113 -0
- data/doc/classes/Hash.html +117 -0
- data/doc/classes/Patterns_all.html +145 -0
- data/doc/classes/Patterns_any.html +145 -0
- data/doc/classes/String.html +470 -0
- data/doc/classes/Symbol.html +145 -0
- data/doc/classes/XML.html +1881 -0
- data/doc/classes/XML_Comment.html +148 -0
- data/doc/classes/XML_PI.html +145 -0
- data/doc/classes/XML_Tests.html +1727 -0
- data/doc/files/magic_xml_rb.html +186 -0
- data/doc/files/simple_examples/xml_hello_f_rb.html +88 -0
- data/doc/files/simple_examples/xml_hello_m_rb.html +88 -0
- data/doc/files/simple_examples/xml_list_f_rb.html +88 -0
- data/doc/files/simple_examples/xml_list_m_rb.html +88 -0
- data/doc/files/tests_rb.html +94 -0
- data/doc/files/xquery_use_cases/parts/q1_rb.html +117 -0
- data/doc/files/xquery_use_cases/rdb/q10_rb.html +88 -0
- data/doc/files/xquery_use_cases/rdb/q11_rb.html +88 -0
- data/doc/files/xquery_use_cases/rdb/q12_rb.html +88 -0
- data/doc/files/xquery_use_cases/rdb/q13_rb.html +88 -0
- data/doc/files/xquery_use_cases/rdb/q14_rb.html +88 -0
- data/doc/files/xquery_use_cases/rdb/q15_rb.html +88 -0
- data/doc/files/xquery_use_cases/rdb/q16_rb.html +88 -0
- data/doc/files/xquery_use_cases/rdb/q17_rb.html +88 -0
- data/doc/files/xquery_use_cases/rdb/q18_rb.html +88 -0
- data/doc/files/xquery_use_cases/rdb/q1_rb.html +88 -0
- data/doc/files/xquery_use_cases/rdb/q2_rb.html +88 -0
- data/doc/files/xquery_use_cases/rdb/q3_rb.html +88 -0
- data/doc/files/xquery_use_cases/rdb/q4_rb.html +88 -0
- data/doc/files/xquery_use_cases/rdb/q5_rb.html +88 -0
- data/doc/files/xquery_use_cases/rdb/q6_rb.html +88 -0
- data/doc/files/xquery_use_cases/rdb/q7_rb.html +88 -0
- data/doc/files/xquery_use_cases/rdb/q8_rb.html +88 -0
- data/doc/files/xquery_use_cases/rdb/q9_rb.html +88 -0
- data/doc/files/xquery_use_cases/seq/q1_rb.html +88 -0
- data/doc/files/xquery_use_cases/seq/q2_rb.html +88 -0
- data/doc/files/xquery_use_cases/seq/q3_rb.html +88 -0
- data/doc/files/xquery_use_cases/seq/q4_rb.html +88 -0
- data/doc/files/xquery_use_cases/seq/q5_rb.html +88 -0
- data/doc/files/xquery_use_cases/sgml/q10_rb.html +88 -0
- data/doc/files/xquery_use_cases/sgml/q1_rb.html +88 -0
- data/doc/files/xquery_use_cases/sgml/q2_rb.html +88 -0
- data/doc/files/xquery_use_cases/sgml/q3_rb.html +88 -0
- data/doc/files/xquery_use_cases/sgml/q4_rb.html +88 -0
- data/doc/files/xquery_use_cases/sgml/q5_rb.html +88 -0
- data/doc/files/xquery_use_cases/sgml/q6_rb.html +88 -0
- data/doc/files/xquery_use_cases/sgml/q7_rb.html +88 -0
- data/doc/files/xquery_use_cases/sgml/q8a_rb.html +88 -0
- data/doc/files/xquery_use_cases/sgml/q8b_rb.html +88 -0
- data/doc/files/xquery_use_cases/sgml/q9_rb.html +88 -0
- data/doc/files/xquery_use_cases/solution_sizes_rb.html +88 -0
- data/doc/files/xquery_use_cases/string/q1_rb.html +88 -0
- data/doc/files/xquery_use_cases/string/q2_rb.html +93 -0
- data/doc/files/xquery_use_cases/string/q4_rb.html +88 -0
- data/doc/files/xquery_use_cases/string/q5_rb.html +88 -0
- data/doc/files/xquery_use_cases/test_driver_rb.html +92 -0
- data/doc/files/xquery_use_cases/tree/q1_rb.html +111 -0
- data/doc/files/xquery_use_cases/tree/q2_rb.html +88 -0
- data/doc/files/xquery_use_cases/tree/q3_rb.html +88 -0
- data/doc/files/xquery_use_cases/tree/q4_rb.html +88 -0
- data/doc/files/xquery_use_cases/tree/q5_rb.html +88 -0
- data/doc/files/xquery_use_cases/tree/q6_rb.html +113 -0
- data/doc/files/xquery_use_cases/xmp/q10_rb.html +88 -0
- data/doc/files/xquery_use_cases/xmp/q11_rb.html +88 -0
- data/doc/files/xquery_use_cases/xmp/q12_rb.html +88 -0
- data/doc/files/xquery_use_cases/xmp/q1_rb.html +88 -0
- data/doc/files/xquery_use_cases/xmp/q2_rb.html +88 -0
- data/doc/files/xquery_use_cases/xmp/q3_rb.html +88 -0
- data/doc/files/xquery_use_cases/xmp/q4_rb.html +88 -0
- data/doc/files/xquery_use_cases/xmp/q5_rb.html +92 -0
- data/doc/files/xquery_use_cases/xmp/q6_rb.html +88 -0
- data/doc/files/xquery_use_cases/xmp/q7_rb.html +88 -0
- data/doc/files/xquery_use_cases/xmp/q8_rb.html +88 -0
- data/doc/files/xquery_use_cases/xmp/q9_rb.html +88 -0
- data/doc/fr_class_index.html +56 -0
- data/doc/fr_file_index.html +110 -0
- data/doc/fr_method_index.html +159 -0
- data/doc/index.html +26 -0
- data/doc/rdoc-style.css +175 -0
- data/lib/magic_xml.rb +1400 -0
- data/simple_examples/README +14 -0
- data/simple_examples/xml_hello_f.rb +32 -0
- data/simple_examples/xml_hello_m.rb +32 -0
- data/simple_examples/xml_list_f.rb +36 -0
- data/simple_examples/xml_list_m.rb +36 -0
- data/test/helper.rb +9 -0
- data/test/test_magic_xml.rb +855 -0
- data/xquery_use_cases/README +17 -0
- data/xquery_use_cases/parts/README +12 -0
- data/xquery_use_cases/parts/partlist.xml +13 -0
- data/xquery_use_cases/parts/q1.out +16 -0
- data/xquery_use_cases/parts/q1.rb +38 -0
- data/xquery_use_cases/parts/q1.xquery +18 -0
- data/xquery_use_cases/rdb/README +50 -0
- data/xquery_use_cases/rdb/bids.xml +81 -0
- data/xquery_use_cases/rdb/items.xml +57 -0
- data/xquery_use_cases/rdb/q1.out +10 -0
- data/xquery_use_cases/rdb/q1.rb +31 -0
- data/xquery_use_cases/rdb/q1.xquery +14 -0
- data/xquery_use_cases/rdb/q10.out +27 -0
- data/xquery_use_cases/rdb/q10.rb +37 -0
- data/xquery_use_cases/rdb/q10.xquery +15 -0
- data/xquery_use_cases/rdb/q11.out +7 -0
- data/xquery_use_cases/rdb/q11.rb +38 -0
- data/xquery_use_cases/rdb/q11.xquery +15 -0
- data/xquery_use_cases/rdb/q12.out +12 -0
- data/xquery_use_cases/rdb/q12.rb +42 -0
- data/xquery_use_cases/rdb/q12.xquery +28 -0
- data/xquery_use_cases/rdb/q13.out +32 -0
- data/xquery_use_cases/rdb/q13.rb +45 -0
- data/xquery_use_cases/rdb/q13.xquery +15 -0
- data/xquery_use_cases/rdb/q14.out +14 -0
- data/xquery_use_cases/rdb/q14.rb +42 -0
- data/xquery_use_cases/rdb/q14.xquery +14 -0
- data/xquery_use_cases/rdb/q15.out +5 -0
- data/xquery_use_cases/rdb/q15.rb +31 -0
- data/xquery_use_cases/rdb/q15.xquery +9 -0
- data/xquery_use_cases/rdb/q16.out +35 -0
- data/xquery_use_cases/rdb/q16.rb +35 -0
- data/xquery_use_cases/rdb/q16.xquery +17 -0
- data/xquery_use_cases/rdb/q17.out +1 -0
- data/xquery_use_cases/rdb/q17.rb +35 -0
- data/xquery_use_cases/rdb/q17.xquery +11 -0
- data/xquery_use_cases/rdb/q18.out +32 -0
- data/xquery_use_cases/rdb/q18.rb +40 -0
- data/xquery_use_cases/rdb/q18.xquery +19 -0
- data/xquery_use_cases/rdb/q2.out +22 -0
- data/xquery_use_cases/rdb/q2.rb +36 -0
- data/xquery_use_cases/rdb/q2.xquery +14 -0
- data/xquery_use_cases/rdb/q3.out +8 -0
- data/xquery_use_cases/rdb/q3.rb +34 -0
- data/xquery_use_cases/rdb/q3.xquery +16 -0
- data/xquery_use_cases/rdb/q4.out +14 -0
- data/xquery_use_cases/rdb/q4.rb +31 -0
- data/xquery_use_cases/rdb/q4.xquery +11 -0
- data/xquery_use_cases/rdb/q5.out +12 -0
- data/xquery_use_cases/rdb/q5.rb +46 -0
- data/xquery_use_cases/rdb/q5.xquery +25 -0
- data/xquery_use_cases/rdb/q6.out +14 -0
- data/xquery_use_cases/rdb/q6.rb +38 -0
- data/xquery_use_cases/rdb/q6.xquery +15 -0
- data/xquery_use_cases/rdb/q7.out +1 -0
- data/xquery_use_cases/rdb/q7.rb +30 -0
- data/xquery_use_cases/rdb/q7.xquery +10 -0
- data/xquery_use_cases/rdb/q8.out +1 -0
- data/xquery_use_cases/rdb/q8.rb +23 -0
- data/xquery_use_cases/rdb/q8.xquery +8 -0
- data/xquery_use_cases/rdb/q9.out +22 -0
- data/xquery_use_cases/rdb/q9.rb +32 -0
- data/xquery_use_cases/rdb/q9.xquery +16 -0
- data/xquery_use_cases/rdb/users.xml +25 -0
- data/xquery_use_cases/seq/README +12 -0
- data/xquery_use_cases/seq/q1.out +1 -0
- data/xquery_use_cases/seq/q1.rb +25 -0
- data/xquery_use_cases/seq/q1.xquery +2 -0
- data/xquery_use_cases/seq/q2.out +2 -0
- data/xquery_use_cases/seq/q2.rb +25 -0
- data/xquery_use_cases/seq/q2.xquery +2 -0
- data/xquery_use_cases/seq/q3.out +2 -0
- data/xquery_use_cases/seq/q3.rb +26 -0
- data/xquery_use_cases/seq/q3.xquery +3 -0
- data/xquery_use_cases/seq/q4.out +0 -0
- data/xquery_use_cases/seq/q4.rb +27 -0
- data/xquery_use_cases/seq/q4.xquery +4 -0
- data/xquery_use_cases/seq/q5.out +5 -0
- data/xquery_use_cases/seq/q5.rb +29 -0
- data/xquery_use_cases/seq/q5.xquery +10 -0
- data/xquery_use_cases/seq/report1.xml +40 -0
- data/xquery_use_cases/sgml/README +53 -0
- data/xquery_use_cases/sgml/q1.out +44 -0
- data/xquery_use_cases/sgml/q1.rb +23 -0
- data/xquery_use_cases/sgml/q1.xquery +5 -0
- data/xquery_use_cases/sgml/q10.out +1 -0
- data/xquery_use_cases/sgml/q10.rb +28 -0
- data/xquery_use_cases/sgml/q10.xquery +7 -0
- data/xquery_use_cases/sgml/q2.out +26 -0
- data/xquery_use_cases/sgml/q2.rb +23 -0
- data/xquery_use_cases/sgml/q2.xquery +5 -0
- data/xquery_use_cases/sgml/q3.out +6 -0
- data/xquery_use_cases/sgml/q3.rb +28 -0
- data/xquery_use_cases/sgml/q3.xquery +7 -0
- data/xquery_use_cases/sgml/q4.out +4 -0
- data/xquery_use_cases/sgml/q4.rb +25 -0
- data/xquery_use_cases/sgml/q4.xquery +5 -0
- data/xquery_use_cases/sgml/q5.out +3 -0
- data/xquery_use_cases/sgml/q5.rb +23 -0
- data/xquery_use_cases/sgml/q5.xquery +5 -0
- data/xquery_use_cases/sgml/q6.out +1 -0
- data/xquery_use_cases/sgml/q6.rb +27 -0
- data/xquery_use_cases/sgml/q6.xquery +6 -0
- data/xquery_use_cases/sgml/q7.out +1 -0
- data/xquery_use_cases/sgml/q7.rb +27 -0
- data/xquery_use_cases/sgml/q7.xquery +7 -0
- data/xquery_use_cases/sgml/q8a.out +34 -0
- data/xquery_use_cases/sgml/q8a.rb +27 -0
- data/xquery_use_cases/sgml/q8a.xquery +5 -0
- data/xquery_use_cases/sgml/q8b.out +26 -0
- data/xquery_use_cases/sgml/q8b.rb +32 -0
- data/xquery_use_cases/sgml/q8b.xquery +5 -0
- data/xquery_use_cases/sgml/q9.out +9 -0
- data/xquery_use_cases/sgml/q9.rb +29 -0
- data/xquery_use_cases/sgml/q9.xquery +6 -0
- data/xquery_use_cases/sgml/sgml.xml +101 -0
- data/xquery_use_cases/solution_sizes.rb +48 -0
- data/xquery_use_cases/string/README +29 -0
- data/xquery_use_cases/string/company-data.xml +20 -0
- data/xquery_use_cases/string/q1.out +4 -0
- data/xquery_use_cases/string/q1.rb +25 -0
- data/xquery_use_cases/string/q1.xquery +1 -0
- data/xquery_use_cases/string/q2.out +13 -0
- data/xquery_use_cases/string/q2.rb +32 -0
- data/xquery_use_cases/string/q2.xquery +23 -0
- data/xquery_use_cases/string/q4.out +50 -0
- data/xquery_use_cases/string/q4.rb +34 -0
- data/xquery_use_cases/string/q4.xquery +14 -0
- data/xquery_use_cases/string/q5.out +12 -0
- data/xquery_use_cases/string/q5.rb +33 -0
- data/xquery_use_cases/string/q5.xquery +8 -0
- data/xquery_use_cases/string/string.xml +82 -0
- data/xquery_use_cases/test_driver.rb +60 -0
- data/xquery_use_cases/tree/README +23 -0
- data/xquery_use_cases/tree/book.xml +50 -0
- data/xquery_use_cases/tree/q1.out +23 -0
- data/xquery_use_cases/tree/q1.rb +31 -0
- data/xquery_use_cases/tree/q1.xquery +14 -0
- data/xquery_use_cases/tree/q2.out +11 -0
- data/xquery_use_cases/tree/q2.rb +27 -0
- data/xquery_use_cases/tree/q2.xquery +10 -0
- data/xquery_use_cases/tree/q3.out +2 -0
- data/xquery_use_cases/tree/q3.rb +26 -0
- data/xquery_use_cases/tree/q3.xquery +2 -0
- data/xquery_use_cases/tree/q4.out +1 -0
- data/xquery_use_cases/tree/q4.rb +23 -0
- data/xquery_use_cases/tree/q4.xquery +5 -0
- data/xquery_use_cases/tree/q5.out +9 -0
- data/xquery_use_cases/tree/q5.rb +30 -0
- data/xquery_use_cases/tree/q5.xquery +8 -0
- data/xquery_use_cases/tree/q6.out +30 -0
- data/xquery_use_cases/tree/q6.rb +35 -0
- data/xquery_use_cases/tree/q6.xquery +21 -0
- data/xquery_use_cases/xmp/README +41 -0
- data/xquery_use_cases/xmp/bib.xml +35 -0
- data/xquery_use_cases/xmp/books.xml +15 -0
- data/xquery_use_cases/xmp/prices.xml +32 -0
- data/xquery_use_cases/xmp/q1.out +8 -0
- data/xquery_use_cases/xmp/q1.rb +29 -0
- data/xquery_use_cases/xmp/q1.xquery +10 -0
- data/xquery_use_cases/xmp/q10.out +11 -0
- data/xquery_use_cases/xmp/q10.rb +36 -0
- data/xquery_use_cases/xmp/q10.xquery +11 -0
- data/xquery_use_cases/xmp/q11.out +35 -0
- data/xquery_use_cases/xmp/q11.rb +37 -0
- data/xquery_use_cases/xmp/q11.xquery +18 -0
- data/xquery_use_cases/xmp/q12.out +6 -0
- data/xquery_use_cases/xmp/q12.rb +35 -0
- data/xquery_use_cases/xmp/q12.xquery +20 -0
- data/xquery_use_cases/xmp/q2.out +37 -0
- data/xquery_use_cases/xmp/q2.rb +30 -0
- data/xquery_use_cases/xmp/q2.xquery +12 -0
- data/xquery_use_cases/xmp/q3.out +34 -0
- data/xquery_use_cases/xmp/q3.rb +27 -0
- data/xquery_use_cases/xmp/q3.xquery +10 -0
- data/xquery_use_cases/xmp/q4.out +31 -0
- data/xquery_use_cases/xmp/q4.rb +44 -0
- data/xquery_use_cases/xmp/q4.xquery +21 -0
- data/xquery_use_cases/xmp/q5.out +17 -0
- data/xquery_use_cases/xmp/q5.rb +38 -0
- data/xquery_use_cases/xmp/q5.xquery +13 -0
- data/xquery_use_cases/xmp/q6.out +28 -0
- data/xquery_use_cases/xmp/q6.rb +33 -0
- data/xquery_use_cases/xmp/q6.xquery +19 -0
- data/xquery_use_cases/xmp/q7.out +8 -0
- data/xquery_use_cases/xmp/q7.rb +30 -0
- data/xquery_use_cases/xmp/q7.xquery +12 -0
- data/xquery_use_cases/xmp/q8.out +7 -0
- data/xquery_use_cases/xmp/q8.rb +29 -0
- data/xquery_use_cases/xmp/q8.xquery +9 -0
- data/xquery_use_cases/xmp/q9.out +4 -0
- data/xquery_use_cases/xmp/q9.rb +29 -0
- data/xquery_use_cases/xmp/q9.xquery +7 -0
- data/xquery_use_cases/xmp/reviews.xml +24 -0
- metadata +342 -0
@@ -0,0 +1,855 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#Copyright (c) 2006-2007 Tomasz Wegrzanowski <Tomasz.Wegrzanowski@gmail.com>
|
3
|
+
#
|
4
|
+
#Permission is hereby granted, free of charge, to any person obtaining a
|
5
|
+
#copy of this software and associated documentation files (the "Software"),
|
6
|
+
#to deal in the Software without restriction, including without limitation
|
7
|
+
#the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
8
|
+
#and/or sell copies of the Software, and to permit persons to whom the
|
9
|
+
#Software is furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
#The above copyright notice and this permission notice shall be included in
|
12
|
+
#all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
17
|
+
#THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
18
|
+
#OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
19
|
+
#ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
20
|
+
#DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
require 'helper'
|
23
|
+
|
24
|
+
# For tests
|
25
|
+
require 'stringio'
|
26
|
+
|
27
|
+
class XML_Tests < Test::Unit::TestCase
|
28
|
+
# Test whether XML.new constructors work (without monadic case)
|
29
|
+
def test_constructors
|
30
|
+
br = XML.new(:br)
|
31
|
+
h3 = XML.new(:h3, "Hello")
|
32
|
+
a = XML.new(:a, {:href => "http://www.google.com/"}, "Google")
|
33
|
+
ul = XML.new(:ul, XML.new(:li, "Hello"), XML.new(:li, "world"))
|
34
|
+
|
35
|
+
assert_equal("<br/>", br.to_s, "Constructors should work")
|
36
|
+
assert_equal("<h3>Hello</h3>", h3.to_s, "Constructors should work")
|
37
|
+
assert_equal("<a href='http://www.google.com/'>Google</a>", a.to_s, "Constructors should work")
|
38
|
+
assert_equal("<ul><li>Hello</li><li>world</li></ul>", ul.to_s, "Constructors should work")
|
39
|
+
end
|
40
|
+
|
41
|
+
# Test character escaping on output, in text and in attribute values
|
42
|
+
def test_escapes
|
43
|
+
p = XML.new(:p, "< > &")
|
44
|
+
foo = XML.new(:foo, {:bar=>"< > ' \" &"})
|
45
|
+
|
46
|
+
assert_equal("<p>< > &</p>", p.to_s, "Character escaping should work")
|
47
|
+
assert_equal("<foo bar='< > ' " &'/>", foo.to_s, "Character escaping in attributes should work")
|
48
|
+
end
|
49
|
+
|
50
|
+
# Test #sort_by and #children_sort_by
|
51
|
+
def test_sort_by
|
52
|
+
doc = XML.parse("<foo><bar id='5'/>a<bar id='3'/>c<bar id='4'/>b<bar id='1'/></foo>")
|
53
|
+
|
54
|
+
doc_by_id = doc.sort_by{|c| c[:id]}
|
55
|
+
assert_equal("<foo><bar id='1'/><bar id='3'/><bar id='4'/><bar id='5'/></foo>", doc_by_id.to_s)
|
56
|
+
|
57
|
+
doc_all_by_id = doc.children_sort_by{|c| if c.is_a? XML then [0, c[:id]] else [1, c] end}
|
58
|
+
assert_equal("<foo><bar id='1'/><bar id='3'/><bar id='4'/><bar id='5'/>abc</foo>", doc_all_by_id.to_s)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Test XML#[] and XML#[]= for attribute access
|
62
|
+
def test_attr
|
63
|
+
foo = XML.new(:foo, {:x => "1"})
|
64
|
+
assert_equal("1", foo[:x], "Attribute reading should work")
|
65
|
+
foo[:x] = "2"
|
66
|
+
foo[:y] = "3"
|
67
|
+
assert_equal("2", foo[:x], "Attribute writing should work")
|
68
|
+
assert_equal("3", foo[:y], "Attribute writing should work")
|
69
|
+
end
|
70
|
+
|
71
|
+
# Test XML#<< method for adding children
|
72
|
+
def test_add
|
73
|
+
a = XML.new(:p, "Hello")
|
74
|
+
a << ", "
|
75
|
+
a << "world!"
|
76
|
+
assert_equal("<p>Hello, world!</p>", a.to_s, "XML#<< should work")
|
77
|
+
|
78
|
+
b = XML.new(:foo)
|
79
|
+
b << XML.new(:bar)
|
80
|
+
assert_equal("<foo><bar/></foo>", b.to_s, "XML#<< should work")
|
81
|
+
end
|
82
|
+
|
83
|
+
# Test XML#each method for iterating over children
|
84
|
+
def test_each
|
85
|
+
a = XML.new(:p, "Hello", ", ", "world", XML.new(:br))
|
86
|
+
b = ""
|
87
|
+
a.each{|c| b += c.to_s}
|
88
|
+
assert_equal("Hello, world<br/>", b, "XML#each should work")
|
89
|
+
end
|
90
|
+
|
91
|
+
# Test XML#map method
|
92
|
+
def test_map
|
93
|
+
a = XML.new(:body, XML.new(:h3, "One"), "Hello", XML.new(:h3, "Two"))
|
94
|
+
b = a.map{|c|
|
95
|
+
if c.is_a? XML and c.name == :h3
|
96
|
+
XML.new(:h2, c.attrs, *c.contents)
|
97
|
+
else
|
98
|
+
c
|
99
|
+
end
|
100
|
+
}
|
101
|
+
assert_equal("<body><h3>One</h3>Hello<h3>Two</h3></body>", a.to_s, "XML#map should not modify the argument")
|
102
|
+
assert_equal("<body><h2>One</h2>Hello<h2>Two</h2></body>", b.to_s, "XML#map should work")
|
103
|
+
|
104
|
+
d = a.map(:h3) {|c|
|
105
|
+
XML.new(:h2, c.attrs, *c.contents)
|
106
|
+
}
|
107
|
+
assert_equal("<body><h2>One</h2>Hello<h2>Two</h2></body>", d.to_s, "XML#map should accept selectors")
|
108
|
+
end
|
109
|
+
|
110
|
+
# Test XML#==
|
111
|
+
def test_eqeq
|
112
|
+
a = XML.new(:foo)
|
113
|
+
b = XML.new(:foo)
|
114
|
+
c = XML.new(:bar)
|
115
|
+
assert(a==a, "XML#== should work")
|
116
|
+
assert(a==b, "XML#== should work")
|
117
|
+
assert(a!=c, "XML#== should work")
|
118
|
+
|
119
|
+
d = XML.new(:foo, {:bar => "1"})
|
120
|
+
e = XML.new(:foo, {:bar => "1"})
|
121
|
+
f = XML.new(:foo, {:bar => "2"})
|
122
|
+
assert(d==d, "XML#== should work")
|
123
|
+
assert(d==e, "XML#== should work")
|
124
|
+
assert(d!=f, "XML#== should work")
|
125
|
+
|
126
|
+
a = XML.new(:foo, "Hello, world!")
|
127
|
+
b = XML.new(:foo, "Hello, world!")
|
128
|
+
c = XML.new(:foo, "Hello", ", world!")
|
129
|
+
d = XML.new(:foo, "Hello")
|
130
|
+
e = XML.new(:foo, "Hello", "")
|
131
|
+
assert(a==a, "XML#== should work")
|
132
|
+
assert(a==b, "XML#== should work")
|
133
|
+
assert(a==c, "XML#== should work")
|
134
|
+
assert(a!=d, "XML#== should work")
|
135
|
+
assert(d==e, "Empty children should not affect XML#==")
|
136
|
+
|
137
|
+
# Highly pathological case
|
138
|
+
a = XML.new(:foo, "ab", "cde", "", "fg", "hijk", "", "")
|
139
|
+
b = XML.new(:foo, "", "abc", "d", "efg", "h", "ijk")
|
140
|
+
assert(a==b, "XML#== should work with differently split Strings too")
|
141
|
+
|
142
|
+
# String vs XML
|
143
|
+
a = XML.new(:foo, "Hello")
|
144
|
+
b = XML.new(:foo) {foo!}
|
145
|
+
c = XML.new(:foo) {bar!}
|
146
|
+
assert(a!=b, "XML#== should work with children of different types")
|
147
|
+
assert(b!=c, "XML#== should work recursively")
|
148
|
+
|
149
|
+
a = XML.new(:foo) {foo!; bar!}
|
150
|
+
b = XML.new(:foo) {foo!; foo!}
|
151
|
+
assert(a!=b, "XML#== should work recursively")
|
152
|
+
end
|
153
|
+
|
154
|
+
# Test dup-with-block method
|
155
|
+
def test_dup
|
156
|
+
a = XML.new(:foo, {:a => "1"}, "Hello")
|
157
|
+
b = a.dup{ @name = :bar }
|
158
|
+
c = a.dup{ self[:a] = "2" }
|
159
|
+
d = a.dup{ self << ", world!" }
|
160
|
+
|
161
|
+
assert_equal("<foo a='1'>Hello</foo>", a.to_s, "XML#dup{} should not modify its argument")
|
162
|
+
assert_equal("<bar a='1'>Hello</bar>", b.to_s, "XML#dup{} should work")
|
163
|
+
assert_equal("<foo a='2'>Hello</foo>", c.to_s, "XML#dup{} should work")
|
164
|
+
assert_equal("<foo a='1'>Hello, world!</foo>", d.to_s, "XML#dup{} should work")
|
165
|
+
|
166
|
+
# Deep copy test
|
167
|
+
a = XML.new(:h3, "Hello")
|
168
|
+
b = XML.new(:foo, XML.new(:bar, a))
|
169
|
+
c = b.dup
|
170
|
+
a << ", world!"
|
171
|
+
|
172
|
+
assert_equal("<foo><bar><h3>Hello, world!</h3></bar></foo>", b.to_s, "XML#dup should make a deep copy")
|
173
|
+
assert_equal("<foo><bar><h3>Hello</h3></bar></foo>", c.to_s, "XML#dup should make a deep copy")
|
174
|
+
end
|
175
|
+
|
176
|
+
# Test XML#normalize! method
|
177
|
+
def test_normalize
|
178
|
+
a = XML.new(:foo, "He", "", "llo")
|
179
|
+
b = XML.new(:foo, "")
|
180
|
+
c = XML.new(:foo, "", XML.new(:bar, "1"), "", XML.new(:bar, "2", ""), "X", XML.new(:bar, "", "3"), "")
|
181
|
+
|
182
|
+
a.normalize!
|
183
|
+
b.normalize!
|
184
|
+
c.normalize!
|
185
|
+
|
186
|
+
assert_equal(["Hello"], a.contents, "XML#normalize! should work")
|
187
|
+
assert_equal([], b.contents, "XML#normalize! should work")
|
188
|
+
assert_equal([XML.new(:bar, "1"), XML.new(:bar, "2"), "X", XML.new(:bar, "3")], c.contents, "XML#normalize! should work")
|
189
|
+
end
|
190
|
+
|
191
|
+
# Test the "monadic" interface, that is constructors
|
192
|
+
# with instance_eval'd blocks passed to them:
|
193
|
+
# XML.new(:foo) { bar! } # -> <foo><bar/></foo>
|
194
|
+
def test_monadic
|
195
|
+
a = XML.new(:foo) { bar!; xml!(:xxx) }
|
196
|
+
b = xml(:div) {
|
197
|
+
ul! {
|
198
|
+
li!(XML.a("Hello"))
|
199
|
+
}
|
200
|
+
}
|
201
|
+
assert_equal("<foo><bar/><xxx/></foo>", a.to_s, "Monadic interface should work")
|
202
|
+
assert_equal("<div><ul><li><a>Hello</a></li></ul></div>", b.to_s, "Monadic interface should work")
|
203
|
+
end
|
204
|
+
|
205
|
+
# Test if parsing and printing gives the right results
|
206
|
+
# We test mostly round-trip
|
207
|
+
def test_parse
|
208
|
+
a = "<foo/>"
|
209
|
+
b = "<foo a='1'/>"
|
210
|
+
c = "<foo>Hello</foo>"
|
211
|
+
d = "<foo a='1'><bar b='2'>Hello</bar><bar b='3'>world</bar></foo>"
|
212
|
+
e = "<foo>> < &</foo>"
|
213
|
+
f = "<foo a='b&c'/>"
|
214
|
+
|
215
|
+
assert_equal(a, XML.parse(a).to_s, "XML.parse(x).to_s should equal x for normalized x")
|
216
|
+
assert_equal(b, XML.parse(b).to_s, "XML.parse(x).to_s should equal x for normalized x")
|
217
|
+
assert_equal(c, XML.parse(c).to_s, "XML.parse(x).to_s should equal x for normalized x")
|
218
|
+
assert_equal(d, XML.parse(d).to_s, "XML.parse(x).to_s should equal x for normalized x")
|
219
|
+
assert_equal(e, XML.parse(e).to_s, "XML.parse(x).to_s should equal x for normalized x")
|
220
|
+
assert_equal(f, XML.parse(f).to_s, "XML.parse(x).to_s should equal x for normalized x")
|
221
|
+
end
|
222
|
+
|
223
|
+
# Test parsing &-entities
|
224
|
+
def test_parse_extra_escapes
|
225
|
+
a = "<foo>" '</foo>"
|
226
|
+
a_out = "<foo>\" '</foo>"
|
227
|
+
|
228
|
+
assert_equal(a_out, XML.parse(a).to_s, "XML.parse(x).to_s should normalize entities in x")
|
229
|
+
end
|
230
|
+
|
231
|
+
# Test handling extra cruft
|
232
|
+
# Some things are best ignored or normalized
|
233
|
+
def test_parse_extra_cdata
|
234
|
+
a = "<foo><![CDATA[<greeting>Hello, world!</greeting>]]></foo>"
|
235
|
+
a_out = "<foo><greeting>Hello, world!</greeting></foo>"
|
236
|
+
assert_equal(a_out, XML.parse(a).to_s, "XML.parse(x).to_s should equal normalized x")
|
237
|
+
end
|
238
|
+
|
239
|
+
# Test handling (=ignoring) XML declarations
|
240
|
+
def test_parse_extra_qxml
|
241
|
+
b = "<?xml version=\"1.0\"?><greeting>Hello, world!</greeting>"
|
242
|
+
b_out = "<greeting>Hello, world!</greeting>"
|
243
|
+
assert_equal(b_out, XML.parse(b).to_s, "XML.parse(x).to_s should equal normalized x")
|
244
|
+
end
|
245
|
+
|
246
|
+
# Test handling (=ignoring) DTDs
|
247
|
+
def test_parse_extra_dtd
|
248
|
+
c = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?><!DOCTYPE greeting [<!ELEMENT greeting (#PCDATA)>]><greeting>Hello, world!</greeting>"
|
249
|
+
c_out = "<greeting>Hello, world!</greeting>"
|
250
|
+
assert_equal(c_out, XML.parse(c).to_s, "XML.parse(x).to_s should equal normalized x")
|
251
|
+
end
|
252
|
+
|
253
|
+
# Test handling (=ignoring) DTDs
|
254
|
+
def test_parse_extra_comment
|
255
|
+
c = "<!-- this is a comment --><greeting>Hello,<!-- another comment --> world!</greeting>"
|
256
|
+
c_out = "<greeting>Hello, world!</greeting>"
|
257
|
+
assert_equal(c_out, XML.parse(c).to_s, "XML.parse(x).to_s should equal normalized x")
|
258
|
+
end
|
259
|
+
|
260
|
+
# Test reading from a file
|
261
|
+
def test_parse_file
|
262
|
+
a = File.open("test.xml").xml_parse
|
263
|
+
b = XML.from_file("test.xml")
|
264
|
+
c = XML.from_url("file:test.xml")
|
265
|
+
d = XML.from_url("string:<foo><bar></bar></foo>")
|
266
|
+
e = XML.parse("<foo><bar></bar></foo>")
|
267
|
+
f = "<foo><bar></bar></foo>".xml_parse
|
268
|
+
g = XML.foo { bar! }
|
269
|
+
|
270
|
+
assert_equal(g.to_s, a.to_s, "File#xml_parse should work")
|
271
|
+
assert_equal(g.to_s, b.to_s, "XML.from_file should work")
|
272
|
+
assert_equal(g.to_s, c.to_s, "XML.from_url(\"file:...\") should work")
|
273
|
+
assert_equal(g.to_s, d.to_s, "XML.from_url(\"string:...\") should work")
|
274
|
+
assert_equal(g.to_s, e.to_s, "XML.parse should work")
|
275
|
+
assert_equal(g.to_s, f.to_s, "String#xml_parse should work")
|
276
|
+
end
|
277
|
+
|
278
|
+
# Test XML#children and Array#children
|
279
|
+
def test_chilrden
|
280
|
+
a = XML.bar({:x=>"1"})
|
281
|
+
b = XML.bar({:x=>"3"})
|
282
|
+
c = XML.bar({:x=>"2"}, b)
|
283
|
+
d = XML.foo(a,c)
|
284
|
+
e = d.children(:bar)
|
285
|
+
f = e.children(:bar)
|
286
|
+
assert_equal([a,c], e, "XML#children(tag) should return tag-tagged children")
|
287
|
+
assert_equal([b], f, "Array#children(tag) should return tag-tagged children of its elements")
|
288
|
+
end
|
289
|
+
|
290
|
+
# Test XML#descendants and Array#descendants
|
291
|
+
def test_descendants
|
292
|
+
a = XML.bar({:x=>"1"})
|
293
|
+
b = XML.bar({:x=>"3"})
|
294
|
+
c = XML.bar({:x=>"2"}, b)
|
295
|
+
d = XML.foo(a,c)
|
296
|
+
e = d.descendants(:bar)
|
297
|
+
f = e.descendants(:bar)
|
298
|
+
assert_equal([a,c,b], e, "XML#descendants(tag) should return tag-tagged descendants")
|
299
|
+
assert_equal([b], f, "Array#descendants(tag) should return tag-tagged descendants of its elements")
|
300
|
+
end
|
301
|
+
|
302
|
+
# Test XML#exec! monadic interface
|
303
|
+
def test_exec
|
304
|
+
a = XML.foo
|
305
|
+
a.exec! {
|
306
|
+
bar! { text! "Hello" }
|
307
|
+
text! "world"
|
308
|
+
}
|
309
|
+
assert_equal("<foo><bar>Hello</bar>world</foo>", a.to_s, "XML#exec! should work")
|
310
|
+
end
|
311
|
+
|
312
|
+
# Test XML#child
|
313
|
+
def test_child
|
314
|
+
a = XML.parse("<foo></foo>")
|
315
|
+
b = XML.parse("<foo><bar a='1'/></foo>")
|
316
|
+
c = XML.parse("<foo><bar a='1'/><bar a='2'/></foo>")
|
317
|
+
|
318
|
+
assert_equal(nil, a.child(:bar), "XML#child should return nil if there are no matching children")
|
319
|
+
assert_equal("<bar a='1'/>", b.child(:bar).to_s, "XML#child should work")
|
320
|
+
assert_equal("<bar a='1'/>", c.child(:bar).to_s, "XML#child should return first child if there are many")
|
321
|
+
assert_equal("<bar a='2'/>", c.child({:a => '2'}).to_s, "XML#child should support patterns")
|
322
|
+
end
|
323
|
+
|
324
|
+
# Test XML#descendant
|
325
|
+
def test_descendant
|
326
|
+
a = XML.parse("<foo></foo>")
|
327
|
+
b = XML.parse("<foo><bar a='1'/></foo>")
|
328
|
+
c = XML.parse("<foo><bar a='1'/><bar a='2'/></foo>")
|
329
|
+
d = XML.parse("<foo><bar a='1'><bar a='2'/></bar><bar a='3'/></foo>")
|
330
|
+
e = XML.parse("<foo><foo><bar a='1'/></foo><bar a='2'/></foo>")
|
331
|
+
|
332
|
+
assert_equal(nil, a.descendant(:bar), "XML#descendant should return nil if there are no matching descendants")
|
333
|
+
assert_equal("<bar a='1'/>", b.descendant(:bar).to_s, "XML#descendant should work")
|
334
|
+
assert_equal("<bar a='1'/>", c.descendant(:bar).to_s, "XML#descendant should return first descendant if there are many")
|
335
|
+
assert_equal("<bar a='1'><bar a='2'/></bar>", d.descendant(:bar).to_s, "XML#descendant should return first descendant if there are many")
|
336
|
+
assert_equal("<bar a='1'/>", e.descendant(:bar).to_s, "XML#descendant should return first descendant if there are many")
|
337
|
+
assert_equal("<bar a='2'/>", c.descendant({:a => '2'}).to_s, "XML#descendant should support patterns")
|
338
|
+
assert_equal("<bar a='2'/>", d.descendant({:a => '2'}).to_s, "XML#descendant should support patterns")
|
339
|
+
assert_equal("<bar a='2'/>", e.descendant({:a => '2'}).to_s, "XML#descendant should support patterns")
|
340
|
+
end
|
341
|
+
|
342
|
+
# Test XML#text
|
343
|
+
def test_text
|
344
|
+
a = XML.parse("<foo>Hello</foo>")
|
345
|
+
b = XML.parse("<foo></foo>")
|
346
|
+
c = XML.parse("<foo><bar>Hello</bar></foo>")
|
347
|
+
d = XML.parse("<foo>He<bar>llo</bar></foo>")
|
348
|
+
|
349
|
+
assert_equal("Hello", a.text, "XML#text should work")
|
350
|
+
assert_equal("", b.text, "XML#text should work")
|
351
|
+
assert_equal("Hello", c.text, "XML#text should work")
|
352
|
+
assert_equal("Hello", d.text, "XML#text should work")
|
353
|
+
end
|
354
|
+
|
355
|
+
# Test XML#renormalize and XML#renormalize_sequence
|
356
|
+
def test_renormalize
|
357
|
+
a = "<foo></foo>"
|
358
|
+
b = "<foo></foo><bar></bar>"
|
359
|
+
|
360
|
+
assert_equal("<foo/>", XML.renormalize(a), "XML#renormalize should work")
|
361
|
+
assert_equal("<foo/>", XML.renormalize_sequence(a), "XML#renormalize_sequence should work")
|
362
|
+
assert_equal("<foo/><bar/>", XML.renormalize_sequence(b), "XML#renormalize_sequence should work")
|
363
|
+
end
|
364
|
+
|
365
|
+
# Test XML#range
|
366
|
+
def test_range
|
367
|
+
a = XML.parse "<foo><bar i='0'/><bar i='1'/><bar i='2'/><bar i='3'/><bar i='4'/></foo>"
|
368
|
+
b = a.children(:bar)
|
369
|
+
|
370
|
+
# Non-recursive case
|
371
|
+
ar_n_n = a.range(nil, nil)
|
372
|
+
ar_0_n = a.range(b[0], nil)
|
373
|
+
ar_1_n = a.range(b[1], nil)
|
374
|
+
ar_4_n = a.range(b[4], nil)
|
375
|
+
ar_n_4 = a.range(nil, b[4])
|
376
|
+
ar_n_3 = a.range(nil, b[3])
|
377
|
+
ar_n_0 = a.range(nil, b[0])
|
378
|
+
|
379
|
+
assert_equal("<foo><bar i='0'/><bar i='1'/><bar i='2'/><bar i='3'/><bar i='4'/></foo>", ar_n_n.to_s, "XML#range should work")
|
380
|
+
assert_equal("<foo><bar i='1'/><bar i='2'/><bar i='3'/><bar i='4'/></foo>", ar_0_n.to_s, "XML#range should work")
|
381
|
+
assert_equal("<foo><bar i='2'/><bar i='3'/><bar i='4'/></foo>", ar_1_n.to_s, "XML#range should work")
|
382
|
+
assert_equal("<foo/>", ar_4_n.to_s, "XML#range should work")
|
383
|
+
assert_equal("<foo><bar i='0'/><bar i='1'/><bar i='2'/><bar i='3'/></foo>", ar_n_4.to_s, "XML#range should work")
|
384
|
+
assert_equal("<foo><bar i='0'/><bar i='1'/><bar i='2'/></foo>", ar_n_3.to_s, "XML#range should work")
|
385
|
+
assert_equal("<foo/>", ar_n_0.to_s, "XML#range should work")
|
386
|
+
|
387
|
+
a = XML.parse "<a>
|
388
|
+
<b i='0'><c i='0'/><c i='1'/><c i='2'/></b>
|
389
|
+
<b i='1'><c i='3'/><c i='4'/><c i='5'/></b>
|
390
|
+
<b i='2'><c i='6'/><c i='7'/><c i='8'/></b>
|
391
|
+
</a>"
|
392
|
+
c = a.descendants(:c)
|
393
|
+
|
394
|
+
c.each_with_index{|ci,i|
|
395
|
+
c.each_with_index{|cj,j|
|
396
|
+
next unless i < j
|
397
|
+
ar = a.range(ci,cj)
|
398
|
+
cs_present = ar.descendants(:c).map{|n|n[:i].to_i}
|
399
|
+
assert_equal(((i+1)...j).to_a, cs_present, "XML#range(c#{i}, c#{j}) should contain cs between #{i} and #{j}, exclusive, instead got: #{ar}")
|
400
|
+
}
|
401
|
+
ar = a.range(ci,nil)
|
402
|
+
cs_present = ar.descendants(:c).map{|n|n[:i].to_i}
|
403
|
+
assert_equal(((i+1)..8).to_a, cs_present, "XML#range(c#{i}, nil) should contain cs from #{i+1} to 8, instead got: #{ar}")
|
404
|
+
|
405
|
+
ar = a.range(nil,ci)
|
406
|
+
cs_present = ar.descendants(:c).map{|n|n[:i].to_i}
|
407
|
+
assert_equal((0...i).to_a, cs_present, "XML#range(nil, c#{i}) should contain cs from 0 to #{i-1}, instead got: #{ar}")
|
408
|
+
}
|
409
|
+
end
|
410
|
+
|
411
|
+
# Test XML#subsequence
|
412
|
+
def test_subsequence
|
413
|
+
a = XML.parse "<foo><bar i='0'/><bar i='1'/><bar i='2'/><bar i='3'/><bar i='4'/></foo>"
|
414
|
+
b = a.children(:bar)
|
415
|
+
|
416
|
+
# Non-recursive case
|
417
|
+
ar_n_n = a.subsequence(nil, nil)
|
418
|
+
ar_0_n = a.subsequence(b[0], nil)
|
419
|
+
ar_1_n = a.subsequence(b[1], nil)
|
420
|
+
ar_4_n = a.subsequence(b[4], nil)
|
421
|
+
ar_n_4 = a.subsequence(nil, b[4])
|
422
|
+
ar_n_3 = a.subsequence(nil, b[3])
|
423
|
+
ar_n_0 = a.subsequence(nil, b[0])
|
424
|
+
|
425
|
+
assert_equal("<foo><bar i='0'/><bar i='1'/><bar i='2'/><bar i='3'/><bar i='4'/></foo>", ar_n_n.to_s, "XML#subsequence should work")
|
426
|
+
assert_equal("<bar i='1'/><bar i='2'/><bar i='3'/><bar i='4'/>", ar_0_n.to_s, "XML#subsequence should work")
|
427
|
+
assert_equal("<bar i='2'/><bar i='3'/><bar i='4'/>", ar_1_n.to_s, "XML#subsequence should work")
|
428
|
+
assert_equal("", ar_4_n.to_s, "XML#subsequence should work")
|
429
|
+
assert_equal("<foo><bar i='0'/><bar i='1'/><bar i='2'/><bar i='3'/></foo>", ar_n_4.to_s, "XML#subsequence should work")
|
430
|
+
assert_equal("<foo><bar i='0'/><bar i='1'/><bar i='2'/></foo>", ar_n_3.to_s, "XML#subsequence should work")
|
431
|
+
assert_equal("<foo/>", ar_n_0.to_s, "XML#subsequence should work")
|
432
|
+
|
433
|
+
a = XML.parse "<a>
|
434
|
+
<b j='0'><c i='0'/><c i='1'/><c i='2'/></b>
|
435
|
+
<b j='1'><c i='3'/><c i='4'/><c i='5'/></b>
|
436
|
+
<b j='2'><c i='6'/><c i='7'/><c i='8'/></b>
|
437
|
+
</a>"
|
438
|
+
c = a.descendants(:c)
|
439
|
+
|
440
|
+
# (ar + ar.descendants).find_all{|x| x.is_a? XML and x.name == :c}
|
441
|
+
# instead of ar.descendants(:c) because
|
442
|
+
# we might have returned [<c i='?'/>] as a result,
|
443
|
+
# and then it's not a descendant of the result then.
|
444
|
+
# This is ugly, and it should be fixed somewhere in magic/xml
|
445
|
+
c.each_with_index{|ci,i|
|
446
|
+
c.each_with_index{|cj,j|
|
447
|
+
next unless i < j
|
448
|
+
ar = a.subsequence(ci,cj)
|
449
|
+
cs_present = (ar + ar.descendants).find_all{|x| x.is_a? XML and x.name == :c}.map{|n| n[:i].to_i}
|
450
|
+
assert_equal(((i+1)...j).to_a, cs_present, "XML#subsequence(c#{i}, c#{j}) should contain cs between #{i} and #{j}, exclusive, instead got: #{ar}")
|
451
|
+
}
|
452
|
+
ar = a.subsequence(ci,nil)
|
453
|
+
cs_present = (ar + ar.descendants).find_all{|x| x.is_a? XML and x.name == :c}.map{|n| n[:i].to_i}
|
454
|
+
assert_equal(((i+1)..8).to_a, cs_present, "XML#subsequence(c#{i}, nil) should contain cs from #{i+1} to 8, instead got: #{ar}")
|
455
|
+
|
456
|
+
ar = a.subsequence(nil,ci)
|
457
|
+
cs_present = (ar + ar.descendants).find_all{|x| x.is_a? XML and x.name == :c}.map{|n| n[:i].to_i}
|
458
|
+
assert_equal((0...i).to_a, cs_present, "XML#subsequence(nil, c#{i}) should contain cs from 0 to #{i-1}, instead got: #{ar}")
|
459
|
+
}
|
460
|
+
end
|
461
|
+
|
462
|
+
# Test xml! at top level
|
463
|
+
def test_xml_bang
|
464
|
+
real_stdout = $stdout
|
465
|
+
$stdout = StringIO.new
|
466
|
+
xml!(:foo)
|
467
|
+
assert_equal("<foo/>", $stdout.string, "xml! should work")
|
468
|
+
|
469
|
+
$stdout = StringIO.new
|
470
|
+
XML.bar!
|
471
|
+
assert_equal("<bar/>", $stdout.string, "XML#foo! should work")
|
472
|
+
$stdout = real_stdout
|
473
|
+
end
|
474
|
+
|
475
|
+
# Methods XML#foo! are all catched,
|
476
|
+
# but how about other methods ?
|
477
|
+
def test_real_method_missing
|
478
|
+
foo = XML.new(:foo)
|
479
|
+
exception_raised = false
|
480
|
+
begin
|
481
|
+
foo.bar()
|
482
|
+
rescue NoMethodError
|
483
|
+
exception_raised = true
|
484
|
+
end
|
485
|
+
# FIXME: There are other assertions than assert_equal ;-)
|
486
|
+
assert_equal(true, exception_raised, "XML#bar should raise NoMethodError")
|
487
|
+
end
|
488
|
+
|
489
|
+
# Test XML#parse_as_twigs interface
|
490
|
+
def test_parse_as_twigs
|
491
|
+
stream = "<foo><p><ul><li>1</li><li>2</li><li>3</li></ul></p><p><br/></p><p/><p><bar/></p></foo>"
|
492
|
+
i = 0
|
493
|
+
results = []
|
494
|
+
XML.parse_as_twigs(stream) {|n|
|
495
|
+
n.complete! if i == 1 or i == 3
|
496
|
+
results << n
|
497
|
+
i += 1
|
498
|
+
}
|
499
|
+
assert_equal("<foo/>", results[0].to_s, "XML.parse_as_twigs should work")
|
500
|
+
assert_equal("<p><ul><li>1</li><li>2</li><li>3</li></ul></p>", results[1].to_s, "XML.parse_as_twigs should work")
|
501
|
+
assert_equal("<p/>", results[2].to_s, "XML.parse_as_twigs should work")
|
502
|
+
assert_equal("<br/>", results[3].to_s, "XML.parse_as_twigs should work")
|
503
|
+
assert_equal("<p/>", results[4].to_s, "XML.parse_as_twigs should work")
|
504
|
+
assert_equal("<p/>", results[5].to_s, "XML.parse_as_twigs should work")
|
505
|
+
assert_equal("<bar/>", results[6].to_s, "XML.parse_as_twigs should work")
|
506
|
+
assert_equal(7, results.size, "XML.parse_as_twigs should work")
|
507
|
+
end
|
508
|
+
|
509
|
+
# Test XML#inspect
|
510
|
+
def test_inpsect
|
511
|
+
a = xml(:a, xml(:b, xml(:c)))
|
512
|
+
d = xml(:d)
|
513
|
+
|
514
|
+
assert_equal("<a>...</a>", a.inspect, "XML#inspect should work")
|
515
|
+
assert_equal("<a>...</a>", a.inspect(0), "XML#inspect(levels) should work")
|
516
|
+
assert_equal("<a><b>...</b></a>", a.inspect(1), "XML#inspect(levels) should work")
|
517
|
+
assert_equal("<a><b><c/></b></a>", a.inspect(2), "XML#inspect(levels) should work")
|
518
|
+
assert_equal("<a><b><c/></b></a>", a.inspect(3), "XML#inspect(levels) should work")
|
519
|
+
assert_equal("<d/>", d.inspect, "XML#inspect should work")
|
520
|
+
assert_equal("<d/>", d.inspect(0), "XML#inspect should work")
|
521
|
+
assert_equal("<d/>", d.inspect(1), "XML#inspect should work")
|
522
|
+
end
|
523
|
+
|
524
|
+
# Test XML#[:@foo] pseudoattributes
|
525
|
+
def test_pseudoattributes_read
|
526
|
+
# Ignore the second <x>...</x>
|
527
|
+
a = XML.parse("<foo x='10'><x>20</x><y>30</y><x>40</x></foo>")
|
528
|
+
|
529
|
+
assert_equal("10", a[:x], "XML#[] real attributes should work")
|
530
|
+
assert_nil(a[:y], "XML#[] real attributes should work")
|
531
|
+
assert_nil(a[:z], "XML#[] real attributes should work")
|
532
|
+
assert_equal("20", a[:@x], "XML#[] pseudoattributes should work")
|
533
|
+
assert_equal("30", a[:@y], "XML#[] pseudoattributes should work")
|
534
|
+
assert_nil(a[:@z], "XML#[] pseudoattributes should work")
|
535
|
+
end
|
536
|
+
|
537
|
+
# Test XML#[:@foo] pseudoattributes
|
538
|
+
def test_pseudoattributes_write
|
539
|
+
# Ignore the second <x>...</x>
|
540
|
+
a = XML.parse("<foo x='10'><x>20</x><y>30</y><x>40</x></foo>")
|
541
|
+
|
542
|
+
a[:x] = 100
|
543
|
+
a[:y] = 200
|
544
|
+
a[:z] = 300
|
545
|
+
a[:@x] = 1000
|
546
|
+
a[:@y] = 2000
|
547
|
+
a[:@z] = 3000
|
548
|
+
|
549
|
+
assert_equal("<foo x='100' y='200' z='300'><x>1000</x><y>2000</y><x>40</x><z>3000</z></foo>", a.to_s, "XML#[]= pseudoattributes should work")
|
550
|
+
end
|
551
|
+
|
552
|
+
# Test entity unescaping
|
553
|
+
def test_entities
|
554
|
+
a = XML.parse("<foo>¥ü†</foo>")
|
555
|
+
b = XML.parse("<foo>¥ü†</foo>")
|
556
|
+
c = XML.parse("<foo>¥ü†</foo>")
|
557
|
+
d = ""
|
558
|
+
|
559
|
+
assert_equal(b.text, a.text, "Entity unescaping on XML#Parse should work")
|
560
|
+
assert_equal(c.text, a.text, "Entity unescaping on XML#Parse should work")
|
561
|
+
|
562
|
+
assert_equal(b.to_s, a.to_s, "Entity escaping on XML#to_s should work")
|
563
|
+
assert_equal(c.to_s, a.to_s, "Entity escaping on XML#to_s should work")
|
564
|
+
|
565
|
+
# The escapes assume \XXX are byte escapes and the encoding is UTF-8
|
566
|
+
assert_equal("\302\245\303\274\342\200\240", a.text, "Entity unescaping on XML#Parse should work")
|
567
|
+
assert_equal("<foo>\302\245\303\274\342\200\240</foo>", a.to_s, "Entity escaping on XML#to_s should work")
|
568
|
+
end
|
569
|
+
|
570
|
+
# Test patterns support
|
571
|
+
def test_patterns
|
572
|
+
a = XML.parse "<foo><bar color='blue'>Hello</bar>, <bar color='red'>world</bar><excl>!</excl></foo>"
|
573
|
+
a.normalize!
|
574
|
+
|
575
|
+
blue = []
|
576
|
+
nocolor = []
|
577
|
+
bar = []
|
578
|
+
#hello = []
|
579
|
+
|
580
|
+
a.descendants {|d|
|
581
|
+
case d
|
582
|
+
when :bar
|
583
|
+
bar << d
|
584
|
+
end
|
585
|
+
|
586
|
+
case d
|
587
|
+
when {:color => 'blue'}
|
588
|
+
blue << d
|
589
|
+
end
|
590
|
+
|
591
|
+
case d
|
592
|
+
when {:color => nil}
|
593
|
+
nocolor << d
|
594
|
+
end
|
595
|
+
|
596
|
+
#case d
|
597
|
+
#when /Hello/
|
598
|
+
# hello << d
|
599
|
+
#end
|
600
|
+
}
|
601
|
+
|
602
|
+
assert_equal([XML.parse("<bar color='blue'>Hello</bar>"), XML.parse("<bar color='red'>world</bar>")], bar, "Pattern matching should work")
|
603
|
+
assert_equal([XML.parse("<bar color='blue'>Hello</bar>")], blue, "Pattern matching should work")
|
604
|
+
assert_equal([XML.parse("<excl>!</excl>")], nocolor, "Pattern matching should work")
|
605
|
+
# Commented out, as it requires overloading Regexp#=~ and therefore Binding.of_caller
|
606
|
+
#assert_equal([XML.parse("<bar color='blue'>Hello</bar>"), "Hello"], hello, "Pattern matching should work")
|
607
|
+
end
|
608
|
+
|
609
|
+
# Test pattern support in #descendants (works the same way in #children)
|
610
|
+
def test_patterns_2
|
611
|
+
a = XML.parse "<foo><bar color='blue'>Hello</bar>, <bar color='red'>world</bar><excl color='blue'>!</excl></foo>"
|
612
|
+
a.normalize!
|
613
|
+
|
614
|
+
bar = a.descendants(:bar)
|
615
|
+
blue = a.descendants({:color=>'blue'})
|
616
|
+
blue_bar = a.descendants(all(:bar, {:color=>'blue'}))
|
617
|
+
#hello = a.descendants(/Hello/)
|
618
|
+
xml = a.descendants(XML)
|
619
|
+
string = a.descendants(String)
|
620
|
+
|
621
|
+
assert_equal([XML.parse("<bar color='blue'>Hello</bar>"), XML.parse("<bar color='red'>world</bar>")], bar, "Pattern matching should work")
|
622
|
+
assert_equal([XML.parse("<bar color='blue'>Hello</bar>"), XML.parse("<excl color='blue'>!</excl>")], blue, "Pattern matching should work")
|
623
|
+
assert_equal([XML.parse("<bar color='blue'>Hello</bar>")], blue_bar, "Pattern matching should work")
|
624
|
+
# Commented out, as it requires overloading Regexp#=~ and therefore Binding.of_caller
|
625
|
+
#assert_equal([XML.parse("<bar color='blue'>Hello</bar>"), "Hello"], hello, "Pattern matching should work")
|
626
|
+
assert_equal([XML.parse("<bar color='blue'>Hello</bar>"), XML.parse("<bar color='red'>world</bar>"), XML.parse("<excl color='blue'>!</excl>")], xml, "Pattern matching should work")
|
627
|
+
assert_equal(['Hello', ', ', 'world', '!'], string, "Pattern matching should work")
|
628
|
+
end
|
629
|
+
|
630
|
+
# Test patterns =~ support
|
631
|
+
def test_patterns_3
|
632
|
+
a = XML.parse "<foo><bar color='blue'>Hello</bar>, <bar color='red'>world</bar><excl>!</excl></foo>"
|
633
|
+
a.normalize!
|
634
|
+
|
635
|
+
blue = []
|
636
|
+
nocolor = []
|
637
|
+
bar = []
|
638
|
+
hello = []
|
639
|
+
|
640
|
+
a.descendants {|d|
|
641
|
+
if d =~ :bar
|
642
|
+
bar << d
|
643
|
+
end
|
644
|
+
|
645
|
+
if d =~ {:color => 'blue'}
|
646
|
+
blue << d
|
647
|
+
end
|
648
|
+
|
649
|
+
if d =~ {:color => nil}
|
650
|
+
nocolor << d
|
651
|
+
end
|
652
|
+
|
653
|
+
if d =~ /Hello/
|
654
|
+
hello << d
|
655
|
+
end
|
656
|
+
}
|
657
|
+
|
658
|
+
assert_equal([XML.parse("<bar color='blue'>Hello</bar>"), XML.parse("<bar color='red'>world</bar>")], bar, "Pattern matching should work")
|
659
|
+
assert_equal([XML.parse("<bar color='blue'>Hello</bar>")], blue, "Pattern matching should work")
|
660
|
+
assert_equal([XML.parse("<excl>!</excl>")], nocolor, "Pattern matching should work")
|
661
|
+
assert_equal([XML.parse("<bar color='blue'>Hello</bar>"), "Hello"], hello, "Pattern matching should work")
|
662
|
+
end
|
663
|
+
|
664
|
+
def test_patterns_any_all
|
665
|
+
a = XML.parse "<foo>
|
666
|
+
<bar color='blue' size='big'>1</bar>
|
667
|
+
<bar color='blue'>2</bar>
|
668
|
+
<bar color='blue' size='normal'>3</bar>
|
669
|
+
<bar color='red' size='big'>4</bar>
|
670
|
+
<bar color='red'>5</bar>
|
671
|
+
<bar color='red' size='normal'>6</bar>
|
672
|
+
</foo>"
|
673
|
+
|
674
|
+
p = all({:color => 'red'}, any({:size => nil}, {:size => 'normal'}))
|
675
|
+
# Select childern which color red and size either normal or not specified
|
676
|
+
b = a.children(p)
|
677
|
+
c = a.find_all{|x| x =~ p }
|
678
|
+
d = a.find_all{|x| p === x }
|
679
|
+
|
680
|
+
assert_equal("<bar color='red'>5</bar><bar color='red' size='normal'>6</bar>", b.to_s, "Pattern matching with any/all should work")
|
681
|
+
assert_equal("<bar color='red'>5</bar><bar color='red' size='normal'>6</bar>", c.to_s, "Pattern matching with any/all should work")
|
682
|
+
assert_equal("<bar color='red'>5</bar><bar color='red' size='normal'>6</bar>", d.to_s, "Pattern matching with any/all should work")
|
683
|
+
end
|
684
|
+
|
685
|
+
# Test parse option :ignore_pretty_printing
|
686
|
+
def test_remove_pretty_printing
|
687
|
+
a = "<foo><bar>100</bar><bar>200</bar></foo>"
|
688
|
+
b = "<foo>
|
689
|
+
<bar>
|
690
|
+
100
|
691
|
+
</bar>
|
692
|
+
<bar>
|
693
|
+
200
|
694
|
+
</bar>
|
695
|
+
</foo>"
|
696
|
+
c = XML.parse(a)
|
697
|
+
d = XML.parse(b)
|
698
|
+
e = XML.parse(b)
|
699
|
+
e.remove_pretty_printing!
|
700
|
+
|
701
|
+
assert_not_equal(c.to_s, d.to_s, "XML#parse should not ignore pretty printing by default")
|
702
|
+
assert_equal(c.to_s, e.to_s, "XML#remove_pretty_printing! should work")
|
703
|
+
|
704
|
+
f = XML.parse("<foo> <bar>Hello world</bar> </foo>")
|
705
|
+
f.remove_pretty_printing!
|
706
|
+
g = XML.parse("<foo><bar>Hello world</bar></foo>")
|
707
|
+
assert_equal(f.to_s, g.to_s, "XML#remove_pretty_printing! should work")
|
708
|
+
end
|
709
|
+
|
710
|
+
# Test remove_pretty_printing! with exception list
|
711
|
+
def test_remove_pretty_printing_conditional
|
712
|
+
a = "<foo>
|
713
|
+
<pre>
|
714
|
+
<a> 100 </a>
|
715
|
+
</pre>
|
716
|
+
<xyzzy>
|
717
|
+
<a> 200 </a>
|
718
|
+
</xyzzy>
|
719
|
+
</foo>"
|
720
|
+
b = "<foo><pre>
|
721
|
+
<a> 100 </a>
|
722
|
+
</pre><xyzzy><a>200</a></xyzzy></foo>"
|
723
|
+
|
724
|
+
ax = XML.parse(a)
|
725
|
+
bx = XML.parse(b)
|
726
|
+
|
727
|
+
ax.remove_pretty_printing!([:pre])
|
728
|
+
|
729
|
+
assert_equal(bx.to_s, ax.to_s, "XML#remove_pretty_printing!(exceptions) should work")
|
730
|
+
end
|
731
|
+
|
732
|
+
# Test extra arguments to XML#parse - :comments and :pi
|
733
|
+
def test_parsing_extras
|
734
|
+
a = "<foo><?xml-stylesheet href='http://www.blogger.com/styles/atom.css' type='text/css'?></foo>"
|
735
|
+
b = "<foo><!-- This is a comment --></foo>"
|
736
|
+
|
737
|
+
ax = XML.parse(a)
|
738
|
+
bx = XML.parse(b)
|
739
|
+
|
740
|
+
assert_equal("<foo/>", ax.to_s, "XML#parse should drop PI by default")
|
741
|
+
assert_equal("<foo/>", bx.to_s, "XML#parse should drop comments by default")
|
742
|
+
|
743
|
+
ay = XML.parse(a, :comments => true, :pi => true)
|
744
|
+
by = XML.parse(b, :comments => true, :pi => true)
|
745
|
+
|
746
|
+
assert_equal(a, ay.to_s, "XML#parse(str, :pi=>true) should include PI")
|
747
|
+
assert_equal(b, by.to_s, "XML#parse(str, :comments=>true) should include comments")
|
748
|
+
end
|
749
|
+
|
750
|
+
# Test extra arguments to XML#parse - :remove_pretty_printing.
|
751
|
+
# FIXME: How about a shorter (but still mnemonic) name for that ?
|
752
|
+
def test_parsing_nopp
|
753
|
+
a = "<foo><bar>100</bar><bar>200</bar></foo>"
|
754
|
+
b = "<foo>
|
755
|
+
<bar>
|
756
|
+
100
|
757
|
+
</bar>
|
758
|
+
<bar>
|
759
|
+
200
|
760
|
+
</bar>
|
761
|
+
</foo>"
|
762
|
+
c = XML.parse(a)
|
763
|
+
d = XML.parse(b)
|
764
|
+
e = XML.parse(b, :remove_pretty_printing => true)
|
765
|
+
|
766
|
+
assert_not_equal(c.to_s, d.to_s, "XML#parse should not ignore pretty printing by default")
|
767
|
+
assert_equal(c.to_s, e.to_s, "XML#parse(str, :remove_pretty_printing=>true) should work")
|
768
|
+
end
|
769
|
+
|
770
|
+
# Test XML.parse(str, :extra_entities => ...)
|
771
|
+
def test_parsing_entities
|
772
|
+
a = "<foo>&cat; & &dog;</foo>"
|
773
|
+
b = XML.parse(a, :extra_entities => lambda{|e|
|
774
|
+
case e
|
775
|
+
when "cat"
|
776
|
+
"neko"
|
777
|
+
when "dog"
|
778
|
+
"inu"
|
779
|
+
end
|
780
|
+
})
|
781
|
+
c = XML.parse(a, :extra_entities => {"cat" => "neko", "dog" => "inu"})
|
782
|
+
|
783
|
+
assert_equal("neko & inu", b.text, "XML#parse(str, :extra_entities=>Proc) should work")
|
784
|
+
assert_equal("neko & inu", c.text, "XML#parse(str, :extra_entities=>Hash) should work")
|
785
|
+
|
786
|
+
d = XML.parse(a, :extra_entities => {"cat" => "neko", "dog" => "inu"})
|
787
|
+
|
788
|
+
# Central European characters escapes
|
789
|
+
e = "<foo>żółw</foo>"
|
790
|
+
f = XML.parse(e, :extra_entities => {"zdot" => 380, "oacute" => 243, "lstrok" => 322})
|
791
|
+
|
792
|
+
# Assumes \number does bytes, UTF8
|
793
|
+
assert_equal("\305\274\303\263\305\202w", f.text, "XML#parse(str, :extra_entities=>...) should work with integer codepoints")
|
794
|
+
end
|
795
|
+
|
796
|
+
# Test XML.load
|
797
|
+
def test_load
|
798
|
+
a = XML.load("test.xml")
|
799
|
+
b = XML.load(File.open("test.xml"))
|
800
|
+
c = XML.load("string:<foo><bar></bar></foo>")
|
801
|
+
d = XML.load("file:test.xml")
|
802
|
+
|
803
|
+
assert_equal("<foo><bar/></foo>", a.to_s, "XML#load should work")
|
804
|
+
assert_equal("<foo><bar/></foo>", b.to_s, "XML#load should work")
|
805
|
+
assert_equal("<foo><bar/></foo>", c.to_s, "XML#load should work")
|
806
|
+
assert_equal("<foo><bar/></foo>", d.to_s, "XML#load should work")
|
807
|
+
end
|
808
|
+
|
809
|
+
# Test multielement selectors
|
810
|
+
def test_multielement_selectors
|
811
|
+
a = XML.parse("<foo><bar color='blue'><x/></bar><bar color='red'><x><y i='1'/></x><y i='2'/></bar></foo>")
|
812
|
+
assert_equal("<x/><x><y i='1'/></x>", a.children(:bar, :x).to_s, "Multielement selectors should work")
|
813
|
+
assert_equal("<y i='2'/>", a.children(:bar, :y).to_s, "Multielement selectors should work")
|
814
|
+
assert_equal("<y i='1'/><y i='2'/>", a.children(:bar, :*, :y).to_s, "Multielement selectors should work")
|
815
|
+
assert_equal("<y i='1'/>", a.descendants(:x, :y).to_s, "Multielement selectors should work")
|
816
|
+
assert_equal("<y i='1'/><y i='2'/>", a.children(:bar, :*, :y).to_s, "Multielement selectors should work")
|
817
|
+
end
|
818
|
+
|
819
|
+
# Test deep_map
|
820
|
+
def test_deep_map
|
821
|
+
a = XML.parse("<foo><bar>x</bar> <foo><bar>y</bar></foo></foo>")
|
822
|
+
b = a.deep_map(:bar) {|c| XML.new(c.text.to_sym) }
|
823
|
+
assert_equal("<foo><x/> <foo><y/></foo></foo>", b.to_s, "XML#deep_map should work")
|
824
|
+
|
825
|
+
c = XML.parse("<foo><bar>x</bar> <bar><bar>y</bar></bar></foo>")
|
826
|
+
d = c.deep_map(:bar) {|c| XML.new(:xyz, c.attrs, *c.children) }
|
827
|
+
assert_equal("<foo><xyz>x</xyz> <xyz><bar>y</bar></xyz></foo>", d.to_s, "XML#deep_map should work")
|
828
|
+
end
|
829
|
+
|
830
|
+
# Test XML.load
|
831
|
+
def test_pretty_printer
|
832
|
+
a = XML.parse("<foo><bar>x</bar>Boo!<bar><y><z>f</z></y></bar><xyzzy /><bar>Mutiline\nText\n:-)</bar></foo>")
|
833
|
+
a.add_pretty_printing!
|
834
|
+
expected = "<foo>
|
835
|
+
<bar>
|
836
|
+
x
|
837
|
+
</bar>
|
838
|
+
Boo!
|
839
|
+
<bar>
|
840
|
+
<y>
|
841
|
+
<z>
|
842
|
+
f
|
843
|
+
</z>
|
844
|
+
</y>
|
845
|
+
</bar>
|
846
|
+
<xyzzy/>
|
847
|
+
<bar>
|
848
|
+
Mutiline
|
849
|
+
Text
|
850
|
+
:-)
|
851
|
+
</bar>
|
852
|
+
</foo>"
|
853
|
+
assert_equal(expected, a.to_s, "XML#pretty_print! should work")
|
854
|
+
end
|
855
|
+
end
|