libxml-ruby 4.1.2 → 6.0.0

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 (172) hide show
  1. checksums.yaml +4 -4
  2. data/{HISTORY → CHANGELOG.md} +875 -887
  3. data/LICENSE +20 -20
  4. data/README.md +67 -0
  5. data/Rakefile +77 -98
  6. data/ext/libxml/extconf.rb +39 -20
  7. data/ext/libxml/libxml.c +67 -79
  8. data/ext/libxml/ruby_libxml.h +43 -44
  9. data/ext/libxml/ruby_xml.c +556 -899
  10. data/ext/libxml/ruby_xml.h +9 -10
  11. data/ext/libxml/ruby_xml_attr.c +338 -333
  12. data/ext/libxml/ruby_xml_attr.h +13 -12
  13. data/ext/libxml/ruby_xml_attr_decl.c +19 -12
  14. data/ext/libxml/ruby_xml_attr_decl.h +11 -11
  15. data/ext/libxml/ruby_xml_attributes.c +18 -9
  16. data/ext/libxml/ruby_xml_attributes.h +17 -15
  17. data/ext/libxml/ruby_xml_document.c +1142 -1129
  18. data/ext/libxml/ruby_xml_document.h +12 -11
  19. data/ext/libxml/ruby_xml_dtd.c +287 -248
  20. data/ext/libxml/ruby_xml_dtd.h +10 -9
  21. data/ext/libxml/ruby_xml_encoding.c +250 -250
  22. data/ext/libxml/ruby_xml_encoding.h +20 -18
  23. data/ext/libxml/ruby_xml_error.c +1003 -996
  24. data/ext/libxml/ruby_xml_error.h +14 -14
  25. data/ext/libxml/ruby_xml_html_parser.c +91 -91
  26. data/ext/libxml/ruby_xml_html_parser.h +10 -10
  27. data/ext/libxml/ruby_xml_html_parser_context.c +364 -337
  28. data/ext/libxml/ruby_xml_html_parser_context.h +11 -10
  29. data/ext/libxml/ruby_xml_html_parser_options.c +48 -48
  30. data/ext/libxml/ruby_xml_html_parser_options.h +10 -10
  31. data/ext/libxml/ruby_xml_input_cbg.c +216 -188
  32. data/ext/libxml/ruby_xml_input_cbg.h +20 -20
  33. data/ext/libxml/ruby_xml_io.c +49 -47
  34. data/ext/libxml/ruby_xml_io.h +10 -10
  35. data/ext/libxml/ruby_xml_namespace.c +159 -154
  36. data/ext/libxml/ruby_xml_namespace.h +11 -10
  37. data/ext/libxml/ruby_xml_namespaces.c +313 -293
  38. data/ext/libxml/ruby_xml_namespaces.h +9 -9
  39. data/ext/libxml/ruby_xml_node.c +1433 -1398
  40. data/ext/libxml/ruby_xml_node.h +15 -13
  41. data/ext/libxml/ruby_xml_parser.c +91 -91
  42. data/ext/libxml/ruby_xml_parser.h +10 -10
  43. data/ext/libxml/ruby_xml_parser_context.c +1016 -1001
  44. data/ext/libxml/ruby_xml_parser_context.h +11 -10
  45. data/ext/libxml/ruby_xml_parser_options.c +74 -66
  46. data/ext/libxml/ruby_xml_parser_options.h +10 -10
  47. data/ext/libxml/ruby_xml_reader.c +40 -31
  48. data/ext/libxml/ruby_xml_reader.h +14 -14
  49. data/ext/libxml/ruby_xml_registry.c +31 -0
  50. data/ext/libxml/ruby_xml_registry.h +22 -0
  51. data/ext/libxml/ruby_xml_relaxng.c +21 -5
  52. data/ext/libxml/ruby_xml_relaxng.h +9 -8
  53. data/ext/libxml/ruby_xml_sax2_handler.c +326 -326
  54. data/ext/libxml/ruby_xml_sax2_handler.h +10 -10
  55. data/ext/libxml/ruby_xml_sax_parser.c +108 -116
  56. data/ext/libxml/ruby_xml_sax_parser.h +10 -10
  57. data/ext/libxml/ruby_xml_schema.c +22 -15
  58. data/ext/libxml/ruby_xml_schema.h +26 -25
  59. data/ext/libxml/ruby_xml_schema_attribute.c +7 -7
  60. data/ext/libxml/ruby_xml_schema_attribute.h +37 -37
  61. data/ext/libxml/ruby_xml_schema_element.c +8 -8
  62. data/ext/libxml/ruby_xml_schema_element.h +11 -11
  63. data/ext/libxml/ruby_xml_schema_facet.c +50 -50
  64. data/ext/libxml/ruby_xml_schema_facet.h +9 -9
  65. data/ext/libxml/ruby_xml_schema_type.c +12 -19
  66. data/ext/libxml/ruby_xml_schema_type.h +9 -9
  67. data/ext/libxml/ruby_xml_version.h +9 -9
  68. data/ext/libxml/ruby_xml_writer.c +183 -185
  69. data/ext/libxml/ruby_xml_writer.h +6 -6
  70. data/ext/libxml/ruby_xml_xinclude.c +20 -20
  71. data/ext/libxml/ruby_xml_xinclude.h +11 -11
  72. data/ext/libxml/ruby_xml_xpath.c +195 -195
  73. data/ext/libxml/ruby_xml_xpath.h +15 -15
  74. data/ext/libxml/ruby_xml_xpath_context.c +408 -362
  75. data/ext/libxml/ruby_xml_xpath_context.h +9 -9
  76. data/ext/libxml/ruby_xml_xpath_expression.c +12 -6
  77. data/ext/libxml/ruby_xml_xpath_expression.h +11 -10
  78. data/ext/libxml/ruby_xml_xpath_object.c +69 -54
  79. data/ext/libxml/ruby_xml_xpath_object.h +19 -17
  80. data/ext/vc/libxml_ruby/libxml_ruby.vcxproj +271 -0
  81. data/ext/xcode/libxml-ruby.xcodeproj/project.pbxproj +633 -0
  82. data/ext/xcode/libxml-ruby.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  83. data/ext/xcode/libxml-ruby.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  84. data/ext/xcode/libxml-ruby.xcodeproj/xcshareddata/xcschemes/libxml-ruby.xcscheme +80 -0
  85. data/lib/libxml/attr.rb +122 -122
  86. data/lib/libxml/attr_decl.rb +80 -80
  87. data/lib/libxml/attributes.rb +13 -13
  88. data/lib/libxml/document.rb +165 -194
  89. data/lib/libxml/error.rb +122 -95
  90. data/lib/libxml/html_parser.rb +80 -96
  91. data/lib/libxml/namespace.rb +61 -61
  92. data/lib/libxml/namespaces.rb +37 -37
  93. data/lib/libxml/node.rb +321 -323
  94. data/lib/libxml/parser.rb +94 -100
  95. data/lib/libxml/sax_callbacks.rb +179 -179
  96. data/lib/libxml/sax_parser.rb +40 -40
  97. data/lib/libxml/schema/attribute.rb +27 -19
  98. data/lib/libxml/schema/element.rb +20 -0
  99. data/lib/libxml/schema/type.rb +44 -21
  100. data/lib/libxml/schema.rb +47 -47
  101. data/lib/libxml/tree.rb +28 -28
  102. data/lib/libxml-ruby.rb +30 -30
  103. data/libxml-ruby.gemspec +46 -48
  104. data/test/c14n/result/1-1-without-comments/example-1 +3 -3
  105. data/test/c14n/result/1-1-without-comments/example-2 +10 -10
  106. data/test/c14n/result/1-1-without-comments/example-3 +13 -13
  107. data/test/c14n/result/1-1-without-comments/example-4 +8 -8
  108. data/test/c14n/result/1-1-without-comments/example-5 +2 -2
  109. data/test/c14n/result/with-comments/example-1 +5 -5
  110. data/test/c14n/result/with-comments/example-2 +10 -10
  111. data/test/c14n/result/with-comments/example-3 +13 -13
  112. data/test/c14n/result/with-comments/example-4 +8 -8
  113. data/test/c14n/result/with-comments/example-5 +3 -3
  114. data/test/c14n/result/without-comments/example-1 +3 -3
  115. data/test/c14n/result/without-comments/example-2 +10 -10
  116. data/test/c14n/result/without-comments/example-3 +13 -13
  117. data/test/c14n/result/without-comments/example-4 +8 -8
  118. data/test/c14n/result/without-comments/example-5 +2 -2
  119. data/test/test_attr.rb +179 -180
  120. data/test/test_attr_decl.rb +131 -131
  121. data/test/test_attributes.rb +135 -135
  122. data/test/test_canonicalize.rb +122 -120
  123. data/test/test_document.rb +138 -132
  124. data/test/test_document_write.rb +142 -145
  125. data/test/test_dtd.rb +134 -129
  126. data/test/test_encoding.rb +126 -129
  127. data/test/test_encoding_sax.rb +114 -114
  128. data/test/test_error.rb +197 -194
  129. data/test/test_helper.rb +21 -13
  130. data/test/test_html_parser.rb +166 -162
  131. data/test/test_html_parser_context.rb +22 -22
  132. data/test/test_input_callbacks.rb +36 -0
  133. data/test/test_namespace.rb +58 -60
  134. data/test/test_namespaces.rb +200 -200
  135. data/test/test_node.rb +251 -237
  136. data/test/test_node_cdata.rb +50 -50
  137. data/test/test_node_comment.rb +32 -32
  138. data/test/test_node_copy.rb +40 -40
  139. data/test/test_node_edit.rb +176 -158
  140. data/test/test_node_pi.rb +37 -37
  141. data/test/test_node_text.rb +69 -69
  142. data/test/test_node_write.rb +93 -96
  143. data/test/test_node_xlink.rb +28 -28
  144. data/test/test_parser.rb +297 -324
  145. data/test/test_parser_context.rb +198 -198
  146. data/test/test_properties.rb +38 -38
  147. data/test/test_reader.rb +413 -364
  148. data/test/test_relaxng.rb +59 -53
  149. data/test/test_sax_parser.rb +345 -326
  150. data/test/test_schema.rb +28 -0
  151. data/test/test_traversal.rb +152 -152
  152. data/test/test_writer.rb +469 -468
  153. data/test/test_xinclude.rb +20 -20
  154. data/test/test_xml.rb +164 -267
  155. data/test/test_xpath.rb +244 -244
  156. data/test/test_xpath_context.rb +87 -87
  157. data/test/test_xpath_expression.rb +37 -37
  158. metadata +49 -31
  159. data/README.rdoc +0 -217
  160. data/ext/libxml/extconf.h +0 -3
  161. data/ext/libxml/ruby_xml_cbg.c +0 -85
  162. data/lib/libxml/hpricot.rb +0 -78
  163. data/lib/libxml.rb +0 -5
  164. data/lib/xml/libxml.rb +0 -10
  165. data/lib/xml.rb +0 -14
  166. data/script/benchmark/depixelate +0 -634
  167. data/script/benchmark/hamlet.xml +0 -9055
  168. data/script/benchmark/parsecount +0 -170
  169. data/script/benchmark/sock_entries.xml +0 -507
  170. data/script/benchmark/throughput +0 -41
  171. data/script/test +0 -6
  172. data/test/test_deprecated_require.rb +0 -12
data/test/test_parser.rb CHANGED
@@ -1,324 +1,297 @@
1
- # encoding: UTF-8
2
-
3
- require_relative './test_helper'
4
- require 'stringio'
5
-
6
- class TestParser < Minitest::Test
7
- def setup
8
- LibXML::XML::Error.set_handler(&LibXML::XML::Error::QUIET_HANDLER)
9
- end
10
-
11
- # ----- Sources -------
12
- def test_document
13
- file = File.expand_path(File.join(File.dirname(__FILE__), 'model/bands.utf-8.xml'))
14
- parser = LibXML::XML::Parser.file(file)
15
- doc = parser.parse
16
-
17
- parser = LibXML::XML::Parser.document(doc)
18
-
19
- doc = parser.parse
20
-
21
- assert_instance_of(LibXML::XML::Document, doc)
22
- assert_instance_of(LibXML::XML::Parser::Context, parser.context)
23
- end
24
-
25
- def test_nil_document
26
- error = assert_raises(TypeError) do
27
- LibXML::XML::Parser.document(nil)
28
- end
29
-
30
- assert_equal("Must pass an LibXML::XML::Document object", error.to_s)
31
- end
32
-
33
- def test_file
34
- file = File.expand_path(File.join(File.dirname(__FILE__), 'model/rubynet.xml'))
35
-
36
- parser = LibXML::XML::Parser.file(file)
37
- doc = parser.parse
38
- assert_instance_of(LibXML::XML::Document, doc)
39
- assert_instance_of(LibXML::XML::Parser::Context, parser.context)
40
- end
41
-
42
- def test_noexistent_file
43
- error = assert_raises(LibXML::XML::Error) do
44
- LibXML::XML::Parser.file('i_dont_exist.xml')
45
- end
46
-
47
- assert_equal('Warning: failed to load external entity "i_dont_exist.xml".', error.to_s)
48
- end
49
-
50
- def test_nil_file
51
- error = assert_raises(TypeError) do
52
- LibXML::XML::Parser.file(nil)
53
- end
54
-
55
- assert_match(/nil into String/, error.to_s)
56
- end
57
-
58
- def test_file_encoding
59
- file = File.expand_path(File.join(File.dirname(__FILE__), 'model/bands.utf-8.xml'))
60
- parser = LibXML::XML::Parser.file(file, :encoding => LibXML::XML::Encoding::ISO_8859_1)
61
-
62
- error = assert_raises(LibXML::XML::Error) do
63
- parser.parse
64
- end
65
-
66
- assert(error.to_s.match(/Fatal error: Extra content at the end of the document/))
67
-
68
- parser = LibXML::XML::Parser.file(file, :encoding => LibXML::XML::Encoding::UTF_8)
69
- doc = parser.parse
70
- refute_nil(doc)
71
- end
72
-
73
- def test_file_base_uri
74
- file = File.expand_path(File.join(File.dirname(__FILE__), 'model/bands.utf-8.xml'))
75
-
76
- parser = LibXML::XML::Parser.file(file)
77
- doc = parser.parse
78
- assert(doc.child.base_uri.match(/test\/model\/bands.utf-8.xml/))
79
-
80
- parser = LibXML::XML::Parser.file(file, :base_uri => "http://libxml.org")
81
- doc = parser.parse
82
- assert(doc.child.base_uri.match(/test\/model\/bands.utf-8.xml/))
83
- end
84
-
85
- def test_io
86
- File.open(File.join(File.dirname(__FILE__), 'model/rubynet.xml')) do |io|
87
- parser = LibXML::XML::Parser.io(io)
88
- assert_instance_of(LibXML::XML::Parser, parser)
89
-
90
- doc = parser.parse
91
- assert_instance_of(LibXML::XML::Document, doc)
92
- assert_instance_of(LibXML::XML::Parser::Context, parser.context)
93
- end
94
- end
95
-
96
- def test_io_gc
97
- # Test that the reader keeps a reference
98
- # to the io object
99
- file = File.open(File.join(File.dirname(__FILE__), 'model/rubynet.xml'))
100
- parser = LibXML::XML::Parser.io(file)
101
- file = nil
102
- GC.start
103
- assert(parser.parse)
104
- end
105
-
106
- def test_nil_io
107
- error = assert_raises(TypeError) do
108
- LibXML::XML::Parser.io(nil)
109
- end
110
-
111
- assert_equal("Must pass in an IO object", error.to_s)
112
- end
113
-
114
- def test_string_io
115
- data = File.read(File.join(File.dirname(__FILE__), 'model/rubynet.xml'))
116
- string_io = StringIO.new(data)
117
- parser = LibXML::XML::Parser.io(string_io)
118
-
119
- doc = parser.parse
120
- assert_instance_of(LibXML::XML::Document, doc)
121
- assert_instance_of(LibXML::XML::Parser::Context, parser.context)
122
- end
123
-
124
- def test_string_io_thread
125
- thread = Thread.new do
126
- data = File.read(File.join(File.dirname(__FILE__), 'model/rubynet.xml'))
127
- string_io = StringIO.new(data)
128
- parser = LibXML::XML::Parser.io(string_io)
129
-
130
- doc = parser.parse
131
- assert_instance_of(LibXML::XML::Document, doc)
132
- assert_instance_of(LibXML::XML::Parser::Context, parser.context)
133
- end
134
-
135
- thread.join
136
- assert(true)
137
- puts 'Thread completed'
138
- end
139
-
140
- def test_string
141
- str = '<ruby_array uga="booga" foo="bar"><fixnum>one</fixnum><fixnum>two</fixnum></ruby_array>'
142
-
143
- parser = LibXML::XML::Parser.string(str)
144
- assert_instance_of(LibXML::XML::Parser, parser)
145
-
146
- doc = parser.parse
147
- assert_instance_of(LibXML::XML::Document, doc)
148
- assert_instance_of(LibXML::XML::Parser::Context, parser.context)
149
- end
150
-
151
- def test_nil_string
152
- error = assert_raises(TypeError) do
153
- LibXML::XML::Parser.string(nil)
154
- end
155
-
156
- assert_equal("wrong argument type nil (expected String)", error.to_s)
157
- end
158
-
159
- def test_string_options
160
- xml = <<-EOS
161
- <!DOCTYPE foo [<!ENTITY foo 'bar'>]>
162
- <test>
163
- <cdata><![CDATA[something]]></cdata>
164
- <entity>&foo;</entity>
165
- </test>
166
- EOS
167
-
168
- LibXML::XML::default_substitute_entities = false
169
-
170
- # Parse normally
171
- parser = LibXML::XML::Parser.string(xml)
172
- doc = parser.parse
173
- assert_nil(doc.child.base_uri)
174
-
175
- # Cdata section should be cdata nodes
176
- node = doc.find_first('/test/cdata').child
177
- assert_equal(LibXML::XML::Node::CDATA_SECTION_NODE, node.node_type)
178
-
179
- # Entities should not be subtituted
180
- node = doc.find_first('/test/entity')
181
- assert_equal('&foo;', node.child.to_s)
182
-
183
- # Parse with options
184
- parser = LibXML::XML::Parser.string(xml, :base_uri => 'http://libxml.rubyforge.org',
185
- :options => LibXML::XML::Parser::Options::NOCDATA | LibXML::XML::Parser::Options::NOENT)
186
- doc = parser.parse
187
- assert_equal(doc.child.base_uri, 'http://libxml.rubyforge.org')
188
-
189
- # Cdata section should be text nodes
190
- node = doc.find_first('/test/cdata').child
191
- assert_equal(LibXML::XML::Node::TEXT_NODE, node.node_type)
192
-
193
- # Entities should be subtituted
194
- node = doc.find_first('/test/entity')
195
- assert_equal('bar', node.child.to_s)
196
- end
197
-
198
- def test_string_encoding
199
- # ISO_8859_1:
200
- # ö - f6 in hex, \366 in octal
201
- # ü - fc in hex, \374 in octal
202
-
203
- xml = <<-EOS
204
- <bands>
205
- <metal>m\366tley_cr\374e</metal>
206
- </bands>
207
- EOS
208
-
209
- # Parse as UTF_8
210
- parser = LibXML::XML::Parser.string(xml, :encoding => LibXML::XML::Encoding::UTF_8)
211
-
212
- error = assert_raises(LibXML::XML::Error) do
213
- parser.parse
214
- end
215
-
216
- assert_equal("Fatal error: Input is not proper UTF-8, indicate encoding !\nBytes: 0xF6 0x74 0x6C 0x65 at :2.",
217
- error.to_s)
218
-
219
- # Parse as ISO_8859_1:
220
- parser = LibXML::XML::Parser.string(xml, :encoding => LibXML::XML::Encoding::ISO_8859_1)
221
- doc = parser.parse
222
- node = doc.find_first('//metal')
223
- assert_equal(Encoding::UTF_8, node.content.encoding)
224
- assert_equal("m\303\266tley_cr\303\274e", node.content)
225
- end
226
-
227
- def test_fd_gc
228
- # Test opening # of documents up to the file limit for the OS.
229
- # Ideally it should run until libxml emits a warning,
230
- # thereby knowing we've done a GC sweep. For the time being,
231
- # re-open the same doc `limit descriptors` times.
232
- # If we make it to the end, then we've succeeded,
233
- # otherwise an exception will be thrown.
234
- LibXML::XML::Error.set_handler {|error|}
235
-
236
- max_fd = if RUBY_PLATFORM.match(/mswin32|mswin64|mingw/i)
237
- 500
238
- else
239
- Process.getrlimit(Process::RLIMIT_NOFILE)[0] + 1
240
- end
241
-
242
- file = File.join(File.dirname(__FILE__), 'model/rubynet.xml')
243
- max_fd.times do
244
- LibXML::XML::Parser.file(file).parse
245
- end
246
- LibXML::XML::Error.reset_handler {|error|}
247
- end
248
-
249
- def test_open_many_files
250
- file = File.expand_path(File.join(File.dirname(__FILE__), 'model/atom.xml'))
251
- 1000.times do
252
- LibXML::XML::Parser.file(file).parse
253
- end
254
- end
255
-
256
- # ----- Errors ------
257
- def test_error
258
- error = assert_raises(LibXML::XML::Error) do
259
- LibXML::XML::Parser.string('<foo><bar/></foz>').parse
260
- end
261
-
262
- refute_nil(error)
263
- assert_kind_of(LibXML::XML::Error, error)
264
- assert_equal("Fatal error: Opening and ending tag mismatch: foo line 1 and foz at :1.", error.message)
265
- assert_equal(LibXML::XML::Error::PARSER, error.domain)
266
- assert_equal(LibXML::XML::Error::TAG_NAME_MISMATCH, error.code)
267
- assert_equal(LibXML::XML::Error::FATAL, error.level)
268
- assert_nil(error.file)
269
- assert_equal(1, error.line)
270
- assert_equal('foo', error.str1)
271
- assert_equal('foz', error.str2)
272
- assert_nil(error.str3)
273
- assert_equal(1, error.int1)
274
- assert([18, 20].include?(error.int2))
275
- assert_nil(error.node)
276
- end
277
-
278
- def test_bad_xml
279
- parser = LibXML::XML::Parser.string('<ruby_array uga="booga" foo="bar"<fixnum>one</fixnum><fixnum>two</fixnum></ruby_array>')
280
- error = assert_raises(LibXML::XML::Error) do
281
- refute_nil(parser.parse)
282
- end
283
-
284
- refute_nil(error)
285
- assert_kind_of(LibXML::XML::Error, error)
286
- assert_equal("Fatal error: Extra content at the end of the document at :1.", error.message)
287
- assert_equal(LibXML::XML::Error::PARSER, error.domain)
288
- assert_equal(LibXML::XML::Error::DOCUMENT_END, error.code)
289
- assert_equal(LibXML::XML::Error::FATAL, error.level)
290
- assert_nil(error.file)
291
- assert_equal(1, error.line)
292
- assert_nil(error.str1)
293
- assert_nil(error.str2)
294
- assert_nil(error.str3)
295
- assert_equal(0, error.int1)
296
- assert_equal(34, error.int2)
297
- assert_nil(error.node)
298
- end
299
-
300
- def test_errors_from_background_thread
301
- errors = []
302
- background_errors = []
303
-
304
- begin
305
- LibXML::XML::Error.set_handler do |error|
306
- errors << error
307
- end
308
- parser = LibXML::XML::Parser.string("<moo>")
309
-
310
- thread = Thread.new do
311
- LibXML::XML::Error.set_handler do |error|
312
- background_errors << error
313
- end
314
- parser.parse rescue nil
315
- end
316
- thread.join
317
- ensure
318
- LibXML::XML::Error.set_handler(&LibXML::XML::Error::QUIET_HANDLER)
319
- end
320
-
321
- assert_equal(errors.size, 0)
322
- assert_equal(background_errors.size, 1)
323
- end
324
- end
1
+ # encoding: UTF-8
2
+
3
+ require_relative './test_helper'
4
+ require 'stringio'
5
+
6
+ class TestParser < Minitest::Test
7
+ def setup
8
+ LibXML::XML::Error.set_handler(&LibXML::XML::Error::QUIET_HANDLER)
9
+ end
10
+
11
+ # ----- Sources -------
12
+ def test_document
13
+ file = File.expand_path(File.join(File.dirname(__FILE__), 'model/bands.utf-8.xml'))
14
+ parser = LibXML::XML::Parser.file(file)
15
+ doc = parser.parse
16
+
17
+ parser = LibXML::XML::Parser.document(doc)
18
+
19
+ doc = parser.parse
20
+
21
+ assert_instance_of(LibXML::XML::Document, doc)
22
+ assert_instance_of(LibXML::XML::Parser::Context, parser.context)
23
+ end
24
+
25
+ def test_nil_document
26
+ error = assert_raises(TypeError) do
27
+ LibXML::XML::Parser.document(nil)
28
+ end
29
+
30
+ assert_equal("Must pass an LibXML::XML::Document object", error.message)
31
+ end
32
+
33
+ def test_file
34
+ file = File.expand_path(File.join(File.dirname(__FILE__), 'model/rubynet.xml'))
35
+
36
+ parser = LibXML::XML::Parser.file(file)
37
+ doc = parser.parse
38
+ assert_instance_of(LibXML::XML::Document, doc)
39
+ assert_instance_of(LibXML::XML::Parser::Context, parser.context)
40
+ end
41
+
42
+ def test_noexistent_file
43
+ error = assert_raises(LibXML::XML::Error) do
44
+ LibXML::XML::Parser.file('i_dont_exist.xml')
45
+ end
46
+
47
+ assert_match(/Warning: failed to load.*i_dont_exist\.xml/, error.message)
48
+ end
49
+
50
+ def test_nil_file
51
+ error = assert_raises(TypeError) do
52
+ LibXML::XML::Parser.file(nil)
53
+ end
54
+
55
+ assert_match(/nil into String/, error.message)
56
+ end
57
+
58
+ def test_file_encoding
59
+ file = File.expand_path(File.join(File.dirname(__FILE__), 'model/bands.utf-8.xml'))
60
+ parser = LibXML::XML::Parser.file(file, :encoding => LibXML::XML::Encoding::ISO_8859_1)
61
+
62
+ error = assert_raises(LibXML::XML::Error) do
63
+ parser.parse
64
+ end
65
+
66
+ assert_match(/Fatal error:/, error.message)
67
+
68
+ parser = LibXML::XML::Parser.file(file, :encoding => LibXML::XML::Encoding::UTF_8)
69
+ doc = parser.parse
70
+ refute_nil(doc)
71
+ end
72
+
73
+ def test_file_base_uri
74
+ file = File.expand_path(File.join(File.dirname(__FILE__), 'model/bands.utf-8.xml'))
75
+
76
+ parser = LibXML::XML::Parser.file(file)
77
+ doc = parser.parse
78
+ assert(doc.child.base_uri.match(/test\/model\/bands.utf-8.xml/))
79
+
80
+ parser = LibXML::XML::Parser.file(file, :base_uri => "http://libxml.org")
81
+ doc = parser.parse
82
+ assert(doc.child.base_uri.match(/test\/model\/bands.utf-8.xml/))
83
+ end
84
+
85
+ def test_io
86
+ File.open(File.join(File.dirname(__FILE__), 'model/rubynet.xml')) do |io|
87
+ parser = LibXML::XML::Parser.io(io)
88
+ assert_instance_of(LibXML::XML::Parser, parser)
89
+
90
+ doc = parser.parse
91
+ assert_instance_of(LibXML::XML::Document, doc)
92
+ assert_instance_of(LibXML::XML::Parser::Context, parser.context)
93
+ end
94
+ end
95
+
96
+ def test_io_gc
97
+ # Test that the reader keeps a reference
98
+ # to the io object
99
+ file = File.open(File.join(File.dirname(__FILE__), 'model/rubynet.xml'))
100
+ parser = LibXML::XML::Parser.io(file)
101
+ file = nil
102
+ GC.start
103
+ assert(parser.parse)
104
+ end
105
+
106
+ def test_nil_io
107
+ error = assert_raises(TypeError) do
108
+ LibXML::XML::Parser.io(nil)
109
+ end
110
+
111
+ assert_equal("Must pass in an IO object", error.message)
112
+ end
113
+
114
+ def test_string_io
115
+ data = File.read(File.join(File.dirname(__FILE__), 'model/rubynet.xml'))
116
+ string_io = StringIO.new(data)
117
+ parser = LibXML::XML::Parser.io(string_io)
118
+
119
+ doc = parser.parse
120
+ assert_instance_of(LibXML::XML::Document, doc)
121
+ assert_instance_of(LibXML::XML::Parser::Context, parser.context)
122
+ end
123
+
124
+ def test_string_io_thread
125
+ thread = Thread.new do
126
+ data = File.read(File.join(File.dirname(__FILE__), 'model/rubynet.xml'))
127
+ string_io = StringIO.new(data)
128
+ parser = LibXML::XML::Parser.io(string_io)
129
+
130
+ doc = parser.parse
131
+ assert_instance_of(LibXML::XML::Document, doc)
132
+ assert_instance_of(LibXML::XML::Parser::Context, parser.context)
133
+ end
134
+
135
+ thread.join
136
+ assert(true)
137
+ puts 'Thread completed'
138
+ end
139
+
140
+ def test_string
141
+ str = '<ruby_array uga="booga" foo="bar"><fixnum>one</fixnum><fixnum>two</fixnum></ruby_array>'
142
+
143
+ parser = LibXML::XML::Parser.string(str)
144
+ assert_instance_of(LibXML::XML::Parser, parser)
145
+
146
+ doc = parser.parse
147
+ assert_instance_of(LibXML::XML::Document, doc)
148
+ assert_instance_of(LibXML::XML::Parser::Context, parser.context)
149
+ end
150
+
151
+ def test_nil_string
152
+ error = assert_raises(TypeError) do
153
+ LibXML::XML::Parser.string(nil)
154
+ end
155
+
156
+ assert_equal("wrong argument type nil (expected String)", error.message)
157
+ end
158
+
159
+ def test_string_options
160
+ xml = <<-EOS
161
+ <!DOCTYPE foo [<!ENTITY foo 'bar'>]>
162
+ <test>
163
+ <cdata><![CDATA[something]]></cdata>
164
+ <entity>&foo;</entity>
165
+ </test>
166
+ EOS
167
+
168
+ # Parse normally - entities won't be substituted
169
+ parser = LibXML::XML::Parser.string(xml)
170
+ doc = parser.parse
171
+ assert_nil(doc.child.base_uri)
172
+
173
+ # Cdata section should be cdata nodes
174
+ node = doc.find_first('/test/cdata').child
175
+ assert_equal(LibXML::XML::Node::CDATA_SECTION_NODE, node.node_type)
176
+
177
+ # Entities should not be substituted
178
+ node = doc.find_first('/test/entity')
179
+ assert_equal('&foo;', node.child.to_s)
180
+
181
+ # Parse with options
182
+ parser = LibXML::XML::Parser.string(xml, base_uri: 'http://libxml.rubyforge.org',
183
+ options: LibXML::XML::Parser::Options::NOCDATA | LibXML::XML::Parser::Options::NOENT)
184
+ doc = parser.parse
185
+ assert_equal(doc.child.base_uri, 'http://libxml.rubyforge.org')
186
+
187
+ # Cdata section should be text nodes
188
+ node = doc.find_first('/test/cdata').child
189
+ assert_equal(LibXML::XML::Node::TEXT_NODE, node.node_type)
190
+
191
+ # Entities should be subtituted
192
+ node = doc.find_first('/test/entity')
193
+ assert_equal('bar', node.child.to_s)
194
+ end
195
+
196
+ def test_string_encoding
197
+ # ISO_8859_1:
198
+ # ö - f6 in hex, \366 in octal
199
+ # ü - fc in hex, \374 in octal
200
+
201
+ xml = <<-EOS
202
+ <bands>
203
+ <metal>m\366tley_cr\374e</metal>
204
+ </bands>
205
+ EOS
206
+
207
+ # Parse as UTF_8
208
+ parser = LibXML::XML::Parser.string(xml, :encoding => LibXML::XML::Encoding::UTF_8)
209
+
210
+ error = assert_raises(LibXML::XML::Error) do
211
+ parser.parse
212
+ end
213
+
214
+ assert_match(/Fatal error:.*at :2\./m, error.message)
215
+
216
+ # Parse as ISO_8859_1:
217
+ parser = LibXML::XML::Parser.string(xml, :encoding => LibXML::XML::Encoding::ISO_8859_1)
218
+ doc = parser.parse
219
+ node = doc.find_first('//metal')
220
+ assert_equal(Encoding::UTF_8, node.content.encoding)
221
+ assert_equal("m\303\266tley_cr\303\274e", node.content)
222
+ end
223
+
224
+ def test_error
225
+ error = assert_raises(LibXML::XML::Error) do
226
+ LibXML::XML::Parser.string('<foo><bar/></foz>').parse
227
+ end
228
+
229
+ refute_nil(error)
230
+ assert_kind_of(LibXML::XML::Error, error)
231
+ assert_equal("Fatal error: Opening and ending tag mismatch: foo line 1 and foz at :1.", error.message)
232
+ assert_equal(LibXML::XML::Error::PARSER, error.domain)
233
+ assert_equal(LibXML::XML::Error::TAG_NAME_MISMATCH, error.code)
234
+ assert_equal(LibXML::XML::Error::FATAL, error.level)
235
+ assert_nil(error.file)
236
+ assert_equal(1, error.line)
237
+ assert_equal('foo', error.str1)
238
+ assert_equal('foz', error.str2)
239
+ assert_nil(error.str3)
240
+ assert_equal(1, error.int1)
241
+ assert([18, 20].include?(error.int2))
242
+ assert_nil(error.node)
243
+ end
244
+
245
+ def test_bad_xml
246
+ parser = LibXML::XML::Parser.string('<ruby_array uga="booga" foo="bar"<fixnum>one</fixnum><fixnum>two</fixnum></ruby_array>')
247
+ error = assert_raises(LibXML::XML::Error) do
248
+ refute_nil(parser.parse)
249
+ end
250
+
251
+ refute_nil(error)
252
+ assert_kind_of(LibXML::XML::Error, error)
253
+ if Gem::Version.new(LibXML::XML::LIBXML_VERSION) >= Gem::Version.new("2.12")
254
+ assert_equal("Fatal error: Couldn't find end of Start Tag ruby_array line 1 at :1.", error.message)
255
+ assert_equal(LibXML::XML::Error::GT_REQUIRED, error.code)
256
+ assert_equal("ruby_array", error.str1)
257
+ assert_equal(1, error.int1)
258
+ else
259
+ assert_equal("Fatal error: Extra content at the end of the document at :1.", error.message)
260
+ assert_equal(LibXML::XML::Error::DOCUMENT_END, error.code)
261
+ assert_nil(error.str1)
262
+ assert_equal(0, error.int1)
263
+ end
264
+ assert_equal(LibXML::XML::Error::PARSER, error.domain)
265
+ assert_equal(LibXML::XML::Error::FATAL, error.level)
266
+ assert_nil(error.file)
267
+ assert_equal(1, error.line)
268
+ assert_nil(error.str2)
269
+ assert_nil(error.str3)
270
+ assert_nil(error.node)
271
+ end
272
+
273
+ def test_errors_from_background_thread
274
+ errors = []
275
+ background_errors = []
276
+
277
+ begin
278
+ LibXML::XML::Error.set_handler do |error|
279
+ errors << error
280
+ end
281
+ parser = LibXML::XML::Parser.string("<moo>")
282
+
283
+ thread = Thread.new do
284
+ LibXML::XML::Error.set_handler do |error|
285
+ background_errors << error
286
+ end
287
+ parser.parse rescue nil
288
+ end
289
+ thread.join
290
+ ensure
291
+ LibXML::XML::Error.set_handler(&LibXML::XML::Error::QUIET_HANDLER)
292
+ end
293
+
294
+ assert_equal(errors.size, 0)
295
+ assert_equal(background_errors.size, 1)
296
+ end
297
+ end