nokogiri 1.8.5 → 1.15.3

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