nokogiri 1.9.0.rc1 → 1.9.0

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 (137) hide show
  1. checksums.yaml +4 -4
  2. data/lib/nokogiri/css/parser.rb +61 -61
  3. data/lib/nokogiri/version.rb +1 -1
  4. metadata +4 -146
  5. data/.autotest +0 -22
  6. data/.cross_rubies +0 -8
  7. data/.editorconfig +0 -17
  8. data/.gemtest +0 -0
  9. data/.travis.yml +0 -63
  10. data/CHANGELOG.md +0 -1402
  11. data/CONTRIBUTING.md +0 -42
  12. data/C_CODING_STYLE.rdoc +0 -33
  13. data/Gemfile +0 -23
  14. data/Gemfile-libxml-ruby +0 -3
  15. data/Manifest.txt +0 -371
  16. data/ROADMAP.md +0 -111
  17. data/Rakefile +0 -358
  18. data/SECURITY.md +0 -19
  19. data/STANDARD_RESPONSES.md +0 -47
  20. data/Y_U_NO_GEMSPEC.md +0 -155
  21. data/appveyor.yml +0 -29
  22. data/build_all +0 -48
  23. data/patches/sort-patches-by-date +0 -25
  24. data/suppressions/README.txt +0 -1
  25. data/suppressions/nokogiri_ruby-2.supp +0 -10
  26. data/tasks/test.rb +0 -100
  27. data/test/css/test_nthiness.rb +0 -226
  28. data/test/css/test_parser.rb +0 -386
  29. data/test/css/test_tokenizer.rb +0 -215
  30. data/test/css/test_xpath_visitor.rb +0 -96
  31. data/test/decorators/test_slop.rb +0 -23
  32. data/test/files/2ch.html +0 -108
  33. data/test/files/GH_1042.html +0 -18
  34. data/test/files/address_book.rlx +0 -12
  35. data/test/files/address_book.xml +0 -10
  36. data/test/files/atom.xml +0 -344
  37. data/test/files/bar/bar.xsd +0 -4
  38. data/test/files/bogus.xml +0 -0
  39. data/test/files/dont_hurt_em_why.xml +0 -422
  40. data/test/files/encoding.html +0 -82
  41. data/test/files/encoding.xhtml +0 -84
  42. data/test/files/exslt.xml +0 -8
  43. data/test/files/exslt.xslt +0 -35
  44. data/test/files/foo/foo.xsd +0 -4
  45. data/test/files/metacharset.html +0 -10
  46. data/test/files/namespace_pressure_test.xml +0 -1684
  47. data/test/files/noencoding.html +0 -47
  48. data/test/files/po.xml +0 -32
  49. data/test/files/po.xsd +0 -66
  50. data/test/files/saml/saml20assertion_schema.xsd +0 -283
  51. data/test/files/saml/saml20protocol_schema.xsd +0 -302
  52. data/test/files/saml/xenc_schema.xsd +0 -146
  53. data/test/files/saml/xmldsig_schema.xsd +0 -318
  54. data/test/files/shift_jis.html +0 -10
  55. data/test/files/shift_jis.xml +0 -5
  56. data/test/files/shift_jis_no_charset.html +0 -9
  57. data/test/files/slow-xpath.xml +0 -25509
  58. data/test/files/snuggles.xml +0 -3
  59. data/test/files/staff.dtd +0 -10
  60. data/test/files/staff.xml +0 -59
  61. data/test/files/staff.xslt +0 -32
  62. data/test/files/test_document_url/bar.xml +0 -2
  63. data/test/files/test_document_url/document.dtd +0 -4
  64. data/test/files/test_document_url/document.xml +0 -6
  65. data/test/files/tlm.html +0 -851
  66. data/test/files/to_be_xincluded.xml +0 -2
  67. data/test/files/valid_bar.xml +0 -2
  68. data/test/files/xinclude.xml +0 -4
  69. data/test/helper.rb +0 -271
  70. data/test/html/sax/test_parser.rb +0 -168
  71. data/test/html/sax/test_parser_context.rb +0 -46
  72. data/test/html/sax/test_parser_text.rb +0 -163
  73. data/test/html/sax/test_push_parser.rb +0 -87
  74. data/test/html/test_attributes.rb +0 -85
  75. data/test/html/test_builder.rb +0 -164
  76. data/test/html/test_document.rb +0 -722
  77. data/test/html/test_document_encoding.rb +0 -143
  78. data/test/html/test_document_fragment.rb +0 -310
  79. data/test/html/test_element_description.rb +0 -105
  80. data/test/html/test_named_characters.rb +0 -14
  81. data/test/html/test_node.rb +0 -212
  82. data/test/html/test_node_encoding.rb +0 -91
  83. data/test/namespaces/test_additional_namespaces_in_builder_doc.rb +0 -14
  84. data/test/namespaces/test_namespaces_aliased_default.rb +0 -24
  85. data/test/namespaces/test_namespaces_in_builder_doc.rb +0 -75
  86. data/test/namespaces/test_namespaces_in_cloned_doc.rb +0 -31
  87. data/test/namespaces/test_namespaces_in_created_doc.rb +0 -75
  88. data/test/namespaces/test_namespaces_in_parsed_doc.rb +0 -80
  89. data/test/namespaces/test_namespaces_preservation.rb +0 -31
  90. data/test/test_convert_xpath.rb +0 -135
  91. data/test/test_css_cache.rb +0 -47
  92. data/test/test_encoding_handler.rb +0 -48
  93. data/test/test_memory_leak.rb +0 -226
  94. data/test/test_nokogiri.rb +0 -138
  95. data/test/test_soap4r_sax.rb +0 -52
  96. data/test/test_xslt_transforms.rb +0 -314
  97. data/test/xml/node/test_save_options.rb +0 -28
  98. data/test/xml/node/test_subclass.rb +0 -44
  99. data/test/xml/sax/test_parser.rb +0 -402
  100. data/test/xml/sax/test_parser_context.rb +0 -115
  101. data/test/xml/sax/test_parser_text.rb +0 -202
  102. data/test/xml/sax/test_push_parser.rb +0 -265
  103. data/test/xml/test_attr.rb +0 -96
  104. data/test/xml/test_attribute_decl.rb +0 -86
  105. data/test/xml/test_builder.rb +0 -353
  106. data/test/xml/test_c14n.rb +0 -180
  107. data/test/xml/test_cdata.rb +0 -54
  108. data/test/xml/test_comment.rb +0 -40
  109. data/test/xml/test_document.rb +0 -982
  110. data/test/xml/test_document_encoding.rb +0 -31
  111. data/test/xml/test_document_fragment.rb +0 -312
  112. data/test/xml/test_dtd.rb +0 -187
  113. data/test/xml/test_dtd_encoding.rb +0 -31
  114. data/test/xml/test_element_content.rb +0 -56
  115. data/test/xml/test_element_decl.rb +0 -73
  116. data/test/xml/test_entity_decl.rb +0 -122
  117. data/test/xml/test_entity_reference.rb +0 -262
  118. data/test/xml/test_namespace.rb +0 -96
  119. data/test/xml/test_node.rb +0 -1379
  120. data/test/xml/test_node_attributes.rb +0 -115
  121. data/test/xml/test_node_encoding.rb +0 -75
  122. data/test/xml/test_node_inheritance.rb +0 -32
  123. data/test/xml/test_node_reparenting.rb +0 -661
  124. data/test/xml/test_node_set.rb +0 -828
  125. data/test/xml/test_parse_options.rb +0 -64
  126. data/test/xml/test_processing_instruction.rb +0 -30
  127. data/test/xml/test_reader.rb +0 -620
  128. data/test/xml/test_reader_encoding.rb +0 -134
  129. data/test/xml/test_relax_ng.rb +0 -60
  130. data/test/xml/test_schema.rb +0 -142
  131. data/test/xml/test_syntax_error.rb +0 -36
  132. data/test/xml/test_text.rb +0 -69
  133. data/test/xml/test_unparented_node.rb +0 -483
  134. data/test/xml/test_xinclude.rb +0 -83
  135. data/test/xml/test_xpath.rb +0 -470
  136. data/test/xslt/test_custom_functions.rb +0 -133
  137. data/test/xslt/test_exception_handling.rb +0 -37
@@ -1,386 +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 "//a[count(preceding-sibling::*) = 1]",
86
- @parser.parse("a[2]")
87
- assert_xpath "//a[count(preceding-sibling::*) = 1]",
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[contains(concat(' ', normalize-space(@class), ' '), ' b ')][position() = 1]",
162
- @parser.parse('a.b:first-of-type') # no parens
163
- assert_xpath '//a[position() = 99]', @parser.parse('a:nth-of-type(99)')
164
- assert_xpath "//a[contains(concat(' ', normalize-space(@class), ' '), ' b ')][position() = 99]",
165
- @parser.parse('a.b:nth-of-type(99)')
166
- assert_xpath '//a[position() = last()]', @parser.parse('a:last-of-type()')
167
- assert_xpath '//a[position() = last()]', @parser.parse('a:last-of-type') # no parens
168
- assert_xpath "//a[contains(concat(' ', normalize-space(@class), ' '), ' b ')][position() = last()]",
169
- @parser.parse('a.b:last-of-type') # no parens
170
- assert_xpath '//a[position() = last()]', @parser.parse('a:nth-last-of-type(1)')
171
- assert_xpath '//a[position() = last() - 98]', @parser.parse('a:nth-last-of-type(99)')
172
- assert_xpath "//a[contains(concat(' ', normalize-space(@class), ' '), ' b ')][position() = last() - 98]",
173
- @parser.parse('a.b:nth-last-of-type(99)')
174
- end
175
-
176
- def test_nth_child_selectors
177
- assert_xpath '//a[count(preceding-sibling::*) = 0]', @parser.parse('a:first-child')
178
- assert_xpath '//a[count(preceding-sibling::*) = 98]', @parser.parse('a:nth-child(99)')
179
- assert_xpath '//a[count(following-sibling::*) = 0]', @parser.parse('a:last-child')
180
- assert_xpath '//a[count(following-sibling::*) = 0]', @parser.parse('a:nth-last-child(1)')
181
- assert_xpath '//a[count(following-sibling::*) = 98]', @parser.parse('a:nth-last-child(99)')
182
- end
183
-
184
- def test_miscellaneous_selectors
185
- assert_xpath '//a[count(preceding-sibling::*) = 0 and count(following-sibling::*) = 0]', @parser.parse('a:only-child')
186
- assert_xpath '//a[last() = 1]', @parser.parse('a:only-of-type')
187
- assert_xpath '//a[not(node())]', @parser.parse('a:empty')
188
- end
189
-
190
- def test_nth_a_n_plus_b
191
- assert_xpath '//a[(position() mod 2) = 0]', @parser.parse('a:nth-of-type(2n)')
192
- assert_xpath '//a[(position() >= 1) and (((position()-1) mod 2) = 0)]', @parser.parse('a:nth-of-type(2n+1)')
193
- assert_xpath '//a[(position() mod 2) = 0]', @parser.parse('a:nth-of-type(even)')
194
- assert_xpath '//a[(position() >= 1) and (((position()-1) mod 2) = 0)]', @parser.parse('a:nth-of-type(odd)')
195
- assert_xpath '//a[(position() >= 3) and (((position()-3) mod 4) = 0)]', @parser.parse('a:nth-of-type(4n+3)')
196
- assert_xpath '//a[position() <= 3]', @parser.parse('a:nth-of-type(-1n+3)')
197
- assert_xpath '//a[position() <= 3]', @parser.parse('a:nth-of-type(-n+3)')
198
- assert_xpath '//a[position() >= 3]', @parser.parse('a:nth-of-type(1n+3)')
199
- assert_xpath '//a[position() >= 3]', @parser.parse('a:nth-of-type(n+3)')
200
-
201
- assert_xpath '//a[((last()-position()+1) mod 2) = 0]', @parser.parse('a:nth-last-of-type(2n)')
202
- assert_xpath '//a[((last()-position()+1) >= 1) and ((((last()-position()+1)-1) mod 2) = 0)]', @parser.parse('a:nth-last-of-type(2n+1)')
203
- assert_xpath '//a[((last()-position()+1) mod 2) = 0]', @parser.parse('a:nth-last-of-type(even)')
204
- assert_xpath '//a[((last()-position()+1) >= 1) and ((((last()-position()+1)-1) mod 2) = 0)]', @parser.parse('a:nth-last-of-type(odd)')
205
- assert_xpath '//a[((last()-position()+1) >= 3) and ((((last()-position()+1)-3) mod 4) = 0)]', @parser.parse('a:nth-last-of-type(4n+3)')
206
- assert_xpath '//a[(last()-position()+1) <= 3]', @parser.parse('a:nth-last-of-type(-1n+3)')
207
- assert_xpath '//a[(last()-position()+1) <= 3]', @parser.parse('a:nth-last-of-type(-n+3)')
208
- assert_xpath '//a[(last()-position()+1) >= 3]', @parser.parse('a:nth-last-of-type(1n+3)')
209
- assert_xpath '//a[(last()-position()+1) >= 3]', @parser.parse('a:nth-last-of-type(n+3)')
210
- end
211
-
212
- def test_preceding_selector
213
- assert_xpath "//E/following-sibling::F",
214
- @parser.parse("E ~ F")
215
-
216
- assert_xpath "//E/following-sibling::F//G",
217
- @parser.parse("E ~ F G")
218
- end
219
-
220
- def test_direct_preceding_selector
221
- assert_xpath "//E/following-sibling::*[1]/self::F",
222
- @parser.parse("E + F")
223
-
224
- assert_xpath "//E/following-sibling::*[1]/self::F//G",
225
- @parser.parse("E + F G")
226
- end
227
-
228
- def test_child_selector
229
- assert_xpath("//a//b/i", @parser.parse('a b>i'))
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_child_selector
235
- assert_xpath("./a", @parser.parse('>a'))
236
- assert_xpath("./a", @parser.parse('> a'))
237
- assert_xpath("./a//b/i", @parser.parse('>a b>i'))
238
- assert_xpath("./a/b/i", @parser.parse('> a > b > i'))
239
- end
240
-
241
- def test_prefixless_preceding_sibling_selector
242
- assert_xpath("./following-sibling::a", @parser.parse('~a'))
243
- assert_xpath("./following-sibling::a", @parser.parse('~ a'))
244
- assert_xpath("./following-sibling::a//b/following-sibling::i", @parser.parse('~a b~i'))
245
- assert_xpath("./following-sibling::a//b/following-sibling::i", @parser.parse('~ a b ~ i'))
246
- end
247
-
248
- def test_prefixless_direct_adjacent_selector
249
- assert_xpath("./following-sibling::*[1]/self::a", @parser.parse('+a'))
250
- assert_xpath("./following-sibling::*[1]/self::a", @parser.parse('+ a'))
251
- assert_xpath("./following-sibling::*[1]/self::a/following-sibling::*[1]/self::b", @parser.parse('+a+b'))
252
- assert_xpath("./following-sibling::*[1]/self::a/following-sibling::*[1]/self::b", @parser.parse('+ a + b'))
253
- end
254
-
255
- def test_attribute
256
- assert_xpath "//h1[@a = 'Tender Lovemaking']",
257
- @parser.parse("h1[a='Tender Lovemaking']")
258
- assert_xpath "//h1[@a]",
259
- @parser.parse("h1[a]")
260
- assert_xpath %q{//h1[@a = 'gnewline\n']},
261
- @parser.parse("h1[a='\\gnew\\\nline\\\\n']")
262
- assert_xpath "//h1[@a = 'test']",
263
- @parser.parse(%q{h1[a=\te\st]})
264
- assert_xpath %q{//h1[@a = "'"]},
265
- @parser.parse(%q{h1[a="'"]})
266
- assert_xpath %q{//h1[@a = concat("'", "")]},
267
- @parser.parse(%q{h1[a='\\'']})
268
- assert_xpath %q{//h1[@a = concat("", '"', "'", "")]},
269
- @parser.parse(%q{h1[a='"\'']})
270
- end
271
-
272
- def test_attribute_with_number_or_string
273
- assert_xpath "//img[@width = '200']", @parser.parse("img[width='200']")
274
- assert_xpath "//img[@width = '200']", @parser.parse("img[width=200]")
275
- end
276
-
277
- def test_id
278
- assert_xpath "//*[@id = 'foo']", @parser.parse('#foo')
279
- assert_xpath "//*[@id = 'escape:needed,']", @parser.parse('#escape\:needed\,')
280
- assert_xpath "//*[@id = 'escape:needed,']", @parser.parse('#escape\3Aneeded\,')
281
- assert_xpath "//*[@id = 'escape:needed,']", @parser.parse('#escape\3A needed\2C')
282
- assert_xpath "//*[@id = 'escape:needed']", @parser.parse('#escape\00003Aneeded')
283
- end
284
-
285
- def test_pseudo_class_no_ident
286
- assert_xpath "//*[link(.)]", @parser.parse(':link')
287
- end
288
-
289
- def test_pseudo_class
290
- assert_xpath "//a[link(.)]", @parser.parse('a:link')
291
- assert_xpath "//a[visited(.)]", @parser.parse('a:visited')
292
- assert_xpath "//a[hover(.)]", @parser.parse('a:hover')
293
- assert_xpath "//a[active(.)]", @parser.parse('a:active')
294
- assert_xpath "//a[active(.) and contains(concat(' ', normalize-space(@class), ' '), ' foo ')]",
295
- @parser.parse('a:active.foo')
296
- end
297
-
298
- def test_significant_space
299
- assert_xpath "//x//*[count(preceding-sibling::*) = 0]//*[@a]//*[@b]", @parser.parse("x :first-child [a] [b]")
300
- assert_xpath "//*[@a]//*[@b]", @parser.parse(" [a] [b]")
301
- end
302
-
303
- def test_star
304
- assert_xpath "//*", @parser.parse('*')
305
- assert_xpath "//*[contains(concat(' ', normalize-space(@class), ' '), ' pastoral ')]",
306
- @parser.parse('*.pastoral')
307
- end
308
-
309
- def test_class
310
- assert_xpath "//*[contains(concat(' ', normalize-space(@class), ' '), ' a ') and contains(concat(' ', normalize-space(@class), ' '), ' b ')]",
311
- @parser.parse('.a.b')
312
- assert_xpath "//*[contains(concat(' ', normalize-space(@class), ' '), ' awesome ')]",
313
- @parser.parse('.awesome')
314
- assert_xpath "//foo[contains(concat(' ', normalize-space(@class), ' '), ' awesome ')]",
315
- @parser.parse('foo.awesome')
316
- assert_xpath "//foo//*[contains(concat(' ', normalize-space(@class), ' '), ' awesome ')]",
317
- @parser.parse('foo .awesome')
318
- assert_xpath "//foo//*[contains(concat(' ', normalize-space(@class), ' '), ' awe.some ')]",
319
- @parser.parse('foo .awe\.some')
320
- end
321
-
322
- def test_bare_not
323
- assert_xpath "//*[not(contains(concat(' ', normalize-space(@class), ' '), ' a '))]",
324
- @parser.parse(':not(.a)')
325
- end
326
-
327
- def test_not_so_simple_not
328
- assert_xpath "//*[@id = 'p' and not(contains(concat(' ', normalize-space(@class), ' '), ' a '))]",
329
- @parser.parse('#p:not(.a)')
330
- assert_xpath "//p[contains(concat(' ', normalize-space(@class), ' '), ' a ') and not(contains(concat(' ', normalize-space(@class), ' '), ' b '))]",
331
- @parser.parse('p.a:not(.b)')
332
- assert_xpath "//p[@a = 'foo' and not(contains(concat(' ', normalize-space(@class), ' '), ' b '))]",
333
- @parser.parse("p[a='foo']:not(.b)")
334
- end
335
-
336
- def test_multiple_not
337
- assert_xpath "//p[not(contains(concat(' ', normalize-space(@class), ' '), ' a ')) and not(contains(concat(' ', normalize-space(@class), ' '), ' b ')) and not(contains(concat(' ', normalize-space(@class), ' '), ' c '))]",
338
- @parser.parse("p:not(.a):not(.b):not(.c)")
339
- end
340
-
341
- def test_ident
342
- assert_xpath '//x', @parser.parse('x')
343
- end
344
-
345
- def test_parse_space
346
- assert_xpath '//x//y', @parser.parse('x y')
347
- end
348
-
349
- def test_parse_descendant
350
- assert_xpath '//x/y', @parser.parse('x > y')
351
- end
352
-
353
- def test_parse_slash
354
- ## This is non standard CSS
355
- assert_xpath '//x/y', @parser.parse('x/y')
356
- end
357
-
358
- def test_parse_doubleslash
359
- ## This is non standard CSS
360
- assert_xpath '//x//y', @parser.parse('x//y')
361
- end
362
-
363
- def test_multi_path
364
- assert_xpath ['//x/y', '//y/z'], @parser.parse('x > y, y > z')
365
- assert_xpath ['//x/y', '//y/z'], @parser.parse('x > y,y > z')
366
- ###
367
- # TODO: should we make this work?
368
- # assert_xpath ['//x/y', '//y/z'], @parser.parse('x > y | y > z')
369
- end
370
-
371
- def test_attributes_with_namespace
372
- ## Default namespace is not applied to attributes.
373
- ## So this must be @class, not @xmlns:class.
374
- assert_xpath "//xmlns:a[@class = 'bar']", @parser_with_ns.parse("a[class='bar']")
375
- assert_xpath "//xmlns:a[@hoge:class = 'bar']", @parser_with_ns.parse("a[hoge|class='bar']")
376
- end
377
-
378
- def assert_xpath expecteds, asts
379
- expecteds = [expecteds].flatten
380
- expecteds.zip(asts).each do |expected, actual|
381
- assert_equal expected, actual.to_xpath
382
- end
383
- end
384
- end
385
- end
386
- end
@@ -1,215 +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_nth
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 test_significant_space
190
- @scanner.scan('x :first-child [a] [b]')
191
- assert_tokens([ [:IDENT, 'x'],
192
- [:S, ' '],
193
- [':', ':'],
194
- [:IDENT, 'first-child'],
195
- [:S, ' '],
196
- [:LSQUARE, '['],
197
- [:IDENT, 'a'],
198
- [:RSQUARE, ']'],
199
- [:S, ' '],
200
- [:LSQUARE, '['],
201
- [:IDENT, 'b'],
202
- [:RSQUARE, ']'],
203
- ], @scanner)
204
- end
205
-
206
- def assert_tokens(tokens, scanner)
207
- toks = []
208
- while tok = @scanner.next_token
209
- toks << tok
210
- end
211
- assert_equal(tokens, toks)
212
- end
213
- end
214
- end
215
- end