nokogiri 1.2.3-x86-mswin32-60 → 1.4.5-x86-mswin32-60

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 (319) hide show
  1. data/.autotest +18 -7
  2. data/.gemtest +0 -0
  3. data/CHANGELOG.ja.rdoc +297 -3
  4. data/CHANGELOG.rdoc +289 -0
  5. data/Manifest.txt +148 -37
  6. data/README.ja.rdoc +20 -20
  7. data/README.rdoc +53 -22
  8. data/Rakefile +127 -211
  9. data/bin/nokogiri +54 -0
  10. data/ext/nokogiri/depend +358 -0
  11. data/ext/nokogiri/extconf.rb +89 -54
  12. data/ext/nokogiri/html_document.c +34 -27
  13. data/ext/nokogiri/html_document.h +1 -1
  14. data/ext/nokogiri/html_element_description.c +276 -0
  15. data/ext/nokogiri/html_element_description.h +10 -0
  16. data/ext/nokogiri/html_entity_lookup.c +7 -5
  17. data/ext/nokogiri/html_entity_lookup.h +1 -1
  18. data/ext/nokogiri/html_sax_parser_context.c +94 -0
  19. data/ext/nokogiri/html_sax_parser_context.h +11 -0
  20. data/ext/nokogiri/{native.c → nokogiri.c} +31 -7
  21. data/ext/nokogiri/{native.h → nokogiri.h} +68 -41
  22. data/ext/nokogiri/xml_attr.c +20 -9
  23. data/ext/nokogiri/xml_attr.h +1 -1
  24. data/ext/nokogiri/xml_attribute_decl.c +70 -0
  25. data/ext/nokogiri/xml_attribute_decl.h +9 -0
  26. data/ext/nokogiri/xml_cdata.c +21 -9
  27. data/ext/nokogiri/xml_cdata.h +1 -1
  28. data/ext/nokogiri/xml_comment.c +18 -6
  29. data/ext/nokogiri/xml_comment.h +1 -1
  30. data/ext/nokogiri/xml_document.c +247 -68
  31. data/ext/nokogiri/xml_document.h +5 -3
  32. data/ext/nokogiri/xml_document_fragment.c +15 -7
  33. data/ext/nokogiri/xml_document_fragment.h +1 -1
  34. data/ext/nokogiri/xml_dtd.c +110 -10
  35. data/ext/nokogiri/xml_dtd.h +3 -1
  36. data/ext/nokogiri/xml_element_content.c +123 -0
  37. data/ext/nokogiri/xml_element_content.h +10 -0
  38. data/ext/nokogiri/xml_element_decl.c +69 -0
  39. data/ext/nokogiri/xml_element_decl.h +9 -0
  40. data/ext/nokogiri/xml_encoding_handler.c +79 -0
  41. data/ext/nokogiri/xml_encoding_handler.h +8 -0
  42. data/ext/nokogiri/xml_entity_decl.c +110 -0
  43. data/ext/nokogiri/xml_entity_decl.h +10 -0
  44. data/ext/nokogiri/xml_entity_reference.c +16 -5
  45. data/ext/nokogiri/xml_entity_reference.h +1 -1
  46. data/ext/nokogiri/xml_io.c +40 -8
  47. data/ext/nokogiri/xml_io.h +2 -1
  48. data/ext/nokogiri/xml_libxml2_hacks.c +112 -0
  49. data/ext/nokogiri/xml_libxml2_hacks.h +12 -0
  50. data/ext/nokogiri/xml_namespace.c +84 -0
  51. data/ext/nokogiri/xml_namespace.h +13 -0
  52. data/ext/nokogiri/xml_node.c +782 -225
  53. data/ext/nokogiri/xml_node.h +2 -4
  54. data/ext/nokogiri/xml_node_set.c +253 -34
  55. data/ext/nokogiri/xml_node_set.h +2 -2
  56. data/ext/nokogiri/xml_processing_instruction.c +17 -5
  57. data/ext/nokogiri/xml_processing_instruction.h +1 -1
  58. data/ext/nokogiri/xml_reader.c +277 -85
  59. data/ext/nokogiri/xml_reader.h +1 -1
  60. data/ext/nokogiri/xml_relax_ng.c +168 -0
  61. data/ext/nokogiri/xml_relax_ng.h +9 -0
  62. data/ext/nokogiri/xml_sax_parser.c +183 -111
  63. data/ext/nokogiri/xml_sax_parser.h +30 -1
  64. data/ext/nokogiri/xml_sax_parser_context.c +199 -0
  65. data/ext/nokogiri/xml_sax_parser_context.h +10 -0
  66. data/ext/nokogiri/xml_sax_push_parser.c +42 -12
  67. data/ext/nokogiri/xml_sax_push_parser.h +1 -1
  68. data/ext/nokogiri/xml_schema.c +205 -0
  69. data/ext/nokogiri/xml_schema.h +9 -0
  70. data/ext/nokogiri/xml_syntax_error.c +28 -173
  71. data/ext/nokogiri/xml_syntax_error.h +2 -1
  72. data/ext/nokogiri/xml_text.c +16 -6
  73. data/ext/nokogiri/xml_text.h +1 -1
  74. data/ext/nokogiri/xml_xpath_context.c +104 -47
  75. data/ext/nokogiri/xml_xpath_context.h +1 -1
  76. data/ext/nokogiri/xslt_stylesheet.c +161 -19
  77. data/ext/nokogiri/xslt_stylesheet.h +1 -1
  78. data/lib/nokogiri.rb +47 -8
  79. data/lib/nokogiri/1.8/nokogiri.so +0 -0
  80. data/lib/nokogiri/1.9/nokogiri.so +0 -0
  81. data/lib/nokogiri/css.rb +6 -3
  82. data/lib/nokogiri/css/node.rb +14 -12
  83. data/lib/nokogiri/css/parser.rb +665 -62
  84. data/lib/nokogiri/css/parser.y +20 -10
  85. data/lib/nokogiri/css/parser_extras.rb +91 -0
  86. data/lib/nokogiri/css/tokenizer.rb +148 -5
  87. data/lib/nokogiri/css/tokenizer.rex +10 -9
  88. data/lib/nokogiri/css/xpath_visitor.rb +47 -44
  89. data/lib/nokogiri/decorators/slop.rb +8 -4
  90. data/lib/nokogiri/ffi/encoding_handler.rb +42 -0
  91. data/lib/nokogiri/ffi/html/document.rb +28 -0
  92. data/lib/nokogiri/ffi/html/element_description.rb +81 -0
  93. data/lib/nokogiri/ffi/html/entity_lookup.rb +16 -0
  94. data/lib/nokogiri/ffi/html/sax/parser_context.rb +38 -0
  95. data/lib/nokogiri/ffi/io_callbacks.rb +42 -0
  96. data/lib/nokogiri/ffi/libxml.rb +420 -0
  97. data/lib/nokogiri/ffi/structs/common_node.rb +38 -0
  98. data/lib/nokogiri/ffi/structs/html_elem_desc.rb +24 -0
  99. data/lib/nokogiri/ffi/structs/html_entity_desc.rb +13 -0
  100. data/lib/nokogiri/ffi/structs/xml_alloc.rb +16 -0
  101. data/lib/nokogiri/ffi/structs/xml_attr.rb +20 -0
  102. data/lib/nokogiri/ffi/structs/xml_attribute.rb +27 -0
  103. data/lib/nokogiri/ffi/structs/xml_buffer.rb +16 -0
  104. data/lib/nokogiri/ffi/structs/xml_char_encoding_handler.rb +11 -0
  105. data/lib/nokogiri/ffi/structs/xml_document.rb +117 -0
  106. data/lib/nokogiri/ffi/structs/xml_dtd.rb +28 -0
  107. data/lib/nokogiri/ffi/structs/xml_element.rb +26 -0
  108. data/lib/nokogiri/ffi/structs/xml_element_content.rb +17 -0
  109. data/lib/nokogiri/ffi/structs/xml_entity.rb +32 -0
  110. data/lib/nokogiri/ffi/structs/xml_enumeration.rb +12 -0
  111. data/lib/nokogiri/ffi/structs/xml_node.rb +28 -0
  112. data/lib/nokogiri/ffi/structs/xml_node_set.rb +53 -0
  113. data/lib/nokogiri/ffi/structs/xml_notation.rb +11 -0
  114. data/lib/nokogiri/ffi/structs/xml_ns.rb +15 -0
  115. data/lib/nokogiri/ffi/structs/xml_parser_context.rb +20 -0
  116. data/lib/nokogiri/ffi/structs/xml_parser_input.rb +19 -0
  117. data/lib/nokogiri/ffi/structs/xml_relax_ng.rb +14 -0
  118. data/lib/nokogiri/ffi/structs/xml_sax_handler.rb +51 -0
  119. data/lib/nokogiri/ffi/structs/xml_sax_push_parser_context.rb +124 -0
  120. data/lib/nokogiri/ffi/structs/xml_schema.rb +13 -0
  121. data/lib/nokogiri/ffi/structs/xml_syntax_error.rb +31 -0
  122. data/lib/nokogiri/ffi/structs/xml_text_reader.rb +12 -0
  123. data/lib/nokogiri/ffi/structs/xml_xpath_context.rb +38 -0
  124. data/lib/nokogiri/ffi/structs/xml_xpath_object.rb +35 -0
  125. data/lib/nokogiri/ffi/structs/xml_xpath_parser_context.rb +20 -0
  126. data/lib/nokogiri/ffi/structs/xslt_stylesheet.rb +13 -0
  127. data/lib/nokogiri/ffi/weak_bucket.rb +40 -0
  128. data/lib/nokogiri/ffi/xml/attr.rb +41 -0
  129. data/lib/nokogiri/ffi/xml/attribute_decl.rb +27 -0
  130. data/lib/nokogiri/ffi/xml/cdata.rb +19 -0
  131. data/lib/nokogiri/ffi/xml/comment.rb +18 -0
  132. data/lib/nokogiri/ffi/xml/document.rb +174 -0
  133. data/lib/nokogiri/ffi/xml/document_fragment.rb +21 -0
  134. data/lib/nokogiri/ffi/xml/dtd.rb +67 -0
  135. data/lib/nokogiri/ffi/xml/element_content.rb +43 -0
  136. data/lib/nokogiri/ffi/xml/element_decl.rb +19 -0
  137. data/lib/nokogiri/ffi/xml/entity_decl.rb +36 -0
  138. data/lib/nokogiri/ffi/xml/entity_reference.rb +19 -0
  139. data/lib/nokogiri/ffi/xml/namespace.rb +44 -0
  140. data/lib/nokogiri/ffi/xml/node.rb +559 -0
  141. data/lib/nokogiri/ffi/xml/node_set.rb +150 -0
  142. data/lib/nokogiri/ffi/xml/processing_instruction.rb +20 -0
  143. data/lib/nokogiri/ffi/xml/reader.rb +236 -0
  144. data/lib/nokogiri/ffi/xml/relax_ng.rb +85 -0
  145. data/lib/nokogiri/ffi/xml/sax/parser.rb +143 -0
  146. data/lib/nokogiri/ffi/xml/sax/parser_context.rb +79 -0
  147. data/lib/nokogiri/ffi/xml/sax/push_parser.rb +51 -0
  148. data/lib/nokogiri/ffi/xml/schema.rb +109 -0
  149. data/lib/nokogiri/ffi/xml/syntax_error.rb +98 -0
  150. data/lib/nokogiri/ffi/xml/text.rb +18 -0
  151. data/lib/nokogiri/ffi/xml/xpath.rb +9 -0
  152. data/lib/nokogiri/ffi/xml/xpath_context.rb +153 -0
  153. data/lib/nokogiri/ffi/xslt/stylesheet.rb +77 -0
  154. data/lib/nokogiri/html.rb +13 -47
  155. data/lib/nokogiri/html/builder.rb +27 -1
  156. data/lib/nokogiri/html/document.rb +201 -7
  157. data/lib/nokogiri/html/document_fragment.rb +41 -0
  158. data/lib/nokogiri/html/element_description.rb +23 -0
  159. data/lib/nokogiri/html/entity_lookup.rb +2 -0
  160. data/lib/nokogiri/html/sax/parser.rb +34 -3
  161. data/lib/nokogiri/html/sax/parser_context.rb +16 -0
  162. data/lib/nokogiri/nokogiri.rb +1 -0
  163. data/lib/nokogiri/version.rb +40 -1
  164. data/lib/nokogiri/version_warning.rb +14 -0
  165. data/lib/nokogiri/xml.rb +32 -53
  166. data/lib/nokogiri/xml/attr.rb +5 -0
  167. data/lib/nokogiri/xml/attribute_decl.rb +18 -0
  168. data/lib/nokogiri/xml/builder.rb +349 -29
  169. data/lib/nokogiri/xml/cdata.rb +3 -1
  170. data/lib/nokogiri/xml/character_data.rb +7 -0
  171. data/lib/nokogiri/xml/document.rb +166 -14
  172. data/lib/nokogiri/xml/document_fragment.rb +76 -1
  173. data/lib/nokogiri/xml/dtd.rb +16 -3
  174. data/lib/nokogiri/xml/element_content.rb +36 -0
  175. data/lib/nokogiri/xml/element_decl.rb +13 -0
  176. data/lib/nokogiri/xml/entity_decl.rb +19 -0
  177. data/lib/nokogiri/xml/namespace.rb +13 -0
  178. data/lib/nokogiri/xml/node.rb +561 -166
  179. data/lib/nokogiri/xml/node/save_options.rb +22 -2
  180. data/lib/nokogiri/xml/node_set.rb +202 -40
  181. data/lib/nokogiri/xml/parse_options.rb +93 -0
  182. data/lib/nokogiri/xml/pp.rb +2 -0
  183. data/lib/nokogiri/xml/pp/character_data.rb +18 -0
  184. data/lib/nokogiri/xml/pp/node.rb +56 -0
  185. data/lib/nokogiri/xml/processing_instruction.rb +2 -0
  186. data/lib/nokogiri/xml/reader.rb +93 -8
  187. data/lib/nokogiri/xml/relax_ng.rb +32 -0
  188. data/lib/nokogiri/xml/sax.rb +1 -7
  189. data/lib/nokogiri/xml/sax/document.rb +107 -2
  190. data/lib/nokogiri/xml/sax/parser.rb +57 -7
  191. data/lib/nokogiri/xml/sax/parser_context.rb +16 -0
  192. data/lib/nokogiri/xml/sax/push_parser.rb +13 -1
  193. data/lib/nokogiri/xml/schema.rb +63 -0
  194. data/lib/nokogiri/xml/syntax_error.rb +25 -1
  195. data/lib/nokogiri/xml/text.rb +4 -1
  196. data/lib/nokogiri/xml/xpath.rb +1 -1
  197. data/lib/nokogiri/xml/xpath/syntax_error.rb +3 -0
  198. data/lib/nokogiri/xml/xpath_context.rb +2 -0
  199. data/lib/nokogiri/xslt.rb +26 -2
  200. data/lib/nokogiri/xslt/stylesheet.rb +19 -0
  201. data/lib/xsd/xmlparser/nokogiri.rb +45 -9
  202. data/tasks/cross_compile.rb +173 -0
  203. data/tasks/test.rb +25 -69
  204. data/test/css/test_nthiness.rb +3 -4
  205. data/test/css/test_parser.rb +75 -20
  206. data/test/css/test_tokenizer.rb +23 -1
  207. data/test/css/test_xpath_visitor.rb +10 -1
  208. data/test/decorators/test_slop.rb +16 -0
  209. data/test/ffi/test_document.rb +35 -0
  210. data/test/files/2ch.html +108 -0
  211. data/test/files/address_book.rlx +12 -0
  212. data/test/files/address_book.xml +10 -0
  213. data/test/files/bar/bar.xsd +4 -0
  214. data/test/files/encoding.html +82 -0
  215. data/test/files/encoding.xhtml +84 -0
  216. data/test/files/foo/foo.xsd +4 -0
  217. data/test/files/po.xml +32 -0
  218. data/test/files/po.xsd +66 -0
  219. data/test/files/shift_jis.html +10 -0
  220. data/test/files/shift_jis.xml +5 -0
  221. data/test/files/snuggles.xml +3 -0
  222. data/test/files/staff.dtd +10 -0
  223. data/test/files/valid_bar.xml +2 -0
  224. data/test/helper.rb +101 -23
  225. data/test/html/sax/test_parser.rb +81 -2
  226. data/test/html/sax/test_parser_context.rb +48 -0
  227. data/test/html/test_builder.rb +39 -8
  228. data/test/html/test_document.rb +186 -23
  229. data/test/html/test_document_encoding.rb +78 -1
  230. data/test/html/test_document_fragment.rb +253 -0
  231. data/test/html/test_element_description.rb +98 -0
  232. data/test/html/test_named_characters.rb +1 -1
  233. data/test/html/test_node.rb +124 -36
  234. data/test/html/test_node_encoding.rb +27 -0
  235. data/test/test_convert_xpath.rb +1 -52
  236. data/test/test_css_cache.rb +2 -13
  237. data/test/test_encoding_handler.rb +46 -0
  238. data/test/test_memory_leak.rb +88 -19
  239. data/test/test_nokogiri.rb +38 -5
  240. data/test/test_reader.rb +188 -6
  241. data/test/test_soap4r_sax.rb +52 -0
  242. data/test/test_xslt_transforms.rb +183 -83
  243. data/test/xml/node/test_save_options.rb +1 -1
  244. data/test/xml/node/test_subclass.rb +44 -0
  245. data/test/xml/sax/test_parser.rb +175 -4
  246. data/test/xml/sax/test_parser_context.rb +113 -0
  247. data/test/xml/sax/test_push_parser.rb +90 -2
  248. data/test/xml/test_attr.rb +35 -1
  249. data/test/xml/test_attribute_decl.rb +82 -0
  250. data/test/xml/test_builder.rb +186 -1
  251. data/test/xml/test_cdata.rb +32 -1
  252. data/test/xml/test_comment.rb +13 -1
  253. data/test/xml/test_document.rb +415 -43
  254. data/test/xml/test_document_encoding.rb +1 -1
  255. data/test/xml/test_document_fragment.rb +173 -5
  256. data/test/xml/test_dtd.rb +61 -6
  257. data/test/xml/test_dtd_encoding.rb +3 -1
  258. data/test/xml/test_element_content.rb +56 -0
  259. data/test/xml/test_element_decl.rb +73 -0
  260. data/test/xml/test_entity_decl.rb +120 -0
  261. data/test/xml/test_entity_reference.rb +5 -1
  262. data/test/xml/test_namespace.rb +68 -0
  263. data/test/xml/test_node.rb +546 -201
  264. data/test/xml/test_node_attributes.rb +34 -0
  265. data/test/xml/test_node_encoding.rb +33 -3
  266. data/test/xml/test_node_reparenting.rb +321 -0
  267. data/test/xml/test_node_set.rb +538 -2
  268. data/test/xml/test_parse_options.rb +52 -0
  269. data/test/xml/test_processing_instruction.rb +6 -1
  270. data/test/xml/test_reader_encoding.rb +1 -1
  271. data/test/xml/test_relax_ng.rb +60 -0
  272. data/test/xml/test_schema.rb +94 -0
  273. data/test/xml/test_syntax_error.rb +12 -0
  274. data/test/xml/test_text.rb +35 -1
  275. data/test/xml/test_unparented_node.rb +5 -5
  276. data/test/xml/test_xpath.rb +142 -11
  277. data/test/xslt/test_custom_functions.rb +94 -0
  278. metadata +328 -92
  279. data/ext/nokogiri/html_sax_parser.c +0 -57
  280. data/ext/nokogiri/html_sax_parser.h +0 -11
  281. data/ext/nokogiri/iconv.dll +0 -0
  282. data/ext/nokogiri/libexslt.dll +0 -0
  283. data/ext/nokogiri/libxml2.dll +0 -0
  284. data/ext/nokogiri/libxslt.dll +0 -0
  285. data/ext/nokogiri/native.so +0 -0
  286. data/ext/nokogiri/xml_xpath.c +0 -53
  287. data/ext/nokogiri/xml_xpath.h +0 -11
  288. data/ext/nokogiri/zlib1.dll +0 -0
  289. data/lib/action-nokogiri.rb +0 -30
  290. data/lib/nokogiri/css/generated_parser.rb +0 -713
  291. data/lib/nokogiri/css/generated_tokenizer.rb +0 -144
  292. data/lib/nokogiri/decorators.rb +0 -2
  293. data/lib/nokogiri/decorators/hpricot.rb +0 -3
  294. data/lib/nokogiri/decorators/hpricot/node.rb +0 -56
  295. data/lib/nokogiri/decorators/hpricot/node_set.rb +0 -54
  296. data/lib/nokogiri/decorators/hpricot/xpath_visitor.rb +0 -28
  297. data/lib/nokogiri/hpricot.rb +0 -51
  298. data/lib/nokogiri/xml/comment.rb +0 -6
  299. data/lib/nokogiri/xml/element.rb +0 -6
  300. data/lib/nokogiri/xml/entity_declaration.rb +0 -9
  301. data/lib/nokogiri/xml/fragment_handler.rb +0 -34
  302. data/test/hpricot/files/basic.xhtml +0 -17
  303. data/test/hpricot/files/boingboing.html +0 -2266
  304. data/test/hpricot/files/cy0.html +0 -3653
  305. data/test/hpricot/files/immob.html +0 -400
  306. data/test/hpricot/files/pace_application.html +0 -1320
  307. data/test/hpricot/files/tenderlove.html +0 -16
  308. data/test/hpricot/files/uswebgen.html +0 -220
  309. data/test/hpricot/files/utf8.html +0 -1054
  310. data/test/hpricot/files/week9.html +0 -1723
  311. data/test/hpricot/files/why.xml +0 -19
  312. data/test/hpricot/load_files.rb +0 -11
  313. data/test/hpricot/test_alter.rb +0 -68
  314. data/test/hpricot/test_builder.rb +0 -20
  315. data/test/hpricot/test_parser.rb +0 -426
  316. data/test/hpricot/test_paths.rb +0 -15
  317. data/test/hpricot/test_preserved.rb +0 -77
  318. data/test/hpricot/test_xml.rb +0 -30
  319. data/test/test_gc.rb +0 -15
@@ -0,0 +1,34 @@
1
+ require "helper"
2
+
3
+ module Nokogiri
4
+ module XML
5
+ class TestNodeAttributes < Nokogiri::TestCase
6
+ def test_attribute_with_ns
7
+ doc = Nokogiri::XML <<-eoxml
8
+ <root xmlns:tlm='http://tenderlovemaking.com/'>
9
+ <node tlm:foo='bar' foo='baz' />
10
+ </root>
11
+ eoxml
12
+
13
+ node = doc.at('node')
14
+
15
+ assert_equal 'bar',
16
+ node.attribute_with_ns('foo', 'http://tenderlovemaking.com/').value
17
+ end
18
+
19
+ def test_namespace_key?
20
+ doc = Nokogiri::XML <<-eoxml
21
+ <root xmlns:tlm='http://tenderlovemaking.com/'>
22
+ <node tlm:foo='bar' foo='baz' />
23
+ </root>
24
+ eoxml
25
+
26
+ node = doc.at('node')
27
+
28
+ assert node.namespaced_key?('foo', 'http://tenderlovemaking.com/')
29
+ assert node.namespaced_key?('foo', nil)
30
+ assert !node.namespaced_key?('foo', 'foo')
31
+ end
32
+ end
33
+ end
34
+ end
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '..', "helper"))
1
+ require "helper"
2
2
 
3
3
  module Nokogiri
4
4
  module XML
@@ -14,6 +14,29 @@ module Nokogiri
14
14
  assert_equal @html.encoding, node['href'].encoding.name
15
15
  end
16
16
 
17
+ def test_text_encoding_is_utf_8
18
+ @html = Nokogiri::HTML(File.open(NICH_FILE))
19
+ assert_equal 'UTF-8', @html.text.encoding.name
20
+ end
21
+
22
+ def test_serialize_encoding_html
23
+ @html = Nokogiri::HTML(File.open(NICH_FILE))
24
+ assert_equal @html.encoding.downcase,
25
+ @html.serialize.encoding.name.downcase
26
+
27
+ @doc = Nokogiri::HTML(@html.serialize)
28
+ assert_equal @html.serialize, @doc.serialize
29
+ end
30
+
31
+ def test_serialize_encoding_xml
32
+ @xml = Nokogiri::XML(File.open(SHIFT_JIS_XML))
33
+ assert_equal @xml.encoding.downcase,
34
+ @xml.serialize.encoding.name.downcase
35
+
36
+ @doc = Nokogiri::XML(@xml.serialize)
37
+ assert_equal @xml.serialize, @doc.serialize
38
+ end
39
+
17
40
  def test_encode_special_chars
18
41
  foo = @html.css('a').first.encode_special_chars('foo')
19
42
  assert_equal @html.encoding, foo.encoding.name
@@ -49,7 +72,8 @@ module Nokogiri
49
72
  assert_equal 'UTF-8', doc.encoding
50
73
  n = doc.xpath('//part:tire', { 'part' => 'http://schwinn.com/' }).first
51
74
  assert n
52
- assert_equal doc.encoding, n.namespace.encoding.name
75
+ assert_equal doc.encoding, n.namespace.href.encoding.name
76
+ assert_equal doc.encoding, n.namespace.prefix.encoding.name
53
77
  end
54
78
 
55
79
  def test_namespace_as_hash
@@ -66,9 +90,15 @@ module Nokogiri
66
90
  doc = Nokogiri::XML(xml, nil, 'UTF-8')
67
91
  assert_equal 'UTF-8', doc.encoding
68
92
  assert n = doc.xpath('//car').first
93
+
94
+ n.namespace_definitions.each do |nd|
95
+ assert_equal doc.encoding, nd.href.encoding.name
96
+ assert_equal doc.encoding, nd.prefix.encoding.name
97
+ end
98
+
69
99
  n.namespaces.each do |k,v|
70
- assert_equal doc.encoding, v.encoding.name
71
100
  assert_equal doc.encoding, k.encoding.name
101
+ assert_equal doc.encoding, v.encoding.name
72
102
  end
73
103
  end
74
104
  end
@@ -0,0 +1,321 @@
1
+ require "helper"
2
+
3
+ module Nokogiri
4
+ module XML
5
+ class TestNodeReparenting < Nokogiri::TestCase
6
+
7
+ describe "standard node reparenting behavior" do
8
+ # describe "namespace handling during reparenting" do
9
+ # describe "given a Node" do
10
+ # describe "with a Namespace" do
11
+ # it "keeps the Namespace"
12
+ # end
13
+ # describe "given a parent Node with a default and a non-default Namespace" do
14
+ # describe "passed an Node without a namespace" do
15
+ # it "inserts an Node that inherits the default Namespace"
16
+ # end
17
+ # describe "passed a Node with a Namespace that matches the parent's non-default Namespace" do
18
+ # it "inserts a Node that inherits the matching parent Namespace"
19
+ # end
20
+ # end
21
+ # end
22
+ # describe "given a markup string" do
23
+ # describe "parsed relative to the document" do
24
+ # describe "with a Namespace" do
25
+ # it "keeps the Namespace"
26
+ # end
27
+ # describe "given a parent Node with a default and a non-default Namespace" do
28
+ # describe "passed an Node without a namespace" do
29
+ # it "inserts an Node that inherits the default Namespace"
30
+ # end
31
+ # describe "passed a Node with a Namespace that matches the parent's non-default Namespace" do
32
+ # it "inserts a Node that inherits the matching parent Namespace"
33
+ # end
34
+ # end
35
+ # end
36
+ # describe "parsed relative to a specific node" do
37
+ # describe "with a Namespace" do
38
+ # it "keeps the Namespace"
39
+ # end
40
+ # describe "given a parent Node with a default and a non-default Namespace" do
41
+ # describe "passed an Node without a namespace" do
42
+ # it "inserts an Node that inherits the default Namespace"
43
+ # end
44
+ # describe "passed a Node with a Namespace that matches the parent's non-default Namespace" do
45
+ # it "inserts a Node that inherits the matching parent Namespace"
46
+ # end
47
+ # end
48
+ # end
49
+ # end
50
+ # end
51
+
52
+ {
53
+ :add_child => {:target => "/root/a1", :returns_self => false, :children_tags => %w[text b1 b2]},
54
+ :<< => {:target => "/root/a1", :returns_self => false, :children_tags => %w[text b1 b2]},
55
+
56
+ :replace => {:target => "/root/a1/node()", :returns_self => false, :children_tags => %w[b1 b2]},
57
+ :swap => {:target => "/root/a1/node()", :returns_self => true, :children_tags => %w[b1 b2]},
58
+
59
+ :children= => {:target => "/root/a1", :returns_self => false, :children_tags => %w[b1 b2]},
60
+ :inner_html= => {:target => "/root/a1", :returns_self => true, :children_tags => %w[b1 b2]},
61
+
62
+ :add_previous_sibling => {:target => "/root/a1/text()", :returns_self => false, :children_tags => %w[b1 b2 text]},
63
+ :previous= => {:target => "/root/a1/text()", :returns_self => false, :children_tags => %w[b1 b2 text]},
64
+ :before => {:target => "/root/a1/text()", :returns_self => true, :children_tags => %w[b1 b2 text]},
65
+
66
+ :add_next_sibling => {:target => "/root/a1/text()", :returns_self => false, :children_tags => %w[text b1 b2]},
67
+ :next= => {:target => "/root/a1/text()", :returns_self => false, :children_tags => %w[text b1 b2]},
68
+ :after => {:target => "/root/a1/text()", :returns_self => true, :children_tags => %w[text b1 b2]}
69
+ }.each do |method, params|
70
+
71
+ before do
72
+ @doc = Nokogiri::XML "<root><a1>First node</a1><a2>Second node</a2><a3>Third <bx />node</a3></root>"
73
+ @doc2 = @doc.dup
74
+ @fragment_string = "<b1>foo</b1><b2>bar</b2>"
75
+ @fragment = Nokogiri::XML::DocumentFragment.parse @fragment_string
76
+ @node_set = Nokogiri::XML("<root><b1>foo</b1><b2>bar</b2></root>").xpath("/root/node()")
77
+ end
78
+
79
+ describe "##{method}" do
80
+ describe "passed a Node" do
81
+ [:current, :another].each do |which|
82
+ describe "passed a Node in the #{which} document" do
83
+ before do
84
+ @other_doc = which == :current ? @doc : @doc2
85
+ @other_node = @other_doc.at_xpath("/root/a2")
86
+ end
87
+
88
+ it "unlinks the Node from its previous position" do
89
+ @doc.at_xpath(params[:target]).send(method, @other_node)
90
+ @other_doc.at_xpath("/root/a2").must_be_nil
91
+ end
92
+
93
+ it "inserts the Node in the proper position" do
94
+ @doc.at_xpath(params[:target]).send(method, @other_node)
95
+ @doc.at_xpath("/root/a1/a2").wont_be_nil
96
+ end
97
+
98
+ it "returns the expected value" do
99
+ sendee = @doc.at_xpath(params[:target])
100
+ result = sendee.send(method, @other_node)
101
+ if params[:returns_self]
102
+ result.must_equal sendee
103
+ else
104
+ result.must_equal @other_node
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
110
+ describe "passed a markup string" do
111
+ it "inserts the fragment roots in the proper position" do
112
+ @doc.at_xpath(params[:target]).send(method, @fragment_string)
113
+ @doc.xpath("/root/a1/node()").collect {|n| n.name}.must_equal params[:children_tags]
114
+ end
115
+
116
+ it "returns the expected value" do
117
+ sendee = @doc.at_xpath(params[:target])
118
+ result = sendee.send(method, @fragment_string)
119
+ if params[:returns_self]
120
+ result.must_equal sendee
121
+ else
122
+ result.must_be_kind_of Nokogiri::XML::NodeSet
123
+ result.to_html.must_equal @fragment_string
124
+ end
125
+ end
126
+ end
127
+ describe "passed a fragment" do
128
+ it "inserts the fragment roots in the proper position" do
129
+ @doc.at_xpath(params[:target]).send(method, @fragment)
130
+ @doc.xpath("/root/a1/node()").collect {|n| n.name}.must_equal params[:children_tags]
131
+ end
132
+ end
133
+ describe "passed a document" do
134
+ it "raises an exception" do
135
+ proc { @doc.at_xpath("/root/a1").send(method, @doc2) }.must_raise(ArgumentError)
136
+ end
137
+ end
138
+ describe "passed a non-Node" do
139
+ it "raises an exception" do
140
+ proc { @doc.at_xpath("/root/a1").send(method, 42) }.must_raise(ArgumentError)
141
+ end
142
+ end
143
+ describe "passed a NodeSet" do
144
+ it "inserts each member of the NodeSet in the proper order" do
145
+ @doc.at_xpath(params[:target]).send(method, @node_set)
146
+ @doc.xpath("/root/a1/node()").collect {|n| n.name}.must_equal params[:children_tags]
147
+ end
148
+ end
149
+ end
150
+ end
151
+
152
+ describe "text node merging" do
153
+ describe "#add_child" do
154
+ it "merges the Text node with adjacent Text nodes" do
155
+ @doc.at_xpath("/root/a1").add_child Nokogiri::XML::Text.new('hello', @doc)
156
+ @doc.at_xpath("/root/a1/text()").content.must_equal "First nodehello"
157
+ end
158
+ end
159
+ describe "#replace" do
160
+ it "merges the Text node with adjacent Text nodes" do
161
+ @doc.at_xpath("/root/a3/bx").replace Nokogiri::XML::Text.new('hello', @doc)
162
+ @doc.at_xpath("/root/a3/text()").content.must_equal "Third hellonode"
163
+ end
164
+ end
165
+ end
166
+ end
167
+
168
+ describe "ad hoc node reparenting behavior" do
169
+ describe "#add_child" do
170
+ describe "given a new node with a namespace" do
171
+ it "keeps the namespace" do
172
+ doc = Nokogiri::XML::Document.new
173
+ item = Nokogiri::XML::Element.new('item', doc)
174
+ doc.root = item
175
+
176
+ entry = Nokogiri::XML::Element.new('entry', doc)
177
+ entry.add_namespace('tlm', 'http://tenderlovemaking.com')
178
+ assert_equal 'http://tenderlovemaking.com', entry.namespaces['xmlns:tlm']
179
+ item.add_child(entry)
180
+ assert_equal 'http://tenderlovemaking.com', entry.namespaces['xmlns:tlm']
181
+ end
182
+ end
183
+
184
+ describe "given a parent node with a default namespace" do
185
+ before do
186
+ @doc = Nokogiri::XML(<<-eoxml)
187
+ <root xmlns="http://tenderlovemaking.com/">
188
+ <first>
189
+ </first>
190
+ </root>
191
+ eoxml
192
+ end
193
+
194
+ it "inserts a node that inherits the default namespace" do
195
+ assert node = @doc.at('//xmlns:first')
196
+ child = Nokogiri::XML::Node.new('second', @doc)
197
+ node.add_child(child)
198
+ assert @doc.at('//xmlns:second')
199
+ end
200
+ end
201
+
202
+ describe "given a parent node with a non-default namespace" do
203
+ before do
204
+ @doc = Nokogiri::XML(<<-eoxml)
205
+ <root xmlns="http://tenderlovemaking.com/" xmlns:foo="http://flavorjon.es/">
206
+ <first>
207
+ </first>
208
+ </root>
209
+ eoxml
210
+ end
211
+
212
+ describe "and a child node with a namespace matching the parent's non-default namespace" do
213
+ it "inserts a node that inherits the matching parent namespace" do
214
+ assert node = @doc.at('//xmlns:first')
215
+ child = Nokogiri::XML::Node.new('second', @doc)
216
+
217
+ ns = @doc.root.namespace_definitions.detect { |x| x.prefix == "foo" }
218
+ child.namespace = ns
219
+
220
+ node.add_child(child)
221
+ assert @doc.at('//foo:second', "foo" => "http://flavorjon.es/")
222
+ end
223
+ end
224
+ end
225
+ end
226
+
227
+ describe "#add_previous_sibling" do
228
+ it "should not merge text nodes during the operation" do
229
+ xml = Nokogiri::XML %Q(<root>text node</root>)
230
+ replacee = xml.root.children.first
231
+ replacee.add_previous_sibling "foo <p></p> bar"
232
+ assert_equal "foo <p></p> bartext node", xml.root.children.to_html
233
+ end
234
+ end
235
+
236
+ describe "#add_next_sibling" do
237
+ it "should not merge text nodes during the operation" do
238
+ xml = Nokogiri::XML %Q(<root>text node</root>)
239
+ replacee = xml.root.children.first
240
+ replacee.add_next_sibling "foo <p></p> bar"
241
+ assert_equal "text nodefoo <p></p> bar", xml.root.children.to_html
242
+ end
243
+ end
244
+
245
+ describe "#replace" do
246
+ describe "a text node with a text node" do
247
+ it "should not merge text nodes during the operation" do
248
+ xml = Nokogiri::XML %Q(<root>text node</root>)
249
+ replacee = xml.root.children.first
250
+ replacee.replace "new text node"
251
+ assert_equal "new text node", xml.root.children.first.content
252
+ end
253
+ end
254
+
255
+ describe "when a document has a default namespace" do
256
+ before do
257
+ @fruits = Nokogiri::XML(<<-eoxml)
258
+ <fruit xmlns="http://fruits.org">
259
+ <apple />
260
+ </fruit>
261
+ eoxml
262
+ end
263
+
264
+ it "inserts a node with default namespaces" do
265
+ apple = @fruits.css('apple').first
266
+
267
+ orange = Nokogiri::XML::Node.new('orange', @fruits)
268
+ apple.replace(orange)
269
+
270
+ assert_equal orange, @fruits.css('orange').first
271
+ end
272
+ end
273
+ end
274
+
275
+ describe "unlinking a node and then reparenting it" do
276
+ it "not blow up" do
277
+ # see http://github.com/tenderlove/nokogiri/issues#issue/22
278
+ 10.times do
279
+ STDOUT.putc "."
280
+ STDOUT.flush
281
+ begin
282
+ doc = Nokogiri::XML <<-EOHTML
283
+ <root>
284
+ <a>
285
+ <b/>
286
+ <c/>
287
+ </a>
288
+ </root>
289
+ EOHTML
290
+
291
+ assert root = doc.at("root")
292
+ assert a = root.at("a")
293
+ assert b = a.at("b")
294
+ assert c = a.at("c")
295
+ a.add_next_sibling(b.unlink)
296
+ c.unlink
297
+ end
298
+ GC.start
299
+ end
300
+ end
301
+ end
302
+
303
+ describe "replace-merging text nodes" do
304
+ [
305
+ ['<root>a<br/></root>', 'afoo'],
306
+ ['<root>a<br/>b</root>', 'afoob'],
307
+ ['<root><br/>b</root>', 'foob']
308
+ ].each do |xml, result|
309
+ it "doesn't blow up on #{xml}" do
310
+ doc = Nokogiri::XML.parse(xml)
311
+ saved_nodes = doc.root.children
312
+ doc.at_xpath("/root/br").replace(Nokogiri::XML::Text.new('foo', doc))
313
+ saved_nodes.each { |child| child.inspect } # try to cause a crash
314
+ assert_equal result, doc.at_xpath("/root/text()").inner_text
315
+ end
316
+ end
317
+ end
318
+ end
319
+ end
320
+ end
321
+ end
@@ -1,11 +1,228 @@
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
+ end
26
+
6
27
  def setup
7
28
  super
8
- @xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
29
+ @xml = Nokogiri::XML(File.read(XML_FILE), XML_FILE)
30
+ @list = @xml.css('employee')
31
+ end
32
+
33
+ def test_filter
34
+ list = @xml.css('address').filter('*[domestic="Yes"]')
35
+ assert_equal(%w{ Yes } * 4, list.map { |n| n['domestic'] })
36
+ end
37
+
38
+ def test_remove_attr
39
+ @list.each { |x| x['class'] = 'blah' }
40
+ assert_equal @list, @list.remove_attr('class')
41
+ @list.each { |x| assert_nil x['class'] }
42
+ end
43
+
44
+ def test_add_class
45
+ assert_equal @list, @list.add_class('bar')
46
+ @list.each { |x| assert_equal 'bar', x['class'] }
47
+
48
+ @list.add_class('bar')
49
+ @list.each { |x| assert_equal 'bar', x['class'] }
50
+
51
+ @list.add_class('baz')
52
+ @list.each { |x| assert_equal 'bar baz', x['class'] }
53
+ end
54
+
55
+ def test_remove_class_with_no_class
56
+ assert_equal @list, @list.remove_class('bar')
57
+ @list.each { |e| assert_nil e['class'] }
58
+
59
+ @list.each { |e| e['class'] = '' }
60
+ assert_equal @list, @list.remove_class('bar')
61
+ @list.each { |e| assert_nil e['class'] }
62
+ end
63
+
64
+ def test_remove_class_single
65
+ @list.each { |e| e['class'] = 'foo bar' }
66
+
67
+ assert_equal @list, @list.remove_class('bar')
68
+ @list.each { |e| assert_equal 'foo', e['class'] }
69
+ end
70
+
71
+ def test_remove_class_completely
72
+ @list.each { |e| e['class'] = 'foo' }
73
+
74
+ assert_equal @list, @list.remove_class
75
+ @list.each { |e| assert_nil e['class'] }
76
+ end
77
+
78
+ def test_attribute_set
79
+ @list.each { |e| assert_nil e['foo'] }
80
+
81
+ [ ['attribute', 'bar'], ['attr', 'biz'], ['set', 'baz'] ].each do |t|
82
+ @list.send(t.first.to_sym, 'foo', t.last)
83
+ @list.each { |e| assert_equal t.last, e['foo'] }
84
+ end
85
+ end
86
+
87
+ def test_attribute_set_with_block
88
+ @list.each { |e| assert_nil e['foo'] }
89
+
90
+ [ ['attribute', 'bar'], ['attr', 'biz'], ['set', 'baz'] ].each do |t|
91
+ @list.send(t.first.to_sym, 'foo') { |x| t.last }
92
+ @list.each { |e| assert_equal t.last, e['foo'] }
93
+ end
94
+ end
95
+
96
+ def test_attribute_set_with_hash
97
+ @list.each { |e| assert_nil e['foo'] }
98
+
99
+ [ ['attribute', 'bar'], ['attr', 'biz'], ['set', 'baz'] ].each do |t|
100
+ @list.send(t.first.to_sym, 'foo' => t.last)
101
+ @list.each { |e| assert_equal t.last, e['foo'] }
102
+ end
103
+ end
104
+
105
+ def test_attribute_no_args
106
+ @list.first['foo'] = 'bar'
107
+ assert_equal @list.first.attribute('foo'), @list.attribute('foo')
108
+ end
109
+
110
+ def test_search_empty_node_set
111
+ set = Nokogiri::XML::NodeSet.new(Nokogiri::XML::Document.new)
112
+ assert_equal 0, set.css('foo').length
113
+ assert_equal 0, set.xpath('.//foo').length
114
+ assert_equal 0, set.search('foo').length
115
+ end
116
+
117
+ def test_xpath_with_custom_object
118
+ set = @xml.xpath('//staff')
119
+ custom_employees = set.xpath('//*[awesome(.)]', Class.new {
120
+ def awesome ns
121
+ ns.select { |n| n.name == 'employee' }
122
+ end
123
+ }.new)
124
+
125
+ assert_equal @xml.xpath('//employee'), custom_employees
126
+ end
127
+
128
+ def test_css_with_custom_object
129
+ set = @xml.xpath('//staff')
130
+ custom_employees = set.css('*:awesome', Class.new {
131
+ def awesome ns
132
+ ns.select { |n| n.name == 'employee' }
133
+ end
134
+ }.new)
135
+
136
+ assert_equal @xml.xpath('//employee'), custom_employees
137
+ end
138
+
139
+ def test_search_with_custom_object
140
+ set = @xml.xpath('//staff')
141
+ custom_employees = set.search('//*[awesome(.)]', Class.new {
142
+ def awesome ns
143
+ ns.select { |n| n.name == 'employee' }
144
+ end
145
+ }.new)
146
+
147
+ assert_equal @xml.xpath('//employee'), custom_employees
148
+ end
149
+
150
+ def test_css_searches_match_self
151
+ html = Nokogiri::HTML("<html><body><div class='a'></div></body></html>")
152
+ set = html.xpath("/html/body/div")
153
+ assert_equal set.first, set.css(".a").first
154
+ end
155
+
156
+ def test_search_with_css_matches_self
157
+ html = Nokogiri::HTML("<html><body><div class='a'></div></body></html>")
158
+ set = html.xpath("/html/body/div")
159
+ assert_equal set.first, set.search(".a").first
160
+ end
161
+
162
+ def test_css_search_with_namespace
163
+ fragment = Nokogiri::XML.fragment(<<-eoxml)
164
+ <html xmlns="http://www.w3.org/1999/xhtml">
165
+ <head></head>
166
+ <body></body>
167
+ </html>
168
+ eoxml
169
+ assert_nothing_raised{ fragment.children.search( 'body', { 'xmlns' => 'http://www.w3.org/1999/xhtml' }) }
170
+ end
171
+
172
+ def test_double_equal
173
+ assert node_set_one = @xml.xpath('//employee')
174
+ assert node_set_two = @xml.xpath('//employee')
175
+
176
+ assert_not_equal node_set_one.object_id, node_set_two.object_id
177
+
178
+ assert_equal node_set_one, node_set_two
179
+ end
180
+
181
+ def test_node_set_not_equal_to_string
182
+ node_set_one = @xml.xpath('//employee')
183
+ assert_not_equal node_set_one, "asdfadsf"
184
+ end
185
+
186
+ def test_out_of_order_not_equal
187
+ one = @xml.xpath('//employee')
188
+ two = @xml.xpath('//employee')
189
+ two.push two.shift
190
+ assert_not_equal one, two
191
+ end
192
+
193
+ def test_shorter_is_not_equal
194
+ node_set_one = @xml.xpath('//employee')
195
+ node_set_two = @xml.xpath('//employee')
196
+ node_set_two.delete(node_set_two.first)
197
+
198
+ assert_not_equal node_set_one, node_set_two
199
+ end
200
+
201
+ def test_pop
202
+ set = @xml.xpath('//employee')
203
+ last = set.last
204
+ assert_equal last, set.pop
205
+ end
206
+
207
+ def test_shift
208
+ set = @xml.xpath('//employee')
209
+ first = set.first
210
+ assert_equal first, set.shift
211
+ end
212
+
213
+ def test_shift_empty
214
+ set = Nokogiri::XML::NodeSet.new(@xml)
215
+ assert_nil set.shift
216
+ end
217
+
218
+ def test_pop_empty
219
+ set = Nokogiri::XML::NodeSet.new(@xml)
220
+ assert_nil set.pop
221
+ end
222
+
223
+ def test_first_takes_arguments
224
+ assert node_set = @xml.xpath('//employee')
225
+ assert_equal 2, node_set.first(2).length
9
226
  end
10
227
 
11
228
  def test_dup
@@ -36,6 +253,12 @@ module Nokogiri
36
253
  assert set.at('bar')
37
254
  end
38
255
 
256
+ def test_children_has_document
257
+ set = @xml.root.children
258
+ assert_instance_of(NodeSet, set)
259
+ assert_equal @xml, set.document
260
+ end
261
+
39
262
  def test_length_size
40
263
  assert node_set = @xml.search('//employee')
41
264
  assert_equal node_set.length, node_set.size
@@ -63,11 +286,31 @@ module Nokogiri
63
286
  assert_match '<a>', html
64
287
  end
65
288
 
289
+ def test_gt_string_arg
290
+ assert node_set = @xml.search('//employee')
291
+ assert_equal node_set.xpath('./employeeId'), (node_set > 'employeeId')
292
+ end
293
+
66
294
  def test_at
67
295
  assert node_set = @xml.search('//employee')
68
296
  assert_equal node_set.first, node_set.at(0)
69
297
  end
70
298
 
299
+ def test_at_xpath
300
+ assert node_set = @xml.search('//employee')
301
+ assert_equal node_set.first.first_element_child, node_set.at_xpath('./employeeId')
302
+ end
303
+
304
+ def test_at_css
305
+ assert node_set = @xml.search('//employee')
306
+ assert_equal node_set.first.first_element_child, node_set.at_css('employeeId')
307
+ end
308
+
309
+ def test_percent
310
+ assert node_set = @xml.search('//employee')
311
+ assert_equal node_set.first, node_set % 0
312
+ end
313
+
71
314
  def test_to_ary
72
315
  assert node_set = @xml.search('//employee')
73
316
  foo = []
@@ -85,6 +328,36 @@ module Nokogiri
85
328
  assert node_set.include?(node)
86
329
  end
87
330
 
331
+ def test_delete_with_invalid_argument
332
+ employees = @xml.search("//employee")
333
+ positions = @xml.search("//position")
334
+
335
+ assert_raises(ArgumentError) { employees.delete(positions) }
336
+ end
337
+
338
+ def test_delete_when_present
339
+ employees = @xml.search("//employee")
340
+ wally = employees.first
341
+ assert employees.include?(wally) # testing setup
342
+ length = employees.length
343
+
344
+ result = employees.delete(wally)
345
+ assert_equal result, wally
346
+ assert ! employees.include?(wally)
347
+ assert length-1, employees.length
348
+ end
349
+
350
+ def test_delete_when_not_present
351
+ employees = @xml.search("//employee")
352
+ phb = @xml.search("//position").first
353
+ assert ! employees.include?(phb) # testing setup
354
+ length = employees.length
355
+
356
+ result = employees.delete(phb)
357
+ assert_nil result
358
+ assert length, employees.length
359
+ end
360
+
88
361
  def test_unlink
89
362
  xml = Nokogiri::XML.parse(<<-eoxml)
90
363
  <root>
@@ -167,6 +440,269 @@ module Nokogiri
167
440
  assert_equal 'wrapper', employees[0].parent.name
168
441
  assert_equal 'employee', @xml.search("//wrapper").first.children[0].name
169
442
  end
443
+
444
+ def test_wrap_a_fragment
445
+ frag = Nokogiri::XML::DocumentFragment.parse <<-EOXML
446
+ <employees>
447
+ <employee>hello</employee>
448
+ <employee>goodbye</employee>
449
+ </employees>
450
+ EOXML
451
+ employees = frag.xpath ".//employee"
452
+ employees.wrap("<wrapper/>")
453
+ assert_equal 'wrapper', employees[0].parent.name
454
+ assert_equal 'employee', frag.at(".//wrapper").children.first.name
455
+ end
456
+
457
+ def test_wrap_preserves_document_structure
458
+ assert_equal "employeeId",
459
+ @xml.at_xpath("//employee").children.detect{|j| ! j.text? }.name
460
+ @xml.xpath("//employeeId[text()='EMP0001']").wrap("<wrapper/>")
461
+ assert_equal "wrapper",
462
+ @xml.at_xpath("//employee").children.detect{|j| ! j.text? }.name
463
+ end
464
+
465
+ def test_plus_operator
466
+ names = @xml.search("name")
467
+ positions = @xml.search("position")
468
+
469
+ names_len = names.length
470
+ positions_len = positions.length
471
+
472
+ assert_raises(ArgumentError) { names + positions.first }
473
+
474
+ result = names + positions
475
+ assert_equal names_len, names.length
476
+ assert_equal positions_len, positions.length
477
+ assert_equal names.length + positions.length, result.length
478
+
479
+ names += positions
480
+ assert_equal result.length, names.length
481
+ end
482
+
483
+ def test_union
484
+ names = @xml.search("name")
485
+
486
+ assert_equal(names.length, (names | @xml.search("name")).length)
487
+ end
488
+
489
+ def test_minus_operator
490
+ employees = @xml.search("//employee")
491
+ females = @xml.search("//employee[gender[text()='Female']]")
492
+
493
+ employees_len = employees.length
494
+ females_len = females.length
495
+
496
+ assert_raises(ArgumentError) { employees - females.first }
497
+
498
+ result = employees - females
499
+ assert_equal employees_len, employees.length
500
+ assert_equal females_len, females.length
501
+ assert_equal employees.length - females.length, result.length
502
+
503
+ employees -= females
504
+ assert_equal result.length, employees.length
505
+ end
506
+
507
+ def test_array_index
508
+ employees = @xml.search("//employee")
509
+ other = @xml.search("//position").first
510
+
511
+ assert_equal 3, employees.index(employees[3])
512
+ assert_nil employees.index(other)
513
+ end
514
+
515
+ def test_slice_too_far
516
+ employees = @xml.search("//employee")
517
+ assert_equal employees.length, employees[0, employees.length + 1].length
518
+ assert_equal employees.length, employees[0, employees.length].length
519
+ end
520
+
521
+ def test_slice_waaaaaay_off_the_end
522
+ xml = Nokogiri::XML::Builder.new {
523
+ root { 100.times { div } }
524
+ }.doc
525
+ nodes = xml.css "div"
526
+ assert_equal 1, nodes.slice(99, 100_000).length
527
+ assert_equal 0, nodes.slice(100, 100_000).length
528
+ end
529
+
530
+ def test_array_slice_with_start_and_end
531
+ employees = @xml.search("//employee")
532
+ assert_equal [employees[1], employees[2], employees[3]], employees[1,3].to_a
533
+ end
534
+
535
+ def test_array_index_bracket_equivalence
536
+ employees = @xml.search("//employee")
537
+ assert_equal [employees[1], employees[2], employees[3]], employees[1,3].to_a
538
+ assert_equal [employees[1], employees[2], employees[3]], employees.slice(1,3).to_a
539
+ end
540
+
541
+ def test_array_slice_with_negative_start
542
+ employees = @xml.search("//employee")
543
+ assert_equal [employees[2]], employees[-3,1].to_a
544
+ assert_equal [employees[2], employees[3]], employees[-3,2].to_a
545
+ end
546
+
547
+ def test_array_slice_with_invalid_args
548
+ employees = @xml.search("//employee")
549
+ assert_nil employees[99, 1] # large start
550
+ assert_nil employees[1, -1] # negative len
551
+ assert_equal [], employees[1, 0].to_a # zero len
552
+ end
553
+
554
+ def test_array_slice_with_range
555
+ employees = @xml.search("//employee")
556
+ assert_equal [employees[1], employees[2], employees[3]], employees[1..3].to_a
557
+ assert_equal [employees[0], employees[1], employees[2], employees[3]], employees[0..3].to_a
558
+ end
559
+
560
+ def test_intersection_with_no_overlap
561
+ employees = @xml.search("//employee")
562
+ positions = @xml.search("//position")
563
+
564
+ assert_equal [], (employees & positions).to_a
565
+ end
566
+
567
+ def test_intersection
568
+ employees = @xml.search("//employee")
569
+ first_set = employees[0..2]
570
+ second_set = employees[2..4]
571
+
572
+ assert_equal [employees[2]], (first_set & second_set).to_a
573
+ end
574
+
575
+ def test_include?
576
+ employees = @xml.search("//employee")
577
+ yes = employees.first
578
+ no = @xml.search("//position").first
579
+
580
+ assert employees.include?(yes)
581
+ assert ! employees.include?(no)
582
+ end
583
+
584
+ def test_children
585
+ employees = @xml.search("//employee")
586
+ count = 0
587
+ employees.each do |employee|
588
+ count += employee.children.length
589
+ end
590
+ set = employees.children
591
+ assert_equal count, set.length
592
+ end
593
+
594
+ def test_inspect
595
+ employees = @xml.search("//employee")
596
+ inspected = employees.inspect
597
+
598
+ assert_equal "[#{employees.map { |x| x.inspect }.join(', ')}]",
599
+ inspected
600
+ end
601
+
602
+ def test_should_not_splode_when_accessing_namespace_declarations_in_a_node_set
603
+ xml = Nokogiri::XML "<foo></foo>"
604
+ node_set = xml.xpath("//namespace::*")
605
+ assert_equal 1, node_set.size
606
+ node = node_set.first
607
+ node.to_s # segfaults in 1.4.0 and earlier
608
+
609
+ # if we haven't segfaulted, let's make sure we handled it correctly
610
+ assert_instance_of Nokogiri::XML::Namespace, node
611
+ end
612
+
613
+ def test_should_not_splode_when_arrayifying_node_set_containing_namespace_declarations
614
+ xml = Nokogiri::XML "<foo></foo>"
615
+ node_set = xml.xpath("//namespace::*")
616
+ assert_equal 1, node_set.size
617
+
618
+ node_array = node_set.to_a
619
+ node = node_array.first
620
+ node.to_s # segfaults in 1.4.0 and earlier
621
+
622
+ # if we haven't segfaulted, let's make sure we handled it correctly
623
+ assert_instance_of Nokogiri::XML::Namespace, node
624
+ end
625
+
626
+ def test_should_not_splode_when_unlinking_node_set_containing_namespace_declarations
627
+ xml = Nokogiri::XML "<foo></foo>"
628
+ node_set = xml.xpath("//namespace::*")
629
+ assert_equal 1, node_set.size
630
+
631
+ node_set.unlink
632
+ end
633
+
634
+ def test_reverse
635
+ xml = Nokogiri::XML "<root><a />b<c />d<e /></root>"
636
+ children = xml.root.children
637
+ assert_instance_of Nokogiri::XML::NodeSet, children
638
+
639
+ reversed = children.reverse
640
+ assert_equal reversed[0], children[4]
641
+ assert_equal reversed[1], children[3]
642
+ assert_equal reversed[2], children[2]
643
+ assert_equal reversed[3], children[1]
644
+ assert_equal reversed[4], children[0]
645
+
646
+ assert_equal children, children.reverse.reverse
647
+ end
648
+
649
+ def test_node_set_dup_result_has_document_and_is_decorated
650
+ x = Module.new do
651
+ def awesome! ; end
652
+ end
653
+ util_decorate(@xml, x)
654
+ node_set = @xml.css("address")
655
+ new_set = node_set.dup
656
+ assert_equal node_set.document, new_set.document
657
+ assert new_set.respond_to?(:awesome!)
658
+ end
659
+
660
+ def test_node_set_union_result_has_document_and_is_decorated
661
+ x = Module.new do
662
+ def awesome! ; end
663
+ end
664
+ util_decorate(@xml, x)
665
+ node_set1 = @xml.css("address")
666
+ node_set2 = @xml.css("address")
667
+ new_set = node_set1 | node_set2
668
+ assert_equal node_set1.document, new_set.document
669
+ assert new_set.respond_to?(:awesome!)
670
+ end
671
+
672
+ def test_node_set_intersection_result_has_document_and_is_decorated
673
+ x = Module.new do
674
+ def awesome! ; end
675
+ end
676
+ util_decorate(@xml, x)
677
+ node_set1 = @xml.css("address")
678
+ node_set2 = @xml.css("address")
679
+ new_set = node_set1 & node_set2
680
+ assert_equal node_set1.document, new_set.document
681
+ assert new_set.respond_to?(:awesome!)
682
+ end
683
+
684
+ def test_node_set_difference_result_has_document_and_is_decorated
685
+ x = Module.new do
686
+ def awesome! ; end
687
+ end
688
+ util_decorate(@xml, x)
689
+ node_set1 = @xml.css("address")
690
+ node_set2 = @xml.css("address")
691
+ new_set = node_set1 - node_set2
692
+ assert_equal node_set1.document, new_set.document
693
+ assert new_set.respond_to?(:awesome!)
694
+ end
695
+
696
+ def test_node_set_slice_result_has_document_and_is_decorated
697
+ x = Module.new do
698
+ def awesome! ; end
699
+ end
700
+ util_decorate(@xml, x)
701
+ node_set = @xml.css("address")
702
+ new_set = node_set[0..-1]
703
+ assert_equal node_set.document, new_set.document
704
+ assert new_set.respond_to?(:awesome!)
705
+ end
170
706
  end
171
707
  end
172
708
  end