nokogiri 1.5.10 → 1.10.4

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

Potentially problematic release.


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

Files changed (182) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE-DEPENDENCIES.md +1614 -0
  3. data/LICENSE.md +9 -0
  4. data/README.md +198 -0
  5. data/bin/nokogiri +50 -10
  6. data/dependencies.yml +72 -0
  7. data/ext/nokogiri/extconf.rb +634 -92
  8. data/ext/nokogiri/html_document.c +8 -8
  9. data/ext/nokogiri/html_element_description.c +15 -15
  10. data/ext/nokogiri/html_entity_lookup.c +1 -1
  11. data/ext/nokogiri/html_sax_parser_context.c +4 -4
  12. data/ext/nokogiri/html_sax_push_parser.c +2 -2
  13. data/ext/nokogiri/nokogiri.c +20 -12
  14. data/ext/nokogiri/nokogiri.h +1 -44
  15. data/ext/nokogiri/xml_attr.c +34 -25
  16. data/ext/nokogiri/xml_cdata.c +12 -6
  17. data/ext/nokogiri/xml_comment.c +18 -3
  18. data/ext/nokogiri/xml_document.c +64 -32
  19. data/ext/nokogiri/xml_dtd.c +2 -2
  20. data/ext/nokogiri/xml_encoding_handler.c +3 -3
  21. data/ext/nokogiri/xml_entity_reference.c +1 -1
  22. data/ext/nokogiri/xml_io.c +11 -6
  23. data/ext/nokogiri/xml_namespace.c +50 -17
  24. data/ext/nokogiri/xml_namespace.h +3 -2
  25. data/ext/nokogiri/xml_node.c +459 -240
  26. data/ext/nokogiri/xml_node_set.c +166 -147
  27. data/ext/nokogiri/xml_node_set.h +2 -4
  28. data/ext/nokogiri/xml_processing_instruction.c +2 -2
  29. data/ext/nokogiri/xml_reader.c +6 -19
  30. data/ext/nokogiri/xml_sax_parser.c +11 -13
  31. data/ext/nokogiri/xml_sax_parser_context.c +41 -1
  32. data/ext/nokogiri/xml_sax_push_parser.c +56 -12
  33. data/ext/nokogiri/xml_schema.c +1 -1
  34. data/ext/nokogiri/xml_syntax_error.c +11 -5
  35. data/ext/nokogiri/xml_syntax_error.h +1 -1
  36. data/ext/nokogiri/xml_text.c +1 -1
  37. data/ext/nokogiri/xml_xpath_context.c +17 -38
  38. data/ext/nokogiri/xslt_stylesheet.c +10 -10
  39. data/lib/nokogiri/css/node.rb +0 -50
  40. data/lib/nokogiri/css/parser.rb +263 -233
  41. data/lib/nokogiri/css/parser.y +54 -40
  42. data/lib/nokogiri/css/tokenizer.rb +104 -103
  43. data/lib/nokogiri/css/tokenizer.rex +5 -5
  44. data/lib/nokogiri/css/xpath_visitor.rb +78 -19
  45. data/lib/nokogiri/decorators/slop.rb +12 -5
  46. data/lib/nokogiri/html/document.rb +102 -21
  47. data/lib/nokogiri/html/document_fragment.rb +11 -3
  48. data/lib/nokogiri/html/sax/parser.rb +12 -2
  49. data/lib/nokogiri/html/sax/push_parser.rb +22 -2
  50. data/lib/nokogiri/version.rb +40 -22
  51. data/lib/nokogiri/xml/builder.rb +34 -31
  52. data/lib/nokogiri/xml/document.rb +20 -14
  53. data/lib/nokogiri/xml/document_fragment.rb +50 -2
  54. data/lib/nokogiri/xml/dtd.rb +14 -4
  55. data/lib/nokogiri/xml/entity_reference.rb +18 -0
  56. data/lib/nokogiri/xml/node.rb +148 -203
  57. data/lib/nokogiri/xml/node_set.rb +139 -123
  58. data/lib/nokogiri/xml/parse_options.rb +22 -0
  59. data/lib/nokogiri/xml/sax/document.rb +1 -1
  60. data/lib/nokogiri/xml/sax/parser.rb +7 -8
  61. data/lib/nokogiri/xml/searchable.rb +230 -0
  62. data/lib/nokogiri/xml/syntax_error.rb +24 -1
  63. data/lib/nokogiri/xml.rb +3 -1
  64. data/lib/nokogiri.rb +40 -24
  65. data/patches/libxml2/0001-Revert-Do-not-URI-escape-in-server-side-includes.patch +78 -0
  66. data/patches/libxml2/0002-Remove-script-macro-support.patch +40 -0
  67. data/patches/libxml2/0003-Update-entities-to-remove-handling-of-ssi.patch +44 -0
  68. data/patches/libxslt/0001-Fix-security-framework-bypass.patch +120 -0
  69. data/ports/archives/libxml2-2.9.9.tar.gz +0 -0
  70. data/ports/archives/libxslt-1.1.33.tar.gz +0 -0
  71. metadata +252 -388
  72. data/.autotest +0 -26
  73. data/.gemtest +0 -0
  74. data/CHANGELOG.ja.rdoc +0 -785
  75. data/CHANGELOG.rdoc +0 -783
  76. data/C_CODING_STYLE.rdoc +0 -33
  77. data/Manifest.txt +0 -303
  78. data/README.ja.rdoc +0 -106
  79. data/README.rdoc +0 -175
  80. data/ROADMAP.md +0 -90
  81. data/Rakefile +0 -228
  82. data/STANDARD_RESPONSES.md +0 -47
  83. data/Y_U_NO_GEMSPEC.md +0 -155
  84. data/build_all +0 -105
  85. data/tasks/cross_compile.rb +0 -150
  86. data/tasks/nokogiri.org.rb +0 -24
  87. data/tasks/test.rb +0 -95
  88. data/test/css/test_nthiness.rb +0 -159
  89. data/test/css/test_parser.rb +0 -341
  90. data/test/css/test_tokenizer.rb +0 -198
  91. data/test/css/test_xpath_visitor.rb +0 -91
  92. data/test/decorators/test_slop.rb +0 -16
  93. data/test/files/2ch.html +0 -108
  94. data/test/files/address_book.rlx +0 -12
  95. data/test/files/address_book.xml +0 -10
  96. data/test/files/bar/bar.xsd +0 -4
  97. data/test/files/dont_hurt_em_why.xml +0 -422
  98. data/test/files/encoding.html +0 -82
  99. data/test/files/encoding.xhtml +0 -84
  100. data/test/files/exslt.xml +0 -8
  101. data/test/files/exslt.xslt +0 -35
  102. data/test/files/foo/foo.xsd +0 -4
  103. data/test/files/metacharset.html +0 -10
  104. data/test/files/noencoding.html +0 -47
  105. data/test/files/po.xml +0 -32
  106. data/test/files/po.xsd +0 -66
  107. data/test/files/shift_jis.html +0 -10
  108. data/test/files/shift_jis.xml +0 -5
  109. data/test/files/snuggles.xml +0 -3
  110. data/test/files/staff.dtd +0 -10
  111. data/test/files/staff.xml +0 -59
  112. data/test/files/staff.xslt +0 -32
  113. data/test/files/test_document_url/bar.xml +0 -2
  114. data/test/files/test_document_url/document.dtd +0 -4
  115. data/test/files/test_document_url/document.xml +0 -6
  116. data/test/files/tlm.html +0 -850
  117. data/test/files/to_be_xincluded.xml +0 -2
  118. data/test/files/valid_bar.xml +0 -2
  119. data/test/files/xinclude.xml +0 -4
  120. data/test/helper.rb +0 -154
  121. data/test/html/sax/test_parser.rb +0 -141
  122. data/test/html/sax/test_parser_context.rb +0 -46
  123. data/test/html/test_builder.rb +0 -164
  124. data/test/html/test_document.rb +0 -552
  125. data/test/html/test_document_encoding.rb +0 -138
  126. data/test/html/test_document_fragment.rb +0 -261
  127. data/test/html/test_element_description.rb +0 -105
  128. data/test/html/test_named_characters.rb +0 -14
  129. data/test/html/test_node.rb +0 -196
  130. data/test/html/test_node_encoding.rb +0 -27
  131. data/test/namespaces/test_additional_namespaces_in_builder_doc.rb +0 -14
  132. data/test/namespaces/test_namespaces_in_builder_doc.rb +0 -75
  133. data/test/namespaces/test_namespaces_in_created_doc.rb +0 -75
  134. data/test/namespaces/test_namespaces_in_parsed_doc.rb +0 -66
  135. data/test/test_convert_xpath.rb +0 -135
  136. data/test/test_css_cache.rb +0 -45
  137. data/test/test_encoding_handler.rb +0 -46
  138. data/test/test_memory_leak.rb +0 -156
  139. data/test/test_nokogiri.rb +0 -132
  140. data/test/test_reader.rb +0 -555
  141. data/test/test_soap4r_sax.rb +0 -52
  142. data/test/test_xslt_transforms.rb +0 -254
  143. data/test/xml/node/test_save_options.rb +0 -28
  144. data/test/xml/node/test_subclass.rb +0 -44
  145. data/test/xml/sax/test_parser.rb +0 -366
  146. data/test/xml/sax/test_parser_context.rb +0 -106
  147. data/test/xml/sax/test_push_parser.rb +0 -157
  148. data/test/xml/test_attr.rb +0 -64
  149. data/test/xml/test_attribute_decl.rb +0 -86
  150. data/test/xml/test_builder.rb +0 -306
  151. data/test/xml/test_c14n.rb +0 -151
  152. data/test/xml/test_cdata.rb +0 -48
  153. data/test/xml/test_comment.rb +0 -29
  154. data/test/xml/test_document.rb +0 -828
  155. data/test/xml/test_document_encoding.rb +0 -28
  156. data/test/xml/test_document_fragment.rb +0 -223
  157. data/test/xml/test_dtd.rb +0 -103
  158. data/test/xml/test_dtd_encoding.rb +0 -33
  159. data/test/xml/test_element_content.rb +0 -56
  160. data/test/xml/test_element_decl.rb +0 -73
  161. data/test/xml/test_entity_decl.rb +0 -122
  162. data/test/xml/test_entity_reference.rb +0 -245
  163. data/test/xml/test_namespace.rb +0 -95
  164. data/test/xml/test_node.rb +0 -1137
  165. data/test/xml/test_node_attributes.rb +0 -96
  166. data/test/xml/test_node_encoding.rb +0 -107
  167. data/test/xml/test_node_inheritance.rb +0 -32
  168. data/test/xml/test_node_reparenting.rb +0 -374
  169. data/test/xml/test_node_set.rb +0 -755
  170. data/test/xml/test_parse_options.rb +0 -64
  171. data/test/xml/test_processing_instruction.rb +0 -30
  172. data/test/xml/test_reader_encoding.rb +0 -142
  173. data/test/xml/test_relax_ng.rb +0 -60
  174. data/test/xml/test_schema.rb +0 -103
  175. data/test/xml/test_syntax_error.rb +0 -12
  176. data/test/xml/test_text.rb +0 -45
  177. data/test/xml/test_unparented_node.rb +0 -422
  178. data/test/xml/test_xinclude.rb +0 -83
  179. data/test/xml/test_xpath.rb +0 -295
  180. data/test/xslt/test_custom_functions.rb +0 -133
  181. data/test/xslt/test_exception_handling.rb +0 -37
  182. data/test_all +0 -81
@@ -1,341 +0,0 @@
1
- require "helper"
2
-
3
- module Nokogiri
4
- module CSS
5
- class TestParser < Nokogiri::TestCase
6
- def setup
7
- super
8
- @parser = Nokogiri::CSS::Parser.new
9
- @parser_with_ns = Nokogiri::CSS::Parser.new({
10
- "xmlns" => "http://default.example.com/",
11
- "hoge" => "http://hoge.example.com/",
12
- })
13
- end
14
-
15
- def test_extra_single_quote
16
- assert_raises(CSS::SyntaxError) { @parser.parse("'") }
17
- end
18
-
19
- def test_syntax_error_raised
20
- assert_raises(CSS::SyntaxError) { @parser.parse("a[x=]") }
21
- end
22
-
23
- def test_function_and_pseudo
24
- assert_xpath '//child::text()[position() = 99]', @parser.parse('text():nth-of-type(99)')
25
- end
26
-
27
- def test_find_by_type
28
- ast = @parser.parse("a:nth-child(2)").first
29
- matches = ast.find_by_type(
30
- [:CONDITIONAL_SELECTOR,
31
- [:ELEMENT_NAME],
32
- [:PSEUDO_CLASS,
33
- [:FUNCTION]
34
- ]
35
- ]
36
- )
37
- assert_equal(1, matches.length)
38
- assert_equal(ast, matches.first)
39
- end
40
-
41
- def test_to_type
42
- ast = @parser.parse("a:nth-child(2)").first
43
- assert_equal(
44
- [:CONDITIONAL_SELECTOR,
45
- [:ELEMENT_NAME],
46
- [:PSEUDO_CLASS,
47
- [:FUNCTION]
48
- ]
49
- ], ast.to_type
50
- )
51
- end
52
-
53
- def test_to_a
54
- asts = @parser.parse("a:nth-child(2)")
55
- assert_equal(
56
- [:CONDITIONAL_SELECTOR,
57
- [:ELEMENT_NAME, ["a"]],
58
- [:PSEUDO_CLASS,
59
- [:FUNCTION, ["nth-child("], ["2"]]
60
- ]
61
- ], asts.first.to_a
62
- )
63
- end
64
-
65
- def test_has
66
- assert_xpath "//a[b]", @parser.parse("a:has(b)")
67
- assert_xpath "//a[b/c]", @parser.parse("a:has(b > c)")
68
- end
69
-
70
- def test_dashmatch
71
- assert_xpath "//a[@class = 'bar' or starts-with(@class, concat('bar', '-'))]",
72
- @parser.parse("a[@class|='bar']")
73
- assert_xpath "//a[@class = 'bar' or starts-with(@class, concat('bar', '-'))]",
74
- @parser.parse("a[@class |= 'bar']")
75
- end
76
-
77
- def test_includes
78
- assert_xpath "//a[contains(concat(\" \", @class, \" \"),concat(\" \", 'bar', \" \"))]",
79
- @parser.parse("a[@class~='bar']")
80
- assert_xpath "//a[contains(concat(\" \", @class, \" \"),concat(\" \", 'bar', \" \"))]",
81
- @parser.parse("a[@class ~= 'bar']")
82
- end
83
-
84
- def test_function_with_arguments
85
- assert_xpath "//*[position() = 2 and self::a]",
86
- @parser.parse("a[2]")
87
- assert_xpath "//*[position() = 2 and self::a]",
88
- @parser.parse("a:nth-child(2)")
89
- end
90
-
91
- def test_carrot
92
- assert_xpath "//a[starts-with(@id, 'Boing')]",
93
- @parser.parse("a[id^='Boing']")
94
- assert_xpath "//a[starts-with(@id, 'Boing')]",
95
- @parser.parse("a[id ^= 'Boing']")
96
- end
97
-
98
- def test_suffix_match
99
- assert_xpath "//a[substring(@id, string-length(@id) - string-length('Boing') + 1, string-length('Boing')) = 'Boing']",
100
- @parser.parse("a[id$='Boing']")
101
- assert_xpath "//a[substring(@id, string-length(@id) - string-length('Boing') + 1, string-length('Boing')) = 'Boing']",
102
- @parser.parse("a[id $= 'Boing']")
103
- end
104
-
105
- def test_attributes_with_at
106
- ## This is non standard CSS
107
- assert_xpath "//a[@id = 'Boing']",
108
- @parser.parse("a[@id='Boing']")
109
- assert_xpath "//a[@id = 'Boing']",
110
- @parser.parse("a[@id = 'Boing']")
111
- end
112
-
113
- def test_attributes_with_at_and_stuff
114
- ## This is non standard CSS
115
- assert_xpath "//a[@id = 'Boing']//div",
116
- @parser.parse("a[@id='Boing'] div")
117
- end
118
-
119
- def test_not_equal
120
- ## This is non standard CSS
121
- assert_xpath "//a[child::text() != 'Boing']",
122
- @parser.parse("a[text()!='Boing']")
123
- assert_xpath "//a[child::text() != 'Boing']",
124
- @parser.parse("a[text() != 'Boing']")
125
- end
126
-
127
- def test_function
128
- ## This is non standard CSS
129
- assert_xpath "//a[child::text()]",
130
- @parser.parse("a[text()]")
131
-
132
- ## This is non standard CSS
133
- assert_xpath "//child::text()",
134
- @parser.parse("text()")
135
-
136
- ## This is non standard CSS
137
- assert_xpath "//a[contains(child::text(), 'Boing')]",
138
- @parser.parse("a[text()*='Boing']")
139
- assert_xpath "//a[contains(child::text(), 'Boing')]",
140
- @parser.parse("a[text() *= 'Boing']")
141
-
142
- ## This is non standard CSS
143
- assert_xpath "//script//comment()",
144
- @parser.parse("script comment()")
145
- end
146
-
147
- def test_nonstandard_nth_selectors
148
- ## These are non standard CSS
149
- assert_xpath '//a[position() = 1]', @parser.parse('a:first()')
150
- assert_xpath '//a[position() = 1]', @parser.parse('a:first') # no parens
151
- assert_xpath '//a[position() = 99]', @parser.parse('a:eq(99)')
152
- assert_xpath '//a[position() = 99]', @parser.parse('a:nth(99)')
153
- assert_xpath '//a[position() = last()]', @parser.parse('a:last()')
154
- assert_xpath '//a[position() = last()]', @parser.parse('a:last') # no parens
155
- assert_xpath '//a[node()]', @parser.parse('a:parent')
156
- end
157
-
158
- def test_standard_nth_selectors
159
- assert_xpath '//a[position() = 1]', @parser.parse('a:first-of-type()')
160
- assert_xpath '//a[position() = 1]', @parser.parse('a:first-of-type') # no parens
161
- assert_xpath '//a[position() = 99]', @parser.parse('a:nth-of-type(99)')
162
- assert_xpath '//a[position() = last()]', @parser.parse('a:last-of-type()')
163
- assert_xpath '//a[position() = last()]', @parser.parse('a:last-of-type') # no parens
164
- assert_xpath '//a[position() = last()]', @parser.parse('a:nth-last-of-type(1)')
165
- assert_xpath '//a[position() = last() - 98]', @parser.parse('a:nth-last-of-type(99)')
166
- end
167
-
168
- def test_nth_child_selectors
169
- assert_xpath '//*[position() = 1 and self::a]', @parser.parse('a:first-child')
170
- assert_xpath '//*[position() = 99 and self::a]', @parser.parse('a:nth-child(99)')
171
- assert_xpath '//*[position() = last() and self::a]', @parser.parse('a:last-child')
172
- assert_xpath '//*[position() = last() and self::a]', @parser.parse('a:nth-last-child(1)')
173
- assert_xpath '//*[position() = last() - 98 and self::a]', @parser.parse('a:nth-last-child(99)')
174
- end
175
-
176
- def test_miscellaneous_selectors
177
- assert_xpath '//*[last() = 1 and self::a]',
178
- @parser.parse('a:only-child')
179
- assert_xpath '//a[last() = 1]', @parser.parse('a:only-of-type')
180
- assert_xpath '//a[not(node())]', @parser.parse('a:empty')
181
- end
182
-
183
- def test_nth_a_n_plus_b
184
- assert_xpath '//a[(position() mod 2) = 0]', @parser.parse('a:nth-of-type(2n)')
185
- assert_xpath '//a[(position() >= 1) and (((position()-1) mod 2) = 0)]', @parser.parse('a:nth-of-type(2n+1)')
186
- assert_xpath '//a[(position() mod 2) = 0]', @parser.parse('a:nth-of-type(even)')
187
- assert_xpath '//a[(position() >= 1) and (((position()-1) mod 2) = 0)]', @parser.parse('a:nth-of-type(odd)')
188
- assert_xpath '//a[(position() >= 3) and (((position()-3) mod 4) = 0)]', @parser.parse('a:nth-of-type(4n+3)')
189
- assert_xpath '//a[(position() <= 3) and (((position()-3) mod 1) = 0)]', @parser.parse('a:nth-of-type(-1n+3)')
190
- assert_xpath '//a[(position() <= 3) and (((position()-3) mod 1) = 0)]', @parser.parse('a:nth-of-type(-n+3)')
191
- assert_xpath '//a[(position() >= 3) and (((position()-3) mod 1) = 0)]', @parser.parse('a:nth-of-type(1n+3)')
192
- assert_xpath '//a[(position() >= 3) and (((position()-3) mod 1) = 0)]', @parser.parse('a:nth-of-type(n+3)')
193
-
194
- assert_xpath '//a[((last()-position()+1) mod 2) = 0]', @parser.parse('a:nth-last-of-type(2n)')
195
- assert_xpath '//a[((last()-position()+1) >= 1) and ((((last()-position()+1)-1) mod 2) = 0)]', @parser.parse('a:nth-last-of-type(2n+1)')
196
- assert_xpath '//a[((last()-position()+1) mod 2) = 0]', @parser.parse('a:nth-last-of-type(even)')
197
- assert_xpath '//a[((last()-position()+1) >= 1) and ((((last()-position()+1)-1) mod 2) = 0)]', @parser.parse('a:nth-last-of-type(odd)')
198
- assert_xpath '//a[((last()-position()+1) >= 3) and ((((last()-position()+1)-3) mod 4) = 0)]', @parser.parse('a:nth-last-of-type(4n+3)')
199
- assert_xpath '//a[((last()-position()+1) <= 3) and ((((last()-position()+1)-3) mod 1) = 0)]', @parser.parse('a:nth-last-of-type(-1n+3)')
200
- assert_xpath '//a[((last()-position()+1) <= 3) and ((((last()-position()+1)-3) mod 1) = 0)]', @parser.parse('a:nth-last-of-type(-n+3)')
201
- assert_xpath '//a[((last()-position()+1) >= 3) and ((((last()-position()+1)-3) mod 1) = 0)]', @parser.parse('a:nth-last-of-type(1n+3)')
202
- assert_xpath '//a[((last()-position()+1) >= 3) and ((((last()-position()+1)-3) mod 1) = 0)]', @parser.parse('a:nth-last-of-type(n+3)')
203
- end
204
-
205
- def test_preceding_selector
206
- assert_xpath "//E/following-sibling::F",
207
- @parser.parse("E ~ F")
208
-
209
- assert_xpath "//E/following-sibling::F//G",
210
- @parser.parse("E ~ F G")
211
- end
212
-
213
- def test_direct_preceding_selector
214
- assert_xpath "//E/following-sibling::*[1]/self::F",
215
- @parser.parse("E + F")
216
-
217
- assert_xpath "//E/following-sibling::*[1]/self::F//G",
218
- @parser.parse("E + F G")
219
- end
220
-
221
- def test_child_selector
222
- assert_xpath("//a//b/i", @parser.parse('a b>i'))
223
- assert_xpath("//a//b/i", @parser.parse('a b > i'))
224
- assert_xpath("//a/b/i", @parser.parse('a > b > i'))
225
- end
226
-
227
- def test_prefixless_child_selector
228
- assert_xpath("./a", @parser.parse('>a'))
229
- assert_xpath("./a", @parser.parse('> a'))
230
- assert_xpath("./a//b/i", @parser.parse('>a b>i'))
231
- assert_xpath("./a/b/i", @parser.parse('> a > b > i'))
232
- end
233
-
234
- def test_prefixless_preceding_sibling_selector
235
- assert_xpath("./following-sibling::a", @parser.parse('~a'))
236
- assert_xpath("./following-sibling::a", @parser.parse('~ a'))
237
- assert_xpath("./following-sibling::a//b/following-sibling::i", @parser.parse('~a b~i'))
238
- assert_xpath("./following-sibling::a//b/following-sibling::i", @parser.parse('~ a b ~ i'))
239
- end
240
-
241
- def test_prefixless_direct_adjacent_selector
242
- assert_xpath("./following-sibling::*[1]/self::a", @parser.parse('+a'))
243
- assert_xpath("./following-sibling::*[1]/self::a", @parser.parse('+ a'))
244
- assert_xpath("./following-sibling::*[1]/self::a/following-sibling::*[1]/self::b", @parser.parse('+a+b'))
245
- assert_xpath("./following-sibling::*[1]/self::a/following-sibling::*[1]/self::b", @parser.parse('+ a + b'))
246
- end
247
-
248
- def test_attribute
249
- assert_xpath "//h1[@a = 'Tender Lovemaking']",
250
- @parser.parse("h1[a='Tender Lovemaking']")
251
- end
252
-
253
- def test_id
254
- assert_xpath "//*[@id = 'foo']", @parser.parse('#foo')
255
- end
256
-
257
- def test_pseudo_class_no_ident
258
- assert_xpath "//*[link(.)]", @parser.parse(':link')
259
- end
260
-
261
- def test_pseudo_class
262
- assert_xpath "//a[link(.)]", @parser.parse('a:link')
263
- assert_xpath "//a[visited(.)]", @parser.parse('a:visited')
264
- assert_xpath "//a[hover(.)]", @parser.parse('a:hover')
265
- assert_xpath "//a[active(.)]", @parser.parse('a:active')
266
- assert_xpath "//a[active(.) and contains(concat(' ', normalize-space(@class), ' '), ' foo ')]",
267
- @parser.parse('a:active.foo')
268
- end
269
-
270
- def test_star
271
- assert_xpath "//*", @parser.parse('*')
272
- assert_xpath "//*[contains(concat(' ', normalize-space(@class), ' '), ' pastoral ')]",
273
- @parser.parse('*.pastoral')
274
- end
275
-
276
- def test_class
277
- assert_xpath "//*[contains(concat(' ', normalize-space(@class), ' '), ' a ') and contains(concat(' ', normalize-space(@class), ' '), ' b ')]",
278
- @parser.parse('.a.b')
279
- assert_xpath "//*[contains(concat(' ', normalize-space(@class), ' '), ' awesome ')]",
280
- @parser.parse('.awesome')
281
- assert_xpath "//foo[contains(concat(' ', normalize-space(@class), ' '), ' awesome ')]",
282
- @parser.parse('foo.awesome')
283
- assert_xpath "//foo//*[contains(concat(' ', normalize-space(@class), ' '), ' awesome ')]",
284
- @parser.parse('foo .awesome')
285
- end
286
-
287
- def test_not_so_simple_not
288
- assert_xpath "//*[@id = 'p' and not(contains(concat(' ', normalize-space(@class), ' '), ' a '))]",
289
- @parser.parse('#p:not(.a)')
290
- assert_xpath "//p[contains(concat(' ', normalize-space(@class), ' '), ' a ') and not(contains(concat(' ', normalize-space(@class), ' '), ' b '))]",
291
- @parser.parse('p.a:not(.b)')
292
- assert_xpath "//p[@a = 'foo' and not(contains(concat(' ', normalize-space(@class), ' '), ' b '))]",
293
- @parser.parse("p[a='foo']:not(.b)")
294
- end
295
-
296
- def test_ident
297
- assert_xpath '//x', @parser.parse('x')
298
- end
299
-
300
- def test_parse_space
301
- assert_xpath '//x//y', @parser.parse('x y')
302
- end
303
-
304
- def test_parse_descendant
305
- assert_xpath '//x/y', @parser.parse('x > y')
306
- end
307
-
308
- def test_parse_slash
309
- ## This is non standard CSS
310
- assert_xpath '//x/y', @parser.parse('x/y')
311
- end
312
-
313
- def test_parse_doubleslash
314
- ## This is non standard CSS
315
- assert_xpath '//x//y', @parser.parse('x//y')
316
- end
317
-
318
- def test_multi_path
319
- assert_xpath ['//x/y', '//y/z'], @parser.parse('x > y, y > z')
320
- assert_xpath ['//x/y', '//y/z'], @parser.parse('x > y,y > z')
321
- ###
322
- # TODO: should we make this work?
323
- # assert_xpath ['//x/y', '//y/z'], @parser.parse('x > y | y > z')
324
- end
325
-
326
- def test_attributes_with_namespace
327
- ## Default namespace is not applied to attributes.
328
- ## So this must be @class, not @xmlns:class.
329
- assert_xpath "//xmlns:a[@class = 'bar']", @parser_with_ns.parse("a[class='bar']")
330
- assert_xpath "//xmlns:a[@hoge:class = 'bar']", @parser_with_ns.parse("a[hoge|class='bar']")
331
- end
332
-
333
- def assert_xpath expecteds, asts
334
- expecteds = [expecteds].flatten
335
- expecteds.zip(asts).each do |expected, actual|
336
- assert_equal expected, actual.to_xpath
337
- end
338
- end
339
- end
340
- end
341
- end
@@ -1,198 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
-
3
- require "helper"
4
-
5
- module Nokogiri
6
- module CSS
7
- class Tokenizer
8
- alias :scan :scan_setup
9
- end
10
- end
11
- end
12
-
13
- module Nokogiri
14
- module CSS
15
- class TestTokenizer < Nokogiri::TestCase
16
- def setup
17
- super
18
- @scanner = Nokogiri::CSS::Tokenizer.new
19
- end
20
-
21
- def test_has
22
- @scanner.scan("a:has(b)")
23
- assert_tokens(
24
- [[:IDENT, "a"], [":", ":"], [:HAS, "has("], [:IDENT, "b"], [:RPAREN, ")"]],
25
- @scanner)
26
- end
27
-
28
- def test_unicode
29
- @scanner.scan("a日本語")
30
- assert_tokens([[:IDENT, 'a日本語']], @scanner)
31
- end
32
-
33
- def test_tokenize_bad_single_quote
34
- @scanner.scan("'")
35
- assert_tokens([["'", "'"]], @scanner)
36
- end
37
-
38
- def test_not_equal
39
- @scanner.scan("h1[a!='Tender Lovemaking']")
40
- assert_tokens([ [:IDENT, 'h1'],
41
- [:LSQUARE, '['],
42
- [:IDENT, 'a'],
43
- [:NOT_EQUAL, '!='],
44
- [:STRING, "'Tender Lovemaking'"],
45
- [:RSQUARE, ']'],
46
- ], @scanner)
47
- end
48
-
49
- def test_negation
50
- @scanner.scan("p:not(.a)")
51
- assert_tokens([ [:IDENT, 'p'],
52
- [:NOT, ':not('],
53
- ['.', '.'],
54
- [:IDENT, 'a'],
55
- [:RPAREN, ')'],
56
- ], @scanner)
57
- end
58
-
59
- def test_function
60
- @scanner.scan("script comment()")
61
- assert_tokens([ [:IDENT, 'script'],
62
- [:S, ' '],
63
- [:FUNCTION, 'comment('],
64
- [:RPAREN, ')'],
65
- ], @scanner)
66
- end
67
-
68
- def test_preceding_selector
69
- @scanner.scan("E ~ F")
70
- assert_tokens([ [:IDENT, 'E'],
71
- [:TILDE, ' ~ '],
72
- [:IDENT, 'F'],
73
- ], @scanner)
74
- end
75
-
76
- def test_scan_attribute_string
77
- @scanner.scan("h1[a='Tender Lovemaking']")
78
- assert_tokens([ [:IDENT, 'h1'],
79
- [:LSQUARE, '['],
80
- [:IDENT, 'a'],
81
- [:EQUAL, '='],
82
- [:STRING, "'Tender Lovemaking'"],
83
- [:RSQUARE, ']'],
84
- ], @scanner)
85
- @scanner.scan('h1[a="Tender Lovemaking"]')
86
- assert_tokens([ [:IDENT, 'h1'],
87
- [:LSQUARE, '['],
88
- [:IDENT, 'a'],
89
- [:EQUAL, '='],
90
- [:STRING, '"Tender Lovemaking"'],
91
- [:RSQUARE, ']'],
92
- ], @scanner)
93
- end
94
-
95
- def test_scan_id
96
- @scanner.scan('#foo')
97
- assert_tokens([ [:HASH, '#foo'] ], @scanner)
98
- end
99
-
100
- def test_scan_pseudo
101
- @scanner.scan('a:visited')
102
- assert_tokens([ [:IDENT, 'a'],
103
- [':', ':'],
104
- [:IDENT, 'visited']
105
- ], @scanner)
106
- end
107
-
108
- def test_scan_star
109
- @scanner.scan('*')
110
- assert_tokens([ ['*', '*'], ], @scanner)
111
- end
112
-
113
- def test_scan_class
114
- @scanner.scan('x.awesome')
115
- assert_tokens([ [:IDENT, 'x'],
116
- ['.', '.'],
117
- [:IDENT, 'awesome'],
118
- ], @scanner)
119
- end
120
-
121
- def test_scan_greater
122
- @scanner.scan('x > y')
123
- assert_tokens([ [:IDENT, 'x'],
124
- [:GREATER, ' > '],
125
- [:IDENT, 'y']
126
- ], @scanner)
127
- end
128
-
129
- def test_scan_slash
130
- @scanner.scan('x/y')
131
- assert_tokens([ [:IDENT, 'x'],
132
- [:SLASH, '/'],
133
- [:IDENT, 'y']
134
- ], @scanner)
135
- end
136
-
137
- def test_scan_doubleslash
138
- @scanner.scan('x//y')
139
- assert_tokens([ [:IDENT, 'x'],
140
- [:DOUBLESLASH, '//'],
141
- [:IDENT, 'y']
142
- ], @scanner)
143
- end
144
-
145
- def test_scan_function_selector
146
- @scanner.scan('x:eq(0)')
147
- assert_tokens([ [:IDENT, 'x'],
148
- [':', ':'],
149
- [:FUNCTION, 'eq('],
150
- [:NUMBER, "0"],
151
- [:RPAREN, ')'],
152
- ], @scanner)
153
- end
154
-
155
- def test_scan_an_plus_b
156
- @scanner.scan('x:nth-child(5n+3)')
157
- assert_tokens([ [:IDENT, 'x'],
158
- [':', ':'],
159
- [:FUNCTION, 'nth-child('],
160
- [:NUMBER, '5'],
161
- [:IDENT, 'n'],
162
- [:PLUS, '+'],
163
- [:NUMBER, '3'],
164
- [:RPAREN, ')'],
165
- ], @scanner)
166
-
167
- @scanner.scan('x:nth-child(-1n+3)')
168
- assert_tokens([ [:IDENT, 'x'],
169
- [':', ':'],
170
- [:FUNCTION, 'nth-child('],
171
- [:NUMBER, '-1'],
172
- [:IDENT, 'n'],
173
- [:PLUS, '+'],
174
- [:NUMBER, '3'],
175
- [:RPAREN, ')'],
176
- ], @scanner)
177
-
178
- @scanner.scan('x:nth-child(-n+3)')
179
- assert_tokens([ [:IDENT, 'x'],
180
- [':', ':'],
181
- [:FUNCTION, 'nth-child('],
182
- [:IDENT, '-n'],
183
- [:PLUS, '+'],
184
- [:NUMBER, '3'],
185
- [:RPAREN, ')'],
186
- ], @scanner)
187
- end
188
-
189
- def assert_tokens(tokens, scanner)
190
- toks = []
191
- while tok = @scanner.next_token
192
- toks << tok
193
- end
194
- assert_equal(tokens, toks)
195
- end
196
- end
197
- end
198
- end
@@ -1,91 +0,0 @@
1
- require "helper"
2
-
3
- module Nokogiri
4
- module CSS
5
- class TestXPathVisitor < Nokogiri::TestCase
6
- def setup
7
- super
8
- @parser = Nokogiri::CSS::Parser.new
9
- end
10
-
11
- def test_not_simple_selector
12
- assert_xpath('//ol/*[not(self::li)]', @parser.parse('ol > *:not(li)'))
13
- end
14
-
15
- def test_not_last_child
16
- assert_xpath('//ol/*[not(position() = last())]',
17
- @parser.parse('ol > *:not(:last-child)'))
18
- end
19
-
20
- def test_function_calls_allow_at_params
21
- assert_xpath("//a[foo(., @href)]", @parser.parse('a:foo(@href)'))
22
- assert_xpath("//a[foo(., @a, b)]", @parser.parse('a:foo(@a, b)'))
23
- assert_xpath("//a[foo(., a, 10)]", @parser.parse('a:foo(a, 10)'))
24
- end
25
-
26
- def test_namespace_conversion
27
- assert_xpath("//aaron:a", @parser.parse('aaron|a'))
28
- assert_xpath("//a", @parser.parse('|a'))
29
- end
30
-
31
- def test_namespaced_attribute_conversion
32
- assert_xpath("//a[@flavorjones:href]", @parser.parse('a[flavorjones|href]'))
33
- assert_xpath("//a[@href]", @parser.parse('a[|href]'))
34
- assert_xpath("//*[@flavorjones:href]", @parser.parse('*[flavorjones|href]'))
35
- end
36
-
37
- def test_unknown_psuedo_classes_get_pushed_down
38
- assert_xpath("//a[aaron(.)]", @parser.parse('a:aaron'))
39
- end
40
-
41
- def test_unknown_functions_get_dot_plus_args
42
- assert_xpath("//a[aaron(.)]", @parser.parse('a:aaron()'))
43
- assert_xpath("//a[aaron(., 12)]", @parser.parse('a:aaron(12)'))
44
- assert_xpath("//a[aaron(., 12, 1)]", @parser.parse('a:aaron(12, 1)'))
45
- end
46
-
47
- def test_class_selectors
48
- assert_xpath "//*[contains(concat(' ', normalize-space(@class), ' '), ' red ')]",
49
- @parser.parse(".red")
50
- end
51
-
52
- def test_pipe
53
- assert_xpath "//a[@id = 'Boing' or starts-with(@id, concat('Boing', '-'))]",
54
- @parser.parse("a[id|='Boing']")
55
- end
56
-
57
- def test_custom_functions
58
- visitor = Class.new(XPathVisitor) do
59
- attr_accessor :awesome
60
- def visit_function_aaron node
61
- @awesome = true
62
- 'aaron() = 1'
63
- end
64
- end.new
65
- ast = @parser.parse('a:aaron()').first
66
- assert_equal 'a[aaron() = 1]', visitor.accept(ast)
67
- assert visitor.awesome
68
- end
69
-
70
- def test_custom_psuedo_classes
71
- visitor = Class.new(XPathVisitor) do
72
- attr_accessor :awesome
73
- def visit_pseudo_class_aaron node
74
- @awesome = true
75
- 'aaron() = 1'
76
- end
77
- end.new
78
- ast = @parser.parse('a:aaron').first
79
- assert_equal 'a[aaron() = 1]', visitor.accept(ast)
80
- assert visitor.awesome
81
- end
82
-
83
- def assert_xpath expecteds, asts
84
- expecteds = [expecteds].flatten
85
- expecteds.zip(asts).each do |expected, actual|
86
- assert_equal expected, actual.to_xpath
87
- end
88
- end
89
- end
90
- end
91
- end
@@ -1,16 +0,0 @@
1
- require "helper"
2
-
3
- module Nokogiri
4
- class TestSlop < Nokogiri::TestCase
5
- def test_description_tag
6
- doc = Nokogiri.Slop(<<-eoxml)
7
- <item>
8
- <title>foo</title>
9
- <description>this is the foo thing</description>
10
- </item>
11
- eoxml
12
- assert doc.item.title
13
- assert doc.item._description, 'should have description'
14
- end
15
- end
16
- end