nokogiri 1.6.2.rc1-x64-mingw32

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

Potentially problematic release.


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

Files changed (263) hide show
  1. checksums.yaml +7 -0
  2. data/.autotest +26 -0
  3. data/.editorconfig +17 -0
  4. data/.gemtest +0 -0
  5. data/.travis.yml +25 -0
  6. data/CHANGELOG.ja.rdoc +857 -0
  7. data/CHANGELOG.rdoc +880 -0
  8. data/C_CODING_STYLE.rdoc +33 -0
  9. data/Gemfile +21 -0
  10. data/Manifest.txt +371 -0
  11. data/README.ja.rdoc +112 -0
  12. data/README.rdoc +180 -0
  13. data/ROADMAP.md +89 -0
  14. data/Rakefile +351 -0
  15. data/STANDARD_RESPONSES.md +47 -0
  16. data/Y_U_NO_GEMSPEC.md +155 -0
  17. data/bin/nokogiri +78 -0
  18. data/build_all +130 -0
  19. data/dependencies.yml +4 -0
  20. data/ext/nokogiri/depend +358 -0
  21. data/ext/nokogiri/extconf.rb +453 -0
  22. data/ext/nokogiri/html_document.c +170 -0
  23. data/ext/nokogiri/html_document.h +10 -0
  24. data/ext/nokogiri/html_element_description.c +279 -0
  25. data/ext/nokogiri/html_element_description.h +10 -0
  26. data/ext/nokogiri/html_entity_lookup.c +32 -0
  27. data/ext/nokogiri/html_entity_lookup.h +8 -0
  28. data/ext/nokogiri/html_sax_parser_context.c +116 -0
  29. data/ext/nokogiri/html_sax_parser_context.h +11 -0
  30. data/ext/nokogiri/html_sax_push_parser.c +87 -0
  31. data/ext/nokogiri/html_sax_push_parser.h +9 -0
  32. data/ext/nokogiri/nokogiri.c +148 -0
  33. data/ext/nokogiri/nokogiri.h +164 -0
  34. data/ext/nokogiri/xml_attr.c +94 -0
  35. data/ext/nokogiri/xml_attr.h +9 -0
  36. data/ext/nokogiri/xml_attribute_decl.c +70 -0
  37. data/ext/nokogiri/xml_attribute_decl.h +9 -0
  38. data/ext/nokogiri/xml_cdata.c +56 -0
  39. data/ext/nokogiri/xml_cdata.h +9 -0
  40. data/ext/nokogiri/xml_comment.c +54 -0
  41. data/ext/nokogiri/xml_comment.h +9 -0
  42. data/ext/nokogiri/xml_document.c +577 -0
  43. data/ext/nokogiri/xml_document.h +23 -0
  44. data/ext/nokogiri/xml_document_fragment.c +48 -0
  45. data/ext/nokogiri/xml_document_fragment.h +10 -0
  46. data/ext/nokogiri/xml_dtd.c +202 -0
  47. data/ext/nokogiri/xml_dtd.h +10 -0
  48. data/ext/nokogiri/xml_element_content.c +123 -0
  49. data/ext/nokogiri/xml_element_content.h +10 -0
  50. data/ext/nokogiri/xml_element_decl.c +69 -0
  51. data/ext/nokogiri/xml_element_decl.h +9 -0
  52. data/ext/nokogiri/xml_encoding_handler.c +79 -0
  53. data/ext/nokogiri/xml_encoding_handler.h +8 -0
  54. data/ext/nokogiri/xml_entity_decl.c +110 -0
  55. data/ext/nokogiri/xml_entity_decl.h +10 -0
  56. data/ext/nokogiri/xml_entity_reference.c +52 -0
  57. data/ext/nokogiri/xml_entity_reference.h +9 -0
  58. data/ext/nokogiri/xml_io.c +56 -0
  59. data/ext/nokogiri/xml_io.h +11 -0
  60. data/ext/nokogiri/xml_libxml2_hacks.c +112 -0
  61. data/ext/nokogiri/xml_libxml2_hacks.h +12 -0
  62. data/ext/nokogiri/xml_namespace.c +78 -0
  63. data/ext/nokogiri/xml_namespace.h +13 -0
  64. data/ext/nokogiri/xml_node.c +1541 -0
  65. data/ext/nokogiri/xml_node.h +13 -0
  66. data/ext/nokogiri/xml_node_set.c +467 -0
  67. data/ext/nokogiri/xml_node_set.h +14 -0
  68. data/ext/nokogiri/xml_processing_instruction.c +56 -0
  69. data/ext/nokogiri/xml_processing_instruction.h +9 -0
  70. data/ext/nokogiri/xml_reader.c +681 -0
  71. data/ext/nokogiri/xml_reader.h +10 -0
  72. data/ext/nokogiri/xml_relax_ng.c +161 -0
  73. data/ext/nokogiri/xml_relax_ng.h +9 -0
  74. data/ext/nokogiri/xml_sax_parser.c +312 -0
  75. data/ext/nokogiri/xml_sax_parser.h +39 -0
  76. data/ext/nokogiri/xml_sax_parser_context.c +262 -0
  77. data/ext/nokogiri/xml_sax_parser_context.h +10 -0
  78. data/ext/nokogiri/xml_sax_push_parser.c +115 -0
  79. data/ext/nokogiri/xml_sax_push_parser.h +9 -0
  80. data/ext/nokogiri/xml_schema.c +205 -0
  81. data/ext/nokogiri/xml_schema.h +9 -0
  82. data/ext/nokogiri/xml_syntax_error.c +63 -0
  83. data/ext/nokogiri/xml_syntax_error.h +13 -0
  84. data/ext/nokogiri/xml_text.c +52 -0
  85. data/ext/nokogiri/xml_text.h +9 -0
  86. data/ext/nokogiri/xml_xpath_context.c +307 -0
  87. data/ext/nokogiri/xml_xpath_context.h +10 -0
  88. data/ext/nokogiri/xslt_stylesheet.c +270 -0
  89. data/ext/nokogiri/xslt_stylesheet.h +14 -0
  90. data/lib/nokogiri.rb +137 -0
  91. data/lib/nokogiri/2.0/nokogiri.so +0 -0
  92. data/lib/nokogiri/2.1/nokogiri.so +0 -0
  93. data/lib/nokogiri/css.rb +27 -0
  94. data/lib/nokogiri/css/node.rb +52 -0
  95. data/lib/nokogiri/css/parser.rb +715 -0
  96. data/lib/nokogiri/css/parser.y +249 -0
  97. data/lib/nokogiri/css/parser_extras.rb +91 -0
  98. data/lib/nokogiri/css/syntax_error.rb +7 -0
  99. data/lib/nokogiri/css/tokenizer.rb +152 -0
  100. data/lib/nokogiri/css/tokenizer.rex +55 -0
  101. data/lib/nokogiri/css/xpath_visitor.rb +219 -0
  102. data/lib/nokogiri/decorators/slop.rb +35 -0
  103. data/lib/nokogiri/html.rb +37 -0
  104. data/lib/nokogiri/html/builder.rb +35 -0
  105. data/lib/nokogiri/html/document.rb +333 -0
  106. data/lib/nokogiri/html/document_fragment.rb +41 -0
  107. data/lib/nokogiri/html/element_description.rb +23 -0
  108. data/lib/nokogiri/html/element_description_defaults.rb +671 -0
  109. data/lib/nokogiri/html/entity_lookup.rb +13 -0
  110. data/lib/nokogiri/html/sax/parser.rb +52 -0
  111. data/lib/nokogiri/html/sax/parser_context.rb +16 -0
  112. data/lib/nokogiri/html/sax/push_parser.rb +16 -0
  113. data/lib/nokogiri/syntax_error.rb +4 -0
  114. data/lib/nokogiri/version.rb +106 -0
  115. data/lib/nokogiri/xml.rb +73 -0
  116. data/lib/nokogiri/xml/attr.rb +14 -0
  117. data/lib/nokogiri/xml/attribute_decl.rb +18 -0
  118. data/lib/nokogiri/xml/builder.rb +443 -0
  119. data/lib/nokogiri/xml/cdata.rb +11 -0
  120. data/lib/nokogiri/xml/character_data.rb +7 -0
  121. data/lib/nokogiri/xml/document.rb +279 -0
  122. data/lib/nokogiri/xml/document_fragment.rb +112 -0
  123. data/lib/nokogiri/xml/dtd.rb +32 -0
  124. data/lib/nokogiri/xml/element_content.rb +36 -0
  125. data/lib/nokogiri/xml/element_decl.rb +13 -0
  126. data/lib/nokogiri/xml/entity_decl.rb +19 -0
  127. data/lib/nokogiri/xml/namespace.rb +13 -0
  128. data/lib/nokogiri/xml/node.rb +982 -0
  129. data/lib/nokogiri/xml/node/save_options.rb +61 -0
  130. data/lib/nokogiri/xml/node_set.rb +355 -0
  131. data/lib/nokogiri/xml/notation.rb +6 -0
  132. data/lib/nokogiri/xml/parse_options.rb +98 -0
  133. data/lib/nokogiri/xml/pp.rb +2 -0
  134. data/lib/nokogiri/xml/pp/character_data.rb +18 -0
  135. data/lib/nokogiri/xml/pp/node.rb +56 -0
  136. data/lib/nokogiri/xml/processing_instruction.rb +8 -0
  137. data/lib/nokogiri/xml/reader.rb +112 -0
  138. data/lib/nokogiri/xml/relax_ng.rb +32 -0
  139. data/lib/nokogiri/xml/sax.rb +4 -0
  140. data/lib/nokogiri/xml/sax/document.rb +171 -0
  141. data/lib/nokogiri/xml/sax/parser.rb +123 -0
  142. data/lib/nokogiri/xml/sax/parser_context.rb +16 -0
  143. data/lib/nokogiri/xml/sax/push_parser.rb +60 -0
  144. data/lib/nokogiri/xml/schema.rb +63 -0
  145. data/lib/nokogiri/xml/syntax_error.rb +47 -0
  146. data/lib/nokogiri/xml/text.rb +9 -0
  147. data/lib/nokogiri/xml/xpath.rb +10 -0
  148. data/lib/nokogiri/xml/xpath/syntax_error.rb +11 -0
  149. data/lib/nokogiri/xml/xpath_context.rb +16 -0
  150. data/lib/nokogiri/xslt.rb +56 -0
  151. data/lib/nokogiri/xslt/stylesheet.rb +25 -0
  152. data/lib/xsd/xmlparser/nokogiri.rb +102 -0
  153. data/suppressions/README.txt +1 -0
  154. data/suppressions/nokogiri_ree-1.8.7.358.supp +61 -0
  155. data/suppressions/nokogiri_ruby-1.8.7.370.supp +0 -0
  156. data/suppressions/nokogiri_ruby-1.9.2.320.supp +28 -0
  157. data/suppressions/nokogiri_ruby-1.9.3.327.supp +28 -0
  158. data/tasks/nokogiri.org.rb +24 -0
  159. data/tasks/test.rb +95 -0
  160. data/test/css/test_nthiness.rb +222 -0
  161. data/test/css/test_parser.rb +358 -0
  162. data/test/css/test_tokenizer.rb +198 -0
  163. data/test/css/test_xpath_visitor.rb +96 -0
  164. data/test/decorators/test_slop.rb +16 -0
  165. data/test/files/2ch.html +108 -0
  166. data/test/files/address_book.rlx +12 -0
  167. data/test/files/address_book.xml +10 -0
  168. data/test/files/atom.xml +344 -0
  169. data/test/files/bar/bar.xsd +4 -0
  170. data/test/files/bogus.xml +0 -0
  171. data/test/files/dont_hurt_em_why.xml +422 -0
  172. data/test/files/encoding.html +82 -0
  173. data/test/files/encoding.xhtml +84 -0
  174. data/test/files/exslt.xml +8 -0
  175. data/test/files/exslt.xslt +35 -0
  176. data/test/files/foo/foo.xsd +4 -0
  177. data/test/files/metacharset.html +10 -0
  178. data/test/files/noencoding.html +47 -0
  179. data/test/files/po.xml +32 -0
  180. data/test/files/po.xsd +66 -0
  181. data/test/files/saml/saml20assertion_schema.xsd +283 -0
  182. data/test/files/saml/saml20protocol_schema.xsd +302 -0
  183. data/test/files/saml/xenc_schema.xsd +146 -0
  184. data/test/files/saml/xmldsig_schema.xsd +318 -0
  185. data/test/files/shift_jis.html +10 -0
  186. data/test/files/shift_jis.xml +5 -0
  187. data/test/files/shift_jis_no_charset.html +9 -0
  188. data/test/files/snuggles.xml +3 -0
  189. data/test/files/staff.dtd +10 -0
  190. data/test/files/staff.xml +59 -0
  191. data/test/files/staff.xslt +32 -0
  192. data/test/files/test_document_url/bar.xml +2 -0
  193. data/test/files/test_document_url/document.dtd +4 -0
  194. data/test/files/test_document_url/document.xml +6 -0
  195. data/test/files/tlm.html +850 -0
  196. data/test/files/to_be_xincluded.xml +2 -0
  197. data/test/files/valid_bar.xml +2 -0
  198. data/test/files/xinclude.xml +4 -0
  199. data/test/helper.rb +164 -0
  200. data/test/html/sax/test_parser.rb +141 -0
  201. data/test/html/sax/test_parser_context.rb +46 -0
  202. data/test/html/test_builder.rb +164 -0
  203. data/test/html/test_document.rb +619 -0
  204. data/test/html/test_document_encoding.rb +148 -0
  205. data/test/html/test_document_fragment.rb +261 -0
  206. data/test/html/test_element_description.rb +105 -0
  207. data/test/html/test_named_characters.rb +14 -0
  208. data/test/html/test_node.rb +196 -0
  209. data/test/html/test_node_encoding.rb +27 -0
  210. data/test/namespaces/test_additional_namespaces_in_builder_doc.rb +14 -0
  211. data/test/namespaces/test_namespaces_in_builder_doc.rb +75 -0
  212. data/test/namespaces/test_namespaces_in_cloned_doc.rb +31 -0
  213. data/test/namespaces/test_namespaces_in_created_doc.rb +75 -0
  214. data/test/namespaces/test_namespaces_in_parsed_doc.rb +66 -0
  215. data/test/test_convert_xpath.rb +135 -0
  216. data/test/test_css_cache.rb +45 -0
  217. data/test/test_encoding_handler.rb +46 -0
  218. data/test/test_memory_leak.rb +156 -0
  219. data/test/test_nokogiri.rb +138 -0
  220. data/test/test_reader.rb +558 -0
  221. data/test/test_soap4r_sax.rb +52 -0
  222. data/test/test_xslt_transforms.rb +279 -0
  223. data/test/xml/node/test_save_options.rb +28 -0
  224. data/test/xml/node/test_subclass.rb +44 -0
  225. data/test/xml/sax/test_parser.rb +382 -0
  226. data/test/xml/sax/test_parser_context.rb +115 -0
  227. data/test/xml/sax/test_push_parser.rb +157 -0
  228. data/test/xml/test_attr.rb +64 -0
  229. data/test/xml/test_attribute_decl.rb +86 -0
  230. data/test/xml/test_builder.rb +315 -0
  231. data/test/xml/test_c14n.rb +161 -0
  232. data/test/xml/test_cdata.rb +48 -0
  233. data/test/xml/test_comment.rb +29 -0
  234. data/test/xml/test_document.rb +934 -0
  235. data/test/xml/test_document_encoding.rb +28 -0
  236. data/test/xml/test_document_fragment.rb +228 -0
  237. data/test/xml/test_dtd.rb +187 -0
  238. data/test/xml/test_dtd_encoding.rb +33 -0
  239. data/test/xml/test_element_content.rb +56 -0
  240. data/test/xml/test_element_decl.rb +73 -0
  241. data/test/xml/test_entity_decl.rb +122 -0
  242. data/test/xml/test_entity_reference.rb +245 -0
  243. data/test/xml/test_namespace.rb +95 -0
  244. data/test/xml/test_node.rb +1155 -0
  245. data/test/xml/test_node_attributes.rb +113 -0
  246. data/test/xml/test_node_encoding.rb +107 -0
  247. data/test/xml/test_node_inheritance.rb +32 -0
  248. data/test/xml/test_node_reparenting.rb +374 -0
  249. data/test/xml/test_node_set.rb +755 -0
  250. data/test/xml/test_parse_options.rb +64 -0
  251. data/test/xml/test_processing_instruction.rb +30 -0
  252. data/test/xml/test_reader_encoding.rb +142 -0
  253. data/test/xml/test_relax_ng.rb +60 -0
  254. data/test/xml/test_schema.rb +129 -0
  255. data/test/xml/test_syntax_error.rb +12 -0
  256. data/test/xml/test_text.rb +45 -0
  257. data/test/xml/test_unparented_node.rb +422 -0
  258. data/test/xml/test_xinclude.rb +83 -0
  259. data/test/xml/test_xpath.rb +376 -0
  260. data/test/xslt/test_custom_functions.rb +133 -0
  261. data/test/xslt/test_exception_handling.rb +37 -0
  262. data/test_all +81 -0
  263. metadata +601 -0
@@ -0,0 +1,95 @@
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
+
69
+ def test_remove_entity_namespace
70
+ s = %q{<?xml version='1.0'?><!DOCTYPE schema PUBLIC "-//W3C//DTD XMLSCHEMA 200102//EN" "XMLSchema.dtd" [<!ENTITY % p ''>]>}
71
+ Nokogiri::XML(s).remove_namespaces!
72
+ end
73
+
74
+ def test_maintain_element_namespaces
75
+ doc = Document.new
76
+ subject = Nokogiri::XML::Node.new 'foo', doc
77
+ subject << '<foobar xmlns="barfoo"/>'
78
+ child = subject.children.first
79
+ assert_equal 'foobar', child.name
80
+ assert_equal 'barfoo', child.namespace.href
81
+ assert_empty child.attributes
82
+ end
83
+
84
+ def test_maintain_element_namespaces_in_urn
85
+ doc = Document.new
86
+ subject = Nokogiri::XML::Node.new 'foo', doc
87
+ subject << '<foobar xmlns="urn:xmpp:foospec:barfoo"/>'
88
+ child = subject.children.first
89
+ assert_equal 'foobar', child.name
90
+ assert_equal 'urn:xmpp:foospec:barfoo', child.namespace.href
91
+ assert_empty child.attributes
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,1155 @@
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_parse_invalid_html_markup_results_in_empty_nodeset
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_parse_error_on_fragment_with_empty_document
130
+ doc = Document.new
131
+ fragment = DocumentFragment.new(doc, '<foo><bar/></foo>')
132
+ node = fragment%'bar'
133
+ node.parse('<baz><</baz>')
134
+ end
135
+
136
+ def test_parse_with_unparented_text_context_node
137
+ doc = XML::Document.new
138
+ elem = XML::Text.new("foo", doc)
139
+ elem.parse("<bar/>")
140
+ end
141
+
142
+ def test_subclass_dup
143
+ subclass = Class.new(Nokogiri::XML::Node)
144
+ node = subclass.new('foo', @xml).dup
145
+ assert_instance_of subclass, node
146
+ end
147
+
148
+ def test_gt_string_arg
149
+ node = @xml.at('employee')
150
+ nodes = (node > 'name')
151
+ assert_equal 1, nodes.length
152
+ assert_equal node, nodes.first.parent
153
+ end
154
+
155
+ def test_next_element_when_next_sibling_is_element_should_return_next_sibling
156
+ doc = Nokogiri::XML "<root><foo /><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_there_is_no_next_sibling_should_return_nil
164
+ doc = Nokogiri::XML "<root><foo /><quux /></root>"
165
+ assert_nil doc.at_css("quux").next_element
166
+ end
167
+
168
+ def test_next_element_when_next_sibling_is_not_an_element_should_return_closest_next_element_sibling
169
+ doc = Nokogiri::XML "<root><foo />bar<quux /></root>"
170
+ node = doc.at_css("foo")
171
+ next_element = node.next_element
172
+ assert next_element.element?
173
+ assert_equal doc.at_css("quux"), next_element
174
+ end
175
+
176
+ def test_next_element_when_next_sibling_is_not_an_element_and_no_following_element_should_return_nil
177
+ doc = Nokogiri::XML "<root><foo />bar</root>"
178
+ node = doc.at_css("foo")
179
+ next_element = node.next_element
180
+ assert_nil next_element
181
+ end
182
+
183
+ def test_previous_element_when_previous_sibling_is_element_should_return_previous_sibling
184
+ doc = Nokogiri::XML "<root><foo /><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_there_is_no_previous_sibling_should_return_nil
192
+ doc = Nokogiri::XML "<root><foo /><quux /></root>"
193
+ assert_nil doc.at_css("foo").previous_element
194
+ end
195
+
196
+ def test_previous_element_when_previous_sibling_is_not_an_element_should_return_closest_previous_element_sibling
197
+ doc = Nokogiri::XML "<root><foo />bar<quux /></root>"
198
+ node = doc.at_css("quux")
199
+ previous_element = node.previous_element
200
+ assert previous_element.element?
201
+ assert_equal doc.at_css("foo"), previous_element
202
+ end
203
+
204
+ def test_previous_element_when_previous_sibling_is_not_an_element_and_no_following_element_should_return_nil
205
+ doc = Nokogiri::XML "<root>foo<bar /></root>"
206
+ node = doc.at_css("bar")
207
+ previous_element = node.previous_element
208
+ assert_nil previous_element
209
+ end
210
+
211
+ def test_element?
212
+ assert @xml.root.element?, 'is an element'
213
+ end
214
+
215
+ def test_slash_search
216
+ assert_equal 'EMP0001', (@xml/:staff/:employee/:employeeId).first.text
217
+ end
218
+
219
+ def test_append_with_document
220
+ assert_raises(ArgumentError) do
221
+ @xml.root << Nokogiri::XML::Document.new
222
+ end
223
+ end
224
+
225
+ def test_append_with_attr
226
+ r = Nokogiri.XML('<r a="1" />').root
227
+ assert_raises(ArgumentError) do
228
+ r << r.at_xpath('@a')
229
+ end
230
+ end
231
+
232
+ def test_inspect_ns
233
+ xml = Nokogiri::XML(<<-eoxml) { |c| c.noblanks }
234
+ <root xmlns="http://tenderlovemaking.com/" xmlns:foo="bar">
235
+ <awesome/>
236
+ </root>
237
+ eoxml
238
+ ins = xml.inspect
239
+
240
+ xml.traverse do |node|
241
+ assert_match node.class.name, ins
242
+ if node.respond_to? :attributes
243
+ node.attributes.each do |k,v|
244
+ assert_match k, ins
245
+ assert_match v, ins
246
+ end
247
+ end
248
+
249
+ if node.respond_to?(:namespace) && node.namespace
250
+ assert_match node.namespace.class.name, ins
251
+ assert_match node.namespace.href, ins
252
+ end
253
+ end
254
+ end
255
+
256
+ def test_namespace_definitions_when_some_exist
257
+ xml = Nokogiri::XML <<-eoxml
258
+ <root xmlns="http://tenderlovemaking.com/" xmlns:foo="bar">
259
+ <awesome/>
260
+ </root>
261
+ eoxml
262
+ namespace_definitions = xml.root.namespace_definitions
263
+ assert_equal 2, namespace_definitions.length
264
+ end
265
+
266
+ def test_namespace_definitions_when_no_exist
267
+ xml = Nokogiri::XML <<-eoxml
268
+ <root xmlns="http://tenderlovemaking.com/" xmlns:foo="bar">
269
+ <awesome/>
270
+ </root>
271
+ eoxml
272
+ namespace_definitions = xml.at_xpath('//xmlns:awesome').namespace_definitions
273
+ assert_equal 0, namespace_definitions.length
274
+ end
275
+
276
+ def test_namespace_goes_to_children
277
+ fruits = Nokogiri::XML(<<-eoxml)
278
+ <Fruit xmlns='www.fruits.org'>
279
+ </Fruit>
280
+ eoxml
281
+ apple = Nokogiri::XML::Node.new('Apple', fruits)
282
+ orange = Nokogiri::XML::Node.new('Orange', fruits)
283
+ apple << orange
284
+ fruits.root << apple
285
+ assert fruits.at('//fruit:Orange',{'fruit'=>'www.fruits.org'})
286
+ assert fruits.at('//fruit:Apple',{'fruit'=>'www.fruits.org'})
287
+ end
288
+
289
+ def test_description
290
+ assert_nil @xml.at('employee').description
291
+ end
292
+
293
+ def test_spaceship
294
+ nodes = @xml.xpath('//employee')
295
+ assert_equal(-1, (nodes.first <=> nodes.last))
296
+ list = [nodes.first, nodes.last].sort
297
+ assert_equal nodes.first, list.first
298
+ assert_equal nodes.last, list.last
299
+ end
300
+
301
+ def test_incorrect_spaceship
302
+ nodes = @xml.xpath('//employee')
303
+ assert_nil(nodes.first <=> 'asdf')
304
+ end
305
+
306
+ def test_document_compare
307
+ nodes = @xml.xpath('//employee')
308
+ assert_equal(-1, (nodes.first <=> @xml))
309
+ end
310
+
311
+ def test_different_document_compare
312
+ nodes = @xml.xpath('//employee')
313
+ doc = Nokogiri::XML('<a><b/></a>')
314
+ b = doc.at('b')
315
+ assert_nil(nodes.first <=> b)
316
+ end
317
+
318
+ def test_duplicate_node_removes_namespace
319
+ fruits = Nokogiri::XML(<<-eoxml)
320
+ <Fruit xmlns='www.fruits.org'>
321
+ <Apple></Apple>
322
+ </Fruit>
323
+ eoxml
324
+ apple = fruits.root.xpath('fruit:Apple', {'fruit'=>'www.fruits.org'})[0]
325
+ new_apple = apple.dup
326
+ fruits.root << new_apple
327
+ assert_equal 2, fruits.xpath('//xmlns:Apple').length
328
+ assert_equal 1, fruits.to_xml.scan('www.fruits.org').length
329
+ end
330
+
331
+ [:clone, :dup].each do |symbol|
332
+ define_method "test_#{symbol}" do
333
+ node = @xml.at('//employee')
334
+ other = node.send(symbol)
335
+ assert_equal "employee", other.name
336
+ assert_nil other.parent
337
+ end
338
+ end
339
+
340
+ def test_fragment_creates_elements
341
+ apple = @xml.fragment('<Apple/>')
342
+ apple.children.each do |child|
343
+ assert_equal Nokogiri::XML::Node::ELEMENT_NODE, child.type
344
+ assert_instance_of Nokogiri::XML::Element, child
345
+ end
346
+ end
347
+
348
+ def test_node_added_to_root_should_get_namespace
349
+ fruits = Nokogiri::XML(<<-eoxml)
350
+ <Fruit xmlns='http://www.fruits.org'>
351
+ </Fruit>
352
+ eoxml
353
+ apple = fruits.fragment('<Apple/>')
354
+ fruits.root << apple
355
+ assert_equal 1, fruits.xpath('//xmlns:Apple').length
356
+ end
357
+
358
+ def test_new_node_can_have_ancestors
359
+ xml = Nokogiri::XML('<root>text</root>')
360
+ item = Nokogiri::XML::Element.new('item', xml)
361
+ assert_equal 0, item.ancestors.length
362
+ end
363
+
364
+ def test_children
365
+ doc = Nokogiri::XML(<<-eoxml)
366
+ <root>#{'<a/>' * 9 }</root>
367
+ eoxml
368
+ assert_equal 9, doc.root.children.length
369
+ assert_equal 9, doc.root.children.to_a.length
370
+
371
+ doc = Nokogiri::XML(<<-eoxml)
372
+ <root>#{'<a/>' * 15 }</root>
373
+ eoxml
374
+ assert_equal 15, doc.root.children.length
375
+ assert_equal 15, doc.root.children.to_a.length
376
+ end
377
+
378
+ def test_add_namespace
379
+ node = @xml.at('address')
380
+ node.add_namespace('foo', 'http://tenderlovemaking.com')
381
+ assert_equal 'http://tenderlovemaking.com', node.namespaces['xmlns:foo']
382
+ end
383
+
384
+ def test_add_namespace_twice
385
+ node = @xml.at('address')
386
+ ns = node.add_namespace('foo', 'http://tenderlovemaking.com')
387
+ ns2 = node.add_namespace('foo', 'http://tenderlovemaking.com')
388
+ assert_equal ns, ns2
389
+ end
390
+
391
+ def test_add_default_ns
392
+ node = @xml.at('address')
393
+ node.add_namespace(nil, 'http://tenderlovemaking.com')
394
+ assert_equal 'http://tenderlovemaking.com', node.namespaces['xmlns']
395
+ end
396
+
397
+ def test_add_multiple_namespaces
398
+ node = @xml.at('address')
399
+
400
+ node.add_namespace(nil, 'http://tenderlovemaking.com')
401
+ assert_equal 'http://tenderlovemaking.com', node.namespaces['xmlns']
402
+
403
+ node.add_namespace('foo', 'http://tenderlovemaking.com')
404
+ assert_equal 'http://tenderlovemaking.com', node.namespaces['xmlns:foo']
405
+ end
406
+
407
+ def test_default_namespace=
408
+ node = @xml.at('address')
409
+ node.default_namespace = 'http://tenderlovemaking.com'
410
+ assert_equal 'http://tenderlovemaking.com', node.namespaces['xmlns']
411
+ end
412
+
413
+ def test_namespace=
414
+ node = @xml.at('address')
415
+ assert_nil node.namespace
416
+ definition = node.add_namespace_definition 'bar', 'http://tlm.com/'
417
+
418
+ node.namespace = definition
419
+
420
+ assert_equal definition, node.namespace
421
+
422
+ assert_equal node, @xml.at('//foo:address', {
423
+ 'foo' => 'http://tlm.com/'
424
+ })
425
+ end
426
+
427
+ def test_add_namespace_with_nil_associates_node
428
+ node = @xml.at('address')
429
+ assert_nil node.namespace
430
+ definition = node.add_namespace_definition nil, 'http://tlm.com/'
431
+ assert_equal definition, node.namespace
432
+ end
433
+
434
+ def test_add_namespace_does_not_associate_node
435
+ node = @xml.at('address')
436
+ assert_nil node.namespace
437
+ assert node.add_namespace_definition 'foo', 'http://tlm.com/'
438
+ assert_nil node.namespace
439
+ end
440
+
441
+ def test_set_namespace_from_different_doc
442
+ node = @xml.at('address')
443
+ doc = Nokogiri::XML(File.read(XML_FILE), XML_FILE)
444
+ decl = doc.root.add_namespace_definition 'foo', 'bar'
445
+
446
+ assert_raises(ArgumentError) do
447
+ node.namespace = decl
448
+ end
449
+ end
450
+
451
+ def test_set_namespace_must_only_take_a_namespace
452
+ node = @xml.at('address')
453
+ assert_raises(TypeError) do
454
+ node.namespace = node
455
+ end
456
+ end
457
+
458
+ def test_at
459
+ node = @xml.at('address')
460
+ assert_equal node, @xml.xpath('//address').first
461
+ end
462
+
463
+ def test_at_self
464
+ node = @xml.at('address')
465
+ assert_equal node, node.at('.')
466
+ end
467
+
468
+ def test_at_xpath
469
+ node = @xml.at_xpath('//address')
470
+ nodes = @xml.xpath('//address')
471
+ assert_equal 5, nodes.size
472
+ assert_equal node, nodes.first
473
+ end
474
+
475
+ def test_at_css
476
+ node = @xml.at_css('address')
477
+ nodes = @xml.css('address')
478
+ assert_equal 5, nodes.size
479
+ assert_equal node, nodes.first
480
+ end
481
+
482
+ def test_percent
483
+ node = @xml % ('address')
484
+ assert_equal node, @xml.xpath('//address').first
485
+ end
486
+
487
+ def test_accept
488
+ visitor = Class.new {
489
+ attr_accessor :visited
490
+ def accept target
491
+ target.accept(self)
492
+ end
493
+
494
+ def visit node
495
+ node.children.each { |c| c.accept(self) }
496
+ @visited = true
497
+ end
498
+ }.new
499
+ visitor.accept(@xml.root)
500
+ assert visitor.visited
501
+ end
502
+
503
+ def test_write_to
504
+ io = StringIO.new
505
+ @xml.write_to io
506
+ io.rewind
507
+ assert_equal @xml.to_xml, io.read
508
+ end
509
+
510
+ def test_attribute_with_symbol
511
+ assert_equal 'Yes', @xml.css('address').first[:domestic]
512
+ end
513
+
514
+ def test_non_existent_attribute_should_return_nil
515
+ node = @xml.root.first_element_child
516
+ assert_nil node.attribute('type')
517
+ end
518
+
519
+ def test_write_to_with_block
520
+ called = false
521
+ io = StringIO.new
522
+ conf = nil
523
+ @xml.write_to io do |config|
524
+ called = true
525
+ conf = config
526
+ config.format.as_html.no_empty_tags
527
+ end
528
+ io.rewind
529
+ assert called
530
+ string = io.read
531
+ assert_equal @xml.serialize(nil, conf.options), string
532
+ assert_equal @xml.serialize(nil, conf), string
533
+ end
534
+
535
+ %w{ xml html xhtml }.each do |type|
536
+ define_method(:"test_write_#{type}_to") do
537
+ io = StringIO.new
538
+ assert @xml.send(:"write_#{type}_to", io)
539
+ io.rewind
540
+ assert_match @xml.send(:"to_#{type}"), io.read
541
+ end
542
+ end
543
+
544
+ def test_serialize_with_block
545
+ called = false
546
+ conf = nil
547
+ string = @xml.serialize do |config|
548
+ called = true
549
+ conf = config
550
+ config.format.as_html.no_empty_tags
551
+ end
552
+ assert called
553
+ assert_equal @xml.serialize(nil, conf.options), string
554
+ assert_equal @xml.serialize(nil, conf), string
555
+ end
556
+
557
+ def test_hold_refence_to_subnode
558
+ doc = Nokogiri::XML(<<-eoxml)
559
+ <root>
560
+ <a>
561
+ <b />
562
+ </a>
563
+ </root>
564
+ eoxml
565
+ assert node_a = doc.css('a').first
566
+ assert node_b = node_a.css('b').first
567
+ node_a.unlink
568
+ assert_equal 'b', node_b.name
569
+ end
570
+
571
+ def test_values
572
+ assert_equal %w{ Yes Yes }, @xml.xpath('//address')[1].values
573
+ end
574
+
575
+ def test_keys
576
+ assert_equal %w{ domestic street }, @xml.xpath('//address')[1].keys
577
+ end
578
+
579
+ def test_each
580
+ attributes = []
581
+ @xml.xpath('//address')[1].each do |key, value|
582
+ attributes << [key, value]
583
+ end
584
+ assert_equal [['domestic', 'Yes'], ['street', 'Yes']], attributes
585
+ end
586
+
587
+ def test_new
588
+ assert node = Nokogiri::XML::Node.new('input', @xml)
589
+ assert_equal 1, node.node_type
590
+ assert_instance_of Nokogiri::XML::Element, node
591
+ end
592
+
593
+ def test_to_str
594
+ name = @xml.xpath('//name').first
595
+ assert_match(/Margaret/, '' + name)
596
+ assert_equal('Margaret Martin', '' + name.children.first)
597
+ end
598
+
599
+ def test_ancestors
600
+ address = @xml.xpath('//address').first
601
+ assert_equal 3, address.ancestors.length
602
+ assert_equal ['employee', 'staff', 'document'],
603
+ address.ancestors.map { |x| x.name }
604
+ end
605
+
606
+ def test_read_only?
607
+ assert entity_decl = @xml.internal_subset.children.find { |x|
608
+ x.type == Node::ENTITY_DECL
609
+ }
610
+ assert entity_decl.read_only?
611
+ end
612
+
613
+ def test_remove_attribute
614
+ address = @xml.xpath('/staff/employee/address').first
615
+ assert_equal 'Yes', address['domestic']
616
+ address.remove_attribute 'domestic'
617
+ assert_nil address['domestic']
618
+ end
619
+
620
+ def test_attribute_setter_accepts_non_string
621
+ address = @xml.xpath("/staff/employee/address").first
622
+ assert_equal "Yes", address[:domestic]
623
+ address[:domestic] = "Altered Yes"
624
+ assert_equal "Altered Yes", address[:domestic]
625
+ end
626
+
627
+ def test_attribute_accessor_accepts_non_string
628
+ address = @xml.xpath("/staff/employee/address").first
629
+ assert_equal "Yes", address["domestic"]
630
+ assert_equal "Yes", address[:domestic]
631
+ end
632
+
633
+ def test_empty_attribute_reading
634
+ node = Nokogiri::XML '<foo empty="" whitespace=" "/>'
635
+
636
+ assert_equal '', node.root['empty']
637
+ assert_equal ' ', node.root['whitespace']
638
+ end
639
+
640
+ def test_delete
641
+ address = @xml.xpath('/staff/employee/address').first
642
+ assert_equal 'Yes', address['domestic']
643
+ address.delete 'domestic'
644
+ assert_nil address['domestic']
645
+ end
646
+
647
+ def test_set_content_with_symbol
648
+ node = @xml.at('//name')
649
+ node.content = :foo
650
+ assert_equal 'foo', node.content
651
+ end
652
+
653
+ def test_set_native_content_is_unescaped
654
+ comment = Nokogiri.XML('<r><!-- foo --></r>').at('//comment()')
655
+
656
+ comment.native_content = " < " # content= will escape this string
657
+ assert_equal "<!-- < -->", comment.to_xml
658
+ end
659
+
660
+ def test_find_by_css_class_with_nonstandard_whitespace
661
+ doc = Nokogiri::HTML '
662
+ <html>
663
+ <body>
664
+ <div class="a
665
+ b"></div>
666
+ </body>
667
+ </html>
668
+ '
669
+ assert_not_nil doc.at_css(".b")
670
+ end
671
+
672
+ def test_find_by_css_with_tilde_eql
673
+ xml = Nokogiri::XML.parse(<<-eoxml)
674
+ <root>
675
+ <a>Hello world</a>
676
+ <a class='foo bar'>Bar</a>
677
+ <a class='bar foo'>Bar</a>
678
+ <a class='bar'>Bar</a>
679
+ <a class='baz bar foo'>Bar</a>
680
+ <a class='bazbarfoo'>Awesome</a>
681
+ <a class='bazbar'>Awesome</a>
682
+ </root>
683
+ eoxml
684
+ set = xml.css('a[@class~="bar"]')
685
+ assert_equal 4, set.length
686
+ assert_equal ['Bar'], set.map { |node| node.content }.uniq
687
+ end
688
+
689
+ def test_unlink
690
+ xml = Nokogiri::XML.parse(<<-eoxml)
691
+ <root>
692
+ <a class='foo bar'>Bar</a>
693
+ <a class='bar foo'>Bar</a>
694
+ <a class='bar'>Bar</a>
695
+ <a>Hello world</a>
696
+ <a class='baz bar foo'>Bar</a>
697
+ <a class='bazbarfoo'>Awesome</a>
698
+ <a class='bazbar'>Awesome</a>
699
+ </root>
700
+ eoxml
701
+ node = xml.xpath('//a')[3]
702
+ assert_equal('Hello world', node.text)
703
+ assert_match(/Hello world/, xml.to_s)
704
+ assert node.parent
705
+ assert node.document
706
+ assert node.previous_sibling
707
+ assert node.next_sibling
708
+ node.unlink
709
+ assert !node.parent
710
+ #assert !node.document
711
+ assert !node.previous_sibling
712
+ assert !node.next_sibling
713
+ assert_no_match(/Hello world/, xml.to_s)
714
+ end
715
+
716
+ def test_next_sibling
717
+ assert node = @xml.root
718
+ assert sibling = node.child.next_sibling
719
+ assert_equal('employee', sibling.name)
720
+ end
721
+
722
+ def test_previous_sibling
723
+ assert node = @xml.root
724
+ assert sibling = node.child.next_sibling
725
+ assert_equal('employee', sibling.name)
726
+ assert_equal(sibling.previous_sibling, node.child)
727
+ end
728
+
729
+ def test_name=
730
+ assert node = @xml.root
731
+ node.name = 'awesome'
732
+ assert_equal('awesome', node.name)
733
+ end
734
+
735
+ def test_child
736
+ assert node = @xml.root
737
+ assert child = node.child
738
+ assert_equal('text', child.name)
739
+ end
740
+
741
+ def test_key?
742
+ assert node = @xml.search('//address').first
743
+ assert(!node.key?('asdfasdf'))
744
+ end
745
+
746
+ def test_set_property
747
+ assert node = @xml.search('//address').first
748
+ node['foo'] = 'bar'
749
+ assert_equal('bar', node['foo'])
750
+ end
751
+
752
+ def test_set_property_non_string
753
+ assert node = @xml.search('//address').first
754
+ node['foo'] = 1
755
+ assert_equal('1', node['foo'])
756
+ node['foo'] = false
757
+ assert_equal('false', node['foo'])
758
+ end
759
+
760
+ def test_attributes
761
+ assert node = @xml.search('//address').first
762
+ assert_nil(node['asdfasdfasdf'])
763
+ assert_equal('Yes', node['domestic'])
764
+
765
+ assert node = @xml.search('//address')[2]
766
+ attr = node.attributes
767
+ assert_equal 2, attr.size
768
+ assert_equal 'Yes', attr['domestic'].value
769
+ assert_equal 'Yes', attr['domestic'].to_s
770
+ assert_equal 'No', attr['street'].value
771
+ end
772
+
773
+ def test_path
774
+ assert set = @xml.search('//employee')
775
+ assert node = set.first
776
+ assert_equal('/staff/employee[1]', node.path)
777
+ end
778
+
779
+ def test_parent_xpath
780
+ assert set = @xml.search('//employee')
781
+ assert node = set.first
782
+ assert parent_set = node.search('..')
783
+ assert parent_node = parent_set.first
784
+ assert_equal '/staff', parent_node.path
785
+ assert_equal node.parent, parent_node
786
+ end
787
+
788
+ def test_search_self
789
+ node = @xml.at('//employee')
790
+ assert_equal node.search('.').to_a, [node]
791
+ end
792
+
793
+ def test_search_by_symbol
794
+ assert set = @xml.search(:employee)
795
+ assert 5, set.length
796
+
797
+ assert node = @xml.at(:employee)
798
+ assert node.text =~ /EMP0001/
799
+ end
800
+
801
+ def test_new_node
802
+ node = Nokogiri::XML::Node.new('form', @xml)
803
+ assert_equal('form', node.name)
804
+ assert(node.document)
805
+ end
806
+
807
+ def test_encode_special_chars
808
+ foo = @xml.css('employee').first.encode_special_chars('&')
809
+ assert_equal '&amp;', foo
810
+ end
811
+
812
+ def test_content_equals
813
+ node = Nokogiri::XML::Node.new('form', @xml)
814
+ assert_equal('', node.content)
815
+
816
+ node.content = 'hello world!'
817
+ assert_equal('hello world!', node.content)
818
+
819
+ node.content = '& <foo> &amp;'
820
+ assert_equal('& <foo> &amp;', node.content)
821
+ assert_equal('<form>&amp; &lt;foo&gt; &amp;amp;</form>', node.to_xml)
822
+
823
+ node.content = "1234 <-> 1234"
824
+ assert_equal "1234 <-> 1234", node.content
825
+ assert_equal "<form>1234 &lt;-&gt; 1234</form>", node.to_xml
826
+
827
+ node.content = '1234'
828
+ node.add_child '<foo>5678</foo>'
829
+ assert_equal '12345678', node.content
830
+ end
831
+
832
+ # issue #839
833
+ def test_encoding_of_copied_nodes
834
+ d1 = Nokogiri::XML('<r><a>&amp;</a></r>')
835
+ d2 = Nokogiri::XML('<r></r>')
836
+ ne = d1.root.xpath('//a').first.dup(1)
837
+ ne.content += "& < & > \" &"
838
+ d2.root << ne
839
+ assert_match /<a>&amp;&amp; &lt; &amp; &gt; " &amp;<\/a>/, d2.to_s
840
+ end
841
+
842
+ def test_content_after_appending_text
843
+ doc = Nokogiri::XML '<foo />'
844
+ node = doc.children.first
845
+ node.content = 'bar'
846
+ node << 'baz'
847
+ assert_equal 'barbaz', node.content
848
+ end
849
+
850
+ def test_content_depth_first
851
+ node = Nokogiri::XML '<foo>first<baz>second</baz>third</foo>'
852
+ assert_equal 'firstsecondthird', node.content
853
+ end
854
+
855
+ def test_set_content_should_unlink_existing_content
856
+ node = @xml.at_css("employee")
857
+ children = node.children
858
+ node.content = "hello"
859
+ children.each { |child| assert_nil child.parent }
860
+ end
861
+
862
+ def test_whitespace_nodes
863
+ doc = Nokogiri::XML.parse("<root><b>Foo</b>\n<i>Bar</i> <p>Bazz</p></root>")
864
+ children = doc.at('//root').children.collect{|j| j.to_s}
865
+ assert_equal "\n", children[1]
866
+ assert_equal " ", children[3]
867
+ end
868
+
869
+ def test_node_equality
870
+ doc1 = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
871
+ doc2 = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
872
+
873
+ address1_1 = doc1.xpath('//address').first
874
+ address1_2 = doc1.xpath('//address').first
875
+
876
+ address2 = doc2.xpath('//address').first
877
+
878
+ assert_not_equal address1_1, address2 # two references to very, very similar nodes
879
+ assert_equal address1_1, address1_2 # two references to the exact same node
880
+ end
881
+
882
+ def test_namespace_search_with_xpath_and_hash
883
+ xml = Nokogiri::XML.parse(<<-eoxml)
884
+ <root>
885
+ <car xmlns:part="http://general-motors.com/">
886
+ <part:tire>Michelin Model XGV</part:tire>
887
+ </car>
888
+ <bicycle xmlns:part="http://schwinn.com/">
889
+ <part:tire>I'm a bicycle tire!</part:tire>
890
+ </bicycle>
891
+ </root>
892
+ eoxml
893
+
894
+ tires = xml.xpath('//bike:tire', {'bike' => 'http://schwinn.com/'})
895
+ assert_equal 1, tires.length
896
+ end
897
+
898
+ def test_namespace_search_with_xpath_and_hash_with_symbol_keys
899
+ xml = Nokogiri::XML.parse(<<-eoxml)
900
+ <root>
901
+ <car xmlns:part="http://general-motors.com/">
902
+ <part:tire>Michelin Model XGV</part:tire>
903
+ </car>
904
+ <bicycle xmlns:part="http://schwinn.com/">
905
+ <part:tire>I'm a bicycle tire!</part:tire>
906
+ </bicycle>
907
+ </root>
908
+ eoxml
909
+
910
+ tires = xml.xpath('//bike:tire', :bike => 'http://schwinn.com/')
911
+ assert_equal 1, tires.length
912
+ end
913
+
914
+ def test_namespace_search_with_css
915
+ xml = Nokogiri::XML.parse(<<-eoxml)
916
+ <root>
917
+ <car xmlns:part="http://general-motors.com/">
918
+ <part:tire>Michelin Model XGV</part:tire>
919
+ </car>
920
+ <bicycle xmlns:part="http://schwinn.com/">
921
+ <part:tire>I'm a bicycle tire!</part:tire>
922
+ </bicycle>
923
+ </root>
924
+ eoxml
925
+
926
+ tires = xml.css('bike|tire', 'bike' => 'http://schwinn.com/' )
927
+ assert_equal 1, tires.length
928
+ end
929
+
930
+ def test_namespaced_attribute_search_with_xpath
931
+ # from #593
932
+ xmlContent = <<-EOXML
933
+ <?xml version="1.0"?>
934
+ <ns1:el1 xmlns:ns1="http://blabla.com" >
935
+ <ns1:el2 ns1:att="123">with namespace</ns1:el2 >
936
+ <ns1:el2 att="noNameSpace">no namespace</ns1:el2 >
937
+ </ns1:el1>
938
+ EOXML
939
+ xml_doc = Nokogiri::XML(xmlContent)
940
+
941
+ no_ns = xml_doc.xpath("//*[@att]")
942
+ assert_equal no_ns.length, 1
943
+ assert_equal no_ns.first.content, "no namespace"
944
+
945
+ with_ns = xml_doc.xpath("//*[@ns1:att]")
946
+ assert_equal with_ns.length, 1
947
+ assert_equal with_ns.first.content, "with namespace"
948
+ end
949
+
950
+ def test_namespaced_attribute_search_with_css
951
+ # from #593
952
+ xmlContent = <<-EOXML
953
+ <?xml version="1.0"?>
954
+ <ns1:el1 xmlns:ns1="http://blabla.com" >
955
+ <ns1:el2 ns1:att="123">with namespace</ns1:el2 >
956
+ <ns1:el2 att="noNameSpace">no namespace</ns1:el2 >
957
+ </ns1:el1>
958
+ EOXML
959
+ xml_doc = Nokogiri::XML(xmlContent)
960
+
961
+ no_ns = xml_doc.css('*[att]')
962
+ assert_equal no_ns.length, 1
963
+ assert_equal no_ns.first.content, "no namespace"
964
+
965
+ with_ns = xml_doc.css('*[ns1|att]')
966
+ assert_equal with_ns.length, 1
967
+ assert_equal with_ns.first.content, "with namespace"
968
+ end
969
+
970
+ def test_namespaces_should_include_all_namespace_definitions
971
+ xml = Nokogiri::XML.parse(<<-EOF)
972
+ <x xmlns="http://quux.com/" xmlns:a="http://foo.com/" xmlns:b="http://bar.com/">
973
+ <y xmlns:c="http://bazz.com/">
974
+ <z>hello</z>
975
+ <a xmlns:c="http://newc.com/" />
976
+ </y>
977
+ </x>
978
+ EOF
979
+
980
+ namespaces = xml.namespaces # Document#namespace
981
+ assert_equal({"xmlns" => "http://quux.com/",
982
+ "xmlns:a" => "http://foo.com/",
983
+ "xmlns:b" => "http://bar.com/"}, namespaces)
984
+
985
+ namespaces = xml.root.namespaces
986
+ assert_equal({"xmlns" => "http://quux.com/",
987
+ "xmlns:a" => "http://foo.com/",
988
+ "xmlns:b" => "http://bar.com/"}, namespaces)
989
+
990
+ namespaces = xml.at_xpath("//xmlns:y").namespaces
991
+ assert_equal({"xmlns" => "http://quux.com/",
992
+ "xmlns:a" => "http://foo.com/",
993
+ "xmlns:b" => "http://bar.com/",
994
+ "xmlns:c" => "http://bazz.com/"}, namespaces)
995
+
996
+ namespaces = xml.at_xpath("//xmlns:z").namespaces
997
+ assert_equal({"xmlns" => "http://quux.com/",
998
+ "xmlns:a" => "http://foo.com/",
999
+ "xmlns:b" => "http://bar.com/",
1000
+ "xmlns:c" => "http://bazz.com/"}, namespaces)
1001
+
1002
+ namespaces = xml.at_xpath("//xmlns:a").namespaces
1003
+ assert_equal({"xmlns" => "http://quux.com/",
1004
+ "xmlns:a" => "http://foo.com/",
1005
+ "xmlns:b" => "http://bar.com/",
1006
+ "xmlns:c" => "http://newc.com/"}, namespaces)
1007
+ end
1008
+
1009
+ def test_namespace
1010
+ xml = Nokogiri::XML.parse(<<-EOF)
1011
+ <x xmlns:a='http://foo.com/' xmlns:b='http://bar.com/'>
1012
+ <y xmlns:c='http://bazz.com/'>
1013
+ <a:div>hello a</a:div>
1014
+ <b:div>hello b</b:div>
1015
+ <c:div x="1" b:y="2">hello c</c:div>
1016
+ <div x="1" xmlns="http://ns.example.com/d"/>
1017
+ <div x="1">hello moon</div>
1018
+ </y>
1019
+ </x>
1020
+ EOF
1021
+ set = xml.search("//y/*")
1022
+ assert_equal "a", set[0].namespace.prefix
1023
+ assert_equal 'http://foo.com/', set[0].namespace.href
1024
+ assert_equal "b", set[1].namespace.prefix
1025
+ assert_equal 'http://bar.com/', set[1].namespace.href
1026
+ assert_equal "c", set[2].namespace.prefix
1027
+ assert_equal 'http://bazz.com/', set[2].namespace.href
1028
+ assert_equal nil, set[3].namespace.prefix # default namespace
1029
+ assert_equal 'http://ns.example.com/d', set[3].namespace.href
1030
+ assert_equal nil, set[4].namespace # no namespace
1031
+
1032
+ assert_equal 'b', set[2].attributes['y'].namespace.prefix
1033
+ assert_equal 'http://bar.com/', set[2].attributes['y'].namespace.href
1034
+ assert_equal nil, set[2].attributes['x'].namespace
1035
+ assert_equal nil, set[3].attributes['x'].namespace
1036
+ assert_equal nil, set[4].attributes['x'].namespace
1037
+ end
1038
+
1039
+ if Nokogiri.uses_libxml?
1040
+ def test_namespace_without_an_href_on_html_node
1041
+ # because microsoft word's HTML formatting does this. ick.
1042
+ xml = Nokogiri::HTML.parse <<-EOF
1043
+ <div><o:p>foo</o:p></div>
1044
+ EOF
1045
+
1046
+ assert_not_nil(node = xml.at('p'))
1047
+
1048
+ assert_equal 1, node.namespaces.keys.size
1049
+ assert node.namespaces.has_key?('xmlns:o')
1050
+ assert_equal nil, node.namespaces['xmlns:o']
1051
+ end
1052
+ end
1053
+
1054
+ def test_line
1055
+ xml = Nokogiri::XML(<<-eoxml)
1056
+ <root>
1057
+ <a>
1058
+ Hello world
1059
+ </a>
1060
+ </root>
1061
+ eoxml
1062
+
1063
+ set = xml.search("//a")
1064
+ node = set.first
1065
+ assert_equal 2, node.line
1066
+ end
1067
+
1068
+ def test_xpath_results_have_document_and_are_decorated
1069
+ x = Module.new do
1070
+ def awesome! ; end
1071
+ end
1072
+ util_decorate(@xml, x)
1073
+ node_set = @xml.xpath("//employee")
1074
+ assert_equal @xml, node_set.document
1075
+ assert node_set.respond_to?(:awesome!)
1076
+ end
1077
+
1078
+ def test_css_results_have_document_and_are_decorated
1079
+ x = Module.new do
1080
+ def awesome! ; end
1081
+ end
1082
+ util_decorate(@xml, x)
1083
+ node_set = @xml.css("employee")
1084
+ assert_equal @xml, node_set.document
1085
+ assert node_set.respond_to?(:awesome!)
1086
+ end
1087
+
1088
+ def test_blank
1089
+ doc = Nokogiri::XML('')
1090
+ assert_equal false, doc.blank?
1091
+ end
1092
+
1093
+ def test_to_xml_allows_to_serialize_with_as_xml_save_option
1094
+ xml = Nokogiri::XML("<root><ul><li>Hello world</li></ul></root>")
1095
+ set = xml.search("//ul")
1096
+ node = set.first
1097
+
1098
+ assert_no_match("<ul>\n <li>", xml.to_xml(:save_with => XML::Node::SaveOptions::AS_XML))
1099
+ assert_no_match("<ul>\n <li>", node.to_xml(:save_with => XML::Node::SaveOptions::AS_XML))
1100
+ end
1101
+
1102
+ # issue 647
1103
+ def test_default_namespace_should_be_created
1104
+ subject = Nokogiri::XML.parse('<foo xml:bar="http://bar.com"/>').root
1105
+ ns = subject.attributes['bar'].namespace
1106
+ assert_not_nil ns
1107
+ assert_equal ns.class, Nokogiri::XML::Namespace
1108
+ assert_equal 'xml', ns.prefix
1109
+ assert_equal "http://www.w3.org/XML/1998/namespace", ns.href
1110
+ end
1111
+
1112
+ # issue 648
1113
+ def test_namespace_without_prefix_should_be_set
1114
+ node = Nokogiri::XML.parse('<foo xmlns="http://bar.com"/>').root
1115
+ subject = Nokogiri::XML::Node.new 'foo', node.document
1116
+ subject.namespace = node.namespace
1117
+ ns = subject.namespace
1118
+ assert_equal ns.class, Nokogiri::XML::Namespace
1119
+ assert_nil ns.prefix
1120
+ assert_equal ns.href, "http://bar.com"
1121
+ end
1122
+
1123
+ # issue 695
1124
+ def test_namespace_in_rendered_xml
1125
+ document = Nokogiri::XML::Document.new
1126
+ subject = Nokogiri::XML::Node.new 'foo', document
1127
+ ns = subject.add_namespace nil, 'bar'
1128
+ subject.namespace = ns
1129
+ assert_match(/xmlns="bar"/, subject.to_xml)
1130
+ end
1131
+
1132
+ # issue 771
1133
+ def test_format_noblank
1134
+ content = <<eoxml
1135
+ <foo>
1136
+ <bar>hello</bar>
1137
+ </foo>
1138
+ eoxml
1139
+ subject = Nokogiri::XML(content) do |conf|
1140
+ conf.default_xml.noblanks
1141
+ end
1142
+
1143
+ assert_match %r{<bar>hello</bar>}, subject.to_xml(:indent => 2)
1144
+ end
1145
+
1146
+ def test_text_node_colon
1147
+ document = Nokogiri::XML::Document.new
1148
+ root = Nokogiri::XML::Node.new 'foo', document
1149
+ document.root = root
1150
+ root << "<a>hello:with_colon</a>"
1151
+ assert_match(/hello:with_colon/, document.to_xml)
1152
+ end
1153
+ end
1154
+ end
1155
+ end