nokogiri-maglev- 1.5.0.1

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 (225) hide show
  1. data/.autotest +26 -0
  2. data/.gemtest +0 -0
  3. data/CHANGELOG.ja.rdoc +544 -0
  4. data/CHANGELOG.rdoc +532 -0
  5. data/Manifest.txt +283 -0
  6. data/README.ja.rdoc +106 -0
  7. data/README.rdoc +174 -0
  8. data/Rakefile +171 -0
  9. data/bin/nokogiri +53 -0
  10. data/ext/nokogiri/depend +358 -0
  11. data/ext/nokogiri/extconf.rb +124 -0
  12. data/ext/nokogiri/html_document.c +154 -0
  13. data/ext/nokogiri/html_document.h +10 -0
  14. data/ext/nokogiri/html_element_description.c +276 -0
  15. data/ext/nokogiri/html_element_description.h +10 -0
  16. data/ext/nokogiri/html_entity_lookup.c +32 -0
  17. data/ext/nokogiri/html_entity_lookup.h +8 -0
  18. data/ext/nokogiri/html_sax_parser_context.c +94 -0
  19. data/ext/nokogiri/html_sax_parser_context.h +11 -0
  20. data/ext/nokogiri/nokogiri.c +115 -0
  21. data/ext/nokogiri/nokogiri.h +160 -0
  22. data/ext/nokogiri/st.c +576 -0
  23. data/ext/nokogiri/xml_attr.c +94 -0
  24. data/ext/nokogiri/xml_attr.h +9 -0
  25. data/ext/nokogiri/xml_attribute_decl.c +70 -0
  26. data/ext/nokogiri/xml_attribute_decl.h +9 -0
  27. data/ext/nokogiri/xml_cdata.c +56 -0
  28. data/ext/nokogiri/xml_cdata.h +9 -0
  29. data/ext/nokogiri/xml_comment.c +54 -0
  30. data/ext/nokogiri/xml_comment.h +9 -0
  31. data/ext/nokogiri/xml_document.c +478 -0
  32. data/ext/nokogiri/xml_document.h +23 -0
  33. data/ext/nokogiri/xml_document_fragment.c +48 -0
  34. data/ext/nokogiri/xml_document_fragment.h +10 -0
  35. data/ext/nokogiri/xml_dtd.c +202 -0
  36. data/ext/nokogiri/xml_dtd.h +10 -0
  37. data/ext/nokogiri/xml_element_content.c +123 -0
  38. data/ext/nokogiri/xml_element_content.h +10 -0
  39. data/ext/nokogiri/xml_element_decl.c +69 -0
  40. data/ext/nokogiri/xml_element_decl.h +9 -0
  41. data/ext/nokogiri/xml_encoding_handler.c +79 -0
  42. data/ext/nokogiri/xml_encoding_handler.h +8 -0
  43. data/ext/nokogiri/xml_entity_decl.c +110 -0
  44. data/ext/nokogiri/xml_entity_decl.h +10 -0
  45. data/ext/nokogiri/xml_entity_reference.c +52 -0
  46. data/ext/nokogiri/xml_entity_reference.h +9 -0
  47. data/ext/nokogiri/xml_io.c +56 -0
  48. data/ext/nokogiri/xml_io.h +11 -0
  49. data/ext/nokogiri/xml_libxml2_hacks.c +112 -0
  50. data/ext/nokogiri/xml_libxml2_hacks.h +12 -0
  51. data/ext/nokogiri/xml_namespace.c +84 -0
  52. data/ext/nokogiri/xml_namespace.h +13 -0
  53. data/ext/nokogiri/xml_node.c +1397 -0
  54. data/ext/nokogiri/xml_node.h +13 -0
  55. data/ext/nokogiri/xml_node_set.c +418 -0
  56. data/ext/nokogiri/xml_node_set.h +9 -0
  57. data/ext/nokogiri/xml_processing_instruction.c +56 -0
  58. data/ext/nokogiri/xml_processing_instruction.h +9 -0
  59. data/ext/nokogiri/xml_reader.c +684 -0
  60. data/ext/nokogiri/xml_reader.h +10 -0
  61. data/ext/nokogiri/xml_relax_ng.c +162 -0
  62. data/ext/nokogiri/xml_relax_ng.h +9 -0
  63. data/ext/nokogiri/xml_sax_parser.c +293 -0
  64. data/ext/nokogiri/xml_sax_parser.h +39 -0
  65. data/ext/nokogiri/xml_sax_parser_context.c +199 -0
  66. data/ext/nokogiri/xml_sax_parser_context.h +10 -0
  67. data/ext/nokogiri/xml_sax_push_parser.c +115 -0
  68. data/ext/nokogiri/xml_sax_push_parser.h +9 -0
  69. data/ext/nokogiri/xml_schema.c +205 -0
  70. data/ext/nokogiri/xml_schema.h +9 -0
  71. data/ext/nokogiri/xml_syntax_error.c +58 -0
  72. data/ext/nokogiri/xml_syntax_error.h +13 -0
  73. data/ext/nokogiri/xml_text.c +50 -0
  74. data/ext/nokogiri/xml_text.h +9 -0
  75. data/ext/nokogiri/xml_xpath_context.c +315 -0
  76. data/ext/nokogiri/xml_xpath_context.h +9 -0
  77. data/ext/nokogiri/xslt_stylesheet.c +265 -0
  78. data/ext/nokogiri/xslt_stylesheet.h +9 -0
  79. data/lib/nokogiri.rb +127 -0
  80. data/lib/nokogiri/css.rb +27 -0
  81. data/lib/nokogiri/css/node.rb +99 -0
  82. data/lib/nokogiri/css/parser.rb +677 -0
  83. data/lib/nokogiri/css/parser.y +237 -0
  84. data/lib/nokogiri/css/parser_extras.rb +91 -0
  85. data/lib/nokogiri/css/syntax_error.rb +7 -0
  86. data/lib/nokogiri/css/tokenizer.rb +152 -0
  87. data/lib/nokogiri/css/tokenizer.rex +55 -0
  88. data/lib/nokogiri/css/xpath_visitor.rb +171 -0
  89. data/lib/nokogiri/decorators/slop.rb +35 -0
  90. data/lib/nokogiri/html.rb +36 -0
  91. data/lib/nokogiri/html/builder.rb +35 -0
  92. data/lib/nokogiri/html/document.rb +213 -0
  93. data/lib/nokogiri/html/document_fragment.rb +41 -0
  94. data/lib/nokogiri/html/element_description.rb +23 -0
  95. data/lib/nokogiri/html/element_description_defaults.rb +671 -0
  96. data/lib/nokogiri/html/entity_lookup.rb +13 -0
  97. data/lib/nokogiri/html/sax/parser.rb +52 -0
  98. data/lib/nokogiri/html/sax/parser_context.rb +16 -0
  99. data/lib/nokogiri/syntax_error.rb +4 -0
  100. data/lib/nokogiri/version.rb +88 -0
  101. data/lib/nokogiri/xml.rb +67 -0
  102. data/lib/nokogiri/xml/attr.rb +14 -0
  103. data/lib/nokogiri/xml/attribute_decl.rb +18 -0
  104. data/lib/nokogiri/xml/builder.rb +426 -0
  105. data/lib/nokogiri/xml/cdata.rb +11 -0
  106. data/lib/nokogiri/xml/character_data.rb +7 -0
  107. data/lib/nokogiri/xml/document.rb +234 -0
  108. data/lib/nokogiri/xml/document_fragment.rb +98 -0
  109. data/lib/nokogiri/xml/dtd.rb +22 -0
  110. data/lib/nokogiri/xml/element_content.rb +36 -0
  111. data/lib/nokogiri/xml/element_decl.rb +13 -0
  112. data/lib/nokogiri/xml/entity_decl.rb +19 -0
  113. data/lib/nokogiri/xml/namespace.rb +13 -0
  114. data/lib/nokogiri/xml/node.rb +915 -0
  115. data/lib/nokogiri/xml/node/save_options.rb +61 -0
  116. data/lib/nokogiri/xml/node_set.rb +357 -0
  117. data/lib/nokogiri/xml/notation.rb +6 -0
  118. data/lib/nokogiri/xml/parse_options.rb +93 -0
  119. data/lib/nokogiri/xml/pp.rb +2 -0
  120. data/lib/nokogiri/xml/pp/character_data.rb +18 -0
  121. data/lib/nokogiri/xml/pp/node.rb +56 -0
  122. data/lib/nokogiri/xml/processing_instruction.rb +8 -0
  123. data/lib/nokogiri/xml/reader.rb +112 -0
  124. data/lib/nokogiri/xml/relax_ng.rb +32 -0
  125. data/lib/nokogiri/xml/sax.rb +4 -0
  126. data/lib/nokogiri/xml/sax/document.rb +164 -0
  127. data/lib/nokogiri/xml/sax/parser.rb +115 -0
  128. data/lib/nokogiri/xml/sax/parser_context.rb +16 -0
  129. data/lib/nokogiri/xml/sax/push_parser.rb +60 -0
  130. data/lib/nokogiri/xml/schema.rb +63 -0
  131. data/lib/nokogiri/xml/syntax_error.rb +47 -0
  132. data/lib/nokogiri/xml/text.rb +9 -0
  133. data/lib/nokogiri/xml/xpath.rb +10 -0
  134. data/lib/nokogiri/xml/xpath/syntax_error.rb +11 -0
  135. data/lib/nokogiri/xml/xpath_context.rb +16 -0
  136. data/lib/nokogiri/xslt.rb +52 -0
  137. data/lib/nokogiri/xslt/stylesheet.rb +25 -0
  138. data/lib/xsd/xmlparser/nokogiri.rb +90 -0
  139. data/nokogiri_help_responses.md +40 -0
  140. data/tasks/cross_compile.rb +152 -0
  141. data/tasks/nokogiri.org.rb +18 -0
  142. data/tasks/test.rb +94 -0
  143. data/test/css/test_nthiness.rb +159 -0
  144. data/test/css/test_parser.rb +303 -0
  145. data/test/css/test_tokenizer.rb +198 -0
  146. data/test/css/test_xpath_visitor.rb +85 -0
  147. data/test/decorators/test_slop.rb +16 -0
  148. data/test/files/2ch.html +108 -0
  149. data/test/files/address_book.rlx +12 -0
  150. data/test/files/address_book.xml +10 -0
  151. data/test/files/bar/bar.xsd +4 -0
  152. data/test/files/dont_hurt_em_why.xml +422 -0
  153. data/test/files/encoding.html +82 -0
  154. data/test/files/encoding.xhtml +84 -0
  155. data/test/files/exslt.xml +8 -0
  156. data/test/files/exslt.xslt +35 -0
  157. data/test/files/foo/foo.xsd +4 -0
  158. data/test/files/metacharset.html +10 -0
  159. data/test/files/noencoding.html +47 -0
  160. data/test/files/po.xml +32 -0
  161. data/test/files/po.xsd +66 -0
  162. data/test/files/shift_jis.html +10 -0
  163. data/test/files/shift_jis.xml +5 -0
  164. data/test/files/snuggles.xml +3 -0
  165. data/test/files/staff.dtd +10 -0
  166. data/test/files/staff.xml +59 -0
  167. data/test/files/staff.xslt +32 -0
  168. data/test/files/tlm.html +850 -0
  169. data/test/files/valid_bar.xml +2 -0
  170. data/test/helper.rb +173 -0
  171. data/test/html/sax/test_parser.rb +139 -0
  172. data/test/html/sax/test_parser_context.rb +48 -0
  173. data/test/html/test_builder.rb +165 -0
  174. data/test/html/test_document.rb +472 -0
  175. data/test/html/test_document_encoding.rb +138 -0
  176. data/test/html/test_document_fragment.rb +255 -0
  177. data/test/html/test_element_description.rb +101 -0
  178. data/test/html/test_named_characters.rb +14 -0
  179. data/test/html/test_node.rb +193 -0
  180. data/test/html/test_node_encoding.rb +27 -0
  181. data/test/test_convert_xpath.rb +135 -0
  182. data/test/test_css_cache.rb +45 -0
  183. data/test/test_encoding_handler.rb +46 -0
  184. data/test/test_memory_leak.rb +72 -0
  185. data/test/test_nokogiri.rb +133 -0
  186. data/test/test_reader.rb +425 -0
  187. data/test/test_soap4r_sax.rb +52 -0
  188. data/test/test_xslt_transforms.rb +193 -0
  189. data/test/xml/node/test_save_options.rb +28 -0
  190. data/test/xml/node/test_subclass.rb +44 -0
  191. data/test/xml/sax/test_parser.rb +338 -0
  192. data/test/xml/sax/test_parser_context.rb +113 -0
  193. data/test/xml/sax/test_push_parser.rb +156 -0
  194. data/test/xml/test_attr.rb +65 -0
  195. data/test/xml/test_attribute_decl.rb +86 -0
  196. data/test/xml/test_builder.rb +227 -0
  197. data/test/xml/test_cdata.rb +50 -0
  198. data/test/xml/test_comment.rb +29 -0
  199. data/test/xml/test_document.rb +697 -0
  200. data/test/xml/test_document_encoding.rb +26 -0
  201. data/test/xml/test_document_fragment.rb +192 -0
  202. data/test/xml/test_dtd.rb +107 -0
  203. data/test/xml/test_dtd_encoding.rb +33 -0
  204. data/test/xml/test_element_content.rb +56 -0
  205. data/test/xml/test_element_decl.rb +73 -0
  206. data/test/xml/test_entity_decl.rb +122 -0
  207. data/test/xml/test_entity_reference.rb +21 -0
  208. data/test/xml/test_namespace.rb +70 -0
  209. data/test/xml/test_node.rb +917 -0
  210. data/test/xml/test_node_attributes.rb +34 -0
  211. data/test/xml/test_node_encoding.rb +107 -0
  212. data/test/xml/test_node_reparenting.rb +334 -0
  213. data/test/xml/test_node_set.rb +742 -0
  214. data/test/xml/test_parse_options.rb +52 -0
  215. data/test/xml/test_processing_instruction.rb +30 -0
  216. data/test/xml/test_reader_encoding.rb +126 -0
  217. data/test/xml/test_relax_ng.rb +60 -0
  218. data/test/xml/test_schema.rb +94 -0
  219. data/test/xml/test_syntax_error.rb +12 -0
  220. data/test/xml/test_text.rb +47 -0
  221. data/test/xml/test_unparented_node.rb +381 -0
  222. data/test/xml/test_xpath.rb +237 -0
  223. data/test/xslt/test_custom_functions.rb +94 -0
  224. data/test/xslt/test_exception_handling.rb +37 -0
  225. metadata +548 -0
@@ -0,0 +1,122 @@
1
+ require "helper"
2
+
3
+ module Nokogiri
4
+ module XML
5
+ class TestEntityDecl < Nokogiri::TestCase
6
+ def setup
7
+ super
8
+ @xml = Nokogiri::XML(<<-eoxml)
9
+ <?xml version="1.0"?><?TEST-STYLE PIDATA?>
10
+ <!DOCTYPE staff SYSTEM "staff.dtd" [
11
+ <!ENTITY ent1 "es">
12
+ <!ENTITY nocontent "">
13
+ ]>
14
+ <root />
15
+ eoxml
16
+
17
+ @entities = @xml.internal_subset.children
18
+ @entity_decl = @entities.first
19
+ end
20
+
21
+ def test_constants
22
+ assert_equal 1, EntityDecl::INTERNAL_GENERAL
23
+ assert_equal 2, EntityDecl::EXTERNAL_GENERAL_PARSED
24
+ assert_equal 3, EntityDecl::EXTERNAL_GENERAL_UNPARSED
25
+ assert_equal 4, EntityDecl::INTERNAL_PARAMETER
26
+ assert_equal 5, EntityDecl::EXTERNAL_PARAMETER
27
+ assert_equal 6, EntityDecl::INTERNAL_PREDEFINED
28
+ end
29
+
30
+ def test_create_typed_entity
31
+ entity = @xml.create_entity(
32
+ 'foo', EntityDecl::INTERNAL_GENERAL, nil, nil, nil
33
+ )
34
+ assert_equal EntityDecl::INTERNAL_GENERAL, entity.entity_type
35
+ assert_equal 'foo', entity.name
36
+ end
37
+
38
+ def test_new
39
+ entity = Nokogiri::XML::EntityDecl.new(
40
+ 'foo', @xml, EntityDecl::INTERNAL_GENERAL, nil, nil, nil
41
+ )
42
+ assert_equal EntityDecl::INTERNAL_GENERAL, entity.entity_type
43
+ assert_equal 'foo', entity.name
44
+ end
45
+
46
+ def test_create_default_args
47
+ entity = @xml.create_entity('foo')
48
+ assert_equal EntityDecl::INTERNAL_GENERAL, entity.entity_type
49
+ assert_equal 'foo', entity.name
50
+ end
51
+
52
+ def test_external_id
53
+ assert_nil @entity_decl.external_id
54
+ end
55
+
56
+ def test_system_id
57
+ assert_nil @entity_decl.system_id
58
+ end
59
+
60
+ def test_entity_type
61
+ assert_equal 1, @entity_decl.entity_type
62
+ end
63
+
64
+ def test_original_content
65
+ assert_equal "es", @entity_decl.original_content
66
+ if Nokogiri.jruby?
67
+ assert_nil @entities[1].original_content
68
+ else
69
+ assert_equal "", @entities[1].original_content
70
+ end
71
+ end
72
+
73
+ def test_content
74
+ assert_equal "es", @entity_decl.content
75
+ if Nokogiri.jruby?
76
+ assert_nil @entities[1].content
77
+ else
78
+ assert_equal "", @entities[1].content
79
+ end
80
+ end
81
+
82
+ def test_type
83
+ assert_equal 17, @entities.first.type
84
+ end
85
+
86
+ def test_class
87
+ assert_instance_of Nokogiri::XML::EntityDecl, @entities.first
88
+ end
89
+
90
+ def test_attributes
91
+ assert_raise NoMethodError do
92
+ @entity_decl.attributes
93
+ end
94
+ end
95
+
96
+ def test_namespace
97
+ assert_raise NoMethodError do
98
+ @entity_decl.namespace
99
+ end
100
+ end
101
+
102
+ def test_namespace_definitions
103
+ assert_raise NoMethodError do
104
+ @entity_decl.namespace_definitions
105
+ end
106
+ end
107
+
108
+ def test_line
109
+ assert_raise NoMethodError do
110
+ @entity_decl.line
111
+ end
112
+ end
113
+
114
+ def test_inspect
115
+ assert_equal(
116
+ "#<#{@entity_decl.class.name}:#{sprintf("0x%x", @entity_decl.object_id)} #{@entity_decl.to_s.inspect}>",
117
+ @entity_decl.inspect
118
+ )
119
+ end
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,21 @@
1
+ require "helper"
2
+
3
+ module Nokogiri
4
+ module XML
5
+ class TestEntityReference < Nokogiri::TestCase
6
+ def setup
7
+ super
8
+ @xml = Nokogiri::XML(File.open(XML_FILE), XML_FILE)
9
+ end
10
+
11
+ def test_new
12
+ assert ref = EntityReference.new(@xml, 'ent4')
13
+ assert_instance_of EntityReference, ref
14
+ end
15
+
16
+ def test_many_references
17
+ 100.times { EntityReference.new(@xml, 'foo') }
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,70 @@
1
+ require "helper"
2
+
3
+ module Nokogiri
4
+ module XML
5
+ class TestNamespace < Nokogiri::TestCase
6
+ def setup
7
+ super
8
+ @xml = Nokogiri::XML <<-eoxml
9
+ <root xmlns="http://tenderlovemaking.com/" xmlns:foo="bar">
10
+ <awesome/>
11
+ </root>
12
+ eoxml
13
+ end
14
+
15
+ if Nokogiri.uses_libxml?
16
+ def test_namespace_is_in_node_cache
17
+ node = @xml.root.namespace
18
+ assert @xml.instance_variable_get(:@node_cache).include?(node)
19
+ end
20
+ end
21
+
22
+ def test_built_nodes_keep_namespace_decls
23
+ doc = Document.new
24
+ e = Node.new 'element', doc
25
+ c = Node.new 'child', doc
26
+ c.default_namespace = 'woop:de:doo'
27
+
28
+ assert c.namespace, 'has a namespace'
29
+ e.add_child c
30
+ assert c.namespace, 'has a namespace'
31
+
32
+ doc.add_child e
33
+ assert c.namespace, 'has a namespace'
34
+ end
35
+
36
+ def test_inspect
37
+ ns = @xml.root.namespace
38
+ assert_equal "#<#{ns.class.name}:#{sprintf("0x%x", ns.object_id)} href=#{ns.href.inspect}>", ns.inspect
39
+ end
40
+
41
+ def test_namespace_node_prefix
42
+ namespaces = @xml.root.namespace_definitions
43
+ assert_equal [nil, 'foo'], namespaces.map { |x| x.prefix }
44
+ end
45
+
46
+ def test_namespace_node_href
47
+ namespaces = @xml.root.namespace_definitions
48
+ assert_equal [
49
+ 'http://tenderlovemaking.com/',
50
+ 'bar'
51
+ ], namespaces.map { |x| x.href }
52
+ end
53
+
54
+ def test_equality
55
+ namespaces = @xml.root.namespace_definitions
56
+ assert_equal namespaces, @xml.root.namespace_definitions
57
+ end
58
+
59
+ def test_add_definition
60
+ @xml.root.add_namespace_definition('baz', 'bar')
61
+ assert_equal 3, @xml.root.namespace_definitions.length
62
+ end
63
+
64
+ def test_add_definition_return
65
+ ns = @xml.root.add_namespace_definition('baz', 'bar')
66
+ assert_equal 'baz', ns.prefix
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,917 @@
1
+ require "helper"
2
+
3
+ require 'stringio'
4
+
5
+ module Nokogiri
6
+ module XML
7
+ class TestNode < Nokogiri::TestCase
8
+ def setup
9
+ super
10
+ @xml = Nokogiri::XML(File.read(XML_FILE), XML_FILE)
11
+ end
12
+
13
+ def test_first_element_child
14
+ node = @xml.root.first_element_child
15
+ assert_equal 'employee', node.name
16
+ assert node.element?, 'node is an element'
17
+ end
18
+
19
+ def test_element_children
20
+ nodes = @xml.root.element_children
21
+ assert_equal @xml.root.first_element_child, nodes.first
22
+ assert nodes.all? { |node| node.element? }, 'all nodes are elements'
23
+ end
24
+
25
+ def test_last_element_child
26
+ nodes = @xml.root.element_children
27
+ assert_equal nodes.last, @xml.root.element_children.last
28
+ end
29
+
30
+ def test_bad_xpath
31
+ bad_xpath = '//foo['
32
+
33
+ begin
34
+ @xml.xpath(bad_xpath)
35
+ rescue Nokogiri::XML::XPath::SyntaxError => e
36
+ assert_match(bad_xpath, e.to_s)
37
+ end
38
+ end
39
+
40
+ def test_namespace_type_error
41
+ assert_raises(TypeError) do
42
+ @xml.root.namespace = Object.new
43
+ end
44
+ end
45
+
46
+ def test_remove_namespace
47
+ @xml = Nokogiri::XML('<r xmlns="v"><s /></r>')
48
+ tag = @xml.at('s')
49
+ assert tag.namespace
50
+ tag.namespace = nil
51
+ assert_nil tag.namespace
52
+ end
53
+
54
+ def test_parse_needs_doc
55
+ list = @xml.root.parse('fooooooo <hello />')
56
+ assert_equal 1, list.css('hello').length
57
+ end
58
+
59
+ def test_parse
60
+ list = @xml.root.parse('fooooooo <hello />')
61
+ assert_equal 2, list.length
62
+ end
63
+
64
+ def test_parse_with_block
65
+ called = false
66
+ list = @xml.root.parse('<hello />') { |cfg|
67
+ called = true
68
+ assert_instance_of Nokogiri::XML::ParseOptions, cfg
69
+ }
70
+ assert called, 'config block called'
71
+ assert_equal 1, list.length
72
+ end
73
+
74
+ def test_parse_with_io
75
+ list = @xml.root.parse(StringIO.new('<hello />'))
76
+ assert_equal 1, list.length
77
+ assert_equal 'hello', list.first.name
78
+ end
79
+
80
+ def test_parse_with_empty_string
81
+ list = @xml.root.parse('')
82
+ assert_equal 0, list.length
83
+ end
84
+
85
+ def test_parse_config_option
86
+ node = @xml.root
87
+ options = nil
88
+ node.parse("<item></item>") do |config|
89
+ options = config
90
+ end
91
+ assert_equal Nokogiri::XML::ParseOptions::DEFAULT_XML, options.to_i
92
+ end
93
+
94
+ # descriptive, not prescriptive.
95
+ def test_z_parse_invalid_html_markup_results_in_empty_nodeset # SEGV in spacePop
96
+ doc = Nokogiri::HTML("<html></html>")
97
+ nodeset = doc.root.parse "<div><div>a</div><snippet>b</snippet></div>"
98
+ assert_equal 1, doc.errors.length # "Tag snippet invalid"
99
+ assert_equal 1, nodeset.length
100
+ end
101
+
102
+ def test_node_context_parsing_of_malformed_html_fragment_with_recover_is_corrected
103
+ doc = HTML.parse "<html><body><div></div></body></html>"
104
+ context_node = doc.at_css "div"
105
+ nodeset = context_node.parse("<div </div>") do |options|
106
+ options.recover
107
+ end
108
+ assert_equal "<div></div>", nodeset.to_s
109
+ assert_equal 1, doc.errors.length
110
+ assert_equal 1, nodeset.length
111
+ end
112
+
113
+ def test_node_context_parsing_of_malformed_html_fragment_without_recover_is_not_corrected
114
+ doc = HTML.parse "<html><body><div></div></body></html>"
115
+ context_node = doc.at_css "div"
116
+ nodeset = context_node.parse("<div </div>") do |options|
117
+ options.strict
118
+ end
119
+ assert_equal 1, doc.errors.length
120
+ assert_equal 0, nodeset.length
121
+ end
122
+
123
+ def test_parse_error_list
124
+ error_count = @xml.errors.length
125
+ @xml.root.parse('<hello>')
126
+ assert(error_count < @xml.errors.length, "errors should have increased")
127
+ end
128
+
129
+ def test_subclass_dup
130
+ subclass = Class.new(Nokogiri::XML::Node)
131
+ node = subclass.new('foo', @xml).dup
132
+ assert_instance_of subclass, node
133
+ end
134
+
135
+ def test_gt_string_arg
136
+ node = @xml.at('employee')
137
+ nodes = (node > 'name')
138
+ assert_equal 1, nodes.length
139
+ assert_equal node, nodes.first.parent
140
+ end
141
+
142
+ def test_next_element_when_next_sibling_is_element_should_return_next_sibling
143
+ doc = Nokogiri::XML "<root><foo /><quux /></root>"
144
+ node = doc.at_css("foo")
145
+ next_element = node.next_element
146
+ assert next_element.element?
147
+ assert_equal doc.at_css("quux"), next_element
148
+ end
149
+
150
+ def test_next_element_when_there_is_no_next_sibling_should_return_nil
151
+ doc = Nokogiri::XML "<root><foo /><quux /></root>"
152
+ assert_nil doc.at_css("quux").next_element
153
+ end
154
+
155
+ def test_next_element_when_next_sibling_is_not_an_element_should_return_closest_next_element_sibling
156
+ doc = Nokogiri::XML "<root><foo />bar<quux /></root>"
157
+ node = doc.at_css("foo")
158
+ next_element = node.next_element
159
+ assert next_element.element?
160
+ assert_equal doc.at_css("quux"), next_element
161
+ end
162
+
163
+ def test_next_element_when_next_sibling_is_not_an_element_and_no_following_element_should_return_nil
164
+ doc = Nokogiri::XML "<root><foo />bar</root>"
165
+ node = doc.at_css("foo")
166
+ next_element = node.next_element
167
+ assert_nil next_element
168
+ end
169
+
170
+ def test_previous_element_when_previous_sibling_is_element_should_return_previous_sibling
171
+ doc = Nokogiri::XML "<root><foo /><quux /></root>"
172
+ node = doc.at_css("quux")
173
+ previous_element = node.previous_element
174
+ assert previous_element.element?
175
+ assert_equal doc.at_css("foo"), previous_element
176
+ end
177
+
178
+ def test_previous_element_when_there_is_no_previous_sibling_should_return_nil
179
+ doc = Nokogiri::XML "<root><foo /><quux /></root>"
180
+ assert_nil doc.at_css("foo").previous_element
181
+ end
182
+
183
+ def test_previous_element_when_previous_sibling_is_not_an_element_should_return_closest_previous_element_sibling
184
+ doc = Nokogiri::XML "<root><foo />bar<quux /></root>"
185
+ node = doc.at_css("quux")
186
+ previous_element = node.previous_element
187
+ assert previous_element.element?
188
+ assert_equal doc.at_css("foo"), previous_element
189
+ end
190
+
191
+ def test_previous_element_when_previous_sibling_is_not_an_element_and_no_following_element_should_return_nil
192
+ doc = Nokogiri::XML "<root>foo<bar /></root>"
193
+ node = doc.at_css("bar")
194
+ previous_element = node.previous_element
195
+ assert_nil previous_element
196
+ end
197
+
198
+ def test_element?
199
+ assert @xml.root.element?, 'is an element'
200
+ end
201
+
202
+ def test_slash_search
203
+ assert_equal 'EMP0001', (@xml/:staff/:employee/:employeeId).first.text
204
+ end
205
+
206
+ def test_append_with_document
207
+ assert_raises(ArgumentError) do
208
+ @xml.root << Nokogiri::XML::Document.new
209
+ end
210
+ end
211
+
212
+ def test_inspect_ns
213
+ xml = Nokogiri::XML(<<-eoxml) { |c| c.noblanks }
214
+ <root xmlns="http://tenderlovemaking.com/" xmlns:foo="bar">
215
+ <awesome/>
216
+ </root>
217
+ eoxml
218
+ ins = xml.inspect
219
+
220
+ xml.traverse do |node|
221
+ assert_match node.class.name, ins
222
+ if node.respond_to? :attributes
223
+ node.attributes.each do |k,v|
224
+ assert_match k, ins
225
+ assert_match v, ins
226
+ end
227
+ end
228
+
229
+ if node.respond_to?(:namespace) && node.namespace
230
+ assert_match node.namespace.class.name, ins
231
+ assert_match node.namespace.href, ins
232
+ end
233
+ end
234
+ end
235
+
236
+ def test_namespace_definitions_when_some_exist
237
+ xml = Nokogiri::XML <<-eoxml
238
+ <root xmlns="http://tenderlovemaking.com/" xmlns:foo="bar">
239
+ <awesome/>
240
+ </root>
241
+ eoxml
242
+ namespace_definitions = xml.root.namespace_definitions
243
+ assert_equal 2, namespace_definitions.length
244
+ end
245
+
246
+ def test_namespace_definitions_when_no_exist
247
+ xml = Nokogiri::XML <<-eoxml
248
+ <root xmlns="http://tenderlovemaking.com/" xmlns:foo="bar">
249
+ <awesome/>
250
+ </root>
251
+ eoxml
252
+ namespace_definitions = xml.at_xpath('//xmlns:awesome').namespace_definitions
253
+ assert_equal 0, namespace_definitions.length
254
+ end
255
+
256
+ def test_namespace_goes_to_children
257
+ fruits = Nokogiri::XML(<<-eoxml)
258
+ <Fruit xmlns='www.fruits.org'>
259
+ </Fruit>
260
+ eoxml
261
+ apple = Nokogiri::XML::Node.new('Apple', fruits)
262
+ orange = Nokogiri::XML::Node.new('Orange', fruits)
263
+ apple << orange
264
+ fruits.root << apple
265
+ assert fruits.at('//fruit:Orange',{'fruit'=>'www.fruits.org'})
266
+ assert fruits.at('//fruit:Apple',{'fruit'=>'www.fruits.org'})
267
+ end
268
+
269
+ def test_description
270
+ assert_nil @xml.at('employee').description
271
+ end
272
+
273
+ def test_spaceship
274
+ nodes = @xml.xpath('//employee')
275
+ assert_equal(-1, (nodes.first <=> nodes.last))
276
+ list = [nodes.first, nodes.last].sort
277
+ assert_equal nodes.first, list.first
278
+ assert_equal nodes.last, list.last
279
+ end
280
+
281
+ def test_incorrect_spaceship
282
+ nodes = @xml.xpath('//employee')
283
+ assert_nil(nodes.first <=> 'asdf')
284
+ end
285
+
286
+ def test_document_compare
287
+ nodes = @xml.xpath('//employee')
288
+ assert_equal(-1, (nodes.first <=> @xml))
289
+ end
290
+
291
+ def test_different_document_compare
292
+ nodes = @xml.xpath('//employee')
293
+ doc = Nokogiri::XML('<a><b/></a>')
294
+ b = doc.at('b')
295
+ assert_nil(nodes.first <=> b)
296
+ end
297
+
298
+ def test_duplicate_node_removes_namespace
299
+ fruits = Nokogiri::XML(<<-eoxml)
300
+ <Fruit xmlns='www.fruits.org'>
301
+ <Apple></Apple>
302
+ </Fruit>
303
+ eoxml
304
+ apple = fruits.root.xpath('fruit:Apple', {'fruit'=>'www.fruits.org'})[0]
305
+ new_apple = apple.dup
306
+ fruits.root << new_apple
307
+ assert_equal 2, fruits.xpath('//xmlns:Apple').length
308
+ assert_equal 1, fruits.to_xml.scan('www.fruits.org').length
309
+ end
310
+
311
+ [:clone, :dup].each do |symbol|
312
+ define_method "test_#{symbol}" do
313
+ node = @xml.at('//employee')
314
+ other = node.send(symbol)
315
+ assert_equal "employee", other.name
316
+ assert_nil other.parent
317
+ end
318
+ end
319
+
320
+ def test_fragment_creates_elements
321
+ apple = @xml.fragment('<Apple/>')
322
+ apple.children.each do |child|
323
+ assert_equal Nokogiri::XML::Node::ELEMENT_NODE, child.type
324
+ assert_instance_of Nokogiri::XML::Element, child
325
+ end
326
+ end
327
+
328
+ def test_node_added_to_root_should_get_namespace
329
+ fruits = Nokogiri::XML(<<-eoxml)
330
+ <Fruit xmlns='http://www.fruits.org'>
331
+ </Fruit>
332
+ eoxml
333
+ apple = fruits.fragment('<Apple/>')
334
+ fruits.root << apple
335
+ assert_equal 1, fruits.xpath('//xmlns:Apple').length
336
+ end
337
+
338
+ def test_new_node_can_have_ancestors
339
+ xml = Nokogiri::XML('<root>text</root>')
340
+ item = Nokogiri::XML::Element.new('item', xml)
341
+ assert_equal 0, item.ancestors.length
342
+ end
343
+
344
+ def test_children
345
+ doc = Nokogiri::XML(<<-eoxml)
346
+ <root>#{'<a/>' * 9 }</root>
347
+ eoxml
348
+ assert_equal 9, doc.root.children.length
349
+ assert_equal 9, doc.root.children.to_a.length
350
+
351
+ doc = Nokogiri::XML(<<-eoxml)
352
+ <root>#{'<a/>' * 15 }</root>
353
+ eoxml
354
+ assert_equal 15, doc.root.children.length
355
+ assert_equal 15, doc.root.children.to_a.length
356
+ end
357
+
358
+ def test_add_namespace
359
+ node = @xml.at('address')
360
+ node.add_namespace('foo', 'http://tenderlovemaking.com')
361
+ assert_equal 'http://tenderlovemaking.com', node.namespaces['xmlns:foo']
362
+ end
363
+
364
+ def test_add_namespace_twice
365
+ node = @xml.at('address')
366
+ ns = node.add_namespace('foo', 'http://tenderlovemaking.com')
367
+ ns2 = node.add_namespace('foo', 'http://tenderlovemaking.com')
368
+ assert_equal ns, ns2
369
+ end
370
+
371
+ def test_add_default_ns
372
+ node = @xml.at('address')
373
+ node.add_namespace(nil, 'http://tenderlovemaking.com')
374
+ assert_equal 'http://tenderlovemaking.com', node.namespaces['xmlns']
375
+ end
376
+
377
+ def test_add_multiple_namespaces
378
+ node = @xml.at('address')
379
+
380
+ node.add_namespace(nil, 'http://tenderlovemaking.com')
381
+ assert_equal 'http://tenderlovemaking.com', node.namespaces['xmlns']
382
+
383
+ node.add_namespace('foo', 'http://tenderlovemaking.com')
384
+ assert_equal 'http://tenderlovemaking.com', node.namespaces['xmlns:foo']
385
+ end
386
+
387
+ def test_default_namespace=
388
+ node = @xml.at('address')
389
+ node.default_namespace = 'http://tenderlovemaking.com'
390
+ assert_equal 'http://tenderlovemaking.com', node.namespaces['xmlns']
391
+ end
392
+
393
+ def test_namespace=
394
+ node = @xml.at('address')
395
+ assert_nil node.namespace
396
+ definition = node.add_namespace_definition 'bar', 'http://tlm.com/'
397
+
398
+ node.namespace = definition
399
+
400
+ assert_equal definition, node.namespace
401
+
402
+ assert_equal node, @xml.at('//foo:address', {
403
+ 'foo' => 'http://tlm.com/'
404
+ })
405
+ end
406
+
407
+ def test_add_namespace_with_nil_associates_node
408
+ node = @xml.at('address')
409
+ assert_nil node.namespace
410
+ definition = node.add_namespace_definition nil, 'http://tlm.com/'
411
+ assert_equal definition, node.namespace
412
+ end
413
+
414
+ def test_add_namespace_does_not_associate_node
415
+ node = @xml.at('address')
416
+ assert_nil node.namespace
417
+ assert node.add_namespace_definition 'foo', 'http://tlm.com/'
418
+ assert_nil node.namespace
419
+ end
420
+
421
+ def test_set_namespace_from_different_doc
422
+ node = @xml.at('address')
423
+ doc = Nokogiri::XML(File.read(XML_FILE), XML_FILE)
424
+ decl = doc.root.add_namespace_definition 'foo', 'bar'
425
+
426
+ assert_raises(ArgumentError) do
427
+ node.namespace = decl
428
+ end
429
+ end
430
+
431
+ def test_set_namespace_must_only_take_a_namespace
432
+ node = @xml.at('address')
433
+ assert_raises(TypeError) do
434
+ node.namespace = node
435
+ end
436
+ end
437
+
438
+ def test_at
439
+ node = @xml.at('address')
440
+ assert_equal node, @xml.xpath('//address').first
441
+ end
442
+
443
+ def test_at_xpath
444
+ node = @xml.at_xpath('//address')
445
+ nodes = @xml.xpath('//address')
446
+ assert_equal 5, nodes.size
447
+ assert_equal node, nodes.first
448
+ end
449
+
450
+ def test_at_css
451
+ node = @xml.at_css('address')
452
+ nodes = @xml.css('address')
453
+ assert_equal 5, nodes.size
454
+ assert_equal node, nodes.first
455
+ end
456
+
457
+ def test_percent
458
+ node = @xml % ('address')
459
+ assert_equal node, @xml.xpath('//address').first
460
+ end
461
+
462
+ def test_accept
463
+ visitor = Class.new {
464
+ attr_accessor :visited
465
+ def accept target
466
+ target.accept(self)
467
+ end
468
+
469
+ def visit node
470
+ node.children.each { |c| c.accept(self) }
471
+ @visited = true
472
+ end
473
+ }.new
474
+ visitor.accept(@xml.root)
475
+ assert visitor.visited
476
+ end
477
+
478
+ def test_write_to
479
+ io = StringIO.new
480
+ @xml.write_to io
481
+ io.rewind
482
+ assert_equal @xml.to_xml, io.read
483
+ end
484
+
485
+ def test_attribute_with_symbol
486
+ assert_equal 'Yes', @xml.css('address').first[:domestic]
487
+ end
488
+
489
+ def test_non_existent_attribute_should_return_nil
490
+ node = @xml.root.first_element_child
491
+ assert_nil node.attribute('type')
492
+ end
493
+
494
+ def test_write_to_with_block
495
+ called = false
496
+ io = StringIO.new
497
+ conf = nil
498
+ @xml.write_to io do |config|
499
+ called = true
500
+ conf = config
501
+ config.format.as_html.no_empty_tags
502
+ end
503
+ io.rewind
504
+ assert called
505
+ string = io.read
506
+ assert_equal @xml.serialize(nil, conf.options), string
507
+ assert_equal @xml.serialize(nil, conf), string
508
+ end
509
+
510
+ %w{ xml html xhtml }.each do |type|
511
+ define_method(:"test_write_#{type}_to") do
512
+ io = StringIO.new
513
+ assert @xml.send(:"write_#{type}_to", io)
514
+ io.rewind
515
+ assert_match @xml.send(:"to_#{type}"), io.read
516
+ end
517
+ end
518
+
519
+ def test_serialize_with_block
520
+ called = false
521
+ conf = nil
522
+ string = @xml.serialize do |config|
523
+ called = true
524
+ conf = config
525
+ config.format.as_html.no_empty_tags
526
+ end
527
+ assert called
528
+ assert_equal @xml.serialize(nil, conf.options), string
529
+ assert_equal @xml.serialize(nil, conf), string
530
+ end
531
+
532
+ def test_hold_refence_to_subnode
533
+ doc = Nokogiri::XML(<<-eoxml)
534
+ <root>
535
+ <a>
536
+ <b />
537
+ </a>
538
+ </root>
539
+ eoxml
540
+ assert node_a = doc.css('a').first
541
+ assert node_b = node_a.css('b').first
542
+ node_a.unlink
543
+ assert_equal 'b', node_b.name
544
+ end
545
+
546
+ def test_values
547
+ assert_equal %w{ Yes Yes }, @xml.xpath('//address')[1].values
548
+ end
549
+
550
+ def test_keys
551
+ assert_equal %w{ domestic street }, @xml.xpath('//address')[1].keys
552
+ end
553
+
554
+ def test_each
555
+ attributes = []
556
+ @xml.xpath('//address')[1].each do |key, value|
557
+ attributes << [key, value]
558
+ end
559
+ assert_equal [['domestic', 'Yes'], ['street', 'Yes']], attributes
560
+ end
561
+
562
+ def test_new
563
+ assert node = Nokogiri::XML::Node.new('input', @xml)
564
+ assert_equal 1, node.node_type
565
+ assert_instance_of Nokogiri::XML::Element, node
566
+ end
567
+
568
+ def test_to_str
569
+ name = @xml.xpath('//name').first
570
+ assert_match(/Margaret/, '' + name)
571
+ assert_equal('Margaret Martin', '' + name.children.first)
572
+ end
573
+
574
+ def test_ancestors
575
+ address = @xml.xpath('//address').first
576
+ assert_equal 3, address.ancestors.length
577
+ assert_equal ['employee', 'staff', 'document'],
578
+ address.ancestors.map { |x| x.name }
579
+ end
580
+
581
+ def test_read_only?
582
+ assert entity_decl = @xml.internal_subset.children.find { |x|
583
+ x.type == Node::ENTITY_DECL
584
+ }
585
+ assert entity_decl.read_only?
586
+ end
587
+
588
+ def test_remove_attribute
589
+ address = @xml.xpath('/staff/employee/address').first
590
+ assert_equal 'Yes', address['domestic']
591
+ address.remove_attribute 'domestic'
592
+ assert_nil address['domestic']
593
+ end
594
+
595
+ def test_delete
596
+ address = @xml.xpath('/staff/employee/address').first
597
+ assert_equal 'Yes', address['domestic']
598
+ address.delete 'domestic'
599
+ assert_nil address['domestic']
600
+ end
601
+
602
+ def test_set_content_with_symbol
603
+ node = @xml.at('//name')
604
+ node.content = :foo
605
+ assert_equal 'foo', node.content
606
+ end
607
+
608
+ def test_find_by_css_with_tilde_eql
609
+ xml = Nokogiri::XML.parse(<<-eoxml)
610
+ <root>
611
+ <a>Hello world</a>
612
+ <a class='foo bar'>Bar</a>
613
+ <a class='bar foo'>Bar</a>
614
+ <a class='bar'>Bar</a>
615
+ <a class='baz bar foo'>Bar</a>
616
+ <a class='bazbarfoo'>Awesome</a>
617
+ <a class='bazbar'>Awesome</a>
618
+ </root>
619
+ eoxml
620
+ set = xml.css('a[@class~="bar"]')
621
+ assert_equal 4, set.length
622
+ assert_equal ['Bar'], set.map { |node| node.content }.uniq
623
+ end
624
+
625
+ def test_unlink
626
+ xml = Nokogiri::XML.parse(<<-eoxml)
627
+ <root>
628
+ <a class='foo bar'>Bar</a>
629
+ <a class='bar foo'>Bar</a>
630
+ <a class='bar'>Bar</a>
631
+ <a>Hello world</a>
632
+ <a class='baz bar foo'>Bar</a>
633
+ <a class='bazbarfoo'>Awesome</a>
634
+ <a class='bazbar'>Awesome</a>
635
+ </root>
636
+ eoxml
637
+ node = xml.xpath('//a')[3]
638
+ assert_equal('Hello world', node.text)
639
+ assert_match(/Hello world/, xml.to_s)
640
+ assert node.parent
641
+ assert node.document
642
+ assert node.previous_sibling
643
+ assert node.next_sibling
644
+ node.unlink
645
+ assert !node.parent
646
+ #assert !node.document
647
+ assert !node.previous_sibling
648
+ assert !node.next_sibling
649
+ assert_no_match(/Hello world/, xml.to_s)
650
+ end
651
+
652
+ def test_next_sibling
653
+ assert node = @xml.root
654
+ assert sibling = node.child.next_sibling
655
+ assert_equal('employee', sibling.name)
656
+ end
657
+
658
+ def test_previous_sibling
659
+ assert node = @xml.root
660
+ assert sibling = node.child.next_sibling
661
+ assert_equal('employee', sibling.name)
662
+ assert_equal(sibling.previous_sibling, node.child)
663
+ end
664
+
665
+ def test_name=
666
+ assert node = @xml.root
667
+ node.name = 'awesome'
668
+ assert_equal('awesome', node.name)
669
+ end
670
+
671
+ def test_child
672
+ assert node = @xml.root
673
+ assert child = node.child
674
+ assert_equal('text', child.name)
675
+ end
676
+
677
+ def test_key?
678
+ assert node = @xml.search('//address').first
679
+ assert(!node.key?('asdfasdf'))
680
+ end
681
+
682
+ def test_set_property
683
+ assert node = @xml.search('//address').first
684
+ node['foo'] = 'bar'
685
+ assert_equal('bar', node['foo'])
686
+ end
687
+
688
+ def test_attributes
689
+ assert node = @xml.search('//address').first
690
+ assert_nil(node['asdfasdfasdf'])
691
+ assert_equal('Yes', node['domestic'])
692
+
693
+ assert node = @xml.search('//address')[2]
694
+ attr = node.attributes
695
+ assert_equal 2, attr.size
696
+ assert_equal 'Yes', attr['domestic'].value
697
+ assert_equal 'Yes', attr['domestic'].to_s
698
+ assert_equal 'No', attr['street'].value
699
+ end
700
+
701
+ def test_path
702
+ assert set = @xml.search('//employee')
703
+ assert node = set.first
704
+ assert_equal('/staff/employee[1]', node.path)
705
+ end
706
+
707
+ def test_parent_xpath
708
+ assert set = @xml.search('//employee')
709
+ assert node = set.first
710
+ assert parent_set = node.search('..')
711
+ assert parent_node = parent_set.first
712
+ assert_equal '/staff', parent_node.path
713
+ assert_equal node.parent, parent_node
714
+ end
715
+
716
+ def test_search_by_symbol
717
+ assert set = @xml.search(:employee)
718
+ assert 5, set.length
719
+
720
+ assert node = @xml.at(:employee)
721
+ assert node.text =~ /EMP0001/
722
+ end
723
+
724
+ def test_new_node
725
+ node = Nokogiri::XML::Node.new('form', @xml)
726
+ assert_equal('form', node.name)
727
+ assert(node.document)
728
+ end
729
+
730
+ def test_encode_special_chars
731
+ foo = @xml.css('employee').first.encode_special_chars('&')
732
+ assert_equal '&amp;', foo
733
+ end
734
+
735
+ def test_content_equals
736
+ node = Nokogiri::XML::Node.new('form', @xml)
737
+ assert_equal('', node.content)
738
+
739
+ node.content = 'hello world!'
740
+ assert_equal('hello world!', node.content)
741
+
742
+ node.content = '& <foo> &amp;'
743
+ assert_equal('& <foo> &amp;', node.content)
744
+ assert_equal('<form>&amp; &lt;foo&gt; &amp;amp;</form>', node.to_xml)
745
+
746
+ node.content = "1234 <-> 1234"
747
+ assert_equal "1234 <-> 1234", node.content
748
+ assert_equal "<form>1234 &lt;-&gt; 1234</form>", node.to_xml
749
+ end
750
+
751
+ def test_set_content_should_unlink_existing_content
752
+ node = @xml.at_css("employee")
753
+ children = node.children
754
+ node.content = "hello"
755
+ children.each { |child| assert_nil child.parent }
756
+ end
757
+
758
+ def test_whitespace_nodes
759
+ doc = Nokogiri::XML.parse("<root><b>Foo</b>\n<i>Bar</i> <p>Bazz</p></root>")
760
+ children = doc.at('//root').children.collect{|j| j.to_s}
761
+ assert_equal "\n", children[1]
762
+ assert_equal " ", children[3]
763
+ end
764
+
765
+ def test_node_equality
766
+ doc1 = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
767
+ doc2 = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
768
+
769
+ address1_1 = doc1.xpath('//address').first
770
+ address1_2 = doc1.xpath('//address').first
771
+
772
+ address2 = doc2.xpath('//address').first
773
+
774
+ assert_not_equal address1_1, address2 # two references to very, very similar nodes
775
+ assert_equal address1_1, address1_2 # two references to the exact same node
776
+ end
777
+
778
+ def test_namespace_search_with_xpath_and_hash
779
+ xml = Nokogiri::XML.parse(<<-eoxml)
780
+ <root>
781
+ <car xmlns:part="http://general-motors.com/">
782
+ <part:tire>Michelin Model XGV</part:tire>
783
+ </car>
784
+ <bicycle xmlns:part="http://schwinn.com/">
785
+ <part:tire>I'm a bicycle tire!</part:tire>
786
+ </bicycle>
787
+ </root>
788
+ eoxml
789
+
790
+ tires = xml.xpath('//bike:tire', {'bike' => 'http://schwinn.com/'})
791
+ assert_equal 1, tires.length
792
+ end
793
+
794
+ def test_namespace_search_with_css
795
+ xml = Nokogiri::XML.parse(<<-eoxml)
796
+ <root>
797
+ <car xmlns:part="http://general-motors.com/">
798
+ <part:tire>Michelin Model XGV</part:tire>
799
+ </car>
800
+ <bicycle xmlns:part="http://schwinn.com/">
801
+ <part:tire>I'm a bicycle tire!</part:tire>
802
+ </bicycle>
803
+ </root>
804
+ eoxml
805
+
806
+ tires = xml.css('bike|tire', 'bike' => 'http://schwinn.com/')
807
+ assert_equal 1, tires.length
808
+ end
809
+
810
+ def test_namespaces_should_include_all_namespace_definitions
811
+ xml = Nokogiri::XML.parse(<<-EOF)
812
+ <x xmlns="http://quux.com/" xmlns:a="http://foo.com/" xmlns:b="http://bar.com/">
813
+ <y xmlns:c="http://bazz.com/">
814
+ <z>hello</z>
815
+ <a xmlns:c="http://newc.com/" />
816
+ </y>
817
+ </x>
818
+ EOF
819
+
820
+ namespaces = xml.namespaces # Document#namespace
821
+ assert_equal({"xmlns" => "http://quux.com/",
822
+ "xmlns:a" => "http://foo.com/",
823
+ "xmlns:b" => "http://bar.com/"}, namespaces)
824
+
825
+ namespaces = xml.root.namespaces
826
+ assert_equal({"xmlns" => "http://quux.com/",
827
+ "xmlns:a" => "http://foo.com/",
828
+ "xmlns:b" => "http://bar.com/"}, namespaces)
829
+
830
+ namespaces = xml.at_xpath("//xmlns:y").namespaces
831
+ assert_equal({"xmlns" => "http://quux.com/",
832
+ "xmlns:a" => "http://foo.com/",
833
+ "xmlns:b" => "http://bar.com/",
834
+ "xmlns:c" => "http://bazz.com/"}, namespaces)
835
+
836
+ namespaces = xml.at_xpath("//xmlns:z").namespaces
837
+ assert_equal({"xmlns" => "http://quux.com/",
838
+ "xmlns:a" => "http://foo.com/",
839
+ "xmlns:b" => "http://bar.com/",
840
+ "xmlns:c" => "http://bazz.com/"}, namespaces)
841
+
842
+ namespaces = xml.at_xpath("//xmlns:a").namespaces
843
+ assert_equal({"xmlns" => "http://quux.com/",
844
+ "xmlns:a" => "http://foo.com/",
845
+ "xmlns:b" => "http://bar.com/",
846
+ "xmlns:c" => "http://newc.com/"}, namespaces)
847
+ end
848
+
849
+ def test_namespace
850
+ xml = Nokogiri::XML.parse(<<-EOF)
851
+ <x xmlns:a='http://foo.com/' xmlns:b='http://bar.com/'>
852
+ <y xmlns:c='http://bazz.com/'>
853
+ <a:div>hello a</a:div>
854
+ <b:div>hello b</b:div>
855
+ <c:div>hello c</c:div>
856
+ <div>hello moon</div>
857
+ </y>
858
+ </x>
859
+ EOF
860
+ set = xml.search("//y/*")
861
+ assert_equal "a", set[0].namespace.prefix
862
+ assert_equal "b", set[1].namespace.prefix
863
+ assert_equal "c", set[2].namespace.prefix
864
+ assert_equal nil, set[3].namespace
865
+ end
866
+
867
+ if Nokogiri.uses_libxml?
868
+ def test_namespace_without_an_href_on_html_node
869
+ # because microsoft word's HTML formatting does this. ick.
870
+ xml = Nokogiri::HTML.parse <<-EOF
871
+ <div><o:p>foo</o:p></div>
872
+ EOF
873
+
874
+ assert_not_nil(node = xml.at('p'))
875
+
876
+ assert_equal 1, node.namespaces.keys.size
877
+ assert node.namespaces.has_key?('xmlns:o')
878
+ assert_equal nil, node.namespaces['xmlns:o']
879
+ end
880
+ end
881
+
882
+ def test_line
883
+ xml = Nokogiri::XML(<<-eoxml)
884
+ <root>
885
+ <a>
886
+ Hello world
887
+ </a>
888
+ </root>
889
+ eoxml
890
+
891
+ set = xml.search("//a")
892
+ node = set.first
893
+ assert_equal 2, node.line
894
+ end
895
+
896
+ def test_xpath_results_have_document_and_are_decorated
897
+ x = Module.new do
898
+ def awesome! ; end
899
+ end
900
+ util_decorate(@xml, x)
901
+ node_set = @xml.xpath("//employee")
902
+ assert_equal @xml, node_set.document
903
+ assert node_set.respond_to?(:awesome!)
904
+ end
905
+
906
+ def test_css_results_have_document_and_are_decorated
907
+ x = Module.new do
908
+ def awesome! ; end
909
+ end
910
+ util_decorate(@xml, x)
911
+ node_set = @xml.css("employee")
912
+ assert_equal @xml, node_set.document
913
+ assert node_set.respond_to?(:awesome!)
914
+ end
915
+ end
916
+ end
917
+ end