css_dryer 0.0.1
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 +8 -0
- data/.gitignore +2 -0
- data/CHANGELOG +129 -0
- data/Gemfile +3 -0
- data/MIT-LICENCE +20 -0
- data/README.markdown +273 -0
- data/Rakefile +23 -0
- data/config.ru +14 -0
- data/css_dryer.gemspec +19 -0
- data/generators/css_dryer/USAGE +11 -0
- data/generators/css_dryer/css_dryer_generator.rb +23 -0
- data/generators/css_dryer/templates/_foo.css.ncss +4 -0
- data/generators/css_dryer/templates/stylesheets_controller.rb +11 -0
- data/generators/css_dryer/templates/stylesheets_helper.rb +63 -0
- data/generators/css_dryer/templates/test.css.ncss +12 -0
- data/init.rb +5 -0
- data/install.rb +3 -0
- data/lib/css_dryer/ncss_handler.rb +18 -0
- data/lib/css_dryer/processor.rb +333 -0
- data/lib/rack/css_dryer.rb +47 -0
- data/tasks/css_dryer_tasks.rake +21 -0
- data/test/css_dryer_test.rb +826 -0
- metadata +110 -0
@@ -0,0 +1,826 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.dirname(__FILE__) + '/../lib/css_dryer/processor'
|
3
|
+
|
4
|
+
class TestCssDryer < Test::Unit::TestCase
|
5
|
+
include CssDryer::Processor
|
6
|
+
|
7
|
+
def test_should_build_structure_without_nesting
|
8
|
+
css = <<END
|
9
|
+
/* comment 0 */
|
10
|
+
s0 {
|
11
|
+
k00: v00;
|
12
|
+
k01: v01;
|
13
|
+
}
|
14
|
+
/* comment 1 */
|
15
|
+
s1 { k10: v10; }
|
16
|
+
s2 {
|
17
|
+
k20: v20;
|
18
|
+
/* comment 2 */
|
19
|
+
k21: v21;
|
20
|
+
}
|
21
|
+
END
|
22
|
+
output = nested_css_to_structure(css)
|
23
|
+
assert_equal 5, output.length
|
24
|
+
|
25
|
+
assert_equal '/* comment 0 */', output.shift
|
26
|
+
|
27
|
+
hsh = output.shift
|
28
|
+
assert_equal 1, hsh.length
|
29
|
+
assert hsh.multiline
|
30
|
+
assert_equal 's0', hsh.keys.first
|
31
|
+
ary = hsh.values.first
|
32
|
+
assert_equal 2, ary.length
|
33
|
+
assert_equal ' k00: v00;', ary.first
|
34
|
+
assert_equal ' k01: v01;', ary.last
|
35
|
+
|
36
|
+
assert_equal '/* comment 1 */', output.shift
|
37
|
+
|
38
|
+
hsh = output.shift
|
39
|
+
assert_equal 1, hsh.length
|
40
|
+
assert ! hsh.multiline
|
41
|
+
assert_equal 's1', hsh.keys.first
|
42
|
+
ary = hsh.values.first
|
43
|
+
assert_equal 1, ary.length
|
44
|
+
assert_equal ' k10: v10; ', ary.first
|
45
|
+
|
46
|
+
hsh = output.shift
|
47
|
+
assert_equal 1, hsh.length
|
48
|
+
assert hsh.multiline
|
49
|
+
assert_equal 's2', hsh.keys.first
|
50
|
+
ary = hsh.values.first
|
51
|
+
assert_equal 3, ary.length
|
52
|
+
assert_equal ' k20: v20;', ary.shift
|
53
|
+
assert_equal ' /* comment 2 */', ary.shift
|
54
|
+
assert_equal ' k21: v21;', ary.shift
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_should_build_structure_with_nesting
|
58
|
+
css = <<END
|
59
|
+
/* comment 0 */
|
60
|
+
s0 {
|
61
|
+
k00: v00;
|
62
|
+
k01: v01;
|
63
|
+
}
|
64
|
+
s1 {
|
65
|
+
k10: v10;
|
66
|
+
/* comment 1 */
|
67
|
+
s2 {
|
68
|
+
k20: v20;
|
69
|
+
k21: v21;
|
70
|
+
}
|
71
|
+
k11: v11;
|
72
|
+
s3 { k30: v30; }
|
73
|
+
}
|
74
|
+
END
|
75
|
+
|
76
|
+
# [
|
77
|
+
# '/* comment 0 */',
|
78
|
+
# { 's0' => [ ' k00: v00;', ' k01: v01;' ] },
|
79
|
+
# { 's1' => [ ' k10: v10;',
|
80
|
+
# ' /* comment 1 */',
|
81
|
+
# { 's2' => [ 'k20: v20;', 'k21: v21;'] },
|
82
|
+
# ' k11: v11;',
|
83
|
+
# { 's3' => [ ' k30: v30; ' ] } } ]
|
84
|
+
# ]
|
85
|
+
output = nested_css_to_structure(css)
|
86
|
+
assert_equal 3, output.length
|
87
|
+
|
88
|
+
assert_equal '/* comment 0 */', output.shift
|
89
|
+
|
90
|
+
hsh = output.shift
|
91
|
+
assert_equal 1, hsh.length
|
92
|
+
assert hsh.multiline
|
93
|
+
assert_equal 's0', hsh.keys.first
|
94
|
+
ary = hsh.values.first
|
95
|
+
assert_equal 2, ary.length
|
96
|
+
assert_equal ' k00: v00;', ary.shift
|
97
|
+
assert_equal ' k01: v01;', ary.shift
|
98
|
+
|
99
|
+
hsh = output.shift
|
100
|
+
assert_equal 1, hsh.length
|
101
|
+
assert hsh.multiline
|
102
|
+
assert_equal 's1', hsh.keys.first
|
103
|
+
ary = hsh.values.first
|
104
|
+
assert_equal 5, ary.length
|
105
|
+
|
106
|
+
assert_equal ' k10: v10;', ary.shift
|
107
|
+
assert_equal ' /* comment 1 */', ary.shift
|
108
|
+
s2_hsh = ary.shift
|
109
|
+
assert_equal 1, s2_hsh.length
|
110
|
+
assert s2_hsh.multiline
|
111
|
+
assert_equal 's2', s2_hsh.keys.first
|
112
|
+
s2_ary = s2_hsh.values.first
|
113
|
+
assert_equal 2, s2_ary.length
|
114
|
+
assert_equal 'k20: v20;', s2_ary.shift
|
115
|
+
assert_equal 'k21: v21;', s2_ary.shift
|
116
|
+
assert_equal ' k11: v11;', ary.shift
|
117
|
+
s3_hsh = ary.shift
|
118
|
+
assert_equal 1, s3_hsh.length
|
119
|
+
assert ! s3_hsh.multiline
|
120
|
+
assert_equal 's3', s3_hsh.keys.first
|
121
|
+
s3_ary = s3_hsh.values.first
|
122
|
+
assert_equal 1, s3_ary.length
|
123
|
+
assert_equal ' k30: v30; ', s3_ary.shift
|
124
|
+
end
|
125
|
+
|
126
|
+
def test_should_build_structure_with_triple_nesting
|
127
|
+
css = <<END
|
128
|
+
/* comment 0 */
|
129
|
+
s0 {
|
130
|
+
k00: v00;
|
131
|
+
k01: v01;
|
132
|
+
}
|
133
|
+
s1 {
|
134
|
+
k10: v10;
|
135
|
+
/* comment 1 */
|
136
|
+
s2 {
|
137
|
+
k20: v20;
|
138
|
+
k21: v21;
|
139
|
+
s3 {k30: v30;}
|
140
|
+
}
|
141
|
+
k11: v11;
|
142
|
+
}
|
143
|
+
END
|
144
|
+
|
145
|
+
# [
|
146
|
+
# '/* comment 0 */',
|
147
|
+
# { 's0' => [ ' k00: v00;', ' k01: v01;' ] },
|
148
|
+
# { 's1' => [ ' k10: v10;',
|
149
|
+
# ' /* comment 1 */',
|
150
|
+
# { 's2' => [ 'k20: v20;',
|
151
|
+
# 'k21: v21;',
|
152
|
+
# { 's3' => [ 'k30: v30;' ] } ] },
|
153
|
+
# ' k11: v11;' ]
|
154
|
+
# ]
|
155
|
+
output = nested_css_to_structure(css)
|
156
|
+
assert_equal 3, output.length
|
157
|
+
|
158
|
+
assert_equal '/* comment 0 */', output.shift
|
159
|
+
|
160
|
+
hsh = output.shift
|
161
|
+
assert_equal 1, hsh.length
|
162
|
+
assert hsh.multiline
|
163
|
+
assert_equal 's0', hsh.keys.first
|
164
|
+
ary = hsh.values.first
|
165
|
+
assert_equal 2, ary.length
|
166
|
+
assert_equal ' k00: v00;', ary.shift
|
167
|
+
assert_equal ' k01: v01;', ary.shift
|
168
|
+
|
169
|
+
hsh = output.shift
|
170
|
+
assert_equal 1, hsh.length
|
171
|
+
assert hsh.multiline
|
172
|
+
assert_equal 's1', hsh.keys.first
|
173
|
+
ary = hsh.values.first
|
174
|
+
assert_equal 4, ary.length
|
175
|
+
assert_equal ' k10: v10;', ary.shift
|
176
|
+
assert_equal ' /* comment 1 */', ary.shift
|
177
|
+
hsh = ary.shift
|
178
|
+
assert_equal 1, hsh.length
|
179
|
+
assert hsh.multiline
|
180
|
+
assert_equal 's2', hsh.keys.first
|
181
|
+
ary_prime = hsh.values.first
|
182
|
+
assert_equal 3, ary_prime.length
|
183
|
+
assert_equal 'k20: v20;', ary_prime.shift
|
184
|
+
assert_equal 'k21: v21;', ary_prime.shift
|
185
|
+
hsh = ary_prime.shift
|
186
|
+
assert_equal 1, hsh.length
|
187
|
+
assert ! hsh.multiline
|
188
|
+
assert_equal 's3', hsh.keys.first
|
189
|
+
assert_equal 'k30: v30;', hsh.values.first.shift
|
190
|
+
assert_equal ' k11: v11;', ary.shift
|
191
|
+
end
|
192
|
+
|
193
|
+
def test_should_convert_type_selectors_aka_no_nesting_structure_to_css
|
194
|
+
structure = []
|
195
|
+
structure << '/* comment 0 */'
|
196
|
+
hsh = StyleHash['s0' => [ ' k00: v00;', ' k01: v01;' ] ]
|
197
|
+
hsh.multiline = true
|
198
|
+
structure << hsh
|
199
|
+
structure << '/* comment 1 */'
|
200
|
+
structure << StyleHash['s1' => [ ' k10: v10; ' ] ]
|
201
|
+
hsh = StyleHash['s2' => [ ' k20: v20;', ' /* comment 2 */', ' k21: v21;' ] ]
|
202
|
+
hsh.multiline = true
|
203
|
+
structure << hsh
|
204
|
+
|
205
|
+
assert_equal <<END, structure_to_css(structure)
|
206
|
+
/* comment 0 */
|
207
|
+
s0 {
|
208
|
+
k00: v00;
|
209
|
+
k01: v01;
|
210
|
+
}
|
211
|
+
/* comment 1 */
|
212
|
+
s1 { k10: v10; }
|
213
|
+
s2 {
|
214
|
+
k20: v20;
|
215
|
+
/* comment 2 */
|
216
|
+
k21: v21;
|
217
|
+
}
|
218
|
+
END
|
219
|
+
end
|
220
|
+
|
221
|
+
def test_should_convert_descendant_selectors_structure_to_css
|
222
|
+
structure = []
|
223
|
+
structure << '/* comment 0 */'
|
224
|
+
|
225
|
+
hsh_s0 = StyleHash['s0' => [ ' k00: v00;', ' k01: v01;' ] ]
|
226
|
+
hsh_s0.multiline = true
|
227
|
+
structure << hsh_s0
|
228
|
+
|
229
|
+
hsh_s3 = StyleHash['s3' => [ ' k30: v30; ' ] ]
|
230
|
+
hsh_s2 = StyleHash['s2' => [ 'k20: v20;', 'k21: v21;', hsh_s3 ] ]
|
231
|
+
hsh_s2.multiline = true
|
232
|
+
|
233
|
+
hsh_s1 = StyleHash['s1' => [ ' k10: v10;', ' /* comment 1 */', hsh_s2, ' k11: v11;' ] ]
|
234
|
+
hsh_s1.multiline = true
|
235
|
+
structure << hsh_s1
|
236
|
+
|
237
|
+
assert_equal <<END, structure_to_css(structure)
|
238
|
+
/* comment 0 */
|
239
|
+
s0 {
|
240
|
+
k00: v00;
|
241
|
+
k01: v01;
|
242
|
+
}
|
243
|
+
s1 {
|
244
|
+
k10: v10;
|
245
|
+
/* comment 1 */
|
246
|
+
k11: v11;
|
247
|
+
}
|
248
|
+
s1 s2 {
|
249
|
+
k20: v20;
|
250
|
+
k21: v21;
|
251
|
+
}
|
252
|
+
s1 s2 s3 { k30: v30; }
|
253
|
+
END
|
254
|
+
end
|
255
|
+
|
256
|
+
def test_should_handle_rails_tip_example_of_descendant_selectors
|
257
|
+
input = <<END
|
258
|
+
div#content {
|
259
|
+
/* some styles which apply only to div#content ... */
|
260
|
+
h2 { /* some styles which apply only to div#content h2 ... */ }
|
261
|
+
a {
|
262
|
+
/* some styles which apply only to div#content a ... */
|
263
|
+
}
|
264
|
+
}
|
265
|
+
END
|
266
|
+
|
267
|
+
output = <<END
|
268
|
+
div#content {
|
269
|
+
/* some styles which apply only to div#content ... */
|
270
|
+
}
|
271
|
+
div#content h2 { /* some styles which apply only to div#content h2 ... */ }
|
272
|
+
div#content a {
|
273
|
+
/* some styles which apply only to div#content a ... */
|
274
|
+
}
|
275
|
+
END
|
276
|
+
|
277
|
+
assert_equal output, process(input)
|
278
|
+
end
|
279
|
+
|
280
|
+
def test_should_handle_one_descendant_selector
|
281
|
+
input = <<END
|
282
|
+
div p {
|
283
|
+
color: blue;
|
284
|
+
}
|
285
|
+
END
|
286
|
+
assert_equal input, process(input)
|
287
|
+
end
|
288
|
+
|
289
|
+
def test_should_handle_media_block
|
290
|
+
input = <<END
|
291
|
+
@media screen, projection {
|
292
|
+
div {font-size:100%;}
|
293
|
+
}
|
294
|
+
END
|
295
|
+
|
296
|
+
output = <<END
|
297
|
+
@media screen, projection {
|
298
|
+
div {font-size:100%;}
|
299
|
+
}
|
300
|
+
END
|
301
|
+
|
302
|
+
assert_equal output, process(input)
|
303
|
+
end
|
304
|
+
|
305
|
+
def test_should_handle_inline_media_block
|
306
|
+
input = <<END
|
307
|
+
@media screen, projection { div {font-size:100%;} }
|
308
|
+
END
|
309
|
+
|
310
|
+
output = <<END
|
311
|
+
@media screen, projection { div {font-size:100%;} }
|
312
|
+
END
|
313
|
+
|
314
|
+
assert_equal output, process(input)
|
315
|
+
end
|
316
|
+
|
317
|
+
def test_should_not_output_empty_selectors
|
318
|
+
input = <<END
|
319
|
+
div#content {
|
320
|
+
h2 { /* some styles which apply only to div#content h2 ... */ }
|
321
|
+
a {
|
322
|
+
/* some styles which apply only to div#content a ... */
|
323
|
+
}
|
324
|
+
}
|
325
|
+
END
|
326
|
+
|
327
|
+
output = <<END
|
328
|
+
div#content h2 { /* some styles which apply only to div#content h2 ... */ }
|
329
|
+
div#content a {
|
330
|
+
/* some styles which apply only to div#content a ... */
|
331
|
+
}
|
332
|
+
END
|
333
|
+
|
334
|
+
assert_equal output, process(input)
|
335
|
+
end
|
336
|
+
|
337
|
+
def test_should_not_output_blank_lines
|
338
|
+
input = <<END
|
339
|
+
div {
|
340
|
+
color: red;
|
341
|
+
|
342
|
+
span { color: blue; }
|
343
|
+
|
344
|
+
a {
|
345
|
+
.hover { text-decoration: none; }
|
346
|
+
.visited { text-decoration: none; }
|
347
|
+
}
|
348
|
+
|
349
|
+
}
|
350
|
+
END
|
351
|
+
assert_equal <<END, process(input)
|
352
|
+
div {
|
353
|
+
color: red;
|
354
|
+
}
|
355
|
+
div span { color: blue; }
|
356
|
+
div a.hover { text-decoration: none; }
|
357
|
+
div a.visited { text-decoration: none; }
|
358
|
+
END
|
359
|
+
end
|
360
|
+
|
361
|
+
def test_style_hash_has_non_hash_children
|
362
|
+
hsh = StyleHash[ 'key' => %w( foo ) ]
|
363
|
+
assert hsh.has_non_style_hash_children
|
364
|
+
hsh.value.pop
|
365
|
+
hsh.value << StyleHash.new
|
366
|
+
assert ! hsh.has_non_style_hash_children
|
367
|
+
end
|
368
|
+
|
369
|
+
def test_should_handle_class_selectors
|
370
|
+
input = <<END
|
371
|
+
td {
|
372
|
+
font-family: verdana;
|
373
|
+
.even { background: blue; }
|
374
|
+
.odd {
|
375
|
+
background: green;
|
376
|
+
.odder-still { background: infra-red; }
|
377
|
+
}
|
378
|
+
}
|
379
|
+
END
|
380
|
+
|
381
|
+
output = <<END
|
382
|
+
td {
|
383
|
+
font-family: verdana;
|
384
|
+
}
|
385
|
+
td.even { background: blue; }
|
386
|
+
td.odd {
|
387
|
+
background: green;
|
388
|
+
}
|
389
|
+
td.odd.odder-still { background: infra-red; }
|
390
|
+
END
|
391
|
+
|
392
|
+
assert_equal output, process(input)
|
393
|
+
end
|
394
|
+
|
395
|
+
def test_should_handle_pseudo_class_selectors
|
396
|
+
input = <<END
|
397
|
+
a {
|
398
|
+
text-decoration: underline; padding: 1px;
|
399
|
+
:link { color: #03c; }
|
400
|
+
:visited { color: #03c; }
|
401
|
+
:hover { color: #fff; background-color: #30c; text-decoration: none; }
|
402
|
+
.image:link {
|
403
|
+
background: none;
|
404
|
+
padding: 0;
|
405
|
+
}
|
406
|
+
}
|
407
|
+
END
|
408
|
+
|
409
|
+
output = <<END
|
410
|
+
a {
|
411
|
+
text-decoration: underline; padding: 1px;
|
412
|
+
}
|
413
|
+
a:link { color: #03c; }
|
414
|
+
a:visited { color: #03c; }
|
415
|
+
a:hover { color: #fff; background-color: #30c; text-decoration: none; }
|
416
|
+
a.image:link {
|
417
|
+
background: none;
|
418
|
+
padding: 0;
|
419
|
+
}
|
420
|
+
END
|
421
|
+
|
422
|
+
assert_equal output, process(input)
|
423
|
+
end
|
424
|
+
|
425
|
+
def test_should_handle_id_selectors
|
426
|
+
input = <<END
|
427
|
+
div {
|
428
|
+
color: blue;
|
429
|
+
border: 1px solid green;
|
430
|
+
#flash {
|
431
|
+
background: yellow;
|
432
|
+
font-size: x-large;
|
433
|
+
}
|
434
|
+
}
|
435
|
+
END
|
436
|
+
|
437
|
+
output = <<END
|
438
|
+
div {
|
439
|
+
color: blue;
|
440
|
+
border: 1px solid green;
|
441
|
+
}
|
442
|
+
div#flash {
|
443
|
+
background: yellow;
|
444
|
+
font-size: x-large;
|
445
|
+
}
|
446
|
+
END
|
447
|
+
|
448
|
+
assert_equal output, process(input)
|
449
|
+
end
|
450
|
+
|
451
|
+
def test_should_handle_child_selectors
|
452
|
+
input = <<END
|
453
|
+
div {
|
454
|
+
color: blue;
|
455
|
+
border: 1px solid green;
|
456
|
+
> p {
|
457
|
+
color: yellow;
|
458
|
+
> b { font-variant: small-caps; }
|
459
|
+
}
|
460
|
+
}
|
461
|
+
END
|
462
|
+
|
463
|
+
output = <<END
|
464
|
+
div {
|
465
|
+
color: blue;
|
466
|
+
border: 1px solid green;
|
467
|
+
}
|
468
|
+
div > p {
|
469
|
+
color: yellow;
|
470
|
+
}
|
471
|
+
div > p > b { font-variant: small-caps; }
|
472
|
+
END
|
473
|
+
|
474
|
+
assert_equal output, process(input)
|
475
|
+
end
|
476
|
+
|
477
|
+
def test_should_handle_adjacent_selectors
|
478
|
+
input = <<END
|
479
|
+
div {
|
480
|
+
color: blue;
|
481
|
+
border: 1px solid green;
|
482
|
+
+ p {
|
483
|
+
color: yellow;
|
484
|
+
+ b { font-variant: small-caps; }
|
485
|
+
}
|
486
|
+
}
|
487
|
+
END
|
488
|
+
|
489
|
+
output = <<END
|
490
|
+
div {
|
491
|
+
color: blue;
|
492
|
+
border: 1px solid green;
|
493
|
+
}
|
494
|
+
div + p {
|
495
|
+
color: yellow;
|
496
|
+
}
|
497
|
+
div + p + b { font-variant: small-caps; }
|
498
|
+
END
|
499
|
+
assert_equal output, process(input)
|
500
|
+
end
|
501
|
+
|
502
|
+
def test_should_handle_attribute_selectors
|
503
|
+
input = <<END
|
504
|
+
div {
|
505
|
+
color: blue;
|
506
|
+
border: 1px solid green;
|
507
|
+
[foo] { color: yellow; }
|
508
|
+
[foo~="warning"] { color: blue; }
|
509
|
+
}
|
510
|
+
END
|
511
|
+
|
512
|
+
output = <<END
|
513
|
+
div {
|
514
|
+
color: blue;
|
515
|
+
border: 1px solid green;
|
516
|
+
}
|
517
|
+
div[foo] { color: yellow; }
|
518
|
+
div[foo~="warning"] { color: blue; }
|
519
|
+
END
|
520
|
+
|
521
|
+
assert_equal output, process(input)
|
522
|
+
end
|
523
|
+
|
524
|
+
def test_should_handle_comma_separated_selectors_without_nesting
|
525
|
+
input = <<END
|
526
|
+
h1, h2, h3 {
|
527
|
+
margin-top: 5px;
|
528
|
+
color: red;
|
529
|
+
}
|
530
|
+
END
|
531
|
+
assert_equal <<END, process(input)
|
532
|
+
h1 {
|
533
|
+
margin-top: 5px;
|
534
|
+
color: red;
|
535
|
+
}
|
536
|
+
h2 {
|
537
|
+
margin-top: 5px;
|
538
|
+
color: red;
|
539
|
+
}
|
540
|
+
h3 {
|
541
|
+
margin-top: 5px;
|
542
|
+
color: red;
|
543
|
+
}
|
544
|
+
END
|
545
|
+
end
|
546
|
+
|
547
|
+
def test_should_handle_comma_separated_selectors_with_outer_nesting
|
548
|
+
input = <<END
|
549
|
+
h1, h2, h3 {
|
550
|
+
margin-top: 5px;
|
551
|
+
color: red;
|
552
|
+
p { padding: 3px; }
|
553
|
+
}
|
554
|
+
END
|
555
|
+
assert_equal <<END, process(input)
|
556
|
+
h1 {
|
557
|
+
margin-top: 5px;
|
558
|
+
color: red;
|
559
|
+
}
|
560
|
+
h1 p { padding: 3px; }
|
561
|
+
h2 {
|
562
|
+
margin-top: 5px;
|
563
|
+
color: red;
|
564
|
+
}
|
565
|
+
h2 p { padding: 3px; }
|
566
|
+
h3 {
|
567
|
+
margin-top: 5px;
|
568
|
+
color: red;
|
569
|
+
}
|
570
|
+
h3 p { padding: 3px; }
|
571
|
+
END
|
572
|
+
end
|
573
|
+
|
574
|
+
def test_should_handle_comma_separated_selectors_with_inner_nesting
|
575
|
+
input = <<END
|
576
|
+
h1 {
|
577
|
+
color: red;
|
578
|
+
p, span { padding: 3px; }
|
579
|
+
}
|
580
|
+
END
|
581
|
+
assert_equal <<END, process(input)
|
582
|
+
h1 {
|
583
|
+
color: red;
|
584
|
+
}
|
585
|
+
h1 p {
|
586
|
+
padding: 3px;
|
587
|
+
}
|
588
|
+
h1 span {
|
589
|
+
padding: 3px;
|
590
|
+
}
|
591
|
+
END
|
592
|
+
end
|
593
|
+
|
594
|
+
def test_should_handle_comma_separated_selectors_with_deep_nesting
|
595
|
+
input = <<END
|
596
|
+
div {
|
597
|
+
color: red;
|
598
|
+
h1 {
|
599
|
+
color: blue;
|
600
|
+
p, span {
|
601
|
+
font-weight: strong;
|
602
|
+
}
|
603
|
+
}
|
604
|
+
}
|
605
|
+
END
|
606
|
+
assert_equal <<END, process(input)
|
607
|
+
div {
|
608
|
+
color: red;
|
609
|
+
}
|
610
|
+
div h1 {
|
611
|
+
color: blue;
|
612
|
+
}
|
613
|
+
div h1 p {
|
614
|
+
font-weight: strong;
|
615
|
+
}
|
616
|
+
div h1 span {
|
617
|
+
font-weight: strong;
|
618
|
+
}
|
619
|
+
END
|
620
|
+
end
|
621
|
+
|
622
|
+
def test_should_handle_comma_separated_selectors_with_inner_and_outer_nesting
|
623
|
+
input = <<END
|
624
|
+
div, span {
|
625
|
+
color: red;
|
626
|
+
h1, h2 {
|
627
|
+
font-weight: strong;
|
628
|
+
}
|
629
|
+
}
|
630
|
+
END
|
631
|
+
assert_equal <<END, process(input)
|
632
|
+
div {
|
633
|
+
color: red;
|
634
|
+
}
|
635
|
+
div h1 {
|
636
|
+
font-weight: strong;
|
637
|
+
}
|
638
|
+
div h2 {
|
639
|
+
font-weight: strong;
|
640
|
+
}
|
641
|
+
span {
|
642
|
+
color: red;
|
643
|
+
}
|
644
|
+
span h1 {
|
645
|
+
font-weight: strong;
|
646
|
+
}
|
647
|
+
span h2 {
|
648
|
+
font-weight: strong;
|
649
|
+
}
|
650
|
+
END
|
651
|
+
end
|
652
|
+
|
653
|
+
def test_should_handle_comma_separated_selectors_on_subsequent_lines_inline_styles
|
654
|
+
input = <<END
|
655
|
+
div#some,
|
656
|
+
div#another,
|
657
|
+
div#third { color: red; }
|
658
|
+
END
|
659
|
+
assert_equal <<END, process(input)
|
660
|
+
div#some {
|
661
|
+
color: red;
|
662
|
+
}
|
663
|
+
div#another {
|
664
|
+
color: red;
|
665
|
+
}
|
666
|
+
div#third {
|
667
|
+
color: red;
|
668
|
+
}
|
669
|
+
END
|
670
|
+
end
|
671
|
+
|
672
|
+
def test_should_handle_comma_separated_selectors_on_subsequent_lines_multiline_styles
|
673
|
+
input = <<END
|
674
|
+
div#some,
|
675
|
+
div#another,
|
676
|
+
div#third {
|
677
|
+
color: red;
|
678
|
+
}
|
679
|
+
END
|
680
|
+
assert_equal <<END, process(input)
|
681
|
+
div#some {
|
682
|
+
color: red;
|
683
|
+
}
|
684
|
+
div#another {
|
685
|
+
color: red;
|
686
|
+
}
|
687
|
+
div#third {
|
688
|
+
color: red;
|
689
|
+
}
|
690
|
+
END
|
691
|
+
end
|
692
|
+
|
693
|
+
def test_should_handle_comma_separated_fonts
|
694
|
+
input = <<END
|
695
|
+
html, body {
|
696
|
+
font-family: "Lucida Grande", Verdana, sans-serif;
|
697
|
+
}
|
698
|
+
END
|
699
|
+
assert_equal <<END, process(input)
|
700
|
+
html {
|
701
|
+
font-family: "Lucida Grande", Verdana, sans-serif;
|
702
|
+
}
|
703
|
+
body {
|
704
|
+
font-family: "Lucida Grande", Verdana, sans-serif;
|
705
|
+
}
|
706
|
+
END
|
707
|
+
end
|
708
|
+
|
709
|
+
def test_should_handle_multiline_comments
|
710
|
+
input = <<END
|
711
|
+
/*
|
712
|
+
* Multilined comment outside a selector.
|
713
|
+
*/
|
714
|
+
html {
|
715
|
+
/*
|
716
|
+
* Multilined comment inside a selector.
|
717
|
+
*/
|
718
|
+
p {
|
719
|
+
/*
|
720
|
+
* And another one.
|
721
|
+
*/
|
722
|
+
color: blue;
|
723
|
+
}
|
724
|
+
}
|
725
|
+
END
|
726
|
+
assert_equal <<END, process(input)
|
727
|
+
/*
|
728
|
+
* Multilined comment outside a selector.
|
729
|
+
*/
|
730
|
+
html {
|
731
|
+
/*
|
732
|
+
* Multilined comment inside a selector.
|
733
|
+
*/
|
734
|
+
}
|
735
|
+
html p {
|
736
|
+
/*
|
737
|
+
* And another one.
|
738
|
+
*/
|
739
|
+
color: blue;
|
740
|
+
}
|
741
|
+
END
|
742
|
+
end
|
743
|
+
|
744
|
+
def test_should_handle_comments_with_blank_lines
|
745
|
+
input = <<END
|
746
|
+
/*
|
747
|
+
* This is a multiline comment.
|
748
|
+
|
749
|
+
*/
|
750
|
+
html {
|
751
|
+
color: blue;
|
752
|
+
/*
|
753
|
+
* This is a multiline comment.
|
754
|
+
|
755
|
+
*/
|
756
|
+
p {
|
757
|
+
color: red;
|
758
|
+
}
|
759
|
+
}
|
760
|
+
END
|
761
|
+
assert_equal <<END, process(input)
|
762
|
+
/*
|
763
|
+
* This is a multiline comment.
|
764
|
+
|
765
|
+
*/
|
766
|
+
html {
|
767
|
+
color: blue;
|
768
|
+
/*
|
769
|
+
* This is a multiline comment.
|
770
|
+
*/
|
771
|
+
}
|
772
|
+
html p {
|
773
|
+
color: red;
|
774
|
+
}
|
775
|
+
END
|
776
|
+
end
|
777
|
+
|
778
|
+
def test_should_handle_comments_with_commas
|
779
|
+
input = <<END
|
780
|
+
/*********************************************************
|
781
|
+
Structural styling, sizing and positioning of elements
|
782
|
+
********************************************************/
|
783
|
+
|
784
|
+
* {
|
785
|
+
margin: 0;
|
786
|
+
padding: 0;
|
787
|
+
}
|
788
|
+
|
789
|
+
body {
|
790
|
+
z-index: 2;
|
791
|
+
}
|
792
|
+
END
|
793
|
+
assert_equal <<END, process(input)
|
794
|
+
/*********************************************************
|
795
|
+
Structural styling sizing and positioning of elements
|
796
|
+
********************************************************/
|
797
|
+
|
798
|
+
* {
|
799
|
+
margin: 0;
|
800
|
+
padding: 0;
|
801
|
+
}
|
802
|
+
|
803
|
+
body {
|
804
|
+
z-index: 2;
|
805
|
+
}
|
806
|
+
END
|
807
|
+
end
|
808
|
+
|
809
|
+
def test_should_fail_on_missing_closing_brace
|
810
|
+
input = <<END
|
811
|
+
* html {
|
812
|
+
body {
|
813
|
+
padding: 4px;
|
814
|
+
}
|
815
|
+
END
|
816
|
+
# TODO: decide what css_dryer should do with invalid input.
|
817
|
+
# Currently it doesn't test for CSS or nested CSS validity,
|
818
|
+
# and here it (accidentally) automagically replaces missing
|
819
|
+
# brace. Handy, but a recipe for disaster.
|
820
|
+
assert_not_equal <<END, process(input)
|
821
|
+
* html body {
|
822
|
+
padding: 4px;
|
823
|
+
}
|
824
|
+
END
|
825
|
+
end
|
826
|
+
end
|