nokogiri 1.6.8.rc3-x64-mingw32 → 1.6.8-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of nokogiri might be problematic. Click here for more details.

@@ -0,0 +1,589 @@
1
+ # -*- coding: utf-8 -*-
2
+ require "helper"
3
+
4
+ module Nokogiri
5
+ module XML
6
+ class TestReader < Nokogiri::TestCase
7
+ def test_from_io_sets_io_as_source
8
+ io = File.open SNUGGLES_FILE
9
+ reader = Nokogiri::XML::Reader.from_io(io)
10
+ assert_equal io, reader.source
11
+ end
12
+
13
+ def test_empty_element?
14
+ reader = Nokogiri::XML::Reader.from_memory(<<-eoxml)
15
+ <xml><city>Paris</city><state/></xml>
16
+ eoxml
17
+
18
+ results = reader.map do |node|
19
+ if node.node_type == Nokogiri::XML::Node::ELEMENT_NODE
20
+ node.empty_element?
21
+ end
22
+ end
23
+ assert_equal [false, false, nil, nil, true, nil], results
24
+ end
25
+
26
+ def test_self_closing?
27
+ reader = Nokogiri::XML::Reader.from_memory(<<-eoxml)
28
+ <xml><city>Paris</city><state/></xml>
29
+ eoxml
30
+
31
+ results = reader.map do |node|
32
+ if node.node_type == Nokogiri::XML::Node::ELEMENT_NODE
33
+ node.self_closing?
34
+ end
35
+ end
36
+ assert_equal [false, false, nil, nil, true, nil], results
37
+ end
38
+
39
+ # Issue #831
40
+ # Make sure that the reader doesn't block reading the entire input
41
+ def test_reader_blocking
42
+ rd, wr = IO.pipe()
43
+ node_out = nil
44
+ t = Thread.start do
45
+ reader = Nokogiri::XML::Reader(rd, 'UTF-8')
46
+ reader.each do |node|
47
+ node_out = node
48
+ break
49
+ end
50
+ rd.close
51
+ end
52
+ sleep(1) # sleep for one second to make sure the reader will actually block for input
53
+ begin
54
+ wr.puts "<foo>"
55
+ wr.puts "<bar/>" * 10000
56
+ wr.flush
57
+ rescue Errno::EPIPE
58
+ end
59
+ res = t.join(5) # wait 5 seconds for the thread to finish
60
+ wr.close
61
+ refute_nil node_out, "Didn't read any nodes, exclude the trivial case"
62
+ refute_nil res, "Reader blocks trying to read the entire stream"
63
+ end
64
+
65
+ def test_reader_takes_block
66
+ options = nil
67
+ Nokogiri::XML::Reader(File.read(XML_FILE), XML_FILE) do |cfg|
68
+ options = cfg
69
+ options.nonet.nowarning.dtdattr
70
+ end
71
+ assert options.nonet?
72
+ assert options.nowarning?
73
+ assert options.dtdattr?
74
+ end
75
+
76
+ def test_nil_raises
77
+ assert_raises(ArgumentError) {
78
+ Nokogiri::XML::Reader.from_memory(nil)
79
+ }
80
+ assert_raises(ArgumentError) {
81
+ Nokogiri::XML::Reader.from_io(nil)
82
+ }
83
+ end
84
+
85
+ def test_from_io
86
+ io = File.open SNUGGLES_FILE
87
+ reader = Nokogiri::XML::Reader.from_io(io)
88
+ assert_equal false, reader.default?
89
+ assert_equal [false, false, false, false, false, false, false],
90
+ reader.map(&:default?)
91
+ end
92
+
93
+ def test_io
94
+ io = File.open SNUGGLES_FILE
95
+ reader = Nokogiri::XML::Reader(io)
96
+ assert_equal false, reader.default?
97
+ assert_equal [false, false, false, false, false, false, false],
98
+ reader.map(&:default?)
99
+ end
100
+
101
+ def test_string_io
102
+ io = StringIO.new(<<-eoxml)
103
+ <x xmlns:tenderlove='http://tenderlovemaking.com/'>
104
+ <tenderlove:foo awesome='true'>snuggles!</tenderlove:foo>
105
+ </x>
106
+ eoxml
107
+ reader = Nokogiri::XML::Reader(io)
108
+ assert_equal false, reader.default?
109
+ assert_equal [false, false, false, false, false, false, false],
110
+ reader.map(&:default?)
111
+ end
112
+
113
+ class ReallyBadIO
114
+ def read(size)
115
+ 'a' * size ** 10
116
+ end
117
+ end
118
+
119
+ class ReallyBadIO4Java
120
+ def read(size=1)
121
+ 'a' * size ** 10
122
+ end
123
+ end
124
+
125
+ def test_io_that_reads_too_much
126
+ if Nokogiri.jruby?
127
+ io = ReallyBadIO4Java.new
128
+ Nokogiri::XML::Reader(io)
129
+ else
130
+ io = ReallyBadIO.new
131
+ Nokogiri::XML::Reader(io)
132
+ end
133
+ end
134
+
135
+ def test_in_memory
136
+ assert Nokogiri::XML::Reader(<<-eoxml)
137
+ <x xmlns:tenderlove='http://tenderlovemaking.com/'>
138
+ <tenderlove:foo awesome='true'>snuggles!</tenderlove:foo>
139
+ </x>
140
+ eoxml
141
+ end
142
+
143
+ def test_reader_holds_on_to_string
144
+ xml = <<-eoxml
145
+ <x xmlns:tenderlove='http://tenderlovemaking.com/'>
146
+ <tenderlove:foo awesome='true'>snuggles!</tenderlove:foo>
147
+ </x>
148
+ eoxml
149
+ reader = Nokogiri::XML::Reader(xml)
150
+ assert_equal xml, reader.source
151
+ end
152
+
153
+ def test_default?
154
+ reader = Nokogiri::XML::Reader.from_memory(<<-eoxml)
155
+ <x xmlns:tenderlove='http://tenderlovemaking.com/'>
156
+ <tenderlove:foo awesome='true'>snuggles!</tenderlove:foo>
157
+ </x>
158
+ eoxml
159
+ assert_equal false, reader.default?
160
+ assert_equal [false, false, false, false, false, false, false],
161
+ reader.map(&:default?)
162
+ end
163
+
164
+ def test_value?
165
+ reader = Nokogiri::XML::Reader.from_memory(<<-eoxml)
166
+ <x xmlns:tenderlove='http://tenderlovemaking.com/'>
167
+ <tenderlove:foo awesome='true'>snuggles!</tenderlove:foo>
168
+ </x>
169
+ eoxml
170
+ assert_equal false, reader.value?
171
+ assert_equal [false, true, false, true, false, true, false],
172
+ reader.map(&:value?)
173
+ end
174
+
175
+ def test_read_error_document
176
+ reader = Nokogiri::XML::Reader.from_memory(<<-eoxml)
177
+ <x xmlns:tenderlove='http://tenderlovemaking.com/'>
178
+ <tenderlove:foo awesome='true'>snuggles!</tenderlove:foo>
179
+ <foo>
180
+ </x>
181
+ eoxml
182
+ assert_raises(Nokogiri::XML::SyntaxError) do
183
+ reader.each { |node| }
184
+ end
185
+ assert 1, reader.errors.length
186
+ end
187
+
188
+ def test_attributes?
189
+ reader = Nokogiri::XML::Reader.from_memory(<<-eoxml)
190
+ <x xmlns:tenderlove='http://tenderlovemaking.com/'>
191
+ <tenderlove:foo awesome='true'>snuggles!</tenderlove:foo>
192
+ </x>
193
+ eoxml
194
+ assert_equal false, reader.attributes?
195
+ assert_equal [true, false, true, false, true, false, true],
196
+ reader.map(&:attributes?)
197
+ end
198
+
199
+ def test_attributes
200
+ reader = Nokogiri::XML::Reader.from_memory(<<-eoxml)
201
+ <x xmlns:tenderlove='http://tenderlovemaking.com/'
202
+ xmlns='http://mothership.connection.com/'
203
+ >
204
+ <tenderlove:foo awesome='true'>snuggles!</tenderlove:foo>
205
+ </x>
206
+ eoxml
207
+ assert_equal({}, reader.attributes)
208
+ assert_equal [{'xmlns:tenderlove'=>'http://tenderlovemaking.com/',
209
+ 'xmlns'=>'http://mothership.connection.com/'},
210
+ {}, {"awesome"=>"true"}, {}, {"awesome"=>"true"}, {},
211
+ {'xmlns:tenderlove'=>'http://tenderlovemaking.com/',
212
+ 'xmlns'=>'http://mothership.connection.com/'}],
213
+ reader.map(&:attributes)
214
+ end
215
+
216
+ def test_attribute_roundtrip
217
+ reader = Nokogiri::XML::Reader.from_memory(<<-eoxml)
218
+ <x xmlns:tenderlove='http://tenderlovemaking.com/'
219
+ xmlns='http://mothership.connection.com/'
220
+ >
221
+ <tenderlove:foo awesome='true' size='giant'>snuggles!</tenderlove:foo>
222
+ </x>
223
+ eoxml
224
+ reader.each do |node|
225
+ node.attributes.each do |key, value|
226
+ assert_equal value, node.attribute(key)
227
+ end
228
+ end
229
+ end
230
+
231
+ def test_attribute_at
232
+ reader = Nokogiri::XML::Reader.from_memory(<<-eoxml)
233
+ <x xmlns:tenderlove='http://tenderlovemaking.com/'>
234
+ <tenderlove:foo awesome='true'>snuggles!</tenderlove:foo>
235
+ </x>
236
+ eoxml
237
+ assert_nil reader.attribute_at(nil)
238
+ assert_nil reader.attribute_at(0)
239
+ assert_equal ['http://tenderlovemaking.com/', nil, 'true', nil, 'true', nil, 'http://tenderlovemaking.com/'],
240
+ reader.map { |x| x.attribute_at(0) }
241
+ end
242
+
243
+ def test_attribute
244
+ reader = Nokogiri::XML::Reader.from_memory(<<-eoxml)
245
+ <x xmlns:tenderlove='http://tenderlovemaking.com/'>
246
+ <tenderlove:foo awesome='true'>snuggles!</tenderlove:foo>
247
+ </x>
248
+ eoxml
249
+ assert_nil reader.attribute(nil)
250
+ assert_nil reader.attribute('awesome')
251
+ assert_equal [nil, nil, 'true', nil, 'true', nil, nil],
252
+ reader.map { |x| x.attribute('awesome') }
253
+ end
254
+
255
+ def test_attribute_length
256
+ reader = Nokogiri::XML::Reader.from_memory(<<-eoxml)
257
+ <x xmlns:tenderlove='http://tenderlovemaking.com/'>
258
+ <tenderlove:foo awesome='true'>snuggles!</tenderlove:foo>
259
+ </x>
260
+ eoxml
261
+ assert_equal 0, reader.attribute_count
262
+ assert_equal [1, 0, 1, 0, 0, 0, 0], reader.map(&:attribute_count)
263
+ end
264
+
265
+ def test_depth
266
+ reader = Nokogiri::XML::Reader.from_memory(<<-eoxml)
267
+ <x xmlns:tenderlove='http://tenderlovemaking.com/'>
268
+ <tenderlove:foo>snuggles!</tenderlove:foo>
269
+ </x>
270
+ eoxml
271
+ assert_equal 0, reader.depth
272
+ assert_equal [0, 1, 1, 2, 1, 1, 0], reader.map(&:depth)
273
+ end
274
+
275
+ def test_encoding
276
+ string = <<-eoxml
277
+ <awesome>
278
+ <p xml:lang="en">The quick brown fox jumps over the lazy dog.</p>
279
+ <p xml:lang="ja">日本語が上手です</p>
280
+ </awesome>
281
+ eoxml
282
+ reader = Nokogiri::XML::Reader.from_memory(string, nil, 'UTF-8')
283
+ assert_equal ['UTF-8'], reader.map(&:encoding).uniq
284
+ end
285
+
286
+ def test_xml_version
287
+ reader = Nokogiri::XML::Reader.from_memory(<<-eoxml)
288
+ <x xmlns:tenderlove='http://tenderlovemaking.com/'>
289
+ <tenderlove:foo>snuggles!</tenderlove:foo>
290
+ </x>
291
+ eoxml
292
+ assert_nil reader.xml_version
293
+ assert_equal ['1.0'], reader.map(&:xml_version).uniq
294
+ end
295
+
296
+ def test_lang
297
+ reader = Nokogiri::XML::Reader.from_memory(<<-eoxml)
298
+ <awesome>
299
+ <p xml:lang="en">The quick brown fox jumps over the lazy dog.</p>
300
+ <p xml:lang="ja">日本語が上手です</p>
301
+ </awesome>
302
+ eoxml
303
+ assert_nil reader.lang
304
+ assert_equal [nil, nil, "en", "en", "en", nil, "ja", "ja", "ja", nil, nil],
305
+ reader.map(&:lang)
306
+ end
307
+
308
+ def test_value
309
+ reader = Nokogiri::XML::Reader.from_memory(<<-eoxml)
310
+ <x xmlns:tenderlove='http://tenderlovemaking.com/'>
311
+ <tenderlove:foo>snuggles!</tenderlove:foo>
312
+ </x>
313
+ eoxml
314
+ assert_nil reader.value
315
+ assert_equal [nil, "\n ", nil, "snuggles!", nil, "\n ", nil],
316
+ reader.map(&:value)
317
+ end
318
+
319
+ def test_prefix
320
+ reader = Nokogiri::XML::Reader.from_memory(<<-eoxml)
321
+ <x xmlns:edi='http://ecommerce.example.org/schema'>
322
+ <edi:foo>hello</edi:foo>
323
+ </x>
324
+ eoxml
325
+ assert_nil reader.prefix
326
+ assert_equal [nil, nil, "edi", nil, "edi", nil, nil],
327
+ reader.map(&:prefix)
328
+ end
329
+
330
+ def test_node_type
331
+ reader = Nokogiri::XML::Reader.from_memory(<<-eoxml)
332
+ <x>
333
+ <y>hello</y>
334
+ </x>
335
+ eoxml
336
+ assert_equal 0, reader.node_type
337
+ assert_equal [1, 14, 1, 3, 15, 14, 15], reader.map(&:node_type)
338
+ end
339
+
340
+ def test_inner_xml
341
+ str = "<x><y>hello</y></x>"
342
+ reader = Nokogiri::XML::Reader.from_memory(str)
343
+
344
+ reader.read
345
+
346
+ assert_equal "<y>hello</y>", reader.inner_xml
347
+ end
348
+
349
+ def test_outer_xml
350
+ str = ["<x><y>hello</y></x>", "<y>hello</y>", "hello", "<y/>", "<x/>"]
351
+ reader = Nokogiri::XML::Reader.from_memory(str.first)
352
+
353
+ xml = []
354
+ reader.map { |node| xml << node.outer_xml }
355
+
356
+ assert_equal str, xml
357
+ end
358
+
359
+ def test_outer_xml_with_empty_nodes
360
+ str = ["<x><y/></x>", "<y/>", "<x/>"]
361
+ reader = Nokogiri::XML::Reader.from_memory(str.first)
362
+
363
+ xml = []
364
+ reader.map { |node| xml << node.outer_xml }
365
+
366
+ assert_equal str, xml
367
+ end
368
+
369
+ def test_state
370
+ reader = Nokogiri::XML::Reader.from_memory('<foo>bar</bar>')
371
+ assert reader.state
372
+ end
373
+
374
+ def test_ns_uri
375
+ reader = Nokogiri::XML::Reader.from_memory(<<-eoxml)
376
+ <x xmlns:edi='http://ecommerce.example.org/schema'>
377
+ <edi:foo>hello</edi:foo>
378
+ </x>
379
+ eoxml
380
+ assert_nil reader.namespace_uri
381
+ assert_equal([nil,
382
+ nil,
383
+ "http://ecommerce.example.org/schema",
384
+ nil,
385
+ "http://ecommerce.example.org/schema",
386
+ nil,
387
+ nil],
388
+ reader.map(&:namespace_uri))
389
+ end
390
+
391
+ def test_namespaced_attributes
392
+ reader = Nokogiri::XML::Reader.from_memory(<<-eoxml)
393
+ <x xmlns:edi='http://ecommerce.example.org/schema' xmlns:commons="http://rets.org/xsd/RETSCommons">
394
+ <edi:foo commons:street-number="43">hello</edi:foo>
395
+ <y edi:name="francis" bacon="87"/>
396
+ </x>
397
+ eoxml
398
+ attr_ns = []
399
+ while reader.read
400
+ if reader.node_type == Nokogiri::XML::Node::ELEMENT_NODE
401
+ reader.attribute_nodes.each {|attr| attr_ns << (attr.namespace.nil? ? nil : attr.namespace.prefix) }
402
+ end
403
+ end
404
+ assert_equal(['commons',
405
+ 'edi',
406
+ nil],
407
+ attr_ns)
408
+ end
409
+
410
+ def test_local_name
411
+ reader = Nokogiri::XML::Reader.from_memory(<<-eoxml)
412
+ <x xmlns:edi='http://ecommerce.example.org/schema'>
413
+ <edi:foo>hello</edi:foo>
414
+ </x>
415
+ eoxml
416
+ assert_nil reader.local_name
417
+ assert_equal(["x", "#text", "foo", "#text", "foo", "#text", "x"],
418
+ reader.map(&:local_name))
419
+ end
420
+
421
+ def test_name
422
+ reader = Nokogiri::XML::Reader.from_memory(<<-eoxml)
423
+ <x xmlns:edi='http://ecommerce.example.org/schema'>
424
+ <edi:foo>hello</edi:foo>
425
+ </x>
426
+ eoxml
427
+ assert_nil reader.name
428
+ assert_equal(["x", "#text", "edi:foo", "#text", "edi:foo", "#text", "x"],
429
+ reader.map(&:name))
430
+ end
431
+
432
+ def test_base_uri
433
+ reader = Nokogiri::XML::Reader.from_memory(<<-eoxml)
434
+ <x xml:base="http://base.example.org/base/">
435
+ <link href="link"/>
436
+ <other xml:base="http://other.example.org/"/>
437
+ <relative xml:base="relative">
438
+ <link href="stuff" />
439
+ </relative>
440
+ </x>
441
+ eoxml
442
+
443
+ assert_nil reader.base_uri
444
+ assert_equal(["http://base.example.org/base/",
445
+ "http://base.example.org/base/",
446
+ "http://base.example.org/base/",
447
+ "http://base.example.org/base/",
448
+ "http://other.example.org/",
449
+ "http://base.example.org/base/",
450
+ "http://base.example.org/base/relative",
451
+ "http://base.example.org/base/relative",
452
+ "http://base.example.org/base/relative",
453
+ "http://base.example.org/base/relative",
454
+ "http://base.example.org/base/relative",
455
+ "http://base.example.org/base/",
456
+ "http://base.example.org/base/"],
457
+ reader.map(&:base_uri))
458
+ end
459
+
460
+ def test_xlink_href_without_base_uri
461
+ reader = Nokogiri::XML::Reader(<<-eoxml)
462
+ <x xmlns:xlink="http://www.w3.org/1999/xlink">
463
+ <link xlink:href="#other">Link</link>
464
+ <other id="other">Linked Element</other>
465
+ </x>
466
+ eoxml
467
+
468
+ reader.each do |node|
469
+ if node.node_type == Nokogiri::XML::Reader::TYPE_ELEMENT
470
+ if node.name == 'link'
471
+ assert_nil node.base_uri
472
+ end
473
+ end
474
+ end
475
+ end
476
+
477
+ def test_xlink_href_with_base_uri
478
+ reader = Nokogiri::XML::Reader(<<-eoxml)
479
+ <x xml:base="http://base.example.org/base/"
480
+ xmlns:xlink="http://www.w3.org/1999/xlink">
481
+ <link xlink:href="#other">Link</link>
482
+ <other id="other">Linked Element</other>
483
+ </x>
484
+ eoxml
485
+
486
+ reader.each do |node|
487
+ if node.node_type == Nokogiri::XML::Reader::TYPE_ELEMENT
488
+ assert_equal node.base_uri, "http://base.example.org/base/"
489
+ end
490
+ end
491
+ end
492
+
493
+ def test_read_from_memory
494
+ called = false
495
+ reader = Nokogiri::XML::Reader.from_memory('<foo>bar</foo>')
496
+ reader.each do |node|
497
+ called = true
498
+ assert node
499
+ end
500
+ assert called
501
+ end
502
+
503
+ def test_large_document_smoke_test
504
+ # simply run on a large document to verify that there no GC issues
505
+ xml = []
506
+ xml << "<elements>"
507
+ 10000.times { |j| xml << "<element id=\"#{j}\"/>" }
508
+ xml << "</elements>"
509
+ xml = xml.join("\n")
510
+
511
+ Nokogiri::XML::Reader.from_memory(xml).each do |e|
512
+ e.attributes
513
+ end
514
+ end
515
+
516
+ def test_correct_outer_xml_inclusion
517
+ xml = Nokogiri::XML::Reader.from_io(StringIO.new(<<-eoxml))
518
+ <root-element>
519
+ <children>
520
+ <child n="1">
521
+ <field>child-1</field>
522
+ </child>
523
+ <child n="2">
524
+ <field>child-2</field>
525
+ </child>
526
+ <child n="3">
527
+ <field>child-3</field>
528
+ </child>
529
+ </children>
530
+ </root-element>
531
+ eoxml
532
+
533
+ nodelengths = []
534
+ has_child2 = []
535
+
536
+ xml.each do |node|
537
+ if node.node_type == Nokogiri::XML::Reader::TYPE_ELEMENT and node.name == "child"
538
+ nodelengths << node.outer_xml.length
539
+ has_child2 << !!(node.outer_xml =~ /child-2/)
540
+ end
541
+ end
542
+
543
+ assert_equal(nodelengths[0], nodelengths[1])
544
+ assert(has_child2[1])
545
+ assert(!has_child2[0])
546
+ end
547
+
548
+ def test_correct_inner_xml_inclusion
549
+ xml = Nokogiri::XML::Reader.from_io(StringIO.new(<<-eoxml))
550
+ <root-element>
551
+ <children>
552
+ <child n="1">
553
+ <field>child-1</field>
554
+ </child>
555
+ <child n="2">
556
+ <field>child-2</field>
557
+ </child>
558
+ <child n="3">
559
+ <field>child-3</field>
560
+ </child>
561
+ </children>
562
+ </root-element>
563
+ eoxml
564
+
565
+ nodelengths = []
566
+ has_child2 = []
567
+
568
+ xml.each do |node|
569
+ if node.node_type == Nokogiri::XML::Reader::TYPE_ELEMENT and node.name == "child"
570
+ nodelengths << node.inner_xml.length
571
+ has_child2 << !!(node.inner_xml =~ /child-2/)
572
+ end
573
+ end
574
+
575
+ assert_equal(nodelengths[0], nodelengths[1])
576
+ assert(has_child2[1])
577
+ assert(!has_child2[0])
578
+ end
579
+
580
+ def test_nonexistent_attribute
581
+ require 'nokogiri'
582
+ reader = Nokogiri::XML::Reader("<root xmlns='bob'><el attr='fred' /></root>")
583
+ reader.read # root
584
+ reader.read # el
585
+ assert_equal nil, reader.attribute('other')
586
+ end
587
+ end
588
+ end
589
+ end