libxml-ruby 5.0.4 → 5.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/HISTORY +10 -6
  3. data/README.rdoc +1 -1
  4. data/ext/libxml/extconf.rb +5 -0
  5. data/ext/libxml/ruby_xml.c +556 -556
  6. data/ext/libxml/ruby_xml_attributes.h +17 -17
  7. data/ext/libxml/ruby_xml_document.c +1129 -1129
  8. data/ext/libxml/ruby_xml_dtd.c +257 -257
  9. data/ext/libxml/ruby_xml_encoding.c +250 -250
  10. data/ext/libxml/ruby_xml_error.c +1003 -1003
  11. data/ext/libxml/ruby_xml_error.h +14 -14
  12. data/ext/libxml/ruby_xml_html_parser_context.c +351 -351
  13. data/ext/libxml/ruby_xml_input_cbg.c +188 -188
  14. data/ext/libxml/ruby_xml_namespace.c +151 -151
  15. data/ext/libxml/ruby_xml_parser.h +10 -10
  16. data/ext/libxml/ruby_xml_parser_context.c +1009 -1009
  17. data/ext/libxml/ruby_xml_parser_options.c +74 -74
  18. data/ext/libxml/ruby_xml_parser_options.h +10 -10
  19. data/ext/libxml/ruby_xml_sax2_handler.c +326 -326
  20. data/ext/libxml/ruby_xml_sax_parser.c +108 -108
  21. data/ext/libxml/ruby_xml_version.h +9 -9
  22. data/lib/libxml/attr.rb +122 -122
  23. data/lib/libxml/attr_decl.rb +80 -80
  24. data/lib/libxml/attributes.rb +13 -13
  25. data/lib/libxml/document.rb +194 -194
  26. data/lib/libxml/error.rb +95 -95
  27. data/lib/libxml/hpricot.rb +77 -77
  28. data/lib/libxml/html_parser.rb +96 -96
  29. data/lib/libxml/namespace.rb +61 -61
  30. data/lib/libxml/namespaces.rb +37 -37
  31. data/lib/libxml/node.rb +323 -323
  32. data/lib/libxml/parser.rb +102 -102
  33. data/lib/libxml/sax_callbacks.rb +179 -179
  34. data/lib/libxml/sax_parser.rb +40 -40
  35. data/lib/libxml/tree.rb +28 -28
  36. data/lib/libxml.rb +4 -4
  37. data/lib/xml/libxml.rb +10 -10
  38. data/lib/xml.rb +13 -13
  39. data/libxml-ruby.gemspec +50 -49
  40. data/test/test_document.rb +140 -140
  41. data/test/test_document_write.rb +142 -142
  42. data/test/test_dtd.rb +126 -126
  43. data/test/test_encoding.rb +126 -126
  44. data/test/test_error.rb +194 -194
  45. data/test/test_helper.rb +20 -20
  46. data/test/test_namespace.rb +58 -58
  47. data/test/test_node.rb +235 -235
  48. data/test/test_node_write.rb +93 -93
  49. data/test/test_parser.rb +333 -333
  50. data/test/test_reader.rb +364 -364
  51. data/test/test_xml.rb +168 -168
  52. metadata +5 -4
data/test/test_reader.rb CHANGED
@@ -1,364 +1,364 @@
1
- # encoding: UTF-8
2
-
3
- require_relative './test_helper'
4
- require 'stringio'
5
-
6
- class TestReader < Minitest::Test
7
- XML_FILE = File.join(File.dirname(__FILE__), 'model/atom.xml')
8
-
9
- def verify_simple(reader)
10
- node_types = []
11
-
12
- # Read each node
13
- 26.times do
14
- assert(reader.read)
15
- node_types << reader.node_type
16
- end
17
-
18
- # There are no more nodes
19
- assert(!reader.read)
20
-
21
- # Check what was read
22
- expected = [LibXML::XML::Reader::TYPE_PROCESSING_INSTRUCTION,
23
- LibXML::XML::Reader::TYPE_ELEMENT,
24
- LibXML::XML::Reader::TYPE_SIGNIFICANT_WHITESPACE,
25
- LibXML::XML::Reader::TYPE_COMMENT,
26
- LibXML::XML::Reader::TYPE_SIGNIFICANT_WHITESPACE,
27
- LibXML::XML::Reader::TYPE_ELEMENT,
28
- LibXML::XML::Reader::TYPE_SIGNIFICANT_WHITESPACE,
29
- LibXML::XML::Reader::TYPE_ELEMENT,
30
- LibXML::XML::Reader::TYPE_CDATA,
31
- LibXML::XML::Reader::TYPE_END_ELEMENT,
32
- LibXML::XML::Reader::TYPE_SIGNIFICANT_WHITESPACE,
33
- LibXML::XML::Reader::TYPE_ELEMENT,
34
- LibXML::XML::Reader::TYPE_SIGNIFICANT_WHITESPACE,
35
- LibXML::XML::Reader::TYPE_ELEMENT,
36
- LibXML::XML::Reader::TYPE_SIGNIFICANT_WHITESPACE,
37
- LibXML::XML::Reader::TYPE_ELEMENT,
38
- LibXML::XML::Reader::TYPE_TEXT,
39
- LibXML::XML::Reader::TYPE_END_ELEMENT,
40
- LibXML::XML::Reader::TYPE_SIGNIFICANT_WHITESPACE,
41
- LibXML::XML::Reader::TYPE_END_ELEMENT,
42
- LibXML::XML::Reader::TYPE_SIGNIFICANT_WHITESPACE,
43
- LibXML::XML::Reader::TYPE_END_ELEMENT,
44
- LibXML::XML::Reader::TYPE_SIGNIFICANT_WHITESPACE,
45
- LibXML::XML::Reader::TYPE_END_ELEMENT,
46
- LibXML::XML::Reader::TYPE_SIGNIFICANT_WHITESPACE,
47
- LibXML::XML::Reader::TYPE_END_ELEMENT]
48
-
49
- assert_equal(expected, node_types)
50
- end
51
-
52
- def test_document
53
- reader = LibXML::XML::Reader.document(LibXML::XML::Document.file(XML_FILE))
54
- verify_simple(reader)
55
- end
56
-
57
- def test_file
58
- reader = LibXML::XML::Reader.file(XML_FILE)
59
- verify_simple(reader)
60
- end
61
-
62
- def test_invalid_file
63
- error = assert_raises(Errno::ENOENT) do
64
- LibXML::XML::Reader.file('/does/not/exist')
65
- end
66
- assert_equal("No such file or directory - /does/not/exist", error.message)
67
- end
68
-
69
- def test_string
70
- reader = LibXML::XML::Reader.string(File.read(XML_FILE))
71
- verify_simple(reader)
72
- end
73
-
74
- def test_io
75
- File.open(XML_FILE, 'rb') do |io|
76
- reader = LibXML::XML::Reader.io(io)
77
- verify_simple(reader)
78
- end
79
- end
80
-
81
- def test_io_gc
82
- # Test that the reader keeps a reference
83
- # to the io object
84
- file = File.open(XML_FILE, 'rb')
85
- reader = LibXML::XML::Reader.io(file)
86
- file = nil
87
- GC.start
88
- assert(reader.read)
89
- end
90
-
91
- def test_string_io
92
- data = File.read(XML_FILE)
93
- string_io = StringIO.new(data)
94
- reader = LibXML::XML::Reader.io(string_io)
95
- verify_simple(reader)
96
- end
97
-
98
- def test_error
99
- reader = LibXML::XML::Reader.string('<foo blah')
100
-
101
- error = assert_raises(LibXML::XML::Error) do
102
- reader.read
103
- end
104
- assert_equal("Fatal error: Couldn't find end of Start Tag foo at :1.", error.to_s)
105
- end
106
-
107
- def test_attr
108
- parser = LibXML::XML::Reader.string("<foo x='1' y='2'/>")
109
- assert(parser.read)
110
- assert_equal('foo', parser.name)
111
- assert_equal('1', parser['x'])
112
- assert_equal('1', parser[0])
113
- assert_equal('2', parser['y'])
114
- assert_equal('2', parser[1])
115
- assert_nil(parser['z'])
116
- assert_nil(parser[2])
117
- end
118
-
119
- def test_move_attr
120
- reader = LibXML::XML::Reader.string('<root xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xhtml="http://www.w3.org/1999/xhtml"><link xml:id="abc" xlink:href="def" xhtml:class="ghi" bar="jkl" /></root>')
121
- assert(reader.read) # <root/>
122
- assert(reader.read) # <link/>
123
-
124
- assert(reader.move_to_attribute_no(1))
125
- assert_equal(reader.value, 'def')
126
- assert(reader.move_to_attribute_ns('id', 'http://www.w3.org/XML/1998/namespace'))
127
- assert_equal(reader.value, 'abc')
128
- assert(reader.move_to_attribute('bar'))
129
- assert_equal(reader.value, 'jkl')
130
-
131
- # 1 in case of success, -1 in case of error, 0 if not found
132
- assert_equal(reader.move_to_attribute_no(12), 0)
133
- assert_equal(reader.move_to_attribute('baz'), 0)
134
- assert_equal(reader.move_to_attribute_ns('baz', 'http://ruby/namespace'), 0)
135
- end
136
-
137
- def test_get_attr
138
- reader = LibXML::XML::Reader.string('<root xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xhtml="http://www.w3.org/1999/xhtml"><link xml:id="abc" xlink:href="def" xhtml:class="ghi" bar="jkl" /></root>')
139
- assert(reader.read) # <root/>
140
- assert(reader.read) # <link/>
141
-
142
- assert_equal(reader.get_attribute_no(1), 'def')
143
- assert_equal(reader.get_attribute_ns('id', 'http://www.w3.org/XML/1998/namespace'), 'abc')
144
- assert_equal(reader.get_attribute('bar'), 'jkl')
145
-
146
- assert_nil(reader.get_attribute_no(12))
147
- assert_nil(reader.get_attribute('baz'))
148
- assert_nil(reader.get_attribute_ns('baz', 'http://ruby/namespace'))
149
- end
150
-
151
- def test_value
152
- parser = LibXML::XML::Reader.string("<foo><bar>1</bar><bar>2</bar><bar>3</bar></foo>")
153
- assert(parser.read)
154
- assert_equal('foo', parser.name)
155
- assert_nil(parser.value)
156
- 3.times do |i|
157
- assert(parser.read)
158
- assert_equal(LibXML::XML::Reader::TYPE_ELEMENT, parser.node_type)
159
- assert_equal('bar', parser.name)
160
- assert(parser.read)
161
- assert_equal(LibXML::XML::Reader::TYPE_TEXT, parser.node_type)
162
- assert_equal((i + 1).to_s, parser.value)
163
- assert(parser.read)
164
- assert_equal(LibXML::XML::Reader::TYPE_END_ELEMENT, parser.node_type)
165
- end
166
- end
167
-
168
- def test_expand
169
- reader = LibXML::XML::Reader.file(XML_FILE)
170
- reader.read.to_s
171
- reader.read
172
-
173
- # Read a node
174
- node = reader.expand
175
- refute_nil(node.doc)
176
- assert_equal('feed', node.name)
177
- assert_equal(::Encoding::UTF_8, node.name.encoding) if defined?(::Encoding)
178
- end
179
-
180
- def test_expand_find
181
- reader = LibXML::XML::Reader.file(XML_FILE)
182
- reader.read.to_s
183
- reader.read
184
-
185
- # Read first node which
186
- node = reader.expand
187
- assert_equal('feed', node.name)
188
-
189
- # We need to create document to use xpath
190
- reader.doc
191
-
192
- # Search for entries
193
- entries = node.find('atom:entry', 'atom:http://www.w3.org/2005/Atom')
194
-
195
- assert_equal(1, entries.length)
196
- end
197
-
198
- def test_expand_invalid
199
- reader = LibXML::XML::Reader.file(XML_FILE)
200
-
201
- # Expand a node before one has been read
202
- node = reader.expand
203
- assert_nil(node)
204
- end
205
-
206
- def test_expand_should_be_invalid
207
- reader = LibXML::XML::Reader.file(XML_FILE)
208
-
209
- # Read a couple of nodes
210
- reader.read
211
- reader.read
212
-
213
- # Expand the node
214
- node = reader.expand
215
- assert_equal('feed', node.name)
216
-
217
- # Read another node, this makes the last node invalid
218
- reader.next
219
-
220
- # The previous node is now invalid - this should be an error but isn't
221
- assert_equal('feed', node.name)
222
- end
223
-
224
- def test_expand_incorrectly_use_returned_node
225
- file = File.join(File.dirname(__FILE__), 'model/cwm_1_0.xml')
226
- reader = LibXML::XML::Reader.file(file)
227
-
228
- nodes = Array.new
229
- while reader.read
230
- node = reader.expand
231
- refute_nil(node)
232
- refute_nil(node.doc)
233
-
234
- # NOTE - DO NOT do this in real code, these nodes are invalid after the next read. This *will* cause
235
- # a segmentation fault next time the garbage collector runs. The reason is the parent node will be
236
- # called in the mark phase, but its underlying xml node will be gone. Same goes for calling children,
237
- # attributes, etc. You must let go of the expanded node *before* calling xml reader again and
238
- # call the garbage collector to be safe.
239
- #refute_nil(node.parent)
240
- nodes << node
241
- end
242
- assert(true)
243
- end
244
-
245
- def test_mode
246
- reader = LibXML::XML::Reader.string('<xml/>')
247
- assert_equal(LibXML::XML::Reader::MODE_INITIAL, reader.read_state)
248
- reader.read
249
- assert_equal(LibXML::XML::Reader::MODE_EOF, reader.read_state)
250
- end
251
-
252
- def test_bytes_consumed
253
- ending_are_rn = File.binread(XML_FILE).include? "\r\n"
254
- reader = LibXML::XML::Reader.file(XML_FILE)
255
- reader.read
256
- assert_equal(ending_are_rn ? 428 : 416, reader.byte_consumed)
257
- end
258
-
259
- def test_node
260
- reader = LibXML::XML::Reader.file(XML_FILE)
261
-
262
- # first try to get a node
263
- assert_nil(reader.node)
264
-
265
- reader.read
266
- assert_instance_of(LibXML::XML::Node, reader.node)
267
- end
268
-
269
- def test_base_uri
270
- # UTF8:
271
- # ö - c3 b6 in hex, \303\266 in octal
272
- # ü - c3 bc in hex, \303\274 in octal
273
- xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><bands genre=\"metal\">\n <m\303\266tley_cr\303\274e country=\"us\">An American heavy metal band formed in Los Angeles, California in 1981.</m\303\266tley_cr\303\274e>\n <iron_maiden country=\"uk\">British heavy metal band formed in 1975.</iron_maiden>\n</bands>"
274
- reader = LibXML::XML::Reader.string(xml, :base_uri => "http://libxml.rubyforge.org")
275
-
276
- reader.read
277
- assert_equal(reader.base_uri, "http://libxml.rubyforge.org")
278
- assert_equal(::Encoding::UTF_8, reader.base_uri.encoding) if defined?(::Encoding)
279
- end
280
-
281
- def test_options
282
- xml = <<-EOS
283
- <!DOCTYPE foo [<!ENTITY foo 'bar'>]>
284
- <test>
285
- <cdata><![CDATA[something]]></cdata>
286
- <entity>&foo;</entity>
287
- </test>
288
- EOS
289
-
290
- # Parse normally
291
- reader = LibXML::XML::Reader.string(xml)
292
- reader.read # foo
293
- reader.read # test
294
- reader.read # text
295
- reader.read # cdata
296
- reader.read # cdata-section
297
- assert_equal(LibXML::XML::Node::CDATA_SECTION_NODE, reader.node_type)
298
-
299
- # Convert cdata section to text
300
- reader = LibXML::XML::Reader.string(xml, :options => LibXML::XML::Parser::Options::NOCDATA)
301
- reader.read # foo
302
- reader.read # test
303
- reader.read # text
304
- reader.read # cdata
305
- reader.read # cdata-section
306
- assert_equal(LibXML::XML::Node::TEXT_NODE, reader.node_type)
307
- end
308
-
309
- def test_encoding
310
- # ISO_8859_1:
311
- # ö - f6 in hex, \366 in octal
312
- # ü - fc in hex, \374 in octal
313
- xml = "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?><bands genre=\"metal\">\n <m\366tley_cr\374e country=\"us\">An American heavy metal band formed in Los Angeles, California in 1981.</m\366tley_cr\374e>\n <iron_maiden country=\"uk\">British heavy metal band formed in 1975.</iron_maiden>\n</bands>"
314
-
315
- reader = LibXML::XML::Reader.string(xml, :encoding => LibXML::XML::Encoding::ISO_8859_1)
316
- reader.read
317
-
318
- assert_equal(Encoding::ISO8859_1, reader.read_outer_xml.encoding)
319
- assert_equal(Encoding::ISO8859_1, reader.read_inner_xml.encoding)
320
- assert_equal(Encoding::ISO8859_1, reader.read_string.encoding)
321
-
322
- assert_equal("<bands genre=\"metal\">\n <m\xC3\xB6tley_cr\xC3\xBCe country=\"us\">An American heavy metal band formed in Los Angeles, California in 1981.</m\xC3\xB6tley_cr\xC3\xBCe>\n <iron_maiden country=\"uk\">British heavy metal band formed in 1975.</iron_maiden>\n</bands>".force_encoding(Encoding::ISO8859_1),
323
- reader.read_outer_xml)
324
- assert_equal("\n <m\xC3\xB6tley_cr\xC3\xBCe country=\"us\">An American heavy metal band formed in Los Angeles, California in 1981.</m\xC3\xB6tley_cr\xC3\xBCe>\n <iron_maiden country=\"uk\">British heavy metal band formed in 1975.</iron_maiden>\n".force_encoding(Encoding::ISO8859_1),
325
- reader.read_inner_xml)
326
- assert_equal("\n An American heavy metal band formed in Los Angeles, California in 1981.\n British heavy metal band formed in 1975.\n".force_encoding(Encoding::ISO8859_1),
327
- reader.read_string)
328
- end
329
-
330
- def test_invalid_encoding
331
- # ISO_8859_1:
332
- # ö - f6 in hex, \366 in octal
333
- # ü - fc in hex, \374 in octal
334
- xml = "<bands genre=\"metal\">\n <m\366tley_cr\374e country=\"us\">An American heavy metal band formed in Los Angeles, California in 1981.</m\366tley_cr\374e>\n <iron_maiden country=\"uk\">British heavy metal band formed in 1975.</iron_maiden>\n</bands>"
335
-
336
- reader = LibXML::XML::Reader.string(xml)
337
- error = assert_raises(LibXML::XML::Error) do
338
- reader.read
339
- end
340
-
341
- assert_equal("Fatal error: Input is not proper UTF-8, indicate encoding !\nBytes: 0xF6 0x74 0x6C 0x65 at :2.",
342
- error.to_s)
343
-
344
- end
345
-
346
- def test_file_encoding
347
- reader = LibXML::XML::Reader.file(XML_FILE)
348
- reader.read
349
- assert_equal(LibXML::XML::Encoding::UTF_8, reader.encoding)
350
- assert_equal(Encoding::UTF_8, reader.value.encoding)
351
- end
352
-
353
- def test_string_encoding
354
- # ISO_8859_1:
355
- # ö - f6 in hex, \366 in octal
356
- # ü - fc in hex, \374 in octal
357
- xml = "<bands genre=\"metal\">\n <m\366tley_cr\374e country=\"us\">An American heavy metal band formed in Los Angeles, California in 1981.</m\366tley_cr\374e>\n <iron_maiden country=\"uk\">British heavy metal band formed in 1975.</iron_maiden>\n</bands>"
358
- reader = LibXML::XML::Reader.string(xml, :encoding => LibXML::XML::Encoding::ISO_8859_1)
359
- reader.read
360
-
361
- encoding = windows? ? LibXML::XML::Encoding::ISO_8859_1 : LibXML::XML::Encoding::NONE
362
- assert_equal(reader.encoding, encoding)
363
- end
364
- end
1
+ # encoding: UTF-8
2
+
3
+ require_relative './test_helper'
4
+ require 'stringio'
5
+
6
+ class TestReader < Minitest::Test
7
+ XML_FILE = File.join(File.dirname(__FILE__), 'model/atom.xml')
8
+
9
+ def verify_simple(reader)
10
+ node_types = []
11
+
12
+ # Read each node
13
+ 26.times do
14
+ assert(reader.read)
15
+ node_types << reader.node_type
16
+ end
17
+
18
+ # There are no more nodes
19
+ assert(!reader.read)
20
+
21
+ # Check what was read
22
+ expected = [LibXML::XML::Reader::TYPE_PROCESSING_INSTRUCTION,
23
+ LibXML::XML::Reader::TYPE_ELEMENT,
24
+ LibXML::XML::Reader::TYPE_SIGNIFICANT_WHITESPACE,
25
+ LibXML::XML::Reader::TYPE_COMMENT,
26
+ LibXML::XML::Reader::TYPE_SIGNIFICANT_WHITESPACE,
27
+ LibXML::XML::Reader::TYPE_ELEMENT,
28
+ LibXML::XML::Reader::TYPE_SIGNIFICANT_WHITESPACE,
29
+ LibXML::XML::Reader::TYPE_ELEMENT,
30
+ LibXML::XML::Reader::TYPE_CDATA,
31
+ LibXML::XML::Reader::TYPE_END_ELEMENT,
32
+ LibXML::XML::Reader::TYPE_SIGNIFICANT_WHITESPACE,
33
+ LibXML::XML::Reader::TYPE_ELEMENT,
34
+ LibXML::XML::Reader::TYPE_SIGNIFICANT_WHITESPACE,
35
+ LibXML::XML::Reader::TYPE_ELEMENT,
36
+ LibXML::XML::Reader::TYPE_SIGNIFICANT_WHITESPACE,
37
+ LibXML::XML::Reader::TYPE_ELEMENT,
38
+ LibXML::XML::Reader::TYPE_TEXT,
39
+ LibXML::XML::Reader::TYPE_END_ELEMENT,
40
+ LibXML::XML::Reader::TYPE_SIGNIFICANT_WHITESPACE,
41
+ LibXML::XML::Reader::TYPE_END_ELEMENT,
42
+ LibXML::XML::Reader::TYPE_SIGNIFICANT_WHITESPACE,
43
+ LibXML::XML::Reader::TYPE_END_ELEMENT,
44
+ LibXML::XML::Reader::TYPE_SIGNIFICANT_WHITESPACE,
45
+ LibXML::XML::Reader::TYPE_END_ELEMENT,
46
+ LibXML::XML::Reader::TYPE_SIGNIFICANT_WHITESPACE,
47
+ LibXML::XML::Reader::TYPE_END_ELEMENT]
48
+
49
+ assert_equal(expected, node_types)
50
+ end
51
+
52
+ def test_document
53
+ reader = LibXML::XML::Reader.document(LibXML::XML::Document.file(XML_FILE))
54
+ verify_simple(reader)
55
+ end
56
+
57
+ def test_file
58
+ reader = LibXML::XML::Reader.file(XML_FILE)
59
+ verify_simple(reader)
60
+ end
61
+
62
+ def test_invalid_file
63
+ error = assert_raises(Errno::ENOENT) do
64
+ LibXML::XML::Reader.file('/does/not/exist')
65
+ end
66
+ assert_equal("No such file or directory - /does/not/exist", error.message)
67
+ end
68
+
69
+ def test_string
70
+ reader = LibXML::XML::Reader.string(File.read(XML_FILE))
71
+ verify_simple(reader)
72
+ end
73
+
74
+ def test_io
75
+ File.open(XML_FILE, 'rb') do |io|
76
+ reader = LibXML::XML::Reader.io(io)
77
+ verify_simple(reader)
78
+ end
79
+ end
80
+
81
+ def test_io_gc
82
+ # Test that the reader keeps a reference
83
+ # to the io object
84
+ file = File.open(XML_FILE, 'rb')
85
+ reader = LibXML::XML::Reader.io(file)
86
+ file = nil
87
+ GC.start
88
+ assert(reader.read)
89
+ end
90
+
91
+ def test_string_io
92
+ data = File.read(XML_FILE)
93
+ string_io = StringIO.new(data)
94
+ reader = LibXML::XML::Reader.io(string_io)
95
+ verify_simple(reader)
96
+ end
97
+
98
+ def test_error
99
+ reader = LibXML::XML::Reader.string('<foo blah')
100
+
101
+ error = assert_raises(LibXML::XML::Error) do
102
+ reader.read
103
+ end
104
+ assert_equal("Fatal error: Couldn't find end of Start Tag foo at :1.", error.to_s)
105
+ end
106
+
107
+ def test_attr
108
+ parser = LibXML::XML::Reader.string("<foo x='1' y='2'/>")
109
+ assert(parser.read)
110
+ assert_equal('foo', parser.name)
111
+ assert_equal('1', parser['x'])
112
+ assert_equal('1', parser[0])
113
+ assert_equal('2', parser['y'])
114
+ assert_equal('2', parser[1])
115
+ assert_nil(parser['z'])
116
+ assert_nil(parser[2])
117
+ end
118
+
119
+ def test_move_attr
120
+ reader = LibXML::XML::Reader.string('<root xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xhtml="http://www.w3.org/1999/xhtml"><link xml:id="abc" xlink:href="def" xhtml:class="ghi" bar="jkl" /></root>')
121
+ assert(reader.read) # <root/>
122
+ assert(reader.read) # <link/>
123
+
124
+ assert(reader.move_to_attribute_no(1))
125
+ assert_equal(reader.value, 'def')
126
+ assert(reader.move_to_attribute_ns('id', 'http://www.w3.org/XML/1998/namespace'))
127
+ assert_equal(reader.value, 'abc')
128
+ assert(reader.move_to_attribute('bar'))
129
+ assert_equal(reader.value, 'jkl')
130
+
131
+ # 1 in case of success, -1 in case of error, 0 if not found
132
+ assert_equal(reader.move_to_attribute_no(12), 0)
133
+ assert_equal(reader.move_to_attribute('baz'), 0)
134
+ assert_equal(reader.move_to_attribute_ns('baz', 'http://ruby/namespace'), 0)
135
+ end
136
+
137
+ def test_get_attr
138
+ reader = LibXML::XML::Reader.string('<root xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xhtml="http://www.w3.org/1999/xhtml"><link xml:id="abc" xlink:href="def" xhtml:class="ghi" bar="jkl" /></root>')
139
+ assert(reader.read) # <root/>
140
+ assert(reader.read) # <link/>
141
+
142
+ assert_equal(reader.get_attribute_no(1), 'def')
143
+ assert_equal(reader.get_attribute_ns('id', 'http://www.w3.org/XML/1998/namespace'), 'abc')
144
+ assert_equal(reader.get_attribute('bar'), 'jkl')
145
+
146
+ assert_nil(reader.get_attribute_no(12))
147
+ assert_nil(reader.get_attribute('baz'))
148
+ assert_nil(reader.get_attribute_ns('baz', 'http://ruby/namespace'))
149
+ end
150
+
151
+ def test_value
152
+ parser = LibXML::XML::Reader.string("<foo><bar>1</bar><bar>2</bar><bar>3</bar></foo>")
153
+ assert(parser.read)
154
+ assert_equal('foo', parser.name)
155
+ assert_nil(parser.value)
156
+ 3.times do |i|
157
+ assert(parser.read)
158
+ assert_equal(LibXML::XML::Reader::TYPE_ELEMENT, parser.node_type)
159
+ assert_equal('bar', parser.name)
160
+ assert(parser.read)
161
+ assert_equal(LibXML::XML::Reader::TYPE_TEXT, parser.node_type)
162
+ assert_equal((i + 1).to_s, parser.value)
163
+ assert(parser.read)
164
+ assert_equal(LibXML::XML::Reader::TYPE_END_ELEMENT, parser.node_type)
165
+ end
166
+ end
167
+
168
+ def test_expand
169
+ reader = LibXML::XML::Reader.file(XML_FILE)
170
+ reader.read.to_s
171
+ reader.read
172
+
173
+ # Read a node
174
+ node = reader.expand
175
+ refute_nil(node.doc)
176
+ assert_equal('feed', node.name)
177
+ assert_equal(::Encoding::UTF_8, node.name.encoding) if defined?(::Encoding)
178
+ end
179
+
180
+ def test_expand_find
181
+ reader = LibXML::XML::Reader.file(XML_FILE)
182
+ reader.read.to_s
183
+ reader.read
184
+
185
+ # Read first node which
186
+ node = reader.expand
187
+ assert_equal('feed', node.name)
188
+
189
+ # We need to create document to use xpath
190
+ reader.doc
191
+
192
+ # Search for entries
193
+ entries = node.find('atom:entry', 'atom:http://www.w3.org/2005/Atom')
194
+
195
+ assert_equal(1, entries.length)
196
+ end
197
+
198
+ def test_expand_invalid
199
+ reader = LibXML::XML::Reader.file(XML_FILE)
200
+
201
+ # Expand a node before one has been read
202
+ node = reader.expand
203
+ assert_nil(node)
204
+ end
205
+
206
+ def test_expand_should_be_invalid
207
+ reader = LibXML::XML::Reader.file(XML_FILE)
208
+
209
+ # Read a couple of nodes
210
+ reader.read
211
+ reader.read
212
+
213
+ # Expand the node
214
+ node = reader.expand
215
+ assert_equal('feed', node.name)
216
+
217
+ # Read another node, this makes the last node invalid
218
+ reader.next
219
+
220
+ # The previous node is now invalid - this should be an error but isn't
221
+ assert_equal('feed', node.name)
222
+ end
223
+
224
+ def test_expand_incorrectly_use_returned_node
225
+ file = File.join(File.dirname(__FILE__), 'model/cwm_1_0.xml')
226
+ reader = LibXML::XML::Reader.file(file)
227
+
228
+ nodes = Array.new
229
+ while reader.read
230
+ node = reader.expand
231
+ refute_nil(node)
232
+ refute_nil(node.doc)
233
+
234
+ # NOTE - DO NOT do this in real code, these nodes are invalid after the next read. This *will* cause
235
+ # a segmentation fault next time the garbage collector runs. The reason is the parent node will be
236
+ # called in the mark phase, but its underlying xml node will be gone. Same goes for calling children,
237
+ # attributes, etc. You must let go of the expanded node *before* calling xml reader again and
238
+ # call the garbage collector to be safe.
239
+ #refute_nil(node.parent)
240
+ nodes << node
241
+ end
242
+ assert(true)
243
+ end
244
+
245
+ def test_mode
246
+ reader = LibXML::XML::Reader.string('<xml/>')
247
+ assert_equal(LibXML::XML::Reader::MODE_INITIAL, reader.read_state)
248
+ reader.read
249
+ assert_equal(LibXML::XML::Reader::MODE_EOF, reader.read_state)
250
+ end
251
+
252
+ def test_bytes_consumed
253
+ ending_are_rn = File.binread(XML_FILE).include? "\r\n"
254
+ reader = LibXML::XML::Reader.file(XML_FILE)
255
+ reader.read
256
+ assert_equal(ending_are_rn ? 428 : 416, reader.byte_consumed)
257
+ end
258
+
259
+ def test_node
260
+ reader = LibXML::XML::Reader.file(XML_FILE)
261
+
262
+ # first try to get a node
263
+ assert_nil(reader.node)
264
+
265
+ reader.read
266
+ assert_instance_of(LibXML::XML::Node, reader.node)
267
+ end
268
+
269
+ def test_base_uri
270
+ # UTF8:
271
+ # ö - c3 b6 in hex, \303\266 in octal
272
+ # ü - c3 bc in hex, \303\274 in octal
273
+ xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><bands genre=\"metal\">\n <m\303\266tley_cr\303\274e country=\"us\">An American heavy metal band formed in Los Angeles, California in 1981.</m\303\266tley_cr\303\274e>\n <iron_maiden country=\"uk\">British heavy metal band formed in 1975.</iron_maiden>\n</bands>"
274
+ reader = LibXML::XML::Reader.string(xml, :base_uri => "http://libxml.rubyforge.org")
275
+
276
+ reader.read
277
+ assert_equal(reader.base_uri, "http://libxml.rubyforge.org")
278
+ assert_equal(::Encoding::UTF_8, reader.base_uri.encoding) if defined?(::Encoding)
279
+ end
280
+
281
+ def test_options
282
+ xml = <<-EOS
283
+ <!DOCTYPE foo [<!ENTITY foo 'bar'>]>
284
+ <test>
285
+ <cdata><![CDATA[something]]></cdata>
286
+ <entity>&foo;</entity>
287
+ </test>
288
+ EOS
289
+
290
+ # Parse normally
291
+ reader = LibXML::XML::Reader.string(xml)
292
+ reader.read # foo
293
+ reader.read # test
294
+ reader.read # text
295
+ reader.read # cdata
296
+ reader.read # cdata-section
297
+ assert_equal(LibXML::XML::Node::CDATA_SECTION_NODE, reader.node_type)
298
+
299
+ # Convert cdata section to text
300
+ reader = LibXML::XML::Reader.string(xml, :options => LibXML::XML::Parser::Options::NOCDATA)
301
+ reader.read # foo
302
+ reader.read # test
303
+ reader.read # text
304
+ reader.read # cdata
305
+ reader.read # cdata-section
306
+ assert_equal(LibXML::XML::Node::TEXT_NODE, reader.node_type)
307
+ end
308
+
309
+ def test_encoding
310
+ # ISO_8859_1:
311
+ # ö - f6 in hex, \366 in octal
312
+ # ü - fc in hex, \374 in octal
313
+ xml = "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?><bands genre=\"metal\">\n <m\366tley_cr\374e country=\"us\">An American heavy metal band formed in Los Angeles, California in 1981.</m\366tley_cr\374e>\n <iron_maiden country=\"uk\">British heavy metal band formed in 1975.</iron_maiden>\n</bands>"
314
+
315
+ reader = LibXML::XML::Reader.string(xml, :encoding => LibXML::XML::Encoding::ISO_8859_1)
316
+ reader.read
317
+
318
+ assert_equal(Encoding::ISO8859_1, reader.read_outer_xml.encoding)
319
+ assert_equal(Encoding::ISO8859_1, reader.read_inner_xml.encoding)
320
+ assert_equal(Encoding::ISO8859_1, reader.read_string.encoding)
321
+
322
+ assert_equal("<bands genre=\"metal\">\n <m\xC3\xB6tley_cr\xC3\xBCe country=\"us\">An American heavy metal band formed in Los Angeles, California in 1981.</m\xC3\xB6tley_cr\xC3\xBCe>\n <iron_maiden country=\"uk\">British heavy metal band formed in 1975.</iron_maiden>\n</bands>".force_encoding(Encoding::ISO8859_1),
323
+ reader.read_outer_xml)
324
+ assert_equal("\n <m\xC3\xB6tley_cr\xC3\xBCe country=\"us\">An American heavy metal band formed in Los Angeles, California in 1981.</m\xC3\xB6tley_cr\xC3\xBCe>\n <iron_maiden country=\"uk\">British heavy metal band formed in 1975.</iron_maiden>\n".force_encoding(Encoding::ISO8859_1),
325
+ reader.read_inner_xml)
326
+ assert_equal("\n An American heavy metal band formed in Los Angeles, California in 1981.\n British heavy metal band formed in 1975.\n".force_encoding(Encoding::ISO8859_1),
327
+ reader.read_string)
328
+ end
329
+
330
+ def test_invalid_encoding
331
+ # ISO_8859_1:
332
+ # ö - f6 in hex, \366 in octal
333
+ # ü - fc in hex, \374 in octal
334
+ xml = "<bands genre=\"metal\">\n <m\366tley_cr\374e country=\"us\">An American heavy metal band formed in Los Angeles, California in 1981.</m\366tley_cr\374e>\n <iron_maiden country=\"uk\">British heavy metal band formed in 1975.</iron_maiden>\n</bands>"
335
+
336
+ reader = LibXML::XML::Reader.string(xml)
337
+ error = assert_raises(LibXML::XML::Error) do
338
+ reader.read
339
+ end
340
+
341
+ assert_equal("Fatal error: Input is not proper UTF-8, indicate encoding !\nBytes: 0xF6 0x74 0x6C 0x65 at :2.",
342
+ error.to_s)
343
+
344
+ end
345
+
346
+ def test_file_encoding
347
+ reader = LibXML::XML::Reader.file(XML_FILE)
348
+ reader.read
349
+ assert_equal(LibXML::XML::Encoding::UTF_8, reader.encoding)
350
+ assert_equal(Encoding::UTF_8, reader.value.encoding)
351
+ end
352
+
353
+ def test_string_encoding
354
+ # ISO_8859_1:
355
+ # ö - f6 in hex, \366 in octal
356
+ # ü - fc in hex, \374 in octal
357
+ xml = "<bands genre=\"metal\">\n <m\366tley_cr\374e country=\"us\">An American heavy metal band formed in Los Angeles, California in 1981.</m\366tley_cr\374e>\n <iron_maiden country=\"uk\">British heavy metal band formed in 1975.</iron_maiden>\n</bands>"
358
+ reader = LibXML::XML::Reader.string(xml, :encoding => LibXML::XML::Encoding::ISO_8859_1)
359
+ reader.read
360
+
361
+ encoding = windows? ? LibXML::XML::Encoding::ISO_8859_1 : LibXML::XML::Encoding::NONE
362
+ assert_equal(reader.encoding, encoding)
363
+ end
364
+ end