sass 3.6.0 → 3.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. checksums.yaml +5 -5
  2. data/CONTRIBUTING.md +1 -1
  3. data/README.md +10 -0
  4. data/VERSION +1 -1
  5. data/VERSION_DATE +1 -1
  6. data/lib/sass/script/css_parser.rb +4 -1
  7. data/lib/sass/script/functions.rb +15 -25
  8. data/lib/sass/script/lexer.rb +45 -7
  9. data/lib/sass/script/parser.rb +259 -93
  10. data/lib/sass/scss/parser.rb +43 -16
  11. data/lib/sass/scss/static_parser.rb +15 -15
  12. data/lib/sass/util.rb +31 -0
  13. metadata +8 -156
  14. data/Rakefile +0 -364
  15. data/test/sass-spec.yml +0 -3
  16. data/test/sass/cache_test.rb +0 -130
  17. data/test/sass/callbacks_test.rb +0 -60
  18. data/test/sass/compiler_test.rb +0 -225
  19. data/test/sass/conversion_test.rb +0 -2138
  20. data/test/sass/css2sass_test.rb +0 -523
  21. data/test/sass/css_variable_test.rb +0 -237
  22. data/test/sass/data/hsl-rgb.txt +0 -319
  23. data/test/sass/encoding_test.rb +0 -188
  24. data/test/sass/engine_test.rb +0 -3499
  25. data/test/sass/exec_test.rb +0 -95
  26. data/test/sass/extend_test.rb +0 -1679
  27. data/test/sass/fixtures/test_staleness_check_across_importers.css +0 -1
  28. data/test/sass/fixtures/test_staleness_check_across_importers.scss +0 -1
  29. data/test/sass/functions_test.rb +0 -2021
  30. data/test/sass/importer_test.rb +0 -420
  31. data/test/sass/logger_test.rb +0 -57
  32. data/test/sass/mock_importer.rb +0 -49
  33. data/test/sass/more_results/more1.css +0 -9
  34. data/test/sass/more_results/more1_with_line_comments.css +0 -26
  35. data/test/sass/more_results/more_import.css +0 -29
  36. data/test/sass/more_templates/_more_partial.sass +0 -2
  37. data/test/sass/more_templates/more1.sass +0 -23
  38. data/test/sass/more_templates/more_import.sass +0 -11
  39. data/test/sass/plugin_test.rb +0 -552
  40. data/test/sass/results/alt.css +0 -4
  41. data/test/sass/results/basic.css +0 -9
  42. data/test/sass/results/cached_import_option.css +0 -3
  43. data/test/sass/results/compact.css +0 -5
  44. data/test/sass/results/complex.css +0 -86
  45. data/test/sass/results/compressed.css +0 -1
  46. data/test/sass/results/expanded.css +0 -19
  47. data/test/sass/results/filename_fn.css +0 -3
  48. data/test/sass/results/if.css +0 -3
  49. data/test/sass/results/import.css +0 -31
  50. data/test/sass/results/import_charset.css +0 -5
  51. data/test/sass/results/import_charset_ibm866.css +0 -5
  52. data/test/sass/results/import_content.css +0 -1
  53. data/test/sass/results/line_numbers.css +0 -49
  54. data/test/sass/results/mixins.css +0 -95
  55. data/test/sass/results/multiline.css +0 -24
  56. data/test/sass/results/nested.css +0 -22
  57. data/test/sass/results/options.css +0 -1
  58. data/test/sass/results/parent_ref.css +0 -13
  59. data/test/sass/results/script.css +0 -16
  60. data/test/sass/results/scss_import.css +0 -31
  61. data/test/sass/results/scss_importee.css +0 -2
  62. data/test/sass/results/subdir/nested_subdir/nested_subdir.css +0 -1
  63. data/test/sass/results/subdir/subdir.css +0 -3
  64. data/test/sass/results/units.css +0 -11
  65. data/test/sass/results/warn.css +0 -0
  66. data/test/sass/results/warn_imported.css +0 -0
  67. data/test/sass/script_conversion_test.rb +0 -365
  68. data/test/sass/script_test.rb +0 -1427
  69. data/test/sass/scss/css_test.rb +0 -1266
  70. data/test/sass/scss/rx_test.rb +0 -159
  71. data/test/sass/scss/scss_test.rb +0 -4238
  72. data/test/sass/scss/test_helper.rb +0 -37
  73. data/test/sass/source_map_test.rb +0 -1063
  74. data/test/sass/superselector_test.rb +0 -209
  75. data/test/sass/templates/_cached_import_option_partial.scss +0 -1
  76. data/test/sass/templates/_double_import_loop2.sass +0 -1
  77. data/test/sass/templates/_filename_fn_import.scss +0 -11
  78. data/test/sass/templates/_imported_charset_ibm866.sass +0 -4
  79. data/test/sass/templates/_imported_charset_utf8.sass +0 -4
  80. data/test/sass/templates/_imported_content.sass +0 -3
  81. data/test/sass/templates/_partial.sass +0 -2
  82. data/test/sass/templates/_same_name_different_partiality.scss +0 -1
  83. data/test/sass/templates/alt.sass +0 -16
  84. data/test/sass/templates/basic.sass +0 -23
  85. data/test/sass/templates/bork1.sass +0 -2
  86. data/test/sass/templates/bork2.sass +0 -2
  87. data/test/sass/templates/bork3.sass +0 -2
  88. data/test/sass/templates/bork4.sass +0 -2
  89. data/test/sass/templates/bork5.sass +0 -3
  90. data/test/sass/templates/cached_import_option.scss +0 -3
  91. data/test/sass/templates/compact.sass +0 -17
  92. data/test/sass/templates/complex.sass +0 -305
  93. data/test/sass/templates/compressed.sass +0 -15
  94. data/test/sass/templates/double_import_loop1.sass +0 -1
  95. data/test/sass/templates/expanded.sass +0 -17
  96. data/test/sass/templates/filename_fn.scss +0 -18
  97. data/test/sass/templates/if.sass +0 -11
  98. data/test/sass/templates/import.sass +0 -12
  99. data/test/sass/templates/import_charset.sass +0 -9
  100. data/test/sass/templates/import_charset_ibm866.sass +0 -11
  101. data/test/sass/templates/import_content.sass +0 -4
  102. data/test/sass/templates/importee.less +0 -2
  103. data/test/sass/templates/importee.sass +0 -19
  104. data/test/sass/templates/line_numbers.sass +0 -13
  105. data/test/sass/templates/mixin_bork.sass +0 -5
  106. data/test/sass/templates/mixins.sass +0 -76
  107. data/test/sass/templates/multiline.sass +0 -20
  108. data/test/sass/templates/nested.sass +0 -25
  109. data/test/sass/templates/nested_bork1.sass +0 -2
  110. data/test/sass/templates/nested_bork2.sass +0 -2
  111. data/test/sass/templates/nested_bork3.sass +0 -2
  112. data/test/sass/templates/nested_bork4.sass +0 -2
  113. data/test/sass/templates/nested_import.sass +0 -2
  114. data/test/sass/templates/nested_mixin_bork.sass +0 -6
  115. data/test/sass/templates/options.sass +0 -2
  116. data/test/sass/templates/parent_ref.sass +0 -25
  117. data/test/sass/templates/same_name_different_ext.sass +0 -2
  118. data/test/sass/templates/same_name_different_ext.scss +0 -1
  119. data/test/sass/templates/same_name_different_partiality.scss +0 -1
  120. data/test/sass/templates/script.sass +0 -101
  121. data/test/sass/templates/scss_import.scss +0 -12
  122. data/test/sass/templates/scss_importee.scss +0 -1
  123. data/test/sass/templates/single_import_loop.sass +0 -1
  124. data/test/sass/templates/subdir/import_up1.scss +0 -1
  125. data/test/sass/templates/subdir/import_up2.scss +0 -1
  126. data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +0 -2
  127. data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +0 -3
  128. data/test/sass/templates/subdir/subdir.sass +0 -6
  129. data/test/sass/templates/units.sass +0 -11
  130. data/test/sass/templates/warn.sass +0 -3
  131. data/test/sass/templates/warn_imported.sass +0 -4
  132. data/test/sass/test_helper.rb +0 -8
  133. data/test/sass/util/multibyte_string_scanner_test.rb +0 -152
  134. data/test/sass/util/normalized_map_test.rb +0 -50
  135. data/test/sass/util/subset_map_test.rb +0 -90
  136. data/test/sass/util_test.rb +0 -393
  137. data/test/sass/value_helpers_test.rb +0 -178
  138. data/test/test_helper.rb +0 -149
@@ -1,1266 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- require File.dirname(__FILE__) + '/test_helper'
3
- require 'sass/scss/css_parser'
4
-
5
- # These tests just test the parsing of CSS
6
- # (both standard and any hacks we intend to support).
7
- # Tests of SCSS-specific behavior go in scss_test.rb.
8
- class ScssCssTest < MiniTest::Test
9
- include ScssTestHelper
10
-
11
- def test_basic_scss
12
- assert_parses <<SCSS
13
- selector {
14
- property: value;
15
- property2: value; }
16
- SCSS
17
-
18
- assert_equal <<CSS, render('sel{p:v}')
19
- sel {
20
- p: v; }
21
- CSS
22
- end
23
-
24
- def test_empty_rule
25
- assert_equal "", render("#foo .bar {}")
26
- assert_equal "", render(<<SCSS)
27
- #foo .bar {
28
- }
29
- SCSS
30
- end
31
-
32
- def test_cdo_and_cdc_ignored_at_toplevel
33
- assert_equal <<CSS, render(<<SCSS)
34
- foo {
35
- bar: baz; }
36
-
37
- bar {
38
- bar: baz; }
39
-
40
- baz {
41
- bar: baz; }
42
- CSS
43
- foo {bar: baz}
44
- <!--
45
- bar {bar: baz}
46
- -->
47
- baz {bar: baz}
48
- SCSS
49
- end
50
-
51
- def test_unicode
52
- assert_parses <<SCSS
53
- @charset "UTF-8";
54
- foo {
55
- bar: föö bâr; }
56
- SCSS
57
- assert_equal <<CSS, render(<<SCSS)
58
- @charset "UTF-8";
59
- foo {
60
- bar: föö bâr; }
61
- CSS
62
- foo {
63
- bar: föö bâr; }
64
- SCSS
65
- end
66
-
67
- def test_invisible_comments
68
- assert_equal <<CSS, render(<<SCSS)
69
- foo {
70
- a: d; }
71
- CSS
72
- foo {a: /* b; c: */ d}
73
- SCSS
74
- assert_equal <<CSS, render(<<SCSS)
75
- foo {
76
- a: d; }
77
- CSS
78
- foo {a /*: b; c */: d}
79
- SCSS
80
- end
81
-
82
- def test_crazy_comments
83
- # http://www.w3.org/Style/CSS/Test/CSS2.1/current/xhtml1/t040109-c17-comments-00-b.xht
84
- assert_equal <<CSS, render(<<SCSS)
85
- /* This is a CSS comment. */
86
- .one {
87
- color: green; }
88
-
89
- /* Another comment */
90
- /* The following should not be used:
91
- .two {color: red;} */
92
- .three {
93
- color: green;
94
- /* color: red; */ }
95
-
96
- /**
97
- .four {color: red;} */
98
- .five {
99
- color: green; }
100
-
101
- /**/
102
- .six {
103
- color: green; }
104
-
105
- /*********/
106
- .seven {
107
- color: green; }
108
-
109
- /* a comment **/
110
- .eight {
111
- color: green; }
112
- CSS
113
- /* This is a CSS comment. */
114
- .one {color: green;} /* Another comment */
115
- /* The following should not be used:
116
- .two {color: red;} */
117
- .three {color: green; /* color: red; */}
118
- /**
119
- .four {color: red;} */
120
- .five {color: green;}
121
- /**/
122
- .six {color: green;}
123
- /*********/
124
- .seven {color: green;}
125
- /* a comment **/
126
- .eight {color: green;}
127
- SCSS
128
- end
129
-
130
- def test_rule_comments
131
- assert_parses <<SCSS
132
- /* Foo */
133
- .foo {
134
- a: b; }
135
- SCSS
136
- assert_equal <<CSS, render(<<SCSS)
137
- /* Foo
138
- * Bar */
139
- .foo {
140
- a: b; }
141
- CSS
142
- /* Foo
143
- * Bar */.foo {
144
- a: b; }
145
- SCSS
146
- end
147
-
148
- def test_property_comments
149
- assert_parses <<SCSS
150
- .foo {
151
- /* Foo */
152
- a: b; }
153
- SCSS
154
- assert_equal <<CSS, render(<<SCSS)
155
- .foo {
156
- /* Foo
157
- * Bar */
158
- a: b; }
159
- CSS
160
- .foo {
161
- /* Foo
162
- * Bar */a: b; }
163
- SCSS
164
- end
165
-
166
- def test_selector_comments
167
- assert_equal <<CSS, render(<<SCSS)
168
- .foo #bar:baz(bip) {
169
- a: b; }
170
- CSS
171
- .foo /* .a #foo */ #bar:baz(/* bang )*/ bip) {
172
- a: b; }
173
- SCSS
174
- end
175
-
176
- def test_lonely_comments
177
- assert_parses <<SCSS
178
- /* Foo
179
- * Bar */
180
- SCSS
181
- assert_parses <<SCSS
182
- .foo {
183
- /* Foo
184
- * Bar */ }
185
- SCSS
186
- end
187
-
188
- def test_multiple_comments
189
- assert_parses <<SCSS
190
- /* Foo
191
- * Bar */
192
- /* Baz
193
- * Bang */
194
- SCSS
195
- assert_parses <<SCSS
196
- .foo {
197
- /* Foo
198
- * Bar */
199
- /* Baz
200
- * Bang */ }
201
- SCSS
202
- assert_equal <<CSS, render(<<SCSS)
203
- .foo {
204
- /* Foo Bar */
205
- /* Baz Bang */ }
206
- CSS
207
- .foo {
208
- /* Foo Bar *//* Baz Bang */ }
209
- SCSS
210
- end
211
-
212
- def test_bizarrely_formatted_comments
213
- assert_parses <<SCSS
214
- .foo {
215
- /* Foo
216
- Bar
217
- Baz */
218
- a: b; }
219
- SCSS
220
- assert_parses <<SCSS
221
- .foo {
222
- /* Foo
223
- Bar
224
- Baz */
225
- a: b; }
226
- SCSS
227
- assert_equal <<CSS, render(<<SCSS)
228
- .foo {
229
- /* Foo
230
- Bar */
231
- a: b; }
232
- CSS
233
- .foo {/* Foo
234
- Bar */
235
- a: b; }
236
- SCSS
237
- assert_equal <<CSS, render(<<SCSS)
238
- .foo {
239
- /* Foo
240
- Bar
241
- Baz */
242
- a: b; }
243
- CSS
244
- .foo {/* Foo
245
- Bar
246
- Baz */
247
- a: b; }
248
- SCSS
249
- end
250
-
251
- ## Declarations
252
-
253
- def test_vendor_properties
254
- assert_parses <<SCSS
255
- foo {
256
- -moz-foo-bar: blat;
257
- -o-flat-blang: wibble; }
258
- SCSS
259
- end
260
-
261
- def test_empty_declarations
262
- assert_equal <<CSS, render(<<SCSS)
263
- foo {
264
- bar: baz; }
265
- CSS
266
- foo {;;;;
267
- bar: baz;;;;
268
- ;;}
269
- SCSS
270
- end
271
-
272
- def test_basic_property_types
273
- assert_parses <<SCSS
274
- foo {
275
- a: 2;
276
- b: 2.3em;
277
- c: 50%;
278
- d: "fraz bran";
279
- e: flanny-blanny-blan;
280
- f: url(http://sass-lang.com);
281
- g: U+ffa?;
282
- h: #aabbcc; }
283
- SCSS
284
- end
285
-
286
- def test_functions
287
- assert_parses <<SCSS
288
- foo {
289
- a: foo-bar(12);
290
- b: -foo-bar-baz(13, 14 15); }
291
- SCSS
292
- end
293
-
294
- def test_unary_minus
295
- assert_parses <<SCSS
296
- foo {
297
- a: -2;
298
- b: -2.3em;
299
- c: -50%;
300
- d: -foo(bar baz); }
301
- SCSS
302
- end
303
-
304
- def test_operators
305
- assert_parses <<SCSS
306
- foo {
307
- a: foo bar baz;
308
- b: foo, #aabbcc, -12;
309
- c: 1px/2px/-3px;
310
- d: foo bar, baz/bang; }
311
- SCSS
312
- end
313
-
314
- def test_important
315
- assert_parses <<SCSS
316
- foo {
317
- a: foo !important;
318
- b: foo bar !important;
319
- b: foo, bar !important; }
320
- SCSS
321
- end
322
-
323
- def test_initial_hyphen
324
- assert_parses <<SCSS
325
- foo {
326
- a: -moz-bar-baz;
327
- b: foo -o-bar-baz; }
328
- SCSS
329
- end
330
-
331
- def test_ms_long_filter_syntax
332
- assert_equal <<CSS, render(<<SCSS)
333
- foo {
334
- filter: progid:DXImageTransform.Microsoft.gradient(GradientType=1, startColorstr=#c0ff3300, endColorstr=#ff000000);
335
- filter: progid:DXImageTransform.Microsoft.gradient(GradientType=1, startColorstr=#c0ff3300, endColorstr=#ff000000); }
336
- CSS
337
- foo {
338
- filter: progid:DXImageTransform.Microsoft.gradient(GradientType=1, startColorstr=#c0ff3300, endColorstr=#ff000000);
339
- filter:progid:DXImageTransform.Microsoft.gradient(GradientType=1, startColorstr=#c0ff3300, endColorstr=#ff000000); }
340
- SCSS
341
- end
342
-
343
- def test_ms_short_filter_syntax
344
- assert_parses <<SCSS
345
- foo {
346
- filter: alpha(opacity=20);
347
- filter: alpha(opacity=20, enabled=true);
348
- filter: blaznicate(foo=bar, baz=bang bip, bart=#fa4600); }
349
- SCSS
350
- end
351
-
352
- def test_declaration_hacks
353
- assert_parses <<SCSS
354
- foo {
355
- _name: val;
356
- *name: val;
357
- :name: val;
358
- .name: val;
359
- #name: val;
360
- name/**/: val;
361
- name/*\\**/: val;
362
- name: val; }
363
- SCSS
364
- end
365
-
366
- def test_trailing_hash_hack
367
- assert_parses <<SCSS
368
- foo {
369
- foo: bar;
370
- #baz: bang;
371
- #bip: bop; }
372
- SCSS
373
- end
374
-
375
- def test_zero_arg_functions
376
- assert_parses <<SCSS
377
- foo {
378
- a: foo();
379
- b: bar baz-bang() bip; }
380
- SCSS
381
- end
382
-
383
- def test_expression_function
384
- assert_parses <<SCSS
385
- foo {
386
- a: 12px expression(1 + (3 / Foo.bar("baz" + "bang") + function() {return 12;}) % 12); }
387
- SCSS
388
- end
389
-
390
- def test_calc_function
391
- assert_parses <<SCSS
392
- foo {
393
- a: 12px calc(100%/3 - 2*1em - 2*1px);
394
- b: 12px -moz-calc(100%/3 - 2*1em - 2*1px);
395
- b: 12px -webkit-calc(100%/3 - 2*1em - 2*1px);
396
- b: 12px -foobar-calc(100%/3 - 2*1em - 2*1px); }
397
- SCSS
398
- end
399
-
400
- def test_element_function
401
- assert_parses <<SCSS
402
- foo {
403
- a: -moz-element(#foo);
404
- b: -webkit-element(#foo);
405
- b: -foobar-element(#foo); }
406
- SCSS
407
- end
408
-
409
- def test_unary_ops
410
- assert_equal <<CSS, render(<<SCSS)
411
- foo {
412
- a: -0.5em;
413
- b: +0.5em;
414
- c: -foo(12px);
415
- d: +foo(12px); }
416
- CSS
417
- foo {
418
- a: -0.5em;
419
- b: +0.5em;
420
- c: -foo(12px);
421
- d: +foo(12px); }
422
- SCSS
423
- end
424
-
425
- def test_css_string_escapes
426
- assert_parses <<SCSS
427
- foo {
428
- a: "\\foo bar";
429
- b: "foo\\ bar";
430
- c: "\\2022 \\0020";
431
- d: "foo\\\\bar";
432
- e: "foo\\"'bar"; }
433
- SCSS
434
- end
435
-
436
- def test_css_ident_escapes
437
- assert_parses <<SCSS
438
- foo {
439
- a: \\foo bar;
440
- b: foo\\ bar;
441
- c: \\2022 \\0020;
442
- d: foo\\\\bar;
443
- e: foo\\"\\'bar; }
444
- SCSS
445
- end
446
-
447
- ## Directives
448
-
449
- def test_namespace_directive
450
- assert_parses '@namespace "http://www.w3.org/Profiles/xhtml1-strict";'
451
- assert_parses '@namespace url(http://www.w3.org/Profiles/xhtml1-strict);'
452
- assert_parses '@namespace html url("http://www.w3.org/Profiles/xhtml1-strict");'
453
- end
454
-
455
- def test_media_directive
456
- assert_parses <<SCSS
457
- @media all {
458
- rule1 {
459
- prop: val; }
460
-
461
- rule2 {
462
- prop: val; } }
463
- SCSS
464
- assert_parses <<SCSS
465
- @media screen, print {
466
- rule1 {
467
- prop: val; }
468
-
469
- rule2 {
470
- prop: val; } }
471
- SCSS
472
- end
473
-
474
- def test_media_directive_with_keywords
475
- assert_parses <<SCSS
476
- @media screen and (-webkit-min-device-pixel-ratio: 0) {
477
- a: b; }
478
- SCSS
479
- assert_parses <<SCSS
480
- @media only screen, print and (foo: 0px) and (bar: flam(12px solid)) {
481
- a: b; }
482
- SCSS
483
- end
484
-
485
- def test_import_directive
486
- assert_parses '@import "foo.css";'
487
- assert_parses '@import url("foo.css");'
488
- assert_parses "@import url('foo.css');"
489
- assert_parses '@import url(foo.css);'
490
-
491
- assert_equal <<CSS, render(<<SCSS)
492
- @import "foo.css";
493
- CSS
494
- @import 'foo.css';
495
- SCSS
496
- end
497
-
498
- def test_import_directive_with_backslash_newline
499
- assert_equal <<CSS, render(<<SCSS)
500
- @import "foobar.css";
501
- CSS
502
- @import "foo\\
503
- bar.css";
504
- SCSS
505
- end
506
-
507
- def test_string_import_directive_with_media
508
- assert_parses '@import "foo.css" screen;'
509
- assert_parses '@import "foo.css" screen, print;'
510
- assert_parses '@import "foo.css" screen, print and (foo: 0);'
511
- assert_parses '@import "foo.css" screen, only print, screen and (foo: 0);'
512
- end
513
-
514
- def test_url_import_directive_with_media
515
- assert_parses '@import url("foo.css") screen;'
516
- assert_parses '@import url("foo.css") screen, print;'
517
- assert_parses '@import url("foo.css") screen, print and (foo: 0);'
518
- assert_parses '@import url("foo.css") screen, only print, screen and (foo: 0);'
519
- end
520
-
521
- def test_page_directive
522
- assert_parses <<SCSS
523
- @page {
524
- prop1: val;
525
- prop2: val; }
526
- SCSS
527
- assert_parses <<SCSS
528
- @page flap {
529
- prop1: val;
530
- prop2: val; }
531
- SCSS
532
- assert_parses <<SCSS
533
- @page :first {
534
- prop1: val;
535
- prop2: val; }
536
- SCSS
537
- assert_parses <<SCSS
538
- @page flap:first {
539
- prop1: val;
540
- prop2: val; }
541
- SCSS
542
- end
543
-
544
- def test_blockless_directive_without_semicolon
545
- assert_equal "@foo \"bar\";\n", render('@foo "bar"')
546
- end
547
-
548
- def test_directive_with_lots_of_whitespace
549
- assert_equal "@foo \"bar\";\n", render('@foo "bar" ;')
550
- end
551
-
552
- def test_empty_blockless_directive
553
- assert_parses "@foo;"
554
- end
555
-
556
- def test_multiple_blockless_directives
557
- assert_parses <<SCSS
558
- @foo bar;
559
- @bar baz;
560
- SCSS
561
- end
562
-
563
- def test_empty_block_directive
564
- assert_parses "@foo {}"
565
- assert_equal "@foo {}\n", render(<<SCSS)
566
- @foo {
567
- }
568
- SCSS
569
- end
570
-
571
- def test_multiple_block_directives
572
- assert_parses <<SCSS
573
- @foo bar {
574
- a: b; }
575
- @bar baz {
576
- c: d; }
577
- SCSS
578
- end
579
-
580
- def test_block_directive_with_rule_and_property
581
- assert_parses <<SCSS
582
- @foo {
583
- rule {
584
- a: b; }
585
-
586
- a: b; }
587
- SCSS
588
- end
589
-
590
- def test_block_directive_with_semicolon
591
- assert_equal <<CSS, render(<<SCSS)
592
- @foo {
593
- a: b; }
594
- @bar {
595
- a: b; }
596
- CSS
597
- @foo {a:b};
598
- @bar {a:b};
599
- SCSS
600
- end
601
-
602
- def test_moz_document_directive
603
- assert_equal <<CSS, render(<<SCSS)
604
- @-moz-document url(http://www.w3.org/),
605
- url-prefix(http://www.w3.org/Style/),
606
- domain(mozilla.org),
607
- regexp("^https:.*") {
608
- .foo {
609
- a: b; } }
610
- CSS
611
- @-moz-document url(http://www.w3.org/),
612
- url-prefix(http://www.w3.org/Style/),
613
- domain(mozilla.org),
614
- regexp("^https:.*") {
615
- .foo {a: b}
616
- }
617
- SCSS
618
- end
619
-
620
- def test_supports
621
- assert_equal <<CSS, render(<<SCSS)
622
- @supports (((a: b) and (c: d)) or (not (d: e))) and ((not (f: g)) or (not ((h: i) and (j: k)))) {
623
- .foo {
624
- a: b; } }
625
- @supports (a: b) {
626
- .foo {
627
- a: b; } }
628
- CSS
629
- @supports (((a: b) and (c: d)) or (not (d: e))) and ((not (f: g)) or (not ((h: i) and (j: k)))) {
630
- .foo {
631
- a: b;
632
- }
633
- }
634
-
635
- @supports (a: b) {
636
- .foo {
637
- a: b;
638
- }
639
- }
640
- SCSS
641
- end
642
-
643
- def test_supports_with_prefix
644
- assert_equal <<CSS, render(<<SCSS)
645
- @-prefix-supports (((a: b) and (c: d)) or (not (d: e))) and ((not (f: g)) or (not ((h: i) and (j: k)))) {
646
- .foo {
647
- a: b; } }
648
- CSS
649
- @-prefix-supports (((a: b) and (c: d)) or (not (d: e))) and ((not (f: g)) or (not ((h: i) and (j: k)))) {
650
- .foo {
651
- a: b;
652
- }
653
- }
654
- SCSS
655
- end
656
-
657
- def test_supports_allows_similar_operators_without_parens
658
- assert_equal <<CSS, render(<<SCSS)
659
- @supports (a: b) and (c: d) and (e: f) {
660
- .foo {
661
- a: b; } }
662
- @supports (a: b) or (c: d) or (e: f) {
663
- .foo {
664
- a: b; } }
665
- CSS
666
- @supports (a: b) and (c: d) and (e: f) {
667
- .foo {
668
- a: b;
669
- }
670
- }
671
-
672
- @supports (a: b) or (c: d) or (e: f) {
673
- .foo {
674
- a: b;
675
- }
676
- }
677
- SCSS
678
- end
679
-
680
- def test_keyframes
681
- assert_equal <<CSS, render(<<SCSS)
682
- @keyframes identifier {
683
- 0% {
684
- top: 0;
685
- left: 0; }
686
- 30% {
687
- top: 50px; }
688
- 68%, 72% {
689
- left: 50px; }
690
- 100% {
691
- top: 100px;
692
- left: 100%; } }
693
- CSS
694
- @keyframes identifier {
695
- 0% {top: 0; left: 0}
696
- 30% {top: 50px}
697
- 68%, 72% {left: 50px}
698
- 100% {top: 100px; left: 100%}
699
- }
700
- SCSS
701
- end
702
-
703
- def test_keyframes_with_empty_rules
704
- assert_equal <<CSS, render(<<SCSS)
705
- @keyframes identifier {
706
- 50% {
707
- background-color: black; } }
708
- CSS
709
- @keyframes identifier {
710
- 0% {}
711
- 50% {background-color: black}
712
- 100% {}
713
- }
714
- SCSS
715
- end
716
-
717
- def test_keyframes_with_custom_identifiers
718
- assert_equal <<CSS, render(<<SCSS)
719
- @-skrollr-keyframes identifier {
720
- center-top {
721
- left: 100%; }
722
- top-bottom {
723
- left: 0%; } }
724
- CSS
725
- @-skrollr-keyframes identifier {
726
- center-top {
727
- left: 100%;
728
- }
729
-
730
- top-bottom {
731
- left: 0%;
732
- }
733
- }
734
-
735
- SCSS
736
- end
737
-
738
- ## Selectors
739
-
740
- # Taken from http://dev.w3.org/csswg/selectors4/#overview
741
- def test_summarized_selectors_with_element
742
- assert_selector_parses('*')
743
- assert_selector_parses('E')
744
- assert_selector_parses('E:not(s)')
745
- assert_selector_parses('E:not(s1, s2)')
746
- assert_selector_parses('E:matches(s1, s2)')
747
- assert_selector_parses('E:has(s1, s2)')
748
- assert_selector_parses('E:has(> s1, > s2)')
749
- assert_selector_parses('E.warning')
750
- assert_selector_parses('E#myid')
751
- assert_selector_parses('E[foo]')
752
- assert_selector_parses('E[foo="bar"]')
753
- assert_selector_parses('E[foo="bar" i]')
754
- assert_selector_parses('E[foo~="bar"]')
755
- assert_selector_parses('E[foo^="bar"]')
756
- assert_selector_parses('E[foo$="bar"]')
757
- assert_selector_parses('E[foo*="bar"]')
758
- assert_selector_parses('E[foo|="en"]')
759
- assert_selector_parses('E:dir(ltr)')
760
- assert_selector_parses('E:lang(fr)')
761
- assert_selector_parses('E:lang(zh, *-hant)')
762
- assert_selector_parses('E:any-link')
763
- assert_selector_parses('E:link')
764
- assert_selector_parses('E:visited')
765
- assert_selector_parses('E:local-link')
766
- assert_selector_parses('E:local-link(0)')
767
- assert_selector_parses('E:target')
768
- assert_selector_parses('E:scope')
769
- assert_selector_parses('E:current')
770
- assert_selector_parses('E:current(s)')
771
- assert_selector_parses('E:past')
772
- assert_selector_parses('E:future')
773
- assert_selector_parses('E:active')
774
- assert_selector_parses('E:hover')
775
- assert_selector_parses('E:focus')
776
- assert_selector_parses('E:enabled')
777
- assert_selector_parses('E:disabled')
778
- assert_selector_parses('E:checked')
779
- assert_selector_parses('E:indeterminate')
780
- assert_selector_parses('E:default')
781
- assert_selector_parses('E:in-range')
782
- assert_selector_parses('E:out-of-range')
783
- assert_selector_parses('E:required')
784
- assert_selector_parses('E:optional')
785
- assert_selector_parses('E:read-only')
786
- assert_selector_parses('E:read-write')
787
- assert_selector_parses('E:root')
788
- assert_selector_parses('E:empty')
789
- assert_selector_parses('E:first-child')
790
- assert_selector_parses('E:nth-child(n)')
791
- assert_selector_parses('E:last-child')
792
- assert_selector_parses('E:nth-last-child(n)')
793
- assert_selector_parses('E:only-child')
794
- assert_selector_parses('E:first-of-type')
795
- assert_selector_parses('E:nth-of-type(n)')
796
- assert_selector_parses('E:last-of-type')
797
- assert_selector_parses('E:nth-last-of-type(n)')
798
- assert_selector_parses('E:only-of-type')
799
- assert_selector_parses('E:nth-child(n of selector)')
800
- assert_selector_parses('E:nth-last-child(n of selector)')
801
- assert_selector_parses('E:nth-child(n)')
802
- assert_selector_parses('E:nth-last-child(n)')
803
- assert_selector_parses('E F')
804
- assert_selector_parses('E > F')
805
- assert_selector_parses('E + F')
806
- assert_selector_parses('E ~ F')
807
- silence_warnings {assert_selector_parses('E /foo/ F')}
808
- silence_warnings {assert_selector_parses('E! > F')}
809
-
810
- silence_warnings {assert_selector_parses('E /ns|foo/ F')}
811
-
812
- # From http://dev.w3.org/csswg/css-scoping-1/
813
- assert_selector_parses('E:host(s)')
814
- assert_selector_parses('E:host-context(s)')
815
- end
816
-
817
- # Taken from http://dev.w3.org/csswg/selectors4/#overview, but without element
818
- # names.
819
- def test_more_summarized_selectors
820
- assert_selector_parses(':not(s)')
821
- assert_selector_parses(':not(s1, s2)')
822
- assert_selector_parses(':matches(s1, s2)')
823
- assert_selector_parses(':has(s1, s2)')
824
- assert_selector_parses(':has(> s1, > s2)')
825
- assert_selector_parses('.warning')
826
- assert_selector_parses('#myid')
827
- assert_selector_parses('[foo]')
828
- assert_selector_parses('[foo="bar"]')
829
- assert_selector_parses('[foo="bar" i]')
830
- assert_selector_parses('[foo~="bar"]')
831
- assert_selector_parses('[foo^="bar"]')
832
- assert_selector_parses('[foo$="bar"]')
833
- assert_selector_parses('[foo*="bar"]')
834
- assert_selector_parses('[foo|="en"]')
835
- assert_selector_parses(':dir(ltr)')
836
- assert_selector_parses(':lang(fr)')
837
- assert_selector_parses(':lang(zh, *-hant)')
838
- assert_selector_parses(':any-link')
839
- assert_selector_parses(':link')
840
- assert_selector_parses(':visited')
841
- assert_selector_parses(':local-link')
842
- assert_selector_parses(':local-link(0)')
843
- assert_selector_parses(':target')
844
- assert_selector_parses(':scope')
845
- assert_selector_parses(':current')
846
- assert_selector_parses(':current(s)')
847
- assert_selector_parses(':past')
848
- assert_selector_parses(':future')
849
- assert_selector_parses(':active')
850
- assert_selector_parses(':hover')
851
- assert_selector_parses(':focus')
852
- assert_selector_parses(':enabled')
853
- assert_selector_parses(':disabled')
854
- assert_selector_parses(':checked')
855
- assert_selector_parses(':indeterminate')
856
- assert_selector_parses(':default')
857
- assert_selector_parses(':in-range')
858
- assert_selector_parses(':out-of-range')
859
- assert_selector_parses(':required')
860
- assert_selector_parses(':optional')
861
- assert_selector_parses(':read-only')
862
- assert_selector_parses(':read-write')
863
- assert_selector_parses(':root')
864
- assert_selector_parses(':empty')
865
- assert_selector_parses(':first-child')
866
- assert_selector_parses(':nth-child(n)')
867
- assert_selector_parses(':last-child')
868
- assert_selector_parses(':nth-last-child(n)')
869
- assert_selector_parses(':only-child')
870
- assert_selector_parses(':first-of-type')
871
- assert_selector_parses(':nth-of-type(n)')
872
- assert_selector_parses(':last-of-type')
873
- assert_selector_parses(':nth-last-of-type(n)')
874
- assert_selector_parses(':only-of-type')
875
- assert_selector_parses(':nth-child(n of selector)')
876
- assert_selector_parses(':nth-last-child(n of selector)')
877
- assert_selector_parses(':nth-child(n)')
878
- assert_selector_parses(':nth-last-child(n)')
879
-
880
- # From http://dev.w3.org/csswg/css-scoping-1/
881
- assert_selector_parses(':host(s)')
882
- assert_selector_parses(':host-context(s)')
883
- end
884
-
885
- def test_attribute_selectors_with_identifiers
886
- assert_selector_parses('[foo~=bar]')
887
- assert_selector_parses('[foo^=bar]')
888
- assert_selector_parses('[foo$=bar]')
889
- assert_selector_parses('[foo*=bar]')
890
- assert_selector_parses('[foo|=en]')
891
- end
892
-
893
- def test_nth_selectors
894
- assert_selector_parses(':nth-child(-n)')
895
- assert_selector_parses(':nth-child(+n)')
896
-
897
- assert_selector_parses(':nth-child(even)')
898
- assert_selector_parses(':nth-child(odd)')
899
-
900
- assert_selector_parses(':nth-child(50)')
901
- assert_selector_parses(':nth-child(-50)')
902
- assert_selector_parses(':nth-child(+50)')
903
-
904
- assert_selector_parses(':nth-child(2n+3)')
905
- assert_selector_parses(':nth-child(2n-3)')
906
- assert_selector_parses(':nth-child(+2n-3)')
907
- assert_selector_parses(':nth-child(-2n+3)')
908
- assert_selector_parses(':nth-child(-2n+ 3)')
909
-
910
- assert_equal(<<CSS, render(<<SCSS))
911
- :nth-child(2n + 3) {
912
- a: b; }
913
- CSS
914
- :nth-child( 2n + 3 ) {
915
- a: b; }
916
- SCSS
917
- end
918
-
919
- def test_selectors_containing_selectors
920
- assert_selector_can_contain_selectors(':not(<sel>)')
921
- assert_selector_can_contain_selectors(':current(<sel>)')
922
- assert_selector_can_contain_selectors(':nth-child(n of <sel>)')
923
- assert_selector_can_contain_selectors(':nth-last-child(n of <sel>)')
924
- assert_selector_can_contain_selectors(':-moz-any(<sel>)')
925
- assert_selector_can_contain_selectors(':has(<sel>)')
926
- assert_selector_can_contain_selectors(':has(+ <sel>)')
927
- assert_selector_can_contain_selectors(':host(<sel>)')
928
- assert_selector_can_contain_selectors(':host-context(<sel>)')
929
- end
930
-
931
- def assert_selector_can_contain_selectors(sel)
932
- try = lambda {|subsel| assert_selector_parses(sel.gsub('<sel>', subsel))}
933
-
934
- try['foo|bar']
935
- try['*|bar']
936
-
937
- try['foo|*']
938
- try['*|*']
939
-
940
- try['#blah']
941
- try['.blah']
942
-
943
- try['[foo]']
944
- try['[foo^="bar"]']
945
- try['[baz|foo~="bar"]']
946
-
947
- try[':hover']
948
- try[':nth-child(2n + 3)']
949
-
950
- try['h1, h2, h3']
951
- try['#foo, bar, [baz]']
952
-
953
- # Not technically allowed for most selectors, but what the heck
954
- try[':not(#foo)']
955
- try['a#foo.bar']
956
- try['#foo .bar > baz']
957
- end
958
-
959
- def test_namespaced_selectors
960
- assert_selector_parses('foo|E')
961
- assert_selector_parses('*|E')
962
- assert_selector_parses('foo|*')
963
- assert_selector_parses('*|*')
964
- end
965
-
966
- def test_namespaced_attribute_selectors
967
- assert_selector_parses('[foo|bar=baz]')
968
- assert_selector_parses('[*|bar=baz]')
969
- assert_selector_parses('[foo|bar|=baz]')
970
- end
971
-
972
- def test_comma_selectors
973
- assert_selector_parses('E, F')
974
- assert_selector_parses('E F, G H')
975
- assert_selector_parses('E > F, G > H')
976
- end
977
-
978
- def test_selectors_with_newlines
979
- assert_selector_parses("E,\nF")
980
- assert_selector_parses("E\nF")
981
- assert_selector_parses("E, F\nG, H")
982
- end
983
-
984
- def test_expression_fallback_selectors
985
- assert_directive_parses('0%')
986
- assert_directive_parses('60%')
987
- assert_directive_parses('100%')
988
- assert_directive_parses('12px')
989
- assert_directive_parses('"foo"')
990
- end
991
-
992
- def test_functional_pseudo_selectors
993
- assert_selector_parses(':foo("bar")')
994
- assert_selector_parses(':foo(bar)')
995
- assert_selector_parses(':foo(12px)')
996
- assert_selector_parses(':foo(+)')
997
- assert_selector_parses(':foo(-)')
998
- assert_selector_parses(':foo(+"bar")')
999
- assert_selector_parses(':foo(-++--baz-"bar"12px)')
1000
- end
1001
-
1002
- def test_selector_hacks
1003
- assert_selector_parses('> E')
1004
- assert_selector_parses('+ E')
1005
- assert_selector_parses('~ E')
1006
- assert_selector_parses('> > E')
1007
- assert_equal <<CSS, render(<<SCSS)
1008
- > > E {
1009
- a: b; }
1010
- CSS
1011
- >> E {
1012
- a: b; }
1013
- SCSS
1014
-
1015
- assert_selector_parses('E*')
1016
- assert_selector_parses('E*.foo')
1017
- assert_selector_parses('E*:hover')
1018
- end
1019
-
1020
- def test_spaceless_combo_selectors
1021
- assert_equal "E > F {\n a: b; }\n", render("E>F { a: b;} ")
1022
- assert_equal "E ~ F {\n a: b; }\n", render("E~F { a: b;} ")
1023
- assert_equal "E + F {\n a: b; }\n", render("E+F { a: b;} ")
1024
- end
1025
-
1026
- def test_escapes_in_selectors
1027
- assert_selector_parses('.\!foo')
1028
- assert_selector_parses('.\66 foo')
1029
- assert_selector_parses('.\21 foo')
1030
- end
1031
-
1032
- def test_subject_selector_deprecation
1033
- assert_warning(<<WARNING) {render(".foo .bar! .baz {a: b}")}
1034
- DEPRECATION WARNING on line 1, column 1:
1035
- The subject selector operator "!" is deprecated and will be removed in a future release.
1036
- This operator has been replaced by ":has()" in the CSS spec.
1037
- For example: .foo .bar:has(.baz)
1038
- WARNING
1039
-
1040
- assert_warning(<<WARNING) {render(".foo .bar! > .baz {a: b}")}
1041
- DEPRECATION WARNING on line 1, column 1:
1042
- The subject selector operator "!" is deprecated and will be removed in a future release.
1043
- This operator has been replaced by ":has()" in the CSS spec.
1044
- For example: .foo .bar:has(> .baz)
1045
- WARNING
1046
-
1047
- assert_warning(<<WARNING) {render(".foo .bar! {a: b}")}
1048
- DEPRECATION WARNING on line 1, column 1:
1049
- The subject selector operator "!" is deprecated and will be removed in a future release.
1050
- This operator has been replaced by ":has()" in the CSS spec.
1051
- For example: .foo .bar
1052
- WARNING
1053
- end
1054
-
1055
- ## Errors
1056
-
1057
- def test_invalid_directives
1058
- assert_not_parses("identifier", '@<err> import "foo";')
1059
- assert_not_parses("identifier", '@<err>12 "foo";')
1060
- end
1061
-
1062
- def test_invalid_classes
1063
- assert_not_parses("class name", 'p.<err> foo {a: b}')
1064
- assert_not_parses("class name", 'p.<err>1foo {a: b}')
1065
- end
1066
-
1067
- def test_invalid_ids
1068
- assert_not_parses("id name", 'p#<err> foo {a: b}')
1069
- end
1070
-
1071
- def test_no_properties_at_toplevel
1072
- assert_not_parses('pseudoclass or pseudoelement', 'a:<err> b;')
1073
- end
1074
-
1075
- def test_no_scss_directives
1076
- assert_parses('@import "foo.sass";')
1077
- assert_parses <<SCSS
1078
- @mixin foo {
1079
- a: b; }
1080
- SCSS
1081
- end
1082
-
1083
- def test_no_variables
1084
- assert_not_parses("selector or at-rule", "<err>$var = 12;")
1085
- assert_not_parses('"}"', "foo { <err>!var = 12; }")
1086
- end
1087
-
1088
- def test_no_parent_selectors
1089
- assert_not_parses('"{"', "foo <err>&.bar {a: b}")
1090
- end
1091
-
1092
- def test_no_selector_interpolation
1093
- assert_not_parses('"{"', 'foo <err>#{"bar"}.baz {a: b}')
1094
- end
1095
-
1096
- def test_no_prop_name_interpolation
1097
- assert_not_parses('":"', 'foo {a<err>#{"bar"}baz: b}')
1098
- end
1099
-
1100
- def test_no_prop_val_interpolation
1101
- assert_not_parses('"}"', 'foo {a: b <err>#{"bar"} c}')
1102
- end
1103
-
1104
- def test_no_string_interpolation
1105
- assert_parses <<SCSS
1106
- foo {
1107
- a: "bang \#{1 + " bar "} bip"; }
1108
- SCSS
1109
- end
1110
-
1111
- def test_no_sass_script_values
1112
- assert_not_parses('"}"', 'foo {a: b <err>* c}')
1113
- end
1114
-
1115
- def test_no_nested_rules
1116
- assert_not_parses('":"', 'foo {bar <err>{a: b}}')
1117
- assert_not_parses('"}"', 'foo {<err>[bar=baz] {a: b}}')
1118
- end
1119
-
1120
- def test_no_nested_properties
1121
- assert_not_parses('expression (e.g. 1px, bold)', 'foo {bar: <err>{a: b}}')
1122
- assert_not_parses('expression (e.g. 1px, bold)', 'foo {bar: bang <err>{a: b}}')
1123
- end
1124
-
1125
- def test_no_nested_directives
1126
- assert_not_parses('"}"', 'foo {<err>@bar {a: b}}')
1127
- end
1128
-
1129
- def test_error_with_windows_newlines
1130
- render <<SCSS
1131
- foo {bar}\r
1132
- baz {a: b}
1133
- SCSS
1134
- assert(false, "Expected syntax error")
1135
- rescue Sass::SyntaxError => e
1136
- assert_equal 'Invalid CSS after "foo {bar": expected ":", was "}"', e.message
1137
- assert_equal 1, e.sass_line
1138
- end
1139
-
1140
- def test_newline_in_property_value
1141
- assert_equal(<<CSS, render(<<SCSS))
1142
- .foo {
1143
- bar: "bazbang"; }
1144
- CSS
1145
- .foo {
1146
- bar: "baz\\
1147
- bang";
1148
- }
1149
- SCSS
1150
- end
1151
-
1152
- ## Regressions
1153
-
1154
- def test_very_long_comment_doesnt_take_forever
1155
- string = 'asdf' * (100000)
1156
- assert_equal(<<CSS, render(<<SCSS))
1157
- /*
1158
- #{string}
1159
- */
1160
- CSS
1161
- /*
1162
- #{string}
1163
- */
1164
- SCSS
1165
- end
1166
-
1167
- def test_long_unclosed_comment_doesnt_take_forever
1168
- assert_raise_message(Sass::SyntaxError,
1169
- 'Invalid CSS after "/*": expected "/", was "//*************..."') {render(<<SCSS)}
1170
- /*
1171
- //**************************************************************************
1172
- SCSS
1173
- end
1174
-
1175
- def test_double_space_string
1176
- assert_equal(<<CSS, render(<<SCSS))
1177
- .a {
1178
- content: " a"; }
1179
- CSS
1180
- .a {
1181
- content: " a";
1182
- }
1183
- SCSS
1184
- end
1185
-
1186
- def test_very_long_number_with_important_doesnt_take_forever
1187
- assert_equal(<<CSS, render(<<SCSS))
1188
- .foo {
1189
- width: 97.916666666666666666666666666667% !important; }
1190
- CSS
1191
- .foo {
1192
- width: 97.916666666666666666666666666667% !important;
1193
- }
1194
- SCSS
1195
- end
1196
-
1197
- def test_selector_without_closing_bracket
1198
- assert_not_parses('"]"', "foo[bar <err>{a: b}")
1199
- end
1200
-
1201
- def test_closing_line_comment_end_with_compact_output
1202
- assert_equal(<<CSS, render(<<SCSS, :style => :compact))
1203
- /* foo */
1204
- bar { baz: bang; }
1205
- CSS
1206
- /*
1207
- * foo
1208
- */
1209
- bar {baz: bang}
1210
- SCSS
1211
- end
1212
-
1213
- def test_single_line_comment_within_multiline_comment
1214
- assert_equal(<<CSS, render(<<SCSS))
1215
- body {
1216
- /*
1217
- //comment here
1218
- */ }
1219
- CSS
1220
- body {
1221
- /*
1222
- //comment here
1223
- */
1224
- }
1225
- SCSS
1226
- end
1227
-
1228
- def test_malformed_media
1229
- render <<SCSS
1230
- @media {
1231
- margin: 0;
1232
- }
1233
- SCSS
1234
- assert(false, "Expected syntax error")
1235
- rescue Sass::SyntaxError => e
1236
- assert_equal 'Invalid CSS after "@media ": expected media query (e.g. print, screen, print and screen), was "{"', e.message
1237
- assert_equal 1, e.sass_line
1238
- end
1239
-
1240
- private
1241
-
1242
- def assert_selector_parses(selector)
1243
- assert_parses <<SCSS
1244
- #{selector} {
1245
- a: b; }
1246
- SCSS
1247
-
1248
- assert_parses <<SCSS
1249
- :not(#{selector}) {
1250
- a: b; }
1251
- SCSS
1252
- end
1253
-
1254
- def assert_directive_parses(param)
1255
- assert_parses <<SCSS
1256
- @unknown #{param} {
1257
- a: b; }
1258
- SCSS
1259
- end
1260
-
1261
- def render(scss, options = {})
1262
- tree = Sass::SCSS::CssParser.new(scss, options[:filename], nil).parse
1263
- tree.options = Sass::Engine::DEFAULT_OPTIONS.merge(options)
1264
- tree.render
1265
- end
1266
- end