nokogiri 1.6.8.1 → 1.13.4

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