nokogiri 1.6.2.rc1-x64-mingw32

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

Potentially problematic release.


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

Files changed (263) hide show
  1. checksums.yaml +7 -0
  2. data/.autotest +26 -0
  3. data/.editorconfig +17 -0
  4. data/.gemtest +0 -0
  5. data/.travis.yml +25 -0
  6. data/CHANGELOG.ja.rdoc +857 -0
  7. data/CHANGELOG.rdoc +880 -0
  8. data/C_CODING_STYLE.rdoc +33 -0
  9. data/Gemfile +21 -0
  10. data/Manifest.txt +371 -0
  11. data/README.ja.rdoc +112 -0
  12. data/README.rdoc +180 -0
  13. data/ROADMAP.md +89 -0
  14. data/Rakefile +351 -0
  15. data/STANDARD_RESPONSES.md +47 -0
  16. data/Y_U_NO_GEMSPEC.md +155 -0
  17. data/bin/nokogiri +78 -0
  18. data/build_all +130 -0
  19. data/dependencies.yml +4 -0
  20. data/ext/nokogiri/depend +358 -0
  21. data/ext/nokogiri/extconf.rb +453 -0
  22. data/ext/nokogiri/html_document.c +170 -0
  23. data/ext/nokogiri/html_document.h +10 -0
  24. data/ext/nokogiri/html_element_description.c +279 -0
  25. data/ext/nokogiri/html_element_description.h +10 -0
  26. data/ext/nokogiri/html_entity_lookup.c +32 -0
  27. data/ext/nokogiri/html_entity_lookup.h +8 -0
  28. data/ext/nokogiri/html_sax_parser_context.c +116 -0
  29. data/ext/nokogiri/html_sax_parser_context.h +11 -0
  30. data/ext/nokogiri/html_sax_push_parser.c +87 -0
  31. data/ext/nokogiri/html_sax_push_parser.h +9 -0
  32. data/ext/nokogiri/nokogiri.c +148 -0
  33. data/ext/nokogiri/nokogiri.h +164 -0
  34. data/ext/nokogiri/xml_attr.c +94 -0
  35. data/ext/nokogiri/xml_attr.h +9 -0
  36. data/ext/nokogiri/xml_attribute_decl.c +70 -0
  37. data/ext/nokogiri/xml_attribute_decl.h +9 -0
  38. data/ext/nokogiri/xml_cdata.c +56 -0
  39. data/ext/nokogiri/xml_cdata.h +9 -0
  40. data/ext/nokogiri/xml_comment.c +54 -0
  41. data/ext/nokogiri/xml_comment.h +9 -0
  42. data/ext/nokogiri/xml_document.c +577 -0
  43. data/ext/nokogiri/xml_document.h +23 -0
  44. data/ext/nokogiri/xml_document_fragment.c +48 -0
  45. data/ext/nokogiri/xml_document_fragment.h +10 -0
  46. data/ext/nokogiri/xml_dtd.c +202 -0
  47. data/ext/nokogiri/xml_dtd.h +10 -0
  48. data/ext/nokogiri/xml_element_content.c +123 -0
  49. data/ext/nokogiri/xml_element_content.h +10 -0
  50. data/ext/nokogiri/xml_element_decl.c +69 -0
  51. data/ext/nokogiri/xml_element_decl.h +9 -0
  52. data/ext/nokogiri/xml_encoding_handler.c +79 -0
  53. data/ext/nokogiri/xml_encoding_handler.h +8 -0
  54. data/ext/nokogiri/xml_entity_decl.c +110 -0
  55. data/ext/nokogiri/xml_entity_decl.h +10 -0
  56. data/ext/nokogiri/xml_entity_reference.c +52 -0
  57. data/ext/nokogiri/xml_entity_reference.h +9 -0
  58. data/ext/nokogiri/xml_io.c +56 -0
  59. data/ext/nokogiri/xml_io.h +11 -0
  60. data/ext/nokogiri/xml_libxml2_hacks.c +112 -0
  61. data/ext/nokogiri/xml_libxml2_hacks.h +12 -0
  62. data/ext/nokogiri/xml_namespace.c +78 -0
  63. data/ext/nokogiri/xml_namespace.h +13 -0
  64. data/ext/nokogiri/xml_node.c +1541 -0
  65. data/ext/nokogiri/xml_node.h +13 -0
  66. data/ext/nokogiri/xml_node_set.c +467 -0
  67. data/ext/nokogiri/xml_node_set.h +14 -0
  68. data/ext/nokogiri/xml_processing_instruction.c +56 -0
  69. data/ext/nokogiri/xml_processing_instruction.h +9 -0
  70. data/ext/nokogiri/xml_reader.c +681 -0
  71. data/ext/nokogiri/xml_reader.h +10 -0
  72. data/ext/nokogiri/xml_relax_ng.c +161 -0
  73. data/ext/nokogiri/xml_relax_ng.h +9 -0
  74. data/ext/nokogiri/xml_sax_parser.c +312 -0
  75. data/ext/nokogiri/xml_sax_parser.h +39 -0
  76. data/ext/nokogiri/xml_sax_parser_context.c +262 -0
  77. data/ext/nokogiri/xml_sax_parser_context.h +10 -0
  78. data/ext/nokogiri/xml_sax_push_parser.c +115 -0
  79. data/ext/nokogiri/xml_sax_push_parser.h +9 -0
  80. data/ext/nokogiri/xml_schema.c +205 -0
  81. data/ext/nokogiri/xml_schema.h +9 -0
  82. data/ext/nokogiri/xml_syntax_error.c +63 -0
  83. data/ext/nokogiri/xml_syntax_error.h +13 -0
  84. data/ext/nokogiri/xml_text.c +52 -0
  85. data/ext/nokogiri/xml_text.h +9 -0
  86. data/ext/nokogiri/xml_xpath_context.c +307 -0
  87. data/ext/nokogiri/xml_xpath_context.h +10 -0
  88. data/ext/nokogiri/xslt_stylesheet.c +270 -0
  89. data/ext/nokogiri/xslt_stylesheet.h +14 -0
  90. data/lib/nokogiri.rb +137 -0
  91. data/lib/nokogiri/2.0/nokogiri.so +0 -0
  92. data/lib/nokogiri/2.1/nokogiri.so +0 -0
  93. data/lib/nokogiri/css.rb +27 -0
  94. data/lib/nokogiri/css/node.rb +52 -0
  95. data/lib/nokogiri/css/parser.rb +715 -0
  96. data/lib/nokogiri/css/parser.y +249 -0
  97. data/lib/nokogiri/css/parser_extras.rb +91 -0
  98. data/lib/nokogiri/css/syntax_error.rb +7 -0
  99. data/lib/nokogiri/css/tokenizer.rb +152 -0
  100. data/lib/nokogiri/css/tokenizer.rex +55 -0
  101. data/lib/nokogiri/css/xpath_visitor.rb +219 -0
  102. data/lib/nokogiri/decorators/slop.rb +35 -0
  103. data/lib/nokogiri/html.rb +37 -0
  104. data/lib/nokogiri/html/builder.rb +35 -0
  105. data/lib/nokogiri/html/document.rb +333 -0
  106. data/lib/nokogiri/html/document_fragment.rb +41 -0
  107. data/lib/nokogiri/html/element_description.rb +23 -0
  108. data/lib/nokogiri/html/element_description_defaults.rb +671 -0
  109. data/lib/nokogiri/html/entity_lookup.rb +13 -0
  110. data/lib/nokogiri/html/sax/parser.rb +52 -0
  111. data/lib/nokogiri/html/sax/parser_context.rb +16 -0
  112. data/lib/nokogiri/html/sax/push_parser.rb +16 -0
  113. data/lib/nokogiri/syntax_error.rb +4 -0
  114. data/lib/nokogiri/version.rb +106 -0
  115. data/lib/nokogiri/xml.rb +73 -0
  116. data/lib/nokogiri/xml/attr.rb +14 -0
  117. data/lib/nokogiri/xml/attribute_decl.rb +18 -0
  118. data/lib/nokogiri/xml/builder.rb +443 -0
  119. data/lib/nokogiri/xml/cdata.rb +11 -0
  120. data/lib/nokogiri/xml/character_data.rb +7 -0
  121. data/lib/nokogiri/xml/document.rb +279 -0
  122. data/lib/nokogiri/xml/document_fragment.rb +112 -0
  123. data/lib/nokogiri/xml/dtd.rb +32 -0
  124. data/lib/nokogiri/xml/element_content.rb +36 -0
  125. data/lib/nokogiri/xml/element_decl.rb +13 -0
  126. data/lib/nokogiri/xml/entity_decl.rb +19 -0
  127. data/lib/nokogiri/xml/namespace.rb +13 -0
  128. data/lib/nokogiri/xml/node.rb +982 -0
  129. data/lib/nokogiri/xml/node/save_options.rb +61 -0
  130. data/lib/nokogiri/xml/node_set.rb +355 -0
  131. data/lib/nokogiri/xml/notation.rb +6 -0
  132. data/lib/nokogiri/xml/parse_options.rb +98 -0
  133. data/lib/nokogiri/xml/pp.rb +2 -0
  134. data/lib/nokogiri/xml/pp/character_data.rb +18 -0
  135. data/lib/nokogiri/xml/pp/node.rb +56 -0
  136. data/lib/nokogiri/xml/processing_instruction.rb +8 -0
  137. data/lib/nokogiri/xml/reader.rb +112 -0
  138. data/lib/nokogiri/xml/relax_ng.rb +32 -0
  139. data/lib/nokogiri/xml/sax.rb +4 -0
  140. data/lib/nokogiri/xml/sax/document.rb +171 -0
  141. data/lib/nokogiri/xml/sax/parser.rb +123 -0
  142. data/lib/nokogiri/xml/sax/parser_context.rb +16 -0
  143. data/lib/nokogiri/xml/sax/push_parser.rb +60 -0
  144. data/lib/nokogiri/xml/schema.rb +63 -0
  145. data/lib/nokogiri/xml/syntax_error.rb +47 -0
  146. data/lib/nokogiri/xml/text.rb +9 -0
  147. data/lib/nokogiri/xml/xpath.rb +10 -0
  148. data/lib/nokogiri/xml/xpath/syntax_error.rb +11 -0
  149. data/lib/nokogiri/xml/xpath_context.rb +16 -0
  150. data/lib/nokogiri/xslt.rb +56 -0
  151. data/lib/nokogiri/xslt/stylesheet.rb +25 -0
  152. data/lib/xsd/xmlparser/nokogiri.rb +102 -0
  153. data/suppressions/README.txt +1 -0
  154. data/suppressions/nokogiri_ree-1.8.7.358.supp +61 -0
  155. data/suppressions/nokogiri_ruby-1.8.7.370.supp +0 -0
  156. data/suppressions/nokogiri_ruby-1.9.2.320.supp +28 -0
  157. data/suppressions/nokogiri_ruby-1.9.3.327.supp +28 -0
  158. data/tasks/nokogiri.org.rb +24 -0
  159. data/tasks/test.rb +95 -0
  160. data/test/css/test_nthiness.rb +222 -0
  161. data/test/css/test_parser.rb +358 -0
  162. data/test/css/test_tokenizer.rb +198 -0
  163. data/test/css/test_xpath_visitor.rb +96 -0
  164. data/test/decorators/test_slop.rb +16 -0
  165. data/test/files/2ch.html +108 -0
  166. data/test/files/address_book.rlx +12 -0
  167. data/test/files/address_book.xml +10 -0
  168. data/test/files/atom.xml +344 -0
  169. data/test/files/bar/bar.xsd +4 -0
  170. data/test/files/bogus.xml +0 -0
  171. data/test/files/dont_hurt_em_why.xml +422 -0
  172. data/test/files/encoding.html +82 -0
  173. data/test/files/encoding.xhtml +84 -0
  174. data/test/files/exslt.xml +8 -0
  175. data/test/files/exslt.xslt +35 -0
  176. data/test/files/foo/foo.xsd +4 -0
  177. data/test/files/metacharset.html +10 -0
  178. data/test/files/noencoding.html +47 -0
  179. data/test/files/po.xml +32 -0
  180. data/test/files/po.xsd +66 -0
  181. data/test/files/saml/saml20assertion_schema.xsd +283 -0
  182. data/test/files/saml/saml20protocol_schema.xsd +302 -0
  183. data/test/files/saml/xenc_schema.xsd +146 -0
  184. data/test/files/saml/xmldsig_schema.xsd +318 -0
  185. data/test/files/shift_jis.html +10 -0
  186. data/test/files/shift_jis.xml +5 -0
  187. data/test/files/shift_jis_no_charset.html +9 -0
  188. data/test/files/snuggles.xml +3 -0
  189. data/test/files/staff.dtd +10 -0
  190. data/test/files/staff.xml +59 -0
  191. data/test/files/staff.xslt +32 -0
  192. data/test/files/test_document_url/bar.xml +2 -0
  193. data/test/files/test_document_url/document.dtd +4 -0
  194. data/test/files/test_document_url/document.xml +6 -0
  195. data/test/files/tlm.html +850 -0
  196. data/test/files/to_be_xincluded.xml +2 -0
  197. data/test/files/valid_bar.xml +2 -0
  198. data/test/files/xinclude.xml +4 -0
  199. data/test/helper.rb +164 -0
  200. data/test/html/sax/test_parser.rb +141 -0
  201. data/test/html/sax/test_parser_context.rb +46 -0
  202. data/test/html/test_builder.rb +164 -0
  203. data/test/html/test_document.rb +619 -0
  204. data/test/html/test_document_encoding.rb +148 -0
  205. data/test/html/test_document_fragment.rb +261 -0
  206. data/test/html/test_element_description.rb +105 -0
  207. data/test/html/test_named_characters.rb +14 -0
  208. data/test/html/test_node.rb +196 -0
  209. data/test/html/test_node_encoding.rb +27 -0
  210. data/test/namespaces/test_additional_namespaces_in_builder_doc.rb +14 -0
  211. data/test/namespaces/test_namespaces_in_builder_doc.rb +75 -0
  212. data/test/namespaces/test_namespaces_in_cloned_doc.rb +31 -0
  213. data/test/namespaces/test_namespaces_in_created_doc.rb +75 -0
  214. data/test/namespaces/test_namespaces_in_parsed_doc.rb +66 -0
  215. data/test/test_convert_xpath.rb +135 -0
  216. data/test/test_css_cache.rb +45 -0
  217. data/test/test_encoding_handler.rb +46 -0
  218. data/test/test_memory_leak.rb +156 -0
  219. data/test/test_nokogiri.rb +138 -0
  220. data/test/test_reader.rb +558 -0
  221. data/test/test_soap4r_sax.rb +52 -0
  222. data/test/test_xslt_transforms.rb +279 -0
  223. data/test/xml/node/test_save_options.rb +28 -0
  224. data/test/xml/node/test_subclass.rb +44 -0
  225. data/test/xml/sax/test_parser.rb +382 -0
  226. data/test/xml/sax/test_parser_context.rb +115 -0
  227. data/test/xml/sax/test_push_parser.rb +157 -0
  228. data/test/xml/test_attr.rb +64 -0
  229. data/test/xml/test_attribute_decl.rb +86 -0
  230. data/test/xml/test_builder.rb +315 -0
  231. data/test/xml/test_c14n.rb +161 -0
  232. data/test/xml/test_cdata.rb +48 -0
  233. data/test/xml/test_comment.rb +29 -0
  234. data/test/xml/test_document.rb +934 -0
  235. data/test/xml/test_document_encoding.rb +28 -0
  236. data/test/xml/test_document_fragment.rb +228 -0
  237. data/test/xml/test_dtd.rb +187 -0
  238. data/test/xml/test_dtd_encoding.rb +33 -0
  239. data/test/xml/test_element_content.rb +56 -0
  240. data/test/xml/test_element_decl.rb +73 -0
  241. data/test/xml/test_entity_decl.rb +122 -0
  242. data/test/xml/test_entity_reference.rb +245 -0
  243. data/test/xml/test_namespace.rb +95 -0
  244. data/test/xml/test_node.rb +1155 -0
  245. data/test/xml/test_node_attributes.rb +113 -0
  246. data/test/xml/test_node_encoding.rb +107 -0
  247. data/test/xml/test_node_inheritance.rb +32 -0
  248. data/test/xml/test_node_reparenting.rb +374 -0
  249. data/test/xml/test_node_set.rb +755 -0
  250. data/test/xml/test_parse_options.rb +64 -0
  251. data/test/xml/test_processing_instruction.rb +30 -0
  252. data/test/xml/test_reader_encoding.rb +142 -0
  253. data/test/xml/test_relax_ng.rb +60 -0
  254. data/test/xml/test_schema.rb +129 -0
  255. data/test/xml/test_syntax_error.rb +12 -0
  256. data/test/xml/test_text.rb +45 -0
  257. data/test/xml/test_unparented_node.rb +422 -0
  258. data/test/xml/test_xinclude.rb +83 -0
  259. data/test/xml/test_xpath.rb +376 -0
  260. data/test/xslt/test_custom_functions.rb +133 -0
  261. data/test/xslt/test_exception_handling.rb +37 -0
  262. data/test_all +81 -0
  263. metadata +601 -0
@@ -0,0 +1,376 @@
1
+ require "helper"
2
+
3
+ module Nokogiri
4
+ module XML
5
+ class TestXPath < Nokogiri::TestCase
6
+
7
+ # ** WHY ALL THOSE _if Nokogiri.uses_libxml?_ **
8
+ # Hi, my dear readers,
9
+ #
10
+ # After reading these tests you may be wondering why all those ugly
11
+ # if Nokogiri.uses_libxml? sparsed over the whole document. Well, let
12
+ # me explain it. While using XPath in Java, you need the extension
13
+ # functions to be in a namespace. This is not required by XPath, afaik,
14
+ # but it is an usual convention though.
15
+ #
16
+ # Furthermore, CSS does not support extension functions but it does in
17
+ # Nokogiri. Result: you cannot use them in JRuby impl. At least, until
18
+ # the CSS to XPath parser is patched, and let me say that there are more
19
+ # important features to add before that happens. I hope you will forgive
20
+ # me.
21
+ #
22
+ # Yours truly,
23
+ #
24
+ # The guy whose headaches belong to Nokogiri JRuby impl.
25
+
26
+
27
+ def setup
28
+ super
29
+
30
+ @xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
31
+
32
+ @ns = @xml.root.namespaces
33
+
34
+ # TODO: Maybe I should move this to the original code.
35
+ @ns["nokogiri"] = "http://www.nokogiri.org/default_ns/ruby/extensions_functions"
36
+
37
+ @handler = Class.new {
38
+ attr_reader :things
39
+
40
+ def initialize
41
+ @things = []
42
+ end
43
+
44
+ def thing thing
45
+ @things << thing
46
+ thing
47
+ end
48
+
49
+ def returns_array node_set
50
+ @things << node_set.to_a
51
+ node_set.to_a
52
+ end
53
+
54
+ def my_filter set, attribute, value
55
+ set.find_all { |x| x[attribute] == value }
56
+ end
57
+
58
+ def saves_node_set node_set
59
+ @things = node_set
60
+ end
61
+
62
+ def value
63
+ 123.456
64
+ end
65
+ }.new
66
+ end
67
+
68
+ def test_variable_binding
69
+ assert_equal 4, @xml.xpath('//address[@domestic=$value]', nil, :value => 'Yes').length
70
+ end
71
+
72
+ def test_unknown_attribute
73
+ assert_equal 0, @xml.xpath('//employee[@id="asdfasdf"]/@fooo').length
74
+ assert_nil @xml.xpath('//employee[@id="asdfasdf"]/@fooo')[0]
75
+ end
76
+
77
+ def test_boolean
78
+ assert_equal false, @xml.xpath('1 = 2')
79
+ end
80
+
81
+ def test_number
82
+ assert_equal 2, @xml.xpath('1 + 1')
83
+ end
84
+
85
+ def test_string
86
+ assert_equal 'foo', @xml.xpath('concat("fo", "o")')
87
+ end
88
+
89
+ def test_css_search_uses_custom_selectors_with_arguments
90
+ set = if Nokogiri.uses_libxml?
91
+ @xml.css('employee > address:my_filter("domestic", "Yes")', @handler)
92
+ else
93
+ @xml.xpath("//employee/address[nokogiri:my_filter(., \"domestic\", \"Yes\")]", @ns, @handler)
94
+ end
95
+ assert set.length > 0
96
+ set.each do |node|
97
+ assert_equal 'Yes', node['domestic']
98
+ end
99
+ end
100
+
101
+ def test_css_search_uses_custom_selectors
102
+ set = @xml.xpath('//employee')
103
+ if Nokogiri.uses_libxml?
104
+ @xml.css('employee:thing()', @handler)
105
+ else
106
+ @xml.xpath("//employee[nokogiri:thing(.)]", @ns, @handler)
107
+ end
108
+ assert_equal(set.length, @handler.things.length)
109
+ assert_equal(set.to_a, @handler.things.flatten)
110
+ end
111
+
112
+ def test_pass_self_to_function
113
+ set = if Nokogiri.uses_libxml?
114
+ @xml.xpath('//employee/address[my_filter(., "domestic", "Yes")]', @handler)
115
+ else
116
+ @xml.xpath('//employee/address[nokogiri:my_filter(., "domestic", "Yes")]', @ns, @handler)
117
+ end
118
+ assert set.length > 0
119
+ set.each do |node|
120
+ assert_equal 'Yes', node['domestic']
121
+ end
122
+ end
123
+
124
+ def test_custom_xpath_function_gets_strings
125
+ set = @xml.xpath('//employee')
126
+ if Nokogiri.uses_libxml?
127
+ @xml.xpath('//employee[thing("asdf")]', @handler)
128
+ else
129
+ @xml.xpath('//employee[nokogiri:thing("asdf")]', @ns, @handler)
130
+ end
131
+ assert_equal(set.length, @handler.things.length)
132
+ assert_equal(['asdf'] * set.length, @handler.things)
133
+ end
134
+
135
+ def parse_params node
136
+ params={}
137
+ node.xpath('./param').each do |p|
138
+ subparams = parse_params p
139
+ if(subparams.length > 0)
140
+ if(not params.has_key? p.attributes['name'].value)
141
+ params[p.attributes['name'].value] = subparams
142
+ else
143
+ if(params[p.attributes['name'].value].is_a? Array)
144
+ params[p.attributes['name'].value] << subparams
145
+ else
146
+ value = params[p.attributes['name'].value]
147
+ params[p.attributes['name'].value] = [value,subparams]
148
+ end
149
+ end
150
+ else
151
+ params[p.attributes['name'].value]=p.text
152
+ end
153
+ end
154
+ params
155
+ end
156
+
157
+ # issue #741 (xpath() around 10x slower in JRuby)
158
+ def test_slow_jruby_xpath
159
+ doc = Nokogiri::XML(File.open(XPATH_FILE))
160
+ start = Time.now
161
+
162
+ doc.xpath('.//category').each do |c|
163
+ c.xpath('programformats/programformat').each do |p|
164
+ p.xpath('./modules/module').each do |m|
165
+ parse_params m
166
+ end
167
+ end
168
+ end
169
+ stop = Time.now
170
+ elapsed_time = stop - start
171
+ assert elapsed_time < 10, "XPath is taking too long"
172
+ end
173
+
174
+ def test_custom_xpath_function_returns_string
175
+ if Nokogiri.uses_libxml?
176
+ result = @xml.xpath('thing("asdf")', @handler)
177
+ else
178
+ result = @xml.xpath('nokogiri:thing("asdf")', @ns, @handler)
179
+ end
180
+ assert_equal 'asdf', result
181
+ end
182
+
183
+ def test_custom_xpath_gets_true_booleans
184
+ set = @xml.xpath('//employee')
185
+ if Nokogiri.uses_libxml?
186
+ @xml.xpath('//employee[thing(true())]', @handler)
187
+ else
188
+ @xml.xpath("//employee[nokogiri:thing(true())]", @ns, @handler)
189
+ end
190
+ assert_equal(set.length, @handler.things.length)
191
+ assert_equal([true] * set.length, @handler.things)
192
+ end
193
+
194
+ def test_custom_xpath_gets_false_booleans
195
+ set = @xml.xpath('//employee')
196
+ if Nokogiri.uses_libxml?
197
+ @xml.xpath('//employee[thing(false())]', @handler)
198
+ else
199
+ @xml.xpath("//employee[nokogiri:thing(false())]", @ns, @handler)
200
+ end
201
+ assert_equal(set.length, @handler.things.length)
202
+ assert_equal([false] * set.length, @handler.things)
203
+ end
204
+
205
+ def test_custom_xpath_gets_numbers
206
+ set = @xml.xpath('//employee')
207
+ if Nokogiri.uses_libxml?
208
+ @xml.xpath('//employee[thing(10)]', @handler)
209
+ else
210
+ @xml.xpath('//employee[nokogiri:thing(10)]', @ns, @handler)
211
+ end
212
+ assert_equal(set.length, @handler.things.length)
213
+ assert_equal([10] * set.length, @handler.things)
214
+ end
215
+
216
+ def test_custom_xpath_gets_node_sets
217
+ set = @xml.xpath('//employee/name')
218
+ if Nokogiri.uses_libxml?
219
+ @xml.xpath('//employee[thing(name)]', @handler)
220
+ else
221
+ @xml.xpath('//employee[nokogiri:thing(name)]', @ns, @handler)
222
+ end
223
+ assert_equal(set.length, @handler.things.length)
224
+ assert_equal(set.to_a, @handler.things.flatten)
225
+ end
226
+
227
+ def test_custom_xpath_gets_node_sets_and_returns_array
228
+ set = @xml.xpath('//employee/name')
229
+ if Nokogiri.uses_libxml?
230
+ @xml.xpath('//employee[returns_array(name)]', @handler)
231
+ else
232
+ @xml.xpath('//employee[nokogiri:returns_array(name)]', @ns, @handler)
233
+ end
234
+ assert_equal(set.length, @handler.things.length)
235
+ assert_equal(set.to_a, @handler.things.flatten)
236
+ end
237
+
238
+ def test_custom_xpath_handler_is_passed_a_decorated_node_set
239
+ x = Module.new do
240
+ def awesome! ; end
241
+ end
242
+ util_decorate(@xml, x)
243
+
244
+ assert @xml.xpath('//employee/name')
245
+
246
+ @xml.xpath('//employee[saves_node_set(name)]', @handler)
247
+ assert_equal @xml, @handler.things.document
248
+ assert @handler.things.respond_to?(:awesome!)
249
+ end
250
+
251
+ def test_code_that_invokes_OP_RESET_inside_libxml2
252
+ doc = "<html><body id='foo'><foo>hi</foo></body></html>"
253
+ xpath = 'id("foo")//foo'
254
+ nokogiri = Nokogiri::HTML.parse(doc)
255
+ assert nokogiri.xpath(xpath)
256
+ end
257
+
258
+ def test_custom_xpath_handler_with_args_under_gc_pressure
259
+ # see http://github.com/sparklemotion/nokogiri/issues/#issue/345
260
+ tool_inspector = Class.new do
261
+ def name_equals(nodeset, name, *args)
262
+ nodeset.all? do |node|
263
+ args.each { |thing| thing.inspect }
264
+ node["name"] == name
265
+ end
266
+ end
267
+ end.new
268
+
269
+ xml = <<-EOXML
270
+ <toolbox>
271
+ #{"<tool name='hammer'/><tool name='wrench'/>" * 10}
272
+ </toolbox>
273
+ EOXML
274
+ doc = Nokogiri::XML xml
275
+
276
+ # long list of long arguments, to apply GC pressure during
277
+ # ruby_funcall argument marshalling
278
+ xpath = ["//tool[name_equals(.,'hammer'"]
279
+ 1000.times { xpath << "'unused argument #{'x' * 1000}'" }
280
+ xpath << "'unused argument')]"
281
+ xpath = xpath.join(',')
282
+
283
+ assert_equal doc.xpath("//tool[@name='hammer']"), doc.xpath(xpath, tool_inspector)
284
+ end
285
+
286
+ def test_custom_xpath_without_arguments
287
+ if Nokogiri.uses_libxml?
288
+ value = @xml.xpath('value()', @handler)
289
+ else
290
+ value = @xml.xpath('nokogiri:value()', @ns, @handler)
291
+ end
292
+ assert_equal 123.456, value
293
+ end
294
+
295
+ def test_custom_xpath_with_bullshit_arguments
296
+ xml = %q{<foo> </foo>}
297
+ doc = Nokogiri::XML.parse(xml)
298
+ foo = doc.xpath('//foo[bool_function(bar/baz)]', Class.new {
299
+ def bool_function(value)
300
+ true
301
+ end
302
+ }.new)
303
+ assert_equal foo, doc.xpath("//foo")
304
+ end
305
+
306
+ def test_node_set_should_be_decorated
307
+ # "called decorate on nill" exception in JRuby issue#514
308
+ process_output= <<END
309
+ <test>
310
+ <track type="Image">
311
+ <Format>LZ77</Format>
312
+ </test>
313
+ END
314
+ doc = Nokogiri::XML.parse(process_output)
315
+ node = doc.xpath(%{//track[@type='Video']})
316
+ assert_equal "[]", node.xpath("Format").inspect
317
+ end
318
+
319
+ def test_very_specific_xml_xpath_making_problems_in_jruby
320
+ # manually merges pull request #681
321
+ xml_string = %q{<?xml version="1.0" encoding="UTF-8"?>
322
+ <ONIXMessage xmlns:elibri="http://elibri.com.pl/ns/extensions" release="3.0" xmlns="http://www.editeur.org/onix/3.0/reference">
323
+ <Product>
324
+ <RecordReference>a</RecordReference>
325
+ </Product>
326
+ </ONIXMessage>}
327
+
328
+ xml_doc = Nokogiri::XML(xml_string)
329
+ onix = xml_doc.children.first
330
+ assert_equal 'a', onix.at_xpath('xmlns:Product').at_xpath('xmlns:RecordReference').text
331
+ end
332
+
333
+ def test_xpath_after_attribute_change
334
+ xml_string = %q{<?xml version="1.0" encoding="UTF-8"?>
335
+ <mods version="3.0" xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-0.xsd" xmlns="http://www.loc.gov/mods/v3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
336
+ <titleInfo>
337
+ <nonSort>THE</nonSort>
338
+ <title xml:lang="eng">ARTICLE TITLE HYDRANGEA ARTICLE 1</title>
339
+ <subTitle>SUBTITLE</subTitle>
340
+ </titleInfo>
341
+ <titleInfo lang="finnish">
342
+ <title>Artikkelin otsikko Hydrangea artiklan 1</title>
343
+ </titleInfo>
344
+ </mods>}
345
+
346
+ xml_doc = Nokogiri::XML(xml_string)
347
+ ns_hash = {'mods'=>'http://www.loc.gov/mods/v3'}
348
+ node = xml_doc.at_xpath('//mods:titleInfo[1]',ns_hash)
349
+ node['lang'] = 'english'
350
+ assert_equal 1, xml_doc.xpath('//mods:titleInfo[1]/@lang',ns_hash).length
351
+ assert_equal 'english', xml_doc.xpath('//mods:titleInfo[1]/@lang',ns_hash).first.value
352
+ end
353
+
354
+ def test_xpath_after_element_removal
355
+ xml_string = %q{<?xml version="1.0" encoding="UTF-8"?>
356
+ <mods version="3.0" xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-0.xsd" xmlns="http://www.loc.gov/mods/v3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
357
+ <titleInfo>
358
+ <nonSort>THE</nonSort>
359
+ <title xml:lang="eng">ARTICLE TITLE HYDRANGEA ARTICLE 1</title>
360
+ <subTitle>SUBTITLE</subTitle>
361
+ </titleInfo>
362
+ <titleInfo lang="finnish">
363
+ <title>Artikkelin otsikko Hydrangea artiklan 1</title>
364
+ </titleInfo>
365
+ </mods>}
366
+
367
+ xml_doc = Nokogiri::XML(xml_string)
368
+ ns_hash = {'mods'=>'http://www.loc.gov/mods/v3'}
369
+ node = xml_doc.at_xpath('//mods:titleInfo[1]',ns_hash)
370
+ node.remove
371
+ assert_equal 1, xml_doc.xpath('//mods:titleInfo',ns_hash).length
372
+ assert_equal 'finnish', xml_doc.xpath('//mods:titleInfo[1]/@lang',ns_hash).first.value
373
+ end
374
+ end
375
+ end
376
+ end
@@ -0,0 +1,133 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require "helper"
4
+
5
+ module Nokogiri
6
+ module XSLT
7
+ class TestCustomFunctions < Nokogiri::TestCase
8
+ def setup
9
+ super
10
+ @xml = Nokogiri.XML(<<-EOXML)
11
+ <?xml version="1.0" encoding="UTF-8"?>
12
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0//EN"
13
+ "http://www.w3.org/TR/MathML2/dtd/xhtml-math11-f.dtd">
14
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
15
+ <head>
16
+ <meta http-equiv="Content-type" content="application/xhtml+xml"/>
17
+ <title>Foo</title>
18
+ </head>
19
+ <body>
20
+ <h1>Foo</h1>
21
+ <p>Lorem ipsum.</p>
22
+ </body>
23
+ </html>
24
+ EOXML
25
+ end
26
+
27
+ def test_function
28
+ skip("Pure Java version doesn't support this feature.") if !Nokogiri.uses_libxml?
29
+ foo = Class.new do
30
+ def capitalize nodes
31
+ nodes.first.content.upcase
32
+ end
33
+ end
34
+
35
+ XSLT.register "http://e.org/functions", foo
36
+
37
+ xsl = Nokogiri.XSLT(<<-EOXSL)
38
+ <?xml version="1.0"?>
39
+ <xsl:stylesheet version="1.0"
40
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
41
+ xmlns:f="http://e.org/functions"
42
+ extension-element-prefixes="f">
43
+
44
+ <xsl:template match="text()">
45
+ <xsl:copy-of select="f:capitalize(.)"/>
46
+ </xsl:template>
47
+
48
+ <xsl:template match="@*|node()">
49
+ <xsl:copy>
50
+ <xsl:apply-templates select="@*|node()"/>
51
+ <xsl:apply-imports/>
52
+ </xsl:copy>
53
+ </xsl:template>
54
+
55
+ </xsl:stylesheet>
56
+ EOXSL
57
+ result = xsl.transform @xml
58
+ assert_equal 'FOO', result.css('title').first.text
59
+ end
60
+
61
+
62
+ def test_function_arguments
63
+ skip("Pure Java version doesn't support this feature.") if !Nokogiri.uses_libxml?
64
+ foo = Class.new do
65
+ include MiniTest::Assertions
66
+ # Minitest 5 uses `self.assertions` in `assert()` which is not
67
+ # defined in the Minitest::Assertions module :-(
68
+ attr_writer :assertions
69
+ def assertions; @assertions ||= 0; end
70
+
71
+ def multiarg *args
72
+ assert_equal ["abc", "xyz"], args
73
+ args.first
74
+ end
75
+
76
+ def numericarg arg
77
+ assert_equal 42, arg
78
+ arg
79
+ end
80
+ end
81
+
82
+ xsl = Nokogiri.XSLT(<<-EOXSL, "http://e.org/functions" => foo)
83
+ <?xml version="1.0"?>
84
+ <xsl:stylesheet version="1.0"
85
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
86
+ xmlns:f="http://e.org/functions"
87
+ extension-element-prefixes="f">
88
+
89
+ <xsl:template match="text()">
90
+ <xsl:copy-of select="f:multiarg('abc', 'xyz')"/>
91
+ <xsl:copy-of select="f:numericarg(42)"/>
92
+ </xsl:template>
93
+ </xsl:stylesheet>
94
+ EOXSL
95
+
96
+ xsl.transform @xml
97
+ end
98
+
99
+
100
+ def test_function_XSLT
101
+ skip("Pure Java version doesn't support this feature.") if !Nokogiri.uses_libxml?
102
+ foo = Class.new do
103
+ def america nodes
104
+ nodes.first.content.upcase
105
+ end
106
+ end
107
+
108
+ xsl = Nokogiri.XSLT(<<-EOXSL, "http://e.org/functions" => foo)
109
+ <?xml version="1.0"?>
110
+ <xsl:stylesheet version="1.0"
111
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
112
+ xmlns:f="http://e.org/functions"
113
+ extension-element-prefixes="f">
114
+
115
+ <xsl:template match="text()">
116
+ <xsl:copy-of select="f:america(.)"/>
117
+ </xsl:template>
118
+
119
+ <xsl:template match="@*|node()">
120
+ <xsl:copy>
121
+ <xsl:apply-templates select="@*|node()"/>
122
+ <xsl:apply-imports/>
123
+ </xsl:copy>
124
+ </xsl:template>
125
+
126
+ </xsl:stylesheet>
127
+ EOXSL
128
+ result = xsl.transform @xml
129
+ assert_equal 'FOO', result.css('title').first.text
130
+ end
131
+ end
132
+ end
133
+ end