csspool-st 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +16 -0
- data/.gemtest +0 -0
- data/CHANGELOG.rdoc +87 -0
- data/Manifest.txt +62 -0
- data/README.rdoc +65 -0
- data/Rakefile +50 -0
- data/lib/csspool/collection.rb +50 -0
- data/lib/csspool/css/charset.rb +13 -0
- data/lib/csspool/css/declaration.rb +19 -0
- data/lib/csspool/css/document.rb +34 -0
- data/lib/csspool/css/document_handler.rb +51 -0
- data/lib/csspool/css/import_rule.rb +27 -0
- data/lib/csspool/css/media.rb +13 -0
- data/lib/csspool/css/parser.rb +1298 -0
- data/lib/csspool/css/parser.y +398 -0
- data/lib/csspool/css/rule_set.rb +17 -0
- data/lib/csspool/css/tokenizer.rb +231 -0
- data/lib/csspool/css/tokenizer.rex +97 -0
- data/lib/csspool/css.rb +8 -0
- data/lib/csspool/node.rb +41 -0
- data/lib/csspool/sac/document.rb +35 -0
- data/lib/csspool/sac/parser.rb +16 -0
- data/lib/csspool/sac.rb +2 -0
- data/lib/csspool/selector.rb +36 -0
- data/lib/csspool/selectors/additional.rb +6 -0
- data/lib/csspool/selectors/attribute.rb +21 -0
- data/lib/csspool/selectors/class.rb +11 -0
- data/lib/csspool/selectors/id.rb +11 -0
- data/lib/csspool/selectors/pseudo_class.rb +13 -0
- data/lib/csspool/selectors/simple.rb +22 -0
- data/lib/csspool/selectors/type.rb +6 -0
- data/lib/csspool/selectors/universal.rb +6 -0
- data/lib/csspool/selectors.rb +9 -0
- data/lib/csspool/terms/function.rb +17 -0
- data/lib/csspool/terms/hash.rb +6 -0
- data/lib/csspool/terms/ident.rb +15 -0
- data/lib/csspool/terms/number.rb +14 -0
- data/lib/csspool/terms/rgb.rb +20 -0
- data/lib/csspool/terms/string.rb +6 -0
- data/lib/csspool/terms/uri.rb +6 -0
- data/lib/csspool/terms.rb +7 -0
- data/lib/csspool/visitors/children.rb +50 -0
- data/lib/csspool/visitors/comparable.rb +84 -0
- data/lib/csspool/visitors/iterator.rb +80 -0
- data/lib/csspool/visitors/to_css.rb +248 -0
- data/lib/csspool/visitors/visitor.rb +17 -0
- data/lib/csspool/visitors.rb +5 -0
- data/lib/csspool.rb +21 -0
- data/test/css/test_document.rb +13 -0
- data/test/css/test_import_rule.rb +42 -0
- data/test/css/test_parser.rb +462 -0
- data/test/css/test_tokenizer.rb +320 -0
- data/test/helper.rb +65 -0
- data/test/sac/test_parser.rb +123 -0
- data/test/sac/test_properties.rb +43 -0
- data/test/sac/test_terms.rb +228 -0
- data/test/test_collection.rb +81 -0
- data/test/test_parser.rb +91 -0
- data/test/test_selector.rb +51 -0
- data/test/visitors/test_children.rb +20 -0
- data/test/visitors/test_comparable.rb +102 -0
- data/test/visitors/test_each.rb +19 -0
- data/test/visitors/test_to_css.rb +309 -0
- metadata +214 -0
@@ -0,0 +1,320 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require "helper"
|
4
|
+
|
5
|
+
module CSSPool
|
6
|
+
module CSS
|
7
|
+
class TestTokenizer < CSSPool::TestCase
|
8
|
+
def setup
|
9
|
+
super
|
10
|
+
@scanner = Class.new(CSSPool::CSS::Tokenizer) {
|
11
|
+
def do_parse
|
12
|
+
end
|
13
|
+
}.new
|
14
|
+
end
|
15
|
+
|
16
|
+
{
|
17
|
+
'em' => :EMS,
|
18
|
+
'ex' => :EXS,
|
19
|
+
'px' => :LENGTH,
|
20
|
+
'cm' => :LENGTH,
|
21
|
+
'mm' => :LENGTH,
|
22
|
+
'in' => :LENGTH,
|
23
|
+
'pt' => :LENGTH,
|
24
|
+
'pc' => :LENGTH,
|
25
|
+
'deg' => :ANGLE,
|
26
|
+
'rad' => :ANGLE,
|
27
|
+
'grad' => :ANGLE,
|
28
|
+
'ms' => :TIME,
|
29
|
+
's' => :TIME,
|
30
|
+
'hz' => :FREQ,
|
31
|
+
'khz' => :FREQ,
|
32
|
+
'%' => :PERCENTAGE,
|
33
|
+
}.each do |unit,sym|
|
34
|
+
define_method :"test_#{unit}" do
|
35
|
+
['10', '0.1'].each do |num|
|
36
|
+
num = "#{num}#{unit}"
|
37
|
+
[num, " #{num}", "#{num} ", " #{num} "].each do |str|
|
38
|
+
@scanner.scan str
|
39
|
+
assert_tokens([[sym, str]], @scanner)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_num
|
46
|
+
['10', '0.1'].each do |num|
|
47
|
+
[num, " #{num}", "#{num} ", " #{num} "].each do |str|
|
48
|
+
@scanner.scan str
|
49
|
+
assert_tokens([[:NUMBER, str]], @scanner)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_important
|
55
|
+
[
|
56
|
+
'!important',
|
57
|
+
' !important',
|
58
|
+
'!important ',
|
59
|
+
'! important ',
|
60
|
+
' ! important ',
|
61
|
+
].each do |str|
|
62
|
+
@scanner.scan str
|
63
|
+
assert_tokens([[:IMPORTANT_SYM, str]], @scanner)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
{
|
68
|
+
'@page' => :PAGE_SYM,
|
69
|
+
'@import' => :IMPORT_SYM,
|
70
|
+
'@media' => :MEDIA_SYM,
|
71
|
+
'@charset' => :CHARSET_SYM,
|
72
|
+
}.each do |k,v|
|
73
|
+
define_method(:"test_#{k.sub(/@/, '')}") do
|
74
|
+
[k, " #{k}", "#{k} ", " #{k} "].each do |str|
|
75
|
+
@scanner.scan str
|
76
|
+
assert_tokens([[v, str]], @scanner)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_invalid
|
82
|
+
str = "'internet"
|
83
|
+
@scanner.scan str
|
84
|
+
assert_tokens([[:INVALID, str]], @scanner)
|
85
|
+
|
86
|
+
str = '"internet'
|
87
|
+
@scanner.scan str
|
88
|
+
assert_tokens([[:INVALID, str]], @scanner)
|
89
|
+
end
|
90
|
+
|
91
|
+
#def test_comment
|
92
|
+
# str = "/**** Hello World ***/"
|
93
|
+
# @scanner.scan str
|
94
|
+
# assert_tokens([[:COMMENT, str]], @scanner)
|
95
|
+
|
96
|
+
# str = "/* Hello World */"
|
97
|
+
# @scanner.scan str
|
98
|
+
# assert_tokens([[:COMMENT, str]], @scanner)
|
99
|
+
#end
|
100
|
+
|
101
|
+
def test_rbrace
|
102
|
+
str = " } \n "
|
103
|
+
@scanner.scan str
|
104
|
+
assert_tokens([[:RBRACE, str]], @scanner)
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_lbrace
|
108
|
+
str = " { "
|
109
|
+
@scanner.scan str
|
110
|
+
assert_tokens([[:LBRACE, str]], @scanner)
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_semi
|
114
|
+
str = " ; "
|
115
|
+
@scanner.scan str
|
116
|
+
assert_tokens([[:SEMI, ';']], @scanner)
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_cdc
|
120
|
+
@scanner.scan("-->")
|
121
|
+
assert_tokens([[:CDC, "-->"]], @scanner)
|
122
|
+
end
|
123
|
+
|
124
|
+
def test_cdo
|
125
|
+
@scanner.scan("<!--")
|
126
|
+
assert_tokens([[:CDO, "<!--"]], @scanner)
|
127
|
+
end
|
128
|
+
|
129
|
+
def test_unicode_range
|
130
|
+
@scanner.scan("U+0-10FFFF")
|
131
|
+
assert_tokens([[:UNICODE_RANGE, "U+0-10FFFF"]], @scanner)
|
132
|
+
end
|
133
|
+
|
134
|
+
def test_url_with_string
|
135
|
+
@scanner.scan("url('http://tlm.com')")
|
136
|
+
assert_tokens([[:URI, "url('http://tlm.com')"]], @scanner)
|
137
|
+
end
|
138
|
+
|
139
|
+
def test_url_with_others
|
140
|
+
@scanner.scan("url(http://tlm.com?f&b)")
|
141
|
+
assert_tokens([[:URI, "url(http://tlm.com?f&b)"]], @scanner)
|
142
|
+
end
|
143
|
+
|
144
|
+
def test_unicode
|
145
|
+
@scanner.scan("a日本語")
|
146
|
+
assert_tokens([[:IDENT, 'a日本語']], @scanner)
|
147
|
+
end
|
148
|
+
|
149
|
+
def test_tokenize_bad_percent
|
150
|
+
@scanner.scan("%")
|
151
|
+
assert_tokens([["%", "%"]], @scanner)
|
152
|
+
end
|
153
|
+
|
154
|
+
def test_not_equal
|
155
|
+
@scanner.scan("h1[a!='Tender Lovemaking']")
|
156
|
+
assert_tokens([ [:IDENT, 'h1'],
|
157
|
+
[:LSQUARE, '['],
|
158
|
+
[:IDENT, 'a'],
|
159
|
+
[:NOT_EQUAL, '!='],
|
160
|
+
[:STRING, "'Tender Lovemaking'"],
|
161
|
+
[:RSQUARE, ']'],
|
162
|
+
], @scanner)
|
163
|
+
end
|
164
|
+
|
165
|
+
def test_negation
|
166
|
+
@scanner.scan("p:not(.a)")
|
167
|
+
assert_tokens([ [:IDENT, 'p'],
|
168
|
+
[:NOT, ':not('],
|
169
|
+
['.', '.'],
|
170
|
+
[:IDENT, 'a'],
|
171
|
+
[:RPAREN, ')'],
|
172
|
+
], @scanner)
|
173
|
+
end
|
174
|
+
|
175
|
+
def test_function
|
176
|
+
@scanner.scan("script comment()")
|
177
|
+
assert_tokens([ [:IDENT, 'script'],
|
178
|
+
[:S, ' '],
|
179
|
+
[:FUNCTION, 'comment('],
|
180
|
+
[:RPAREN, ')'],
|
181
|
+
], @scanner)
|
182
|
+
end
|
183
|
+
|
184
|
+
def test_preceding_selector
|
185
|
+
@scanner.scan("E ~ F")
|
186
|
+
assert_tokens([ [:IDENT, 'E'],
|
187
|
+
[:TILDE, ' ~ '],
|
188
|
+
[:IDENT, 'F'],
|
189
|
+
], @scanner)
|
190
|
+
end
|
191
|
+
|
192
|
+
def test_scan_attribute_string
|
193
|
+
@scanner.scan("h1[a='Tender Lovemaking']")
|
194
|
+
assert_tokens([ [:IDENT, 'h1'],
|
195
|
+
[:LSQUARE, '['],
|
196
|
+
[:IDENT, 'a'],
|
197
|
+
[:EQUAL, '='],
|
198
|
+
[:STRING, "'Tender Lovemaking'"],
|
199
|
+
[:RSQUARE, ']'],
|
200
|
+
], @scanner)
|
201
|
+
@scanner.scan('h1[a="Tender Lovemaking"]')
|
202
|
+
assert_tokens([ [:IDENT, 'h1'],
|
203
|
+
[:LSQUARE, '['],
|
204
|
+
[:IDENT, 'a'],
|
205
|
+
[:EQUAL, '='],
|
206
|
+
[:STRING, '"Tender Lovemaking"'],
|
207
|
+
[:RSQUARE, ']'],
|
208
|
+
], @scanner)
|
209
|
+
end
|
210
|
+
|
211
|
+
def test_scan_id
|
212
|
+
@scanner.scan('#foo')
|
213
|
+
assert_tokens([ [:HASH, '#foo'] ], @scanner)
|
214
|
+
end
|
215
|
+
|
216
|
+
def test_scan_pseudo
|
217
|
+
@scanner.scan('a:visited')
|
218
|
+
assert_tokens([ [:IDENT, 'a'],
|
219
|
+
[':', ':'],
|
220
|
+
[:IDENT, 'visited']
|
221
|
+
], @scanner)
|
222
|
+
end
|
223
|
+
|
224
|
+
def test_scan_star
|
225
|
+
@scanner.scan('*')
|
226
|
+
assert_tokens([ [:STAR, '*'], ], @scanner)
|
227
|
+
end
|
228
|
+
|
229
|
+
def test_ident_with_minus
|
230
|
+
@scanner.scan('-book')
|
231
|
+
assert_tokens([ [:IDENT, '-book'], ], @scanner)
|
232
|
+
end
|
233
|
+
|
234
|
+
def test_scan_class
|
235
|
+
@scanner.scan('x.awesome')
|
236
|
+
assert_tokens([ [:IDENT, 'x'],
|
237
|
+
['.', '.'],
|
238
|
+
[:IDENT, 'awesome'],
|
239
|
+
], @scanner)
|
240
|
+
end
|
241
|
+
|
242
|
+
def test_scan_greater
|
243
|
+
@scanner.scan('x > y')
|
244
|
+
assert_tokens([ [:IDENT, 'x'],
|
245
|
+
[:GREATER, ' > '],
|
246
|
+
[:IDENT, 'y']
|
247
|
+
], @scanner)
|
248
|
+
end
|
249
|
+
|
250
|
+
def test_scan_slash
|
251
|
+
@scanner.scan('x/y')
|
252
|
+
assert_tokens([ [:IDENT, 'x'],
|
253
|
+
[:SLASH, '/'],
|
254
|
+
[:IDENT, 'y']
|
255
|
+
], @scanner)
|
256
|
+
end
|
257
|
+
|
258
|
+
def test_scan_doubleslash
|
259
|
+
@scanner.scan('x//y')
|
260
|
+
assert_tokens([ [:IDENT, 'x'],
|
261
|
+
[:DOUBLESLASH, '//'],
|
262
|
+
[:IDENT, 'y']
|
263
|
+
], @scanner)
|
264
|
+
end
|
265
|
+
|
266
|
+
def test_scan_function_selector
|
267
|
+
@scanner.scan('x:eq(0)')
|
268
|
+
assert_tokens([ [:IDENT, 'x'],
|
269
|
+
[':', ':'],
|
270
|
+
[:FUNCTION, 'eq('],
|
271
|
+
[:NUMBER, "0"],
|
272
|
+
[:RPAREN, ')'],
|
273
|
+
], @scanner)
|
274
|
+
end
|
275
|
+
|
276
|
+
def test_scan_an_plus_b
|
277
|
+
@scanner.scan('x:nth-child(5n+3)')
|
278
|
+
assert_tokens([ [:IDENT, 'x'],
|
279
|
+
[':', ':'],
|
280
|
+
[:FUNCTION, 'nth-child('],
|
281
|
+
[:NUMBER, '5'],
|
282
|
+
[:IDENT, 'n'],
|
283
|
+
[:PLUS, '+'],
|
284
|
+
[:NUMBER, '3'],
|
285
|
+
[:RPAREN, ')'],
|
286
|
+
], @scanner)
|
287
|
+
|
288
|
+
@scanner.scan('x:nth-child(-1n+3)')
|
289
|
+
assert_tokens([ [:IDENT, 'x'],
|
290
|
+
[':', ':'],
|
291
|
+
[:FUNCTION, 'nth-child('],
|
292
|
+
[:MINUS, '-'],
|
293
|
+
[:NUMBER, '1'],
|
294
|
+
[:IDENT, 'n'],
|
295
|
+
[:PLUS, '+'],
|
296
|
+
[:NUMBER, '3'],
|
297
|
+
[:RPAREN, ')'],
|
298
|
+
], @scanner)
|
299
|
+
|
300
|
+
@scanner.scan('x:nth-child(-n+3)')
|
301
|
+
assert_tokens([ [:IDENT, 'x'],
|
302
|
+
[':', ':'],
|
303
|
+
[:FUNCTION, 'nth-child('],
|
304
|
+
[:IDENT, '-n'],
|
305
|
+
[:PLUS, '+'],
|
306
|
+
[:NUMBER, '3'],
|
307
|
+
[:RPAREN, ')'],
|
308
|
+
], @scanner)
|
309
|
+
end
|
310
|
+
|
311
|
+
def assert_tokens(tokens, scanner)
|
312
|
+
toks = []
|
313
|
+
while tok = @scanner.next_token
|
314
|
+
toks << tok
|
315
|
+
end
|
316
|
+
assert_equal(tokens, toks)
|
317
|
+
end
|
318
|
+
end
|
319
|
+
end
|
320
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
require "csspool"
|
3
|
+
|
4
|
+
module CSSPool
|
5
|
+
class TestCase < Test::Unit::TestCase
|
6
|
+
unless RUBY_VERSION >= '1.9'
|
7
|
+
undef :default_test
|
8
|
+
end
|
9
|
+
|
10
|
+
ASSET_DIR = File.join(File.dirname(__FILE__), 'files')
|
11
|
+
|
12
|
+
class MyDoc < CSSPool::CSS::DocumentHandler
|
13
|
+
attr_accessor :start_documents, :end_documents
|
14
|
+
attr_accessor :charsets, :import_styles, :comments, :start_selectors
|
15
|
+
attr_accessor :end_selectors, :properties
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@start_documents = []
|
19
|
+
@end_documents = []
|
20
|
+
@charsets = []
|
21
|
+
@import_styles = []
|
22
|
+
@comments = []
|
23
|
+
@start_selectors = []
|
24
|
+
@end_selectors = []
|
25
|
+
@properties = []
|
26
|
+
end
|
27
|
+
|
28
|
+
def property name, expression, important
|
29
|
+
@properties << [name, expression]
|
30
|
+
end
|
31
|
+
|
32
|
+
def start_document
|
33
|
+
@start_documents << true
|
34
|
+
end
|
35
|
+
|
36
|
+
def end_document
|
37
|
+
@end_documents << true
|
38
|
+
end
|
39
|
+
|
40
|
+
def charset name, location
|
41
|
+
@charsets << [name, location]
|
42
|
+
end
|
43
|
+
|
44
|
+
def import_style media_list, uri, default_ns = nil, location = {}
|
45
|
+
@import_styles << [media_list, uri, default_ns, location]
|
46
|
+
end
|
47
|
+
|
48
|
+
def namespace_declaration prefix, uri, location
|
49
|
+
@import_styles << [prefix, uri, location]
|
50
|
+
end
|
51
|
+
|
52
|
+
def comment string
|
53
|
+
@comments << string
|
54
|
+
end
|
55
|
+
|
56
|
+
def start_selector selectors
|
57
|
+
@start_selectors << selectors
|
58
|
+
end
|
59
|
+
|
60
|
+
def end_selector selectors
|
61
|
+
@end_selectors << selectors
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module CSSPool
|
4
|
+
module SAC
|
5
|
+
class TestParser < CSSPool::TestCase
|
6
|
+
def setup
|
7
|
+
super
|
8
|
+
@doc = MyDoc.new
|
9
|
+
@css = <<-eocss
|
10
|
+
@charset "UTF-8";
|
11
|
+
@import url("foo.css") screen;
|
12
|
+
/* This is a comment */
|
13
|
+
div a.foo, #bar, * { background: red; }
|
14
|
+
div#a, a.foo, a:hover, a[href][int="10"]{ background: red; }
|
15
|
+
::selection, q:before { background: red; }
|
16
|
+
eocss
|
17
|
+
@parser = CSSPool::SAC::Parser.new(@doc)
|
18
|
+
@parser.parse(@css)
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_start_and_end_called_with_the_same
|
22
|
+
assert_equal @doc.start_selectors, @doc.end_selectors
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_parse_no_doc
|
26
|
+
parser = CSSPool::SAC::Parser.new
|
27
|
+
parser.parse(@css)
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_start_document
|
31
|
+
assert_equal [true], @doc.start_documents
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_end_document
|
35
|
+
assert_equal [true], @doc.end_documents
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_charset
|
39
|
+
assert_equal("UTF-8", @doc.charsets.first.first)
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_import_style
|
43
|
+
styles = @doc.import_styles.first
|
44
|
+
assert_equal "screen", styles.first.first.first.value
|
45
|
+
assert_equal "foo.css", styles[1].value
|
46
|
+
assert_nil styles[2]
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_start_selector
|
50
|
+
selectors_for_rule = @doc.start_selectors.first
|
51
|
+
assert selectors_for_rule
|
52
|
+
assert_equal 3, selectors_for_rule.length
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_simple_selector
|
56
|
+
selectors_for_rule = @doc.start_selectors.first
|
57
|
+
selector = selectors_for_rule.first # => div a.foo
|
58
|
+
assert_equal 2, selector.simple_selectors.length
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_additional_selector_list
|
62
|
+
selectors_for_rule = @doc.start_selectors.first
|
63
|
+
selector = selectors_for_rule.first # => div a.foo
|
64
|
+
simple_selector = selector.simple_selectors[1] # => a.foo
|
65
|
+
assert additional_selectors = simple_selector.additional_selectors
|
66
|
+
assert_equal 1, additional_selectors.length
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_additional_selector_class_name
|
70
|
+
selectors_for_rule = @doc.start_selectors.first
|
71
|
+
selector = selectors_for_rule.first # => div a.foo
|
72
|
+
simple_selector = selector.simple_selectors[1] # => a.foo
|
73
|
+
assert additional_selectors = simple_selector.additional_selectors
|
74
|
+
foo_class = additional_selectors.first
|
75
|
+
assert_equal 'foo', foo_class.name
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_id_additional_selector
|
79
|
+
selectors_for_rule = @doc.start_selectors[1]
|
80
|
+
selector = selectors_for_rule.first # => div#a
|
81
|
+
simple_selector = selector.simple_selectors.first # => div#a
|
82
|
+
assert_equal 'a', simple_selector.additional_selectors.first.name
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_pseudo_additional_selector
|
86
|
+
selectors_for_rule = @doc.start_selectors[1]
|
87
|
+
selector = selectors_for_rule[2] # => 'a:hover'
|
88
|
+
simple_selector = selector.simple_selectors.first # => a:hover
|
89
|
+
assert_equal 'hover', simple_selector.additional_selectors.first.name
|
90
|
+
assert_nil simple_selector.additional_selectors.first.extra
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_attribute_selector
|
94
|
+
selectors_for_rule = @doc.start_selectors[1]
|
95
|
+
selector = selectors_for_rule[3] # => a[href][int="10"]
|
96
|
+
simple_selector = selector.simple_selectors.first
|
97
|
+
|
98
|
+
assert_equal 'href', simple_selector.additional_selectors.first.name
|
99
|
+
assert_nil simple_selector.additional_selectors.first.value
|
100
|
+
assert_equal 1, simple_selector.additional_selectors.first.match_way
|
101
|
+
|
102
|
+
assert_equal 'int', simple_selector.additional_selectors[1].name
|
103
|
+
assert_equal '10', simple_selector.additional_selectors[1].value
|
104
|
+
assert_equal 2, simple_selector.additional_selectors[1].match_way
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_pseudo_element_additional_selector
|
108
|
+
selectors_for_rule = @doc.start_selectors[2]
|
109
|
+
selector = selectors_for_rule[0]
|
110
|
+
|
111
|
+
simple_selector = selector.simple_selectors[0] # ::selection
|
112
|
+
assert_equal 'selection', simple_selector.additional_selectors.first.name
|
113
|
+
assert_nil simple_selector.additional_selectors.first.css2
|
114
|
+
|
115
|
+
selector = selectors_for_rule[1]
|
116
|
+
simple_selector = selector.simple_selectors[0] # q.before
|
117
|
+
assert_equal 'before', simple_selector.additional_selectors.first.name
|
118
|
+
assert_equal true, simple_selector.additional_selectors.first.css2
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module CSSPool
|
4
|
+
module SAC
|
5
|
+
class TestProperties < CSSPool::TestCase
|
6
|
+
def setup
|
7
|
+
super
|
8
|
+
@doc = MyDoc.new
|
9
|
+
@css = <<-eocss
|
10
|
+
@charset "UTF-8";
|
11
|
+
@import url("foo.css") screen;
|
12
|
+
/* This is a comment */
|
13
|
+
div a.foo, #bar, * { background: red; }
|
14
|
+
div#a, a.foo, a:hover, a[href][int="10"]{ background: red; }
|
15
|
+
eocss
|
16
|
+
@parser = CSSPool::SAC::Parser.new(@doc)
|
17
|
+
@parser.parse(@css)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_properties
|
21
|
+
assert_equal ['background'], @doc.properties.map { |x| x.first }.uniq
|
22
|
+
@doc.properties.each do |property|
|
23
|
+
assert_equal 1, property[1].length
|
24
|
+
end
|
25
|
+
assert_equal ['red'], @doc.properties.map { |x| x[1].first.value }.uniq
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_ident_with_comma
|
29
|
+
doc = MyDoc.new
|
30
|
+
parser = CSSPool::SAC::Parser.new(doc)
|
31
|
+
parser.parse <<-eocss
|
32
|
+
h1 { font-family: Verdana, sans-serif, monospace; }
|
33
|
+
eocss
|
34
|
+
assert_equal 1, doc.properties.length
|
35
|
+
values = doc.properties.first[1]
|
36
|
+
assert_equal 3, values.length
|
37
|
+
assert_equal [nil, ',', ','],
|
38
|
+
values.map { |value| value.operator }
|
39
|
+
values.each { |value| assert value.parse_location }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|