magic-xml 0.2013.04.14 → 0.2016.05.07

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