nokogiri 1.0.0 → 1.6.8.1

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 (309) hide show
  1. checksums.yaml +7 -0
  2. data/.autotest +26 -0
  3. data/.cross_rubies +9 -0
  4. data/.editorconfig +17 -0
  5. data/.gemtest +0 -0
  6. data/.travis.yml +51 -0
  7. data/CHANGELOG.rdoc +1160 -0
  8. data/CONTRIBUTING.md +42 -0
  9. data/C_CODING_STYLE.rdoc +33 -0
  10. data/Gemfile +22 -0
  11. data/LICENSE.txt +31 -0
  12. data/Manifest.txt +284 -40
  13. data/README.md +166 -0
  14. data/ROADMAP.md +111 -0
  15. data/Rakefile +310 -199
  16. data/STANDARD_RESPONSES.md +47 -0
  17. data/Y_U_NO_GEMSPEC.md +155 -0
  18. data/appveyor.yml +22 -0
  19. data/bin/nokogiri +118 -0
  20. data/build_all +45 -0
  21. data/dependencies.yml +29 -0
  22. data/ext/nokogiri/depend +358 -0
  23. data/ext/nokogiri/extconf.rb +664 -34
  24. data/ext/nokogiri/html_document.c +120 -33
  25. data/ext/nokogiri/html_document.h +1 -1
  26. data/ext/nokogiri/html_element_description.c +279 -0
  27. data/ext/nokogiri/html_element_description.h +10 -0
  28. data/ext/nokogiri/html_entity_lookup.c +32 -0
  29. data/ext/nokogiri/html_entity_lookup.h +8 -0
  30. data/ext/nokogiri/html_sax_parser_context.c +116 -0
  31. data/ext/nokogiri/html_sax_parser_context.h +11 -0
  32. data/ext/nokogiri/html_sax_push_parser.c +87 -0
  33. data/ext/nokogiri/html_sax_push_parser.h +9 -0
  34. data/ext/nokogiri/nokogiri.c +145 -0
  35. data/ext/nokogiri/nokogiri.h +131 -0
  36. data/ext/nokogiri/xml_attr.c +94 -0
  37. data/ext/nokogiri/xml_attr.h +9 -0
  38. data/ext/nokogiri/xml_attribute_decl.c +70 -0
  39. data/ext/nokogiri/xml_attribute_decl.h +9 -0
  40. data/ext/nokogiri/xml_cdata.c +23 -19
  41. data/ext/nokogiri/xml_cdata.h +1 -1
  42. data/ext/nokogiri/xml_comment.c +69 -0
  43. data/ext/nokogiri/xml_comment.h +9 -0
  44. data/ext/nokogiri/xml_document.c +501 -54
  45. data/ext/nokogiri/xml_document.h +14 -1
  46. data/ext/nokogiri/xml_document_fragment.c +48 -0
  47. data/ext/nokogiri/xml_document_fragment.h +10 -0
  48. data/ext/nokogiri/xml_dtd.c +109 -24
  49. data/ext/nokogiri/xml_dtd.h +3 -1
  50. data/ext/nokogiri/xml_element_content.c +123 -0
  51. data/ext/nokogiri/xml_element_content.h +10 -0
  52. data/ext/nokogiri/xml_element_decl.c +69 -0
  53. data/ext/nokogiri/xml_element_decl.h +9 -0
  54. data/ext/nokogiri/xml_encoding_handler.c +79 -0
  55. data/ext/nokogiri/xml_encoding_handler.h +8 -0
  56. data/ext/nokogiri/xml_entity_decl.c +110 -0
  57. data/ext/nokogiri/xml_entity_decl.h +10 -0
  58. data/ext/nokogiri/xml_entity_reference.c +52 -0
  59. data/ext/nokogiri/xml_entity_reference.h +9 -0
  60. data/ext/nokogiri/xml_io.c +60 -0
  61. data/ext/nokogiri/xml_io.h +11 -0
  62. data/ext/nokogiri/xml_libxml2_hacks.c +112 -0
  63. data/ext/nokogiri/xml_libxml2_hacks.h +12 -0
  64. data/ext/nokogiri/xml_namespace.c +117 -0
  65. data/ext/nokogiri/xml_namespace.h +13 -0
  66. data/ext/nokogiri/xml_node.c +1285 -315
  67. data/ext/nokogiri/xml_node.h +4 -6
  68. data/ext/nokogiri/xml_node_set.c +415 -54
  69. data/ext/nokogiri/xml_node_set.h +6 -2
  70. data/ext/nokogiri/xml_processing_instruction.c +56 -0
  71. data/ext/nokogiri/xml_processing_instruction.h +9 -0
  72. data/ext/nokogiri/xml_reader.c +316 -77
  73. data/ext/nokogiri/xml_reader.h +1 -1
  74. data/ext/nokogiri/xml_relax_ng.c +161 -0
  75. data/ext/nokogiri/xml_relax_ng.h +9 -0
  76. data/ext/nokogiri/xml_sax_parser.c +215 -80
  77. data/ext/nokogiri/xml_sax_parser.h +30 -1
  78. data/ext/nokogiri/xml_sax_parser_context.c +262 -0
  79. data/ext/nokogiri/xml_sax_parser_context.h +10 -0
  80. data/ext/nokogiri/xml_sax_push_parser.c +115 -0
  81. data/ext/nokogiri/xml_sax_push_parser.h +9 -0
  82. data/ext/nokogiri/xml_schema.c +205 -0
  83. data/ext/nokogiri/xml_schema.h +9 -0
  84. data/ext/nokogiri/xml_syntax_error.c +45 -175
  85. data/ext/nokogiri/xml_syntax_error.h +4 -2
  86. data/ext/nokogiri/xml_text.c +37 -14
  87. data/ext/nokogiri/xml_text.h +1 -1
  88. data/ext/nokogiri/xml_xpath_context.c +230 -13
  89. data/ext/nokogiri/xml_xpath_context.h +2 -1
  90. data/ext/nokogiri/xslt_stylesheet.c +196 -34
  91. data/ext/nokogiri/xslt_stylesheet.h +6 -1
  92. data/lib/nokogiri/css/node.rb +18 -61
  93. data/lib/nokogiri/css/parser.rb +725 -17
  94. data/lib/nokogiri/css/parser.y +126 -63
  95. data/lib/nokogiri/css/parser_extras.rb +91 -0
  96. data/lib/nokogiri/css/syntax_error.rb +7 -0
  97. data/lib/nokogiri/css/tokenizer.rb +148 -5
  98. data/lib/nokogiri/css/tokenizer.rex +31 -39
  99. data/lib/nokogiri/css/xpath_visitor.rb +109 -51
  100. data/lib/nokogiri/css.rb +24 -3
  101. data/lib/nokogiri/decorators/slop.rb +42 -0
  102. data/lib/nokogiri/html/builder.rb +27 -1
  103. data/lib/nokogiri/html/document.rb +329 -3
  104. data/lib/nokogiri/html/document_fragment.rb +39 -0
  105. data/lib/nokogiri/html/element_description.rb +23 -0
  106. data/lib/nokogiri/html/element_description_defaults.rb +671 -0
  107. data/lib/nokogiri/html/entity_lookup.rb +13 -0
  108. data/lib/nokogiri/html/sax/parser.rb +35 -4
  109. data/lib/nokogiri/html/sax/parser_context.rb +16 -0
  110. data/lib/nokogiri/html/sax/push_parser.rb +36 -0
  111. data/lib/nokogiri/html.rb +18 -76
  112. data/lib/nokogiri/syntax_error.rb +4 -0
  113. data/lib/nokogiri/version.rb +106 -1
  114. data/lib/nokogiri/xml/attr.rb +14 -0
  115. data/lib/nokogiri/xml/attribute_decl.rb +18 -0
  116. data/lib/nokogiri/xml/builder.rb +395 -31
  117. data/lib/nokogiri/xml/cdata.rb +4 -2
  118. data/lib/nokogiri/xml/character_data.rb +7 -0
  119. data/lib/nokogiri/xml/document.rb +267 -12
  120. data/lib/nokogiri/xml/document_fragment.rb +149 -0
  121. data/lib/nokogiri/xml/dtd.rb +27 -1
  122. data/lib/nokogiri/xml/element_content.rb +36 -0
  123. data/lib/nokogiri/xml/element_decl.rb +13 -0
  124. data/lib/nokogiri/xml/entity_decl.rb +19 -0
  125. data/lib/nokogiri/xml/namespace.rb +13 -0
  126. data/lib/nokogiri/xml/node/save_options.rb +61 -0
  127. data/lib/nokogiri/xml/node.rb +748 -109
  128. data/lib/nokogiri/xml/node_set.rb +200 -72
  129. data/lib/nokogiri/xml/parse_options.rb +120 -0
  130. data/lib/nokogiri/xml/pp/character_data.rb +18 -0
  131. data/lib/nokogiri/xml/pp/node.rb +56 -0
  132. data/lib/nokogiri/xml/pp.rb +2 -0
  133. data/lib/nokogiri/xml/processing_instruction.rb +8 -0
  134. data/lib/nokogiri/xml/reader.rb +102 -4
  135. data/lib/nokogiri/xml/relax_ng.rb +32 -0
  136. data/lib/nokogiri/xml/sax/document.rb +114 -2
  137. data/lib/nokogiri/xml/sax/parser.rb +97 -7
  138. data/lib/nokogiri/xml/sax/parser_context.rb +16 -0
  139. data/lib/nokogiri/xml/sax/push_parser.rb +60 -0
  140. data/lib/nokogiri/xml/sax.rb +2 -7
  141. data/lib/nokogiri/xml/schema.rb +63 -0
  142. data/lib/nokogiri/xml/searchable.rb +221 -0
  143. data/lib/nokogiri/xml/syntax_error.rb +27 -1
  144. data/lib/nokogiri/xml/text.rb +4 -1
  145. data/lib/nokogiri/xml/xpath/syntax_error.rb +11 -0
  146. data/lib/nokogiri/xml/xpath.rb +4 -0
  147. data/lib/nokogiri/xml/xpath_context.rb +3 -1
  148. data/lib/nokogiri/xml.rb +45 -38
  149. data/lib/nokogiri/xslt/stylesheet.rb +19 -0
  150. data/lib/nokogiri/xslt.rb +47 -2
  151. data/lib/nokogiri.rb +117 -24
  152. data/lib/xsd/xmlparser/nokogiri.rb +102 -0
  153. data/patches/sort-patches-by-date +25 -0
  154. data/ports/archives/libxml2-2.9.4.tar.gz +0 -0
  155. data/ports/archives/libxslt-1.1.29.tar.gz +0 -0
  156. data/suppressions/README.txt +1 -0
  157. data/suppressions/nokogiri_ree-1.8.7.358.supp +61 -0
  158. data/suppressions/nokogiri_ruby-1.8.7.370.supp +0 -0
  159. data/suppressions/nokogiri_ruby-1.9.2.320.supp +28 -0
  160. data/suppressions/nokogiri_ruby-1.9.3.327.supp +28 -0
  161. data/tasks/test.rb +100 -0
  162. data/test/css/test_nthiness.rb +73 -6
  163. data/test/css/test_parser.rb +184 -39
  164. data/test/css/test_tokenizer.rb +72 -19
  165. data/test/css/test_xpath_visitor.rb +44 -2
  166. data/test/decorators/test_slop.rb +20 -0
  167. data/test/files/2ch.html +108 -0
  168. data/test/files/GH_1042.html +18 -0
  169. data/test/files/address_book.rlx +12 -0
  170. data/test/files/address_book.xml +10 -0
  171. data/test/files/atom.xml +344 -0
  172. data/test/files/bar/bar.xsd +4 -0
  173. data/test/files/bogus.xml +0 -0
  174. data/test/files/dont_hurt_em_why.xml +422 -0
  175. data/test/files/encoding.html +82 -0
  176. data/test/files/encoding.xhtml +84 -0
  177. data/test/files/exslt.xml +8 -0
  178. data/test/files/exslt.xslt +35 -0
  179. data/test/files/foo/foo.xsd +4 -0
  180. data/test/files/metacharset.html +10 -0
  181. data/test/files/namespace_pressure_test.xml +1684 -0
  182. data/test/files/noencoding.html +47 -0
  183. data/test/files/po.xml +32 -0
  184. data/test/files/po.xsd +66 -0
  185. data/test/files/saml/saml20assertion_schema.xsd +283 -0
  186. data/test/files/saml/saml20protocol_schema.xsd +302 -0
  187. data/test/files/saml/xenc_schema.xsd +146 -0
  188. data/test/files/saml/xmldsig_schema.xsd +318 -0
  189. data/test/files/shift_jis.html +10 -0
  190. data/test/files/shift_jis.xml +5 -0
  191. data/test/files/shift_jis_no_charset.html +9 -0
  192. data/test/files/slow-xpath.xml +25509 -0
  193. data/test/files/snuggles.xml +3 -0
  194. data/test/files/staff.dtd +10 -0
  195. data/test/files/test_document_url/bar.xml +2 -0
  196. data/test/files/test_document_url/document.dtd +4 -0
  197. data/test/files/test_document_url/document.xml +6 -0
  198. data/test/files/tlm.html +2 -1
  199. data/test/files/to_be_xincluded.xml +2 -0
  200. data/test/files/valid_bar.xml +2 -0
  201. data/test/files/xinclude.xml +4 -0
  202. data/test/helper.rb +124 -13
  203. data/test/html/sax/test_parser.rb +118 -4
  204. data/test/html/sax/test_parser_context.rb +46 -0
  205. data/test/html/sax/test_push_parser.rb +87 -0
  206. data/test/html/test_builder.rb +94 -8
  207. data/test/html/test_document.rb +626 -11
  208. data/test/html/test_document_encoding.rb +145 -0
  209. data/test/html/test_document_fragment.rb +301 -0
  210. data/test/html/test_element_description.rb +105 -0
  211. data/test/html/test_named_characters.rb +14 -0
  212. data/test/html/test_node.rb +212 -0
  213. data/test/html/test_node_encoding.rb +85 -0
  214. data/test/namespaces/test_additional_namespaces_in_builder_doc.rb +14 -0
  215. data/test/namespaces/test_namespaces_aliased_default.rb +24 -0
  216. data/test/namespaces/test_namespaces_in_builder_doc.rb +75 -0
  217. data/test/namespaces/test_namespaces_in_cloned_doc.rb +31 -0
  218. data/test/namespaces/test_namespaces_in_created_doc.rb +75 -0
  219. data/test/namespaces/test_namespaces_in_parsed_doc.rb +80 -0
  220. data/test/namespaces/test_namespaces_preservation.rb +31 -0
  221. data/test/test_convert_xpath.rb +2 -47
  222. data/test/test_css_cache.rb +45 -0
  223. data/test/test_encoding_handler.rb +48 -0
  224. data/test/test_memory_leak.rb +156 -0
  225. data/test/test_nokogiri.rb +103 -1
  226. data/test/test_soap4r_sax.rb +52 -0
  227. data/test/test_xslt_transforms.rb +293 -8
  228. data/test/xml/node/test_save_options.rb +28 -0
  229. data/test/xml/node/test_subclass.rb +44 -0
  230. data/test/xml/sax/test_parser.rb +309 -8
  231. data/test/xml/sax/test_parser_context.rb +115 -0
  232. data/test/xml/sax/test_push_parser.rb +157 -0
  233. data/test/xml/test_attr.rb +67 -0
  234. data/test/xml/test_attribute_decl.rb +86 -0
  235. data/test/xml/test_builder.rb +327 -2
  236. data/test/xml/test_c14n.rb +180 -0
  237. data/test/xml/test_cdata.rb +32 -2
  238. data/test/xml/test_comment.rb +40 -0
  239. data/test/xml/test_document.rb +846 -35
  240. data/test/xml/test_document_encoding.rb +31 -0
  241. data/test/xml/test_document_fragment.rb +271 -0
  242. data/test/xml/test_dtd.rb +153 -9
  243. data/test/xml/test_dtd_encoding.rb +31 -0
  244. data/test/xml/test_element_content.rb +56 -0
  245. data/test/xml/test_element_decl.rb +73 -0
  246. data/test/xml/test_entity_decl.rb +122 -0
  247. data/test/xml/test_entity_reference.rb +251 -0
  248. data/test/xml/test_namespace.rb +96 -0
  249. data/test/xml/test_node.rb +1126 -105
  250. data/test/xml/test_node_attributes.rb +115 -0
  251. data/test/xml/test_node_encoding.rb +69 -0
  252. data/test/xml/test_node_inheritance.rb +32 -0
  253. data/test/xml/test_node_reparenting.rb +549 -0
  254. data/test/xml/test_node_set.rb +668 -9
  255. data/test/xml/test_parse_options.rb +64 -0
  256. data/test/xml/test_processing_instruction.rb +30 -0
  257. data/test/xml/test_reader.rb +589 -0
  258. data/test/xml/test_reader_encoding.rb +134 -0
  259. data/test/xml/test_relax_ng.rb +60 -0
  260. data/test/xml/test_schema.rb +142 -0
  261. data/test/xml/test_syntax_error.rb +30 -0
  262. data/test/xml/test_text.rb +49 -2
  263. data/test/xml/test_unparented_node.rb +440 -0
  264. data/test/xml/test_xinclude.rb +83 -0
  265. data/test/xml/test_xpath.rb +445 -0
  266. data/test/xslt/test_custom_functions.rb +133 -0
  267. data/test/xslt/test_exception_handling.rb +37 -0
  268. data/test_all +107 -0
  269. metadata +459 -115
  270. data/History.txt +0 -6
  271. data/README.ja.txt +0 -86
  272. data/README.txt +0 -87
  273. data/ext/nokogiri/html_sax_parser.c +0 -32
  274. data/ext/nokogiri/html_sax_parser.h +0 -11
  275. data/ext/nokogiri/native.c +0 -40
  276. data/ext/nokogiri/native.h +0 -51
  277. data/ext/nokogiri/xml_xpath.c +0 -46
  278. data/ext/nokogiri/xml_xpath.h +0 -11
  279. data/lib/nokogiri/css/generated_parser.rb +0 -653
  280. data/lib/nokogiri/css/generated_tokenizer.rb +0 -159
  281. data/lib/nokogiri/decorators/hpricot/node.rb +0 -58
  282. data/lib/nokogiri/decorators/hpricot/node_set.rb +0 -14
  283. data/lib/nokogiri/decorators/hpricot/xpath_visitor.rb +0 -17
  284. data/lib/nokogiri/decorators/hpricot.rb +0 -3
  285. data/lib/nokogiri/decorators.rb +0 -1
  286. data/lib/nokogiri/hpricot.rb +0 -47
  287. data/lib/nokogiri/xml/after_handler.rb +0 -18
  288. data/lib/nokogiri/xml/before_handler.rb +0 -32
  289. data/lib/nokogiri/xml/element.rb +0 -6
  290. data/lib/nokogiri/xml/entity_declaration.rb +0 -9
  291. data/nokogiri.gemspec +0 -34
  292. data/test/hpricot/files/basic.xhtml +0 -17
  293. data/test/hpricot/files/boingboing.html +0 -2266
  294. data/test/hpricot/files/cy0.html +0 -3653
  295. data/test/hpricot/files/immob.html +0 -400
  296. data/test/hpricot/files/pace_application.html +0 -1320
  297. data/test/hpricot/files/tenderlove.html +0 -16
  298. data/test/hpricot/files/uswebgen.html +0 -220
  299. data/test/hpricot/files/utf8.html +0 -1054
  300. data/test/hpricot/files/week9.html +0 -1723
  301. data/test/hpricot/files/why.xml +0 -19
  302. data/test/hpricot/load_files.rb +0 -7
  303. data/test/hpricot/test_alter.rb +0 -67
  304. data/test/hpricot/test_builder.rb +0 -27
  305. data/test/hpricot/test_parser.rb +0 -423
  306. data/test/hpricot/test_paths.rb +0 -15
  307. data/test/hpricot/test_preserved.rb +0 -78
  308. data/test/hpricot/test_xml.rb +0 -30
  309. data/test/test_reader.rb +0 -222
@@ -1,10 +1,294 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '..', "helper"))
1
+ require "helper"
2
2
 
3
3
  module Nokogiri
4
4
  module XML
5
5
  class TestNodeSet < Nokogiri::TestCase
6
+ class TestNodeSetNamespaces < Nokogiri::TestCase
7
+ def setup
8
+ super
9
+ @xml = Nokogiri.XML('<foo xmlns:n0="http://example.com" />')
10
+ @list = @xml.xpath('//namespace::*')
11
+ end
12
+
13
+ def test_include?
14
+ assert @list.include?(@list.first), 'list should have item'
15
+ end
16
+
17
+ def test_push
18
+ @list.push @list.first
19
+ end
20
+
21
+ def test_delete
22
+ @list.push @list.first
23
+ @list.delete @list.first
24
+ end
25
+
26
+ def test_reference_after_delete
27
+ first = @list.first
28
+ @list.delete(first)
29
+ assert_equal 'http://www.w3.org/XML/1998/namespace', first.href
30
+ end
31
+ end
32
+
6
33
  def setup
7
- @xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
34
+ super
35
+ @xml = Nokogiri::XML(File.read(XML_FILE), XML_FILE)
36
+ @list = @xml.css('employee')
37
+ end
38
+
39
+ def test_break_works
40
+ assert_equal 7, @xml.root.elements.each { |x| break 7 }
41
+ end
42
+
43
+ def test_filter
44
+ list = @xml.css('address').filter('*[domestic="Yes"]')
45
+ assert_equal(%w{ Yes } * 4, list.map { |n| n['domestic'] })
46
+ end
47
+
48
+ def test_remove_attr
49
+ @list.each { |x| x['class'] = 'blah' }
50
+ assert_equal @list, @list.remove_attr('class')
51
+ @list.each { |x| assert_nil x['class'] }
52
+ end
53
+
54
+ def test_add_class
55
+ assert_equal @list, @list.add_class('bar')
56
+ @list.each { |x| assert_equal 'bar', x['class'] }
57
+
58
+ @list.add_class('bar')
59
+ @list.each { |x| assert_equal 'bar', x['class'] }
60
+
61
+ @list.add_class('baz')
62
+ @list.each { |x| assert_equal 'bar baz', x['class'] }
63
+ end
64
+
65
+ def test_remove_class_with_no_class
66
+ assert_equal @list, @list.remove_class('bar')
67
+ @list.each { |e| assert_nil e['class'] }
68
+
69
+ @list.each { |e| e['class'] = '' }
70
+ assert_equal @list, @list.remove_class('bar')
71
+ @list.each { |e| assert_nil e['class'] }
72
+ end
73
+
74
+ def test_remove_class_single
75
+ @list.each { |e| e['class'] = 'foo bar' }
76
+
77
+ assert_equal @list, @list.remove_class('bar')
78
+ @list.each { |e| assert_equal 'foo', e['class'] }
79
+ end
80
+
81
+ def test_remove_class_completely
82
+ @list.each { |e| e['class'] = 'foo' }
83
+
84
+ assert_equal @list, @list.remove_class
85
+ @list.each { |e| assert_nil e['class'] }
86
+ end
87
+
88
+ def test_attribute_set
89
+ @list.each { |e| assert_nil e['foo'] }
90
+
91
+ [ ['attribute', 'bar'], ['attr', 'biz'], ['set', 'baz'] ].each do |t|
92
+ @list.send(t.first.to_sym, 'foo', t.last)
93
+ @list.each { |e| assert_equal t.last, e['foo'] }
94
+ end
95
+ end
96
+
97
+ def test_attribute_set_with_block
98
+ @list.each { |e| assert_nil e['foo'] }
99
+
100
+ [ ['attribute', 'bar'], ['attr', 'biz'], ['set', 'baz'] ].each do |t|
101
+ @list.send(t.first.to_sym, 'foo') { |x| t.last }
102
+ @list.each { |e| assert_equal t.last, e['foo'] }
103
+ end
104
+ end
105
+
106
+ def test_attribute_set_with_hash
107
+ @list.each { |e| assert_nil e['foo'] }
108
+
109
+ [ ['attribute', 'bar'], ['attr', 'biz'], ['set', 'baz'] ].each do |t|
110
+ @list.send(t.first.to_sym, 'foo' => t.last)
111
+ @list.each { |e| assert_equal t.last, e['foo'] }
112
+ end
113
+ end
114
+
115
+ def test_attribute_no_args
116
+ @list.first['foo'] = 'bar'
117
+ assert_equal @list.first.attribute('foo'), @list.attribute('foo')
118
+ end
119
+
120
+ def test_search_empty_node_set
121
+ set = Nokogiri::XML::NodeSet.new(Nokogiri::XML::Document.new)
122
+ assert_equal 0, set.css('foo').length
123
+ assert_equal 0, set.xpath('.//foo').length
124
+ assert_equal 0, set.search('foo').length
125
+ end
126
+
127
+ def test_node_set_search_with_multiple_queries
128
+ xml = '<document>
129
+ <thing>
130
+ <div class="title">important thing</div>
131
+ </thing>
132
+ <thing>
133
+ <div class="content">stuff</div>
134
+ </thing>
135
+ <thing>
136
+ <p class="blah">more stuff</div>
137
+ </thing>
138
+ </document>'
139
+ set = Nokogiri::XML(xml).xpath(".//thing")
140
+ assert_kind_of Nokogiri::XML::NodeSet, set
141
+
142
+ assert_equal 3, set.xpath('./div', './p').length
143
+ assert_equal 3, set.css('.title', '.content', 'p').length
144
+ assert_equal 3, set.search('./div', 'p.blah').length
145
+ end
146
+
147
+ def test_search_with_custom_selector
148
+ set = @xml.xpath('//staff')
149
+
150
+ [
151
+ [:xpath, '//*[awesome(.)]'],
152
+ [:search, '//*[awesome(.)]'],
153
+ [:css, '*:awesome'],
154
+ [:search, '*:awesome']
155
+ ].each do |method, query|
156
+ custom_employees = set.send(method, query, Class.new {
157
+ def awesome ns
158
+ ns.select { |n| n.name == 'employee' }
159
+ end
160
+ }.new)
161
+
162
+ assert_equal(@xml.xpath('//employee'), custom_employees,
163
+ "using #{method} with custom selector '#{query}'")
164
+ end
165
+ end
166
+
167
+ def test_search_with_variable_bindings
168
+ set = @xml.xpath('//staff')
169
+
170
+ assert_equal(4, set.xpath('//address[@domestic=$value]', nil, :value => 'Yes').length,
171
+ "using #xpath with variable binding")
172
+
173
+ assert_equal(4, set.search('//address[@domestic=$value]', nil, :value => 'Yes').length,
174
+ "using #search with variable binding")
175
+ end
176
+
177
+ def test_search_self
178
+ set = @xml.xpath('//staff')
179
+ assert_equal set.to_a, set.search('.').to_a
180
+ end
181
+
182
+ def test_css_searches_match_self
183
+ html = Nokogiri::HTML("<html><body><div class='a'></div></body></html>")
184
+ set = html.xpath("/html/body/div")
185
+ assert_equal set.first, set.css(".a").first
186
+ assert_equal set.first, set.search(".a").first
187
+ end
188
+
189
+ def test_css_search_with_namespace
190
+ fragment = Nokogiri::XML.fragment(<<-eoxml)
191
+ <html xmlns="http://www.w3.org/1999/xhtml">
192
+ <head></head>
193
+ <body></body>
194
+ </html>
195
+ eoxml
196
+ assert fragment.children.search( 'body', { 'xmlns' => 'http://www.w3.org/1999/xhtml' })
197
+ end
198
+
199
+ def test_double_equal
200
+ assert node_set_one = @xml.xpath('//employee')
201
+ assert node_set_two = @xml.xpath('//employee')
202
+
203
+ assert_not_equal node_set_one.object_id, node_set_two.object_id
204
+
205
+ assert_equal node_set_one, node_set_two
206
+ end
207
+
208
+ def test_node_set_not_equal_to_string
209
+ node_set_one = @xml.xpath('//employee')
210
+ assert_not_equal node_set_one, "asdfadsf"
211
+ end
212
+
213
+ def test_out_of_order_not_equal
214
+ one = @xml.xpath('//employee')
215
+ two = @xml.xpath('//employee')
216
+ two.push two.shift
217
+ assert_not_equal one, two
218
+ end
219
+
220
+ def test_shorter_is_not_equal
221
+ node_set_one = @xml.xpath('//employee')
222
+ node_set_two = @xml.xpath('//employee')
223
+ node_set_two.delete(node_set_two.first)
224
+
225
+ assert_not_equal node_set_one, node_set_two
226
+ end
227
+
228
+ def test_pop
229
+ set = @xml.xpath('//employee')
230
+ last = set.last
231
+ assert_equal last, set.pop
232
+ end
233
+
234
+ def test_shift
235
+ set = @xml.xpath('//employee')
236
+ first = set.first
237
+ assert_equal first, set.shift
238
+ end
239
+
240
+ def test_shift_empty
241
+ set = Nokogiri::XML::NodeSet.new(@xml)
242
+ assert_nil set.shift
243
+ end
244
+
245
+ def test_pop_empty
246
+ set = Nokogiri::XML::NodeSet.new(@xml)
247
+ assert_nil set.pop
248
+ end
249
+
250
+ def test_first_takes_arguments
251
+ assert node_set = @xml.xpath('//employee')
252
+ assert_equal 2, node_set.first(2).length
253
+ end
254
+
255
+ def test_dup
256
+ assert node_set = @xml.xpath('//employee')
257
+ dup = node_set.dup
258
+ assert_equal node_set.length, dup.length
259
+ node_set.zip(dup).each do |a,b|
260
+ assert_equal a, b
261
+ end
262
+ end
263
+
264
+ def test_dup_on_empty_set
265
+ empty_set = Nokogiri::XML::NodeSet.new @xml, []
266
+ assert_equal 0, empty_set.dup.length # this shouldn't raise null pointer exception
267
+ end
268
+
269
+ def test_xmlns_is_automatically_registered
270
+ doc = Nokogiri::XML(<<-eoxml)
271
+ <root xmlns="http://tenderlovemaking.com/">
272
+ <foo>
273
+ <bar/>
274
+ </foo>
275
+ </root>
276
+ eoxml
277
+ set = doc.css('foo')
278
+ assert_equal 1, set.css('xmlns|bar').length
279
+ assert_equal 0, set.css('|bar').length
280
+ assert_equal 1, set.xpath('//xmlns:bar').length
281
+ assert_equal 1, set.search('xmlns|bar').length
282
+ assert_equal 1, set.search('//xmlns:bar').length
283
+ assert set.at('//xmlns:bar')
284
+ assert set.at('xmlns|bar')
285
+ assert set.at('bar')
286
+ end
287
+
288
+ def test_children_has_document
289
+ set = @xml.root.children
290
+ assert_instance_of(NodeSet, set)
291
+ assert_equal @xml, set.document
8
292
  end
9
293
 
10
294
  def test_length_size
@@ -12,13 +296,70 @@ module Nokogiri
12
296
  assert_equal node_set.length, node_set.size
13
297
  end
14
298
 
15
- def test_at
299
+ def test_to_xml
300
+ assert node_set = @xml.search('//employee')
301
+ assert node_set.to_xml
302
+ end
303
+
304
+ def test_inner_html
305
+ doc = Nokogiri::HTML(<<-eohtml)
306
+ <html>
307
+ <body>
308
+ <div>
309
+ <a>one</a>
310
+ </div>
311
+ <div>
312
+ <a>two</a>
313
+ </div>
314
+ </body>
315
+ </html>
316
+ eohtml
317
+ assert html = doc.css('div').inner_html
318
+ assert_match '<a>', html
319
+ end
320
+
321
+ def test_gt_string_arg
322
+ assert node_set = @xml.search('//employee')
323
+ assert_equal node_set.xpath('./employeeId'), (node_set > 'employeeId')
324
+ end
325
+
326
+ def test_at_performs_a_search_with_css
327
+ assert node_set = @xml.search('//employee')
328
+ assert_equal node_set.first.first_element_child, node_set.at('employeeId')
329
+ assert_equal node_set.first.first_element_child, node_set.%('employeeId')
330
+ end
331
+
332
+ def test_at_performs_a_search_with_xpath
333
+ assert node_set = @xml.search('//employee')
334
+ assert_equal node_set.first.first_element_child, node_set.at('./employeeId')
335
+ assert_equal node_set.first.first_element_child, node_set.%('./employeeId')
336
+ end
337
+
338
+ def test_at_with_integer_index
16
339
  assert node_set = @xml.search('//employee')
17
340
  assert_equal node_set.first, node_set.at(0)
341
+ assert_equal node_set.first, node_set % 0
342
+ end
343
+
344
+ def test_at_xpath
345
+ assert node_set = @xml.search('//employee')
346
+ assert_equal node_set.first.first_element_child, node_set.at_xpath('./employeeId')
347
+ end
348
+
349
+ def test_at_css
350
+ assert node_set = @xml.search('//employee')
351
+ assert_equal node_set.first.first_element_child, node_set.at_css('employeeId')
352
+ end
353
+
354
+ def test_to_ary
355
+ assert node_set = @xml.search('//employee')
356
+ foo = []
357
+ foo += node_set
358
+ assert_equal node_set.length, foo.length
18
359
  end
19
360
 
20
361
  def test_push
21
- node = Nokogiri::XML::Node.new('foo')
362
+ node = Nokogiri::XML::Node.new('foo', @xml)
22
363
  node.content = 'bar'
23
364
 
24
365
  assert node_set = @xml.search('//employee')
@@ -27,6 +368,42 @@ module Nokogiri
27
368
  assert node_set.include?(node)
28
369
  end
29
370
 
371
+ def test_delete_with_invalid_argument
372
+ employees = @xml.search("//employee")
373
+ positions = @xml.search("//position")
374
+
375
+ assert_raises(ArgumentError) { employees.delete(positions) }
376
+ end
377
+
378
+ def test_delete_when_present
379
+ employees = @xml.search("//employee")
380
+ wally = employees.first
381
+ assert employees.include?(wally) # testing setup
382
+ length = employees.length
383
+
384
+ result = employees.delete(wally)
385
+ assert_equal result, wally
386
+ assert ! employees.include?(wally)
387
+ assert length-1, employees.length
388
+ end
389
+
390
+ def test_delete_when_not_present
391
+ employees = @xml.search("//employee")
392
+ phb = @xml.search("//position").first
393
+ assert ! employees.include?(phb) # testing setup
394
+ length = employees.length
395
+
396
+ result = employees.delete(phb)
397
+ assert_nil result
398
+ assert length, employees.length
399
+ end
400
+
401
+ def test_delete_on_empty_set
402
+ empty_set = Nokogiri::XML::NodeSet.new @xml, []
403
+ employee = @xml.at_xpath("//employee")
404
+ assert_equal nil, empty_set.delete(employee)
405
+ end
406
+
30
407
  def test_unlink
31
408
  xml = Nokogiri::XML.parse(<<-eoxml)
32
409
  <root>
@@ -43,12 +420,10 @@ module Nokogiri
43
420
  set.unlink
44
421
  set.each do |node|
45
422
  assert !node.parent
46
- # assert !node.document # ugh. libxml doesn't clear node->doc pointer, due to xmlDict implementation.
423
+ #assert !node.document
47
424
  assert !node.previous_sibling
48
425
  assert !node.next_sibling
49
- assert !node.instance_eval{ owned? }
50
426
  end
51
- assert !set.document
52
427
  assert_no_match(/Hello world/, xml.to_s)
53
428
  end
54
429
 
@@ -70,9 +445,9 @@ module Nokogiri
70
445
  end
71
446
 
72
447
  def test_new_nodeset
73
- node_set = Nokogiri::XML::NodeSet.new
448
+ node_set = Nokogiri::XML::NodeSet.new(@xml)
74
449
  assert_equal(0, node_set.length)
75
- node = Nokogiri::XML::Node.new('form')
450
+ node = Nokogiri::XML::Node.new('form', @xml)
76
451
  node_set << node
77
452
  assert_equal(1, node_set.length)
78
453
  assert_equal(node, node_set.last)
@@ -111,6 +486,290 @@ module Nokogiri
111
486
  assert_equal 'wrapper', employees[0].parent.name
112
487
  assert_equal 'employee', @xml.search("//wrapper").first.children[0].name
113
488
  end
489
+
490
+ def test_wrap_a_fragment
491
+ frag = Nokogiri::XML::DocumentFragment.parse <<-EOXML
492
+ <employees>
493
+ <employee>hello</employee>
494
+ <employee>goodbye</employee>
495
+ </employees>
496
+ EOXML
497
+ employees = frag.xpath ".//employee"
498
+ employees.wrap("<wrapper/>")
499
+ assert_equal 'wrapper', employees[0].parent.name
500
+ assert_equal 'employee', frag.at(".//wrapper").children.first.name
501
+ end
502
+
503
+ def test_wrap_preserves_document_structure
504
+ assert_equal "employeeId",
505
+ @xml.at_xpath("//employee").children.detect{|j| ! j.text? }.name
506
+ @xml.xpath("//employeeId[text()='EMP0001']").wrap("<wrapper/>")
507
+ assert_equal "wrapper",
508
+ @xml.at_xpath("//employee").children.detect{|j| ! j.text? }.name
509
+ end
510
+
511
+ def test_plus_operator
512
+ names = @xml.search("name")
513
+ positions = @xml.search("position")
514
+
515
+ names_len = names.length
516
+ positions_len = positions.length
517
+
518
+ assert_raises(ArgumentError) { names + positions.first }
519
+
520
+ result = names + positions
521
+ assert_equal names_len, names.length
522
+ assert_equal positions_len, positions.length
523
+ assert_equal names.length + positions.length, result.length
524
+
525
+ names += positions
526
+ assert_equal result.length, names.length
527
+ end
528
+
529
+ def test_union
530
+ names = @xml.search("name")
531
+
532
+ assert_equal(names.length, (names | @xml.search("name")).length)
533
+ end
534
+
535
+ def test_minus_operator
536
+ employees = @xml.search("//employee")
537
+ females = @xml.search("//employee[gender[text()='Female']]")
538
+
539
+ employees_len = employees.length
540
+ females_len = females.length
541
+
542
+ assert_raises(ArgumentError) { employees - females.first }
543
+
544
+ result = employees - females
545
+ assert_equal employees_len, employees.length
546
+ assert_equal females_len, females.length
547
+ assert_equal employees.length - females.length, result.length
548
+
549
+ employees -= females
550
+ assert_equal result.length, employees.length
551
+ end
552
+
553
+ def test_array_index
554
+ employees = @xml.search("//employee")
555
+ other = @xml.search("//position").first
556
+
557
+ assert_equal 3, employees.index(employees[3])
558
+ assert_nil employees.index(other)
559
+ end
560
+
561
+ def test_slice_too_far
562
+ employees = @xml.search("//employee")
563
+ assert_equal employees.length, employees[0, employees.length + 1].length
564
+ assert_equal employees.length, employees[0, employees.length].length
565
+ end
566
+
567
+ def test_slice_on_empty_node_set
568
+ empty_set = Nokogiri::XML::NodeSet.new @xml, []
569
+ assert_equal nil, empty_set[99]
570
+ assert_equal nil, empty_set[99..101]
571
+ assert_equal nil, empty_set[99,2]
572
+ end
573
+
574
+ def test_slice_waaaaaay_off_the_end
575
+ xml = Nokogiri::XML::Builder.new {
576
+ root { 100.times { div } }
577
+ }.doc
578
+ nodes = xml.css "div"
579
+ assert_equal 1, nodes.slice(99, 100_000).length
580
+ assert_equal 0, nodes.slice(100, 100_000).length
581
+ end
582
+
583
+ def test_array_slice_with_start_and_end
584
+ employees = @xml.search("//employee")
585
+ assert_equal [employees[1], employees[2], employees[3]], employees[1,3].to_a
586
+ end
587
+
588
+ def test_array_index_bracket_equivalence
589
+ employees = @xml.search("//employee")
590
+ assert_equal [employees[1], employees[2], employees[3]], employees[1,3].to_a
591
+ assert_equal [employees[1], employees[2], employees[3]], employees.slice(1,3).to_a
592
+ end
593
+
594
+ def test_array_slice_with_negative_start
595
+ employees = @xml.search("//employee")
596
+ assert_equal [employees[2]], employees[-3,1].to_a
597
+ assert_equal [employees[2], employees[3]], employees[-3,2].to_a
598
+ end
599
+
600
+ def test_array_slice_with_invalid_args
601
+ employees = @xml.search("//employee")
602
+ assert_nil employees[99, 1] # large start
603
+ assert_nil employees[1, -1] # negative len
604
+ assert_equal [], employees[1, 0].to_a # zero len
605
+ end
606
+
607
+ def test_array_slice_with_range
608
+ employees = @xml.search("//employee")
609
+ assert_equal [employees[1], employees[2], employees[3]], employees[1..3].to_a
610
+ assert_equal [employees[0], employees[1], employees[2], employees[3]], employees[0..3].to_a
611
+ end
612
+
613
+ def test_intersection_with_no_overlap
614
+ employees = @xml.search("//employee")
615
+ positions = @xml.search("//position")
616
+
617
+ assert_equal [], (employees & positions).to_a
618
+ end
619
+
620
+ def test_intersection
621
+ employees = @xml.search("//employee")
622
+ first_set = employees[0..2]
623
+ second_set = employees[2..4]
624
+
625
+ assert_equal [employees[2]], (first_set & second_set).to_a
626
+ end
627
+
628
+ def test_intersection_on_empty_set
629
+ empty_set = Nokogiri::XML::NodeSet.new @xml
630
+ employees = @xml.search("//employee")
631
+ assert_equal 0, (empty_set & employees).length
632
+ end
633
+
634
+ def test_include?
635
+ employees = @xml.search("//employee")
636
+ yes = employees.first
637
+ no = @xml.search("//position").first
638
+
639
+ assert employees.include?(yes)
640
+ assert ! employees.include?(no)
641
+ end
642
+
643
+ def test_include_on_empty_node_set
644
+ empty_set = Nokogiri::XML::NodeSet.new @xml, []
645
+ employee = @xml.at_xpath("//employee")
646
+ assert ! empty_set.include?(employee)
647
+ end
648
+
649
+ def test_children
650
+ employees = @xml.search("//employee")
651
+ count = 0
652
+ employees.each do |employee|
653
+ count += employee.children.length
654
+ end
655
+ set = employees.children
656
+ assert_equal count, set.length
657
+ end
658
+
659
+ def test_inspect
660
+ employees = @xml.search("//employee")
661
+ inspected = employees.inspect
662
+
663
+ assert_equal "[#{employees.map(&:inspect).join(', ')}]",
664
+ inspected
665
+ end
666
+
667
+ def test_should_not_splode_when_accessing_namespace_declarations_in_a_node_set
668
+ 2.times do
669
+ xml = Nokogiri::XML "<foo></foo>"
670
+ node_set = xml.xpath("//namespace::*")
671
+ assert_equal 1, node_set.size
672
+ node = node_set.first
673
+ node.to_s # segfaults in 1.4.0 and earlier
674
+
675
+ # if we haven't segfaulted, let's make sure we handled it correctly
676
+ assert_instance_of Nokogiri::XML::Namespace, node
677
+ end
678
+ end
679
+
680
+ def test_should_not_splode_when_arrayifying_node_set_containing_namespace_declarations
681
+ xml = Nokogiri::XML "<foo></foo>"
682
+ node_set = xml.xpath("//namespace::*")
683
+ assert_equal 1, node_set.size
684
+
685
+ node_array = node_set.to_a
686
+ node = node_array.first
687
+ node.to_s # segfaults in 1.4.0 and earlier
688
+
689
+ # if we haven't segfaulted, let's make sure we handled it correctly
690
+ assert_instance_of Nokogiri::XML::Namespace, node
691
+ end
692
+
693
+ def test_should_not_splode_when_unlinking_node_set_containing_namespace_declarations
694
+ xml = Nokogiri::XML "<foo></foo>"
695
+ node_set = xml.xpath("//namespace::*")
696
+ assert_equal 1, node_set.size
697
+
698
+ node_set.unlink
699
+ end
700
+
701
+ def test_reverse
702
+ xml = Nokogiri::XML "<root><a />b<c />d<e /></root>"
703
+ children = xml.root.children
704
+ assert_instance_of Nokogiri::XML::NodeSet, children
705
+
706
+ reversed = children.reverse
707
+ assert_equal reversed[0], children[4]
708
+ assert_equal reversed[1], children[3]
709
+ assert_equal reversed[2], children[2]
710
+ assert_equal reversed[3], children[1]
711
+ assert_equal reversed[4], children[0]
712
+
713
+ assert_equal children, children.reverse.reverse
714
+ end
715
+
716
+ def test_node_set_dup_result_has_document_and_is_decorated
717
+ x = Module.new do
718
+ def awesome! ; end
719
+ end
720
+ util_decorate(@xml, x)
721
+ node_set = @xml.css("address")
722
+ new_set = node_set.dup
723
+ assert_equal node_set.document, new_set.document
724
+ assert new_set.respond_to?(:awesome!)
725
+ end
726
+
727
+ def test_node_set_union_result_has_document_and_is_decorated
728
+ x = Module.new do
729
+ def awesome! ; end
730
+ end
731
+ util_decorate(@xml, x)
732
+ node_set1 = @xml.css("address")
733
+ node_set2 = @xml.css("address")
734
+ new_set = node_set1 | node_set2
735
+ assert_equal node_set1.document, new_set.document
736
+ assert new_set.respond_to?(:awesome!)
737
+ end
738
+
739
+ def test_node_set_intersection_result_has_document_and_is_decorated
740
+ x = Module.new do
741
+ def awesome! ; end
742
+ end
743
+ util_decorate(@xml, x)
744
+ node_set1 = @xml.css("address")
745
+ node_set2 = @xml.css("address")
746
+ new_set = node_set1 & node_set2
747
+ assert_equal node_set1.document, new_set.document
748
+ assert new_set.respond_to?(:awesome!)
749
+ end
750
+
751
+ def test_node_set_difference_result_has_document_and_is_decorated
752
+ x = Module.new do
753
+ def awesome! ; end
754
+ end
755
+ util_decorate(@xml, x)
756
+ node_set1 = @xml.css("address")
757
+ node_set2 = @xml.css("address")
758
+ new_set = node_set1 - node_set2
759
+ assert_equal node_set1.document, new_set.document
760
+ assert new_set.respond_to?(:awesome!)
761
+ end
762
+
763
+ def test_node_set_slice_result_has_document_and_is_decorated
764
+ x = Module.new do
765
+ def awesome! ; end
766
+ end
767
+ util_decorate(@xml, x)
768
+ node_set = @xml.css("address")
769
+ new_set = node_set[0..-1]
770
+ assert_equal node_set.document, new_set.document
771
+ assert new_set.respond_to?(:awesome!)
772
+ end
114
773
  end
115
774
  end
116
775
  end