csspool-st 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|