sass 3.3.0.rc.2 → 3.3.0.rc.3
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.
- checksums.yaml +15 -0
- data/CONTRIBUTING +1 -1
- data/README.md +7 -7
- data/Rakefile +4 -2
- data/VERSION +1 -1
- data/VERSION_DATE +1 -1
- data/bin/sass +5 -1
- data/bin/sass-convert +5 -1
- data/bin/scss +5 -1
- data/ext/mkrf_conf.rb +23 -0
- data/lib/sass/css.rb +1 -1
- data/lib/sass/engine.rb +19 -9
- data/lib/sass/environment.rb +8 -0
- data/lib/sass/exec.rb +4 -4
- data/lib/sass/features.rb +0 -1
- data/lib/sass/importers/base.rb +13 -6
- data/lib/sass/importers/deprecated_path.rb +8 -2
- data/lib/sass/importers/filesystem.rb +33 -7
- data/lib/sass/logger.rb +1 -4
- data/lib/sass/logger/base.rb +0 -2
- data/lib/sass/logger/log_level.rb +0 -2
- data/lib/sass/plugin.rb +2 -2
- data/lib/sass/plugin/compiler.rb +23 -11
- data/lib/sass/plugin/configuration.rb +0 -1
- data/lib/sass/railtie.rb +1 -0
- data/lib/sass/script/css_lexer.rb +0 -1
- data/lib/sass/script/css_parser.rb +0 -1
- data/lib/sass/script/functions.rb +158 -96
- data/lib/sass/script/lexer.rb +29 -35
- data/lib/sass/script/parser.rb +10 -3
- data/lib/sass/script/tree.rb +0 -1
- data/lib/sass/script/tree/funcall.rb +21 -5
- data/lib/sass/script/tree/list_literal.rb +0 -1
- data/lib/sass/script/value/arg_list.rb +7 -3
- data/lib/sass/script/value/bool.rb +0 -1
- data/lib/sass/script/value/null.rb +0 -1
- data/lib/sass/script/value/number.rb +2 -6
- data/lib/sass/scss/css_parser.rb +0 -1
- data/lib/sass/scss/parser.rb +5 -5
- data/lib/sass/scss/script_lexer.rb +0 -1
- data/lib/sass/scss/script_parser.rb +0 -1
- data/lib/sass/selector.rb +11 -1
- data/lib/sass/selector/comma_sequence.rb +3 -4
- data/lib/sass/selector/sequence.rb +11 -7
- data/lib/sass/selector/simple_sequence.rb +42 -11
- data/lib/sass/source/map.rb +6 -19
- data/lib/sass/tree/at_root_node.rb +1 -1
- data/lib/sass/tree/mixin_node.rb +2 -2
- data/lib/sass/tree/prop_node.rb +0 -1
- data/lib/sass/tree/variable_node.rb +0 -5
- data/lib/sass/tree/visitors/check_nesting.rb +0 -1
- data/lib/sass/tree/visitors/convert.rb +2 -2
- data/lib/sass/tree/visitors/cssize.rb +184 -84
- data/lib/sass/tree/visitors/deep_copy.rb +0 -1
- data/lib/sass/tree/visitors/perform.rb +14 -44
- data/lib/sass/util.rb +59 -12
- data/lib/sass/util/cross_platform_random.rb +19 -0
- data/lib/sass/util/normalized_map.rb +17 -1
- data/test/sass/compiler_test.rb +10 -0
- data/test/sass/conversion_test.rb +36 -0
- data/test/sass/css2sass_test.rb +19 -0
- data/test/sass/engine_test.rb +54 -105
- data/test/sass/functions_test.rb +233 -26
- data/test/sass/importer_test.rb +72 -10
- data/test/sass/plugin_test.rb +14 -0
- data/test/sass/script_conversion_test.rb +4 -4
- data/test/sass/script_test.rb +58 -21
- data/test/sass/scss/css_test.rb +8 -1
- data/test/sass/scss/scss_test.rb +376 -179
- data/test/sass/source_map_test.rb +8 -0
- data/test/sass/templates/subdir/import_up1.scss +1 -0
- data/test/sass/templates/subdir/import_up2.scss +1 -0
- data/test/sass/util_test.rb +16 -0
- data/test/test_helper.rb +12 -4
- metadata +269 -287
- data/lib/sass/script/tree/selector.rb +0 -30
data/test/sass/plugin_test.rb
CHANGED
@@ -164,6 +164,20 @@ CSS
|
|
164
164
|
end
|
165
165
|
end
|
166
166
|
|
167
|
+
def test_import_name_cleanup
|
168
|
+
File.delete(tempfile_loc('subdir/import_up1'))
|
169
|
+
check_for_updates!
|
170
|
+
File.open(tempfile_loc('subdir/import_up1')) do |file|
|
171
|
+
assert_equal(<<CSS.strip, file.read.split("\n")[0...5].join("\n"))
|
172
|
+
/*
|
173
|
+
Syntax error: File to import not found or unreadable: ../subdir/import_up3.scss.
|
174
|
+
Load path: #{template_loc}
|
175
|
+
on line 1 of #{template_loc 'subdir/import_up2'}
|
176
|
+
from line 1 of #{template_loc 'subdir/import_up1'}
|
177
|
+
CSS
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
167
181
|
def test_nonfull_exception_handling
|
168
182
|
old_full_exception = Sass::Plugin.options[:full_exception]
|
169
183
|
Sass::Plugin.options[:full_exception] = false
|
@@ -58,6 +58,10 @@ class SassScriptConversionTest < Test::Unit::TestCase
|
|
58
58
|
assert_renders "foo($karg1: val, $karg2: val2)"
|
59
59
|
end
|
60
60
|
|
61
|
+
def test_funcall_with_hyphen_conversion_keyword_arg
|
62
|
+
assert_renders "foo($a-b_c: val)"
|
63
|
+
end
|
64
|
+
|
61
65
|
def test_url
|
62
66
|
assert_renders "url(foo.gif)"
|
63
67
|
assert_renders "url($var)"
|
@@ -105,10 +109,6 @@ class SassScriptConversionTest < Test::Unit::TestCase
|
|
105
109
|
assert_renders "(foo: (bar, baz), bip: bop)"
|
106
110
|
end
|
107
111
|
|
108
|
-
def test_selector
|
109
|
-
assert_renders "&"
|
110
|
-
end
|
111
|
-
|
112
112
|
def self.test_precedence(outer, inner)
|
113
113
|
op_outer = Sass::Script::Lexer::OPERATORS_REVERSE[outer]
|
114
114
|
op_inner = Sass::Script::Lexer::OPERATORS_REVERSE[inner]
|
data/test/sass/script_test.rb
CHANGED
@@ -401,6 +401,12 @@ SASS
|
|
401
401
|
assert_equal "true", resolve('() != null')
|
402
402
|
end
|
403
403
|
|
404
|
+
def test_mod
|
405
|
+
assert_equal "5", resolve("29 % 12")
|
406
|
+
assert_equal "5px", resolve("29px % 12")
|
407
|
+
assert_equal "5px", resolve("29px % 12px")
|
408
|
+
end
|
409
|
+
|
404
410
|
def test_operation_precedence
|
405
411
|
assert_equal "false true", resolve("true and false false or true")
|
406
412
|
assert_equal "true", resolve("false and true or true and true")
|
@@ -564,27 +570,6 @@ SASS
|
|
564
570
|
assert_equal "true", resolve("$ie or $undef", {}, env('ie' => Sass::Script::Value::Bool.new(true)))
|
565
571
|
end
|
566
572
|
|
567
|
-
def test_selector
|
568
|
-
env = Sass::Environment.new
|
569
|
-
assert_equal "true", resolve("& == null", {}, env)
|
570
|
-
|
571
|
-
env.selector = selector('.foo.bar .baz.bang, .bip.bop')
|
572
|
-
assert_equal ".foo.bar .baz.bang, .bip.bop", resolve("&", {}, env)
|
573
|
-
assert_equal ".foo.bar .baz.bang", resolve("nth(&, 1)", {}, env)
|
574
|
-
assert_equal ".bip.bop", resolve("nth(&, 2)", {}, env)
|
575
|
-
assert_equal ".foo.bar", resolve("nth(nth(&, 1), 1)", {}, env)
|
576
|
-
assert_equal ".baz.bang", resolve("nth(nth(&, 1), 2)", {}, env)
|
577
|
-
assert_equal ".bip.bop", resolve("nth(nth(&, 2), 1)", {}, env)
|
578
|
-
assert_equal "string", resolve("type-of(nth(nth(&, 1), 1))", {}, env)
|
579
|
-
|
580
|
-
env.selector = selector('.foo > .bar')
|
581
|
-
assert_equal ".foo > .bar", resolve("&", {}, env)
|
582
|
-
assert_equal ".foo > .bar", resolve("nth(&, 1)", {}, env)
|
583
|
-
assert_equal ".foo", resolve("nth(nth(&, 1), 1)", {}, env)
|
584
|
-
assert_equal ">", resolve("nth(nth(&, 1), 2)", {}, env)
|
585
|
-
assert_equal ".bar", resolve("nth(nth(&, 1), 3)", {}, env)
|
586
|
-
end
|
587
|
-
|
588
573
|
def test_setting_global_variable_locally_warns
|
589
574
|
assert_warning(<<WARNING) {assert_equal(<<CSS, render(<<SCSS, :syntax => :scss))}
|
590
575
|
DEPRECATION WARNING on line 4 of test_setting_global_variable_locally_warns_inline.scss:
|
@@ -611,6 +596,23 @@ $var: 1;
|
|
611
596
|
SCSS
|
612
597
|
end
|
613
598
|
|
599
|
+
def test_setting_global_variable_locally_warns_only_once
|
600
|
+
assert_warning(<<WARNING) {assert_equal(<<CSS, render(<<SCSS, :syntax => :scss))}
|
601
|
+
DEPRECATION WARNING on line 3 of test_setting_global_variable_locally_warns_only_once_inline.scss:
|
602
|
+
Assigning to global variable "$var" by default is deprecated.
|
603
|
+
In future versions of Sass, this will create a new local variable.
|
604
|
+
If you want to assign to the global variable, use "$var: x !global" instead.
|
605
|
+
WARNING
|
606
|
+
CSS
|
607
|
+
$var: 1;
|
608
|
+
|
609
|
+
@mixin foo {$var: x}
|
610
|
+
@include foo;
|
611
|
+
@include foo;
|
612
|
+
@include foo;
|
613
|
+
SCSS
|
614
|
+
end
|
615
|
+
|
614
616
|
def test_setting_global_variable_globally
|
615
617
|
assert_no_warning {assert_equal(<<CSS, render(<<SCSS, :syntax => :scss))}
|
616
618
|
.foo {
|
@@ -686,6 +688,34 @@ SCSS
|
|
686
688
|
|
687
689
|
# Regression Tests
|
688
690
|
|
691
|
+
def test_minus_without_whitespace
|
692
|
+
assert_equal "5px", resolve("15px-10px")
|
693
|
+
end
|
694
|
+
|
695
|
+
def test_user_defined_function_forces_division
|
696
|
+
assert_equal(<<CSS, render(<<SASS))
|
697
|
+
a {
|
698
|
+
b: 10px; }
|
699
|
+
CSS
|
700
|
+
@function foo()
|
701
|
+
@return 20px
|
702
|
+
|
703
|
+
a
|
704
|
+
b: (foo() / 2)
|
705
|
+
SASS
|
706
|
+
|
707
|
+
assert_equal(<<CSS, render(<<SASS))
|
708
|
+
a {
|
709
|
+
b: 10px; }
|
710
|
+
CSS
|
711
|
+
@function foo()
|
712
|
+
@return 20px
|
713
|
+
|
714
|
+
a
|
715
|
+
b: foo() / 2
|
716
|
+
SASS
|
717
|
+
end
|
718
|
+
|
689
719
|
def test_funcall_has_higher_precedence_than_color_name
|
690
720
|
assert_equal "teal(12)", resolve("teal(12)")
|
691
721
|
assert_equal "tealbang(12)", resolve("tealbang(12)")
|
@@ -693,6 +723,13 @@ SCSS
|
|
693
723
|
assert_equal "teal\\+bang(12)", resolve("teal\\+bang(12)")
|
694
724
|
end
|
695
725
|
|
726
|
+
def test_funcall_has_higher_precedence_than_true_false_null
|
727
|
+
assert_equal "teal(12)", resolve("teal(12)")
|
728
|
+
assert_equal "tealbang(12)", resolve("tealbang(12)")
|
729
|
+
assert_equal "teal-bang(12)", resolve("teal-bang(12)")
|
730
|
+
assert_equal "teal\\+bang(12)", resolve("teal\\+bang(12)")
|
731
|
+
end
|
732
|
+
|
696
733
|
def test_interpolation_after_hash
|
697
734
|
assert_equal "#2", resolve('"##{1 + 1}"')
|
698
735
|
end
|
data/test/sass/scss/css_test.rb
CHANGED
@@ -505,13 +505,20 @@ SCSS
|
|
505
505
|
assert_parses '@import url(foo.css);'
|
506
506
|
end
|
507
507
|
|
508
|
-
def
|
508
|
+
def test_string_import_directive_with_media
|
509
509
|
assert_parses '@import "foo.css" screen;'
|
510
510
|
assert_parses '@import "foo.css" screen, print;'
|
511
511
|
assert_parses '@import "foo.css" screen, print and (foo: 0);'
|
512
512
|
assert_parses '@import "foo.css" screen, only print, screen and (foo: 0);'
|
513
513
|
end
|
514
514
|
|
515
|
+
def test_url_import_directive_with_media
|
516
|
+
assert_parses '@import url("foo.css") screen;'
|
517
|
+
assert_parses '@import url("foo.css") screen, print;'
|
518
|
+
assert_parses '@import url("foo.css") screen, print and (foo: 0);'
|
519
|
+
assert_parses '@import url("foo.css") screen, only print, screen and (foo: 0);'
|
520
|
+
end
|
521
|
+
|
515
522
|
def test_page_directive
|
516
523
|
assert_parses <<SCSS
|
517
524
|
@page {
|
data/test/sass/scss/scss_test.rb
CHANGED
@@ -163,6 +163,51 @@ CSS
|
|
163
163
|
SCSS
|
164
164
|
end
|
165
165
|
|
166
|
+
def test_for_directive_with_same_start_and_end
|
167
|
+
assert_equal <<CSS, render(<<SCSS)
|
168
|
+
CSS
|
169
|
+
.foo {
|
170
|
+
@for $var from 1 to 1 {a: $var;}
|
171
|
+
}
|
172
|
+
SCSS
|
173
|
+
|
174
|
+
assert_equal <<CSS, render(<<SCSS)
|
175
|
+
.foo {
|
176
|
+
a: 1; }
|
177
|
+
CSS
|
178
|
+
.foo {
|
179
|
+
@for $var from 1 through 1 {a: $var;}
|
180
|
+
}
|
181
|
+
SCSS
|
182
|
+
end
|
183
|
+
|
184
|
+
def test_decrementing_estfor_directive
|
185
|
+
assert_equal <<CSS, render(<<SCSS)
|
186
|
+
.foo {
|
187
|
+
a: 5;
|
188
|
+
a: 4;
|
189
|
+
a: 3;
|
190
|
+
a: 2;
|
191
|
+
a: 1; }
|
192
|
+
CSS
|
193
|
+
.foo {
|
194
|
+
@for $var from 5 through 1 {a: $var;}
|
195
|
+
}
|
196
|
+
SCSS
|
197
|
+
|
198
|
+
assert_equal <<CSS, render(<<SCSS)
|
199
|
+
.foo {
|
200
|
+
a: 5;
|
201
|
+
a: 4;
|
202
|
+
a: 3;
|
203
|
+
a: 2; }
|
204
|
+
CSS
|
205
|
+
.foo {
|
206
|
+
@for $var from 5 to 1 {a: $var;}
|
207
|
+
}
|
208
|
+
SCSS
|
209
|
+
end
|
210
|
+
|
166
211
|
def test_if_directive
|
167
212
|
assert_equal <<CSS, render(<<SCSS)
|
168
213
|
foo {
|
@@ -295,6 +340,20 @@ SCSS
|
|
295
340
|
assert_equal "@import url(foo.css);\n", render('@import url(foo.css);')
|
296
341
|
end
|
297
342
|
|
343
|
+
def test_css_string_import_directive_with_media
|
344
|
+
assert_parses '@import "foo.css" screen;'
|
345
|
+
assert_parses '@import "foo.css" screen, print;'
|
346
|
+
assert_parses '@import "foo.css" screen, print and (foo: 0);'
|
347
|
+
assert_parses '@import "foo.css" screen, only print, screen and (foo: 0);'
|
348
|
+
end
|
349
|
+
|
350
|
+
def test_css_url_import_directive_with_media
|
351
|
+
assert_parses '@import url("foo.css") screen;'
|
352
|
+
assert_parses '@import url("foo.css") screen, print;'
|
353
|
+
assert_parses '@import url("foo.css") screen, print and (foo: 0);'
|
354
|
+
assert_parses '@import url("foo.css") screen, only print, screen and (foo: 0);'
|
355
|
+
end
|
356
|
+
|
298
357
|
def test_media_import
|
299
358
|
assert_equal("@import \"./fonts.sass\" all;\n", render("@import \"./fonts.sass\" all;"))
|
300
359
|
end
|
@@ -333,6 +392,44 @@ SCSS
|
|
333
392
|
assert_equal("@import url(fonts.sass);\n", render("@import url(fonts.sass);"))
|
334
393
|
end
|
335
394
|
|
395
|
+
def test_css_import_doesnt_move_through_comments
|
396
|
+
assert_equal <<CSS, render(<<SCSS)
|
397
|
+
/* Comment 1 */
|
398
|
+
@import url("foo.css");
|
399
|
+
/* Comment 2 */
|
400
|
+
@import url("bar.css");
|
401
|
+
CSS
|
402
|
+
/* Comment 1 */
|
403
|
+
@import url("foo.css");
|
404
|
+
|
405
|
+
/* Comment 2 */
|
406
|
+
@import url("bar.css");
|
407
|
+
SCSS
|
408
|
+
end
|
409
|
+
|
410
|
+
def test_css_import_movement_stops_at_comments
|
411
|
+
assert_equal <<CSS, render(<<SCSS)
|
412
|
+
/* Comment 1 */
|
413
|
+
@import url("foo.css");
|
414
|
+
/* Comment 2 */
|
415
|
+
@import url("bar.css");
|
416
|
+
.foo {
|
417
|
+
a: b; }
|
418
|
+
|
419
|
+
/* Comment 3 */
|
420
|
+
CSS
|
421
|
+
/* Comment 1 */
|
422
|
+
@import url("foo.css");
|
423
|
+
|
424
|
+
/* Comment 2 */
|
425
|
+
|
426
|
+
.foo {a: b}
|
427
|
+
|
428
|
+
/* Comment 3 */
|
429
|
+
@import url("bar.css");
|
430
|
+
SCSS
|
431
|
+
end
|
432
|
+
|
336
433
|
def test_block_comment_in_script
|
337
434
|
assert_equal <<CSS, render(<<SCSS)
|
338
435
|
foo {
|
@@ -563,6 +660,33 @@ foo bar {
|
|
563
660
|
SCSS
|
564
661
|
end
|
565
662
|
|
663
|
+
def test_parent_selector_with_suffix
|
664
|
+
assert_equal <<CSS, render(<<SCSS)
|
665
|
+
.foo-bar {
|
666
|
+
a: b; }
|
667
|
+
.foo_bar {
|
668
|
+
c: d; }
|
669
|
+
.foobar {
|
670
|
+
e: f; }
|
671
|
+
.foo123 {
|
672
|
+
e: f; }
|
673
|
+
|
674
|
+
:hover-suffix {
|
675
|
+
g: h; }
|
676
|
+
CSS
|
677
|
+
.foo {
|
678
|
+
&-bar {a: b}
|
679
|
+
&_bar {c: d}
|
680
|
+
&bar {e: f}
|
681
|
+
&123 {e: f}
|
682
|
+
}
|
683
|
+
|
684
|
+
:hover {
|
685
|
+
&-suffix {g: h}
|
686
|
+
}
|
687
|
+
SCSS
|
688
|
+
end
|
689
|
+
|
566
690
|
def test_unknown_directive_bubbling
|
567
691
|
assert_equal(<<CSS, render(<<SCSS, :style => :nested))
|
568
692
|
@fblthp {
|
@@ -1174,6 +1298,49 @@ CSS
|
|
1174
1298
|
SCSS
|
1175
1299
|
end
|
1176
1300
|
|
1301
|
+
def test_mixin_map_splat_converts_hyphens_and_underscores_for_real_args
|
1302
|
+
assert_equal <<CSS, render(<<SCSS)
|
1303
|
+
.foo {
|
1304
|
+
a: 1;
|
1305
|
+
b: 2;
|
1306
|
+
c: 3;
|
1307
|
+
d: 4; }
|
1308
|
+
CSS
|
1309
|
+
@mixin foo($a-1, $b-2, $c_3, $d_4) {
|
1310
|
+
a: $a-1;
|
1311
|
+
b: $b-2;
|
1312
|
+
c: $c_3;
|
1313
|
+
d: $d_4;
|
1314
|
+
}
|
1315
|
+
|
1316
|
+
.foo {
|
1317
|
+
$map: (a-1: 1, b_2: 2, c-3: 3, d_4: 4);
|
1318
|
+
@include foo($map...);
|
1319
|
+
}
|
1320
|
+
SCSS
|
1321
|
+
end
|
1322
|
+
|
1323
|
+
def test_mixin_map_splat_doesnt_convert_hyphens_and_underscores_for_var_args
|
1324
|
+
assert_equal <<CSS, render(<<SCSS)
|
1325
|
+
.foo {
|
1326
|
+
a-1: 1;
|
1327
|
+
b_2: 2;
|
1328
|
+
c-3: 3;
|
1329
|
+
d_4: 4; }
|
1330
|
+
CSS
|
1331
|
+
@mixin foo($args...) {
|
1332
|
+
@each $key, $value in keywords($args) {
|
1333
|
+
\#{$key}: $value;
|
1334
|
+
}
|
1335
|
+
}
|
1336
|
+
|
1337
|
+
.foo {
|
1338
|
+
$map: (a-1: 1, b_2: 2, c-3: 3, d_4: 4);
|
1339
|
+
@include foo($map...);
|
1340
|
+
}
|
1341
|
+
SCSS
|
1342
|
+
end
|
1343
|
+
|
1177
1344
|
def test_mixin_conflicting_splat_after_keyword_args
|
1178
1345
|
assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render(<<SCSS)}
|
1179
1346
|
Mixin foo was passed argument $b both by position and by name.
|
@@ -2167,6 +2334,123 @@ CSS
|
|
2167
2334
|
SCSS
|
2168
2335
|
end
|
2169
2336
|
|
2337
|
+
def test_comments_in_at_root
|
2338
|
+
assert_equal <<CSS, render(<<SCSS)
|
2339
|
+
/* foo */
|
2340
|
+
.bar {
|
2341
|
+
a: b; }
|
2342
|
+
|
2343
|
+
/* baz */
|
2344
|
+
CSS
|
2345
|
+
.foo {
|
2346
|
+
@at-root {
|
2347
|
+
/* foo */
|
2348
|
+
.bar {a: b}
|
2349
|
+
/* baz */
|
2350
|
+
}
|
2351
|
+
}
|
2352
|
+
SCSS
|
2353
|
+
end
|
2354
|
+
|
2355
|
+
def test_comments_in_at_root_in_media
|
2356
|
+
assert_equal <<CSS, render(<<SCSS)
|
2357
|
+
@media screen {
|
2358
|
+
/* foo */
|
2359
|
+
.bar {
|
2360
|
+
a: b; }
|
2361
|
+
|
2362
|
+
/* baz */ }
|
2363
|
+
CSS
|
2364
|
+
@media screen {
|
2365
|
+
.foo {
|
2366
|
+
@at-root {
|
2367
|
+
/* foo */
|
2368
|
+
.bar {a: b}
|
2369
|
+
/* baz */
|
2370
|
+
}
|
2371
|
+
}
|
2372
|
+
}
|
2373
|
+
SCSS
|
2374
|
+
end
|
2375
|
+
|
2376
|
+
def test_comments_in_at_root_in_unknown_directive
|
2377
|
+
assert_equal <<CSS, render(<<SCSS)
|
2378
|
+
@fblthp {
|
2379
|
+
/* foo */
|
2380
|
+
.bar {
|
2381
|
+
a: b; }
|
2382
|
+
|
2383
|
+
/* baz */ }
|
2384
|
+
CSS
|
2385
|
+
@fblthp {
|
2386
|
+
.foo {
|
2387
|
+
@at-root {
|
2388
|
+
/* foo */
|
2389
|
+
.bar {a: b}
|
2390
|
+
/* baz */
|
2391
|
+
}
|
2392
|
+
}
|
2393
|
+
}
|
2394
|
+
SCSS
|
2395
|
+
end
|
2396
|
+
|
2397
|
+
def test_media_directive_in_at_root
|
2398
|
+
assert_equal <<CSS, render(<<SCSS)
|
2399
|
+
@media screen {
|
2400
|
+
.bar {
|
2401
|
+
a: b; } }
|
2402
|
+
CSS
|
2403
|
+
.foo {
|
2404
|
+
@at-root {
|
2405
|
+
@media screen {.bar {a: b}}
|
2406
|
+
}
|
2407
|
+
}
|
2408
|
+
SCSS
|
2409
|
+
end
|
2410
|
+
|
2411
|
+
def test_bubbled_media_directive_in_at_root
|
2412
|
+
assert_equal <<CSS, render(<<SCSS)
|
2413
|
+
@media screen {
|
2414
|
+
.bar .baz {
|
2415
|
+
a: b; } }
|
2416
|
+
CSS
|
2417
|
+
.foo {
|
2418
|
+
@at-root {
|
2419
|
+
.bar {
|
2420
|
+
@media screen {.baz {a: b}}
|
2421
|
+
}
|
2422
|
+
}
|
2423
|
+
}
|
2424
|
+
SCSS
|
2425
|
+
end
|
2426
|
+
|
2427
|
+
def test_unknown_directive_in_at_root
|
2428
|
+
assert_equal <<CSS, render(<<SCSS)
|
2429
|
+
@fblthp {
|
2430
|
+
.bar {
|
2431
|
+
a: b; } }
|
2432
|
+
CSS
|
2433
|
+
.foo {
|
2434
|
+
@at-root {
|
2435
|
+
@fblthp {.bar {a: b}}
|
2436
|
+
}
|
2437
|
+
}
|
2438
|
+
SCSS
|
2439
|
+
end
|
2440
|
+
|
2441
|
+
def test_at_root_in_at_root
|
2442
|
+
assert_equal <<CSS, render(<<SCSS)
|
2443
|
+
.bar {
|
2444
|
+
a: b; }
|
2445
|
+
CSS
|
2446
|
+
.foo {
|
2447
|
+
@at-root {
|
2448
|
+
@at-root .bar {a: b}
|
2449
|
+
}
|
2450
|
+
}
|
2451
|
+
SCSS
|
2452
|
+
end
|
2453
|
+
|
2170
2454
|
def test_at_root_with_parent_ref
|
2171
2455
|
assert_equal <<CSS, render(<<SCSS)
|
2172
2456
|
.foo {
|
@@ -2212,6 +2496,45 @@ CSS
|
|
2212
2496
|
SCSS
|
2213
2497
|
end
|
2214
2498
|
|
2499
|
+
def test_at_root_beneath_comma_selector
|
2500
|
+
assert_equal(<<CSS, render(<<SCSS))
|
2501
|
+
.baz {
|
2502
|
+
a: b; }
|
2503
|
+
CSS
|
2504
|
+
.foo, .bar {
|
2505
|
+
@at-root .baz {
|
2506
|
+
a: b;
|
2507
|
+
}
|
2508
|
+
}
|
2509
|
+
SCSS
|
2510
|
+
end
|
2511
|
+
|
2512
|
+
def test_at_root_with_parent_ref_and_class
|
2513
|
+
assert_equal(<<CSS, render(<<SCSS))
|
2514
|
+
.foo.bar {
|
2515
|
+
a: b; }
|
2516
|
+
CSS
|
2517
|
+
.foo {
|
2518
|
+
@at-root &.bar {
|
2519
|
+
a: b;
|
2520
|
+
}
|
2521
|
+
}
|
2522
|
+
SCSS
|
2523
|
+
end
|
2524
|
+
|
2525
|
+
def test_at_root_beneath_comma_selector_with_parent_ref
|
2526
|
+
assert_equal(<<CSS, render(<<SCSS))
|
2527
|
+
.foo.baz, .bar.baz {
|
2528
|
+
a: b; }
|
2529
|
+
CSS
|
2530
|
+
.foo, .bar {
|
2531
|
+
@at-root &.baz {
|
2532
|
+
a: b;
|
2533
|
+
}
|
2534
|
+
}
|
2535
|
+
SCSS
|
2536
|
+
end
|
2537
|
+
|
2215
2538
|
## @at-root (...)
|
2216
2539
|
|
2217
2540
|
def test_at_root_without_media
|
@@ -2268,6 +2591,7 @@ SCSS
|
|
2268
2591
|
|
2269
2592
|
def test_at_root_without_unknown_directive
|
2270
2593
|
assert_equal <<CSS, render(<<SCSS)
|
2594
|
+
@fblthp {}
|
2271
2595
|
.foo .bar {
|
2272
2596
|
a: b; }
|
2273
2597
|
CSS
|
@@ -2305,6 +2629,8 @@ SCSS
|
|
2305
2629
|
|
2306
2630
|
def test_at_root_without_all
|
2307
2631
|
assert_equal <<CSS, render(<<SCSS)
|
2632
|
+
@supports (foo: bar) {
|
2633
|
+
@fblthp {} }
|
2308
2634
|
.bar {
|
2309
2635
|
a: b; }
|
2310
2636
|
CSS
|
@@ -2325,6 +2651,7 @@ SCSS
|
|
2325
2651
|
def test_at_root_with_media
|
2326
2652
|
assert_equal <<CSS, render(<<SCSS)
|
2327
2653
|
@media screen {
|
2654
|
+
@fblthp {}
|
2328
2655
|
.bar {
|
2329
2656
|
a: b; } }
|
2330
2657
|
CSS
|
@@ -2346,6 +2673,8 @@ SCSS
|
|
2346
2673
|
|
2347
2674
|
def test_at_root_with_rule
|
2348
2675
|
assert_equal <<CSS, render(<<SCSS)
|
2676
|
+
@media screen {
|
2677
|
+
@fblthp {} }
|
2349
2678
|
.foo .bar {
|
2350
2679
|
a: b; }
|
2351
2680
|
CSS
|
@@ -2367,6 +2696,8 @@ SCSS
|
|
2367
2696
|
|
2368
2697
|
def test_at_root_with_supports
|
2369
2698
|
assert_equal <<CSS, render(<<SCSS)
|
2699
|
+
@media screen {
|
2700
|
+
@fblthp {} }
|
2370
2701
|
@supports (foo: bar) {
|
2371
2702
|
.bar {
|
2372
2703
|
a: b; } }
|
@@ -2389,6 +2720,8 @@ SCSS
|
|
2389
2720
|
|
2390
2721
|
def test_at_root_with_unknown_directive
|
2391
2722
|
assert_equal <<CSS, render(<<SCSS)
|
2723
|
+
@media screen {
|
2724
|
+
@fblthp {} }
|
2392
2725
|
@fblthp {
|
2393
2726
|
.bar {
|
2394
2727
|
a: b; } }
|
@@ -2412,6 +2745,7 @@ SCSS
|
|
2412
2745
|
def test_at_root_with_multiple
|
2413
2746
|
assert_equal <<CSS, render(<<SCSS)
|
2414
2747
|
@media screen {
|
2748
|
+
@fblthp {}
|
2415
2749
|
.foo .bar {
|
2416
2750
|
a: b; } }
|
2417
2751
|
CSS
|
@@ -2514,185 +2848,6 @@ CSS
|
|
2514
2848
|
SCSS
|
2515
2849
|
end
|
2516
2850
|
|
2517
|
-
## Selector Script
|
2518
|
-
|
2519
|
-
def test_selector_script
|
2520
|
-
assert_equal(<<CSS, render(<<SCSS))
|
2521
|
-
.foo .bar {
|
2522
|
-
content: ".foo .bar"; }
|
2523
|
-
CSS
|
2524
|
-
.foo .bar {
|
2525
|
-
content: "\#{&}";
|
2526
|
-
}
|
2527
|
-
SCSS
|
2528
|
-
end
|
2529
|
-
|
2530
|
-
def test_nested_selector_script
|
2531
|
-
assert_equal(<<CSS, render(<<SCSS))
|
2532
|
-
.foo .bar {
|
2533
|
-
content: ".foo .bar"; }
|
2534
|
-
CSS
|
2535
|
-
.foo {
|
2536
|
-
.bar {
|
2537
|
-
content: "\#{&}";
|
2538
|
-
}
|
2539
|
-
}
|
2540
|
-
SCSS
|
2541
|
-
end
|
2542
|
-
|
2543
|
-
def test_nested_selector_script_with_outer_comma_selector
|
2544
|
-
assert_equal(<<CSS, render(<<SCSS))
|
2545
|
-
.foo .baz, .bar .baz {
|
2546
|
-
content: ".foo .baz, .bar .baz"; }
|
2547
|
-
CSS
|
2548
|
-
.foo, .bar {
|
2549
|
-
.baz {
|
2550
|
-
content: "\#{&}";
|
2551
|
-
}
|
2552
|
-
}
|
2553
|
-
SCSS
|
2554
|
-
end
|
2555
|
-
|
2556
|
-
def test_nested_selector_script_with_inner_comma_selector
|
2557
|
-
assert_equal(<<CSS, render(<<SCSS))
|
2558
|
-
.foo .bar, .foo .baz {
|
2559
|
-
content: ".foo .bar, .foo .baz"; }
|
2560
|
-
CSS
|
2561
|
-
.foo {
|
2562
|
-
.bar, .baz {
|
2563
|
-
content: "\#{&}";
|
2564
|
-
}
|
2565
|
-
}
|
2566
|
-
SCSS
|
2567
|
-
end
|
2568
|
-
|
2569
|
-
def test_selector_script_through_mixin
|
2570
|
-
assert_equal(<<CSS, render(<<SCSS))
|
2571
|
-
.foo {
|
2572
|
-
content: ".foo"; }
|
2573
|
-
CSS
|
2574
|
-
@mixin mixin {
|
2575
|
-
content: "\#{&}";
|
2576
|
-
}
|
2577
|
-
|
2578
|
-
.foo {
|
2579
|
-
@include mixin;
|
2580
|
-
}
|
2581
|
-
SCSS
|
2582
|
-
end
|
2583
|
-
|
2584
|
-
def test_selector_script_through_content
|
2585
|
-
assert_equal(<<CSS, render(<<SCSS))
|
2586
|
-
.foo {
|
2587
|
-
content: ".foo"; }
|
2588
|
-
CSS
|
2589
|
-
@mixin mixin {
|
2590
|
-
@content;
|
2591
|
-
}
|
2592
|
-
|
2593
|
-
.foo {
|
2594
|
-
@include mixin {
|
2595
|
-
content: "\#{&}";
|
2596
|
-
}
|
2597
|
-
}
|
2598
|
-
SCSS
|
2599
|
-
end
|
2600
|
-
|
2601
|
-
def test_selector_script_through_function
|
2602
|
-
assert_equal(<<CSS, render(<<SCSS))
|
2603
|
-
.foo {
|
2604
|
-
content: ".foo"; }
|
2605
|
-
CSS
|
2606
|
-
@function fn() {
|
2607
|
-
@return "\#{&}";
|
2608
|
-
}
|
2609
|
-
|
2610
|
-
.foo {
|
2611
|
-
content: fn();
|
2612
|
-
}
|
2613
|
-
SCSS
|
2614
|
-
end
|
2615
|
-
|
2616
|
-
def test_selector_script_through_media
|
2617
|
-
assert_equal(<<CSS, render(<<SCSS))
|
2618
|
-
.foo {
|
2619
|
-
content: "outer"; }
|
2620
|
-
@media screen {
|
2621
|
-
.foo .bar {
|
2622
|
-
content: ".foo .bar"; } }
|
2623
|
-
CSS
|
2624
|
-
.foo {
|
2625
|
-
content: "outer";
|
2626
|
-
@media screen {
|
2627
|
-
.bar {
|
2628
|
-
content: "\#{&}";
|
2629
|
-
}
|
2630
|
-
}
|
2631
|
-
}
|
2632
|
-
SCSS
|
2633
|
-
end
|
2634
|
-
|
2635
|
-
def test_selector_script_save_and_reuse
|
2636
|
-
assert_equal(<<CSS, render(<<SCSS))
|
2637
|
-
.bar {
|
2638
|
-
content: ".foo"; }
|
2639
|
-
CSS
|
2640
|
-
$var: null;
|
2641
|
-
.foo {
|
2642
|
-
$var: & !global;
|
2643
|
-
}
|
2644
|
-
|
2645
|
-
.bar {
|
2646
|
-
content: "\#{$var}";
|
2647
|
-
}
|
2648
|
-
SCSS
|
2649
|
-
end
|
2650
|
-
|
2651
|
-
def test_selector_script_with_at_root
|
2652
|
-
assert_equal(<<CSS, render(<<SCSS))
|
2653
|
-
.foo-bar {
|
2654
|
-
a: b; }
|
2655
|
-
CSS
|
2656
|
-
.foo {
|
2657
|
-
@at-root \#{&}-bar {
|
2658
|
-
a: b;
|
2659
|
-
}
|
2660
|
-
}
|
2661
|
-
SCSS
|
2662
|
-
end
|
2663
|
-
|
2664
|
-
def test_multi_level_at_root_with_inner_selector_script
|
2665
|
-
assert_equal <<CSS, render(<<SCSS)
|
2666
|
-
.bar {
|
2667
|
-
a: b; }
|
2668
|
-
CSS
|
2669
|
-
.foo {
|
2670
|
-
@at-root .bar {
|
2671
|
-
@at-root \#{&} {
|
2672
|
-
a: b;
|
2673
|
-
}
|
2674
|
-
}
|
2675
|
-
}
|
2676
|
-
SCSS
|
2677
|
-
end
|
2678
|
-
|
2679
|
-
def test_at_root_with_at_root_through_mixin
|
2680
|
-
assert_equal(<<CSS, render(<<SCSS))
|
2681
|
-
.bar-baz {
|
2682
|
-
a: b; }
|
2683
|
-
CSS
|
2684
|
-
@mixin foo {
|
2685
|
-
.bar {
|
2686
|
-
@at-root \#{&}-baz {
|
2687
|
-
a: b;
|
2688
|
-
}
|
2689
|
-
}
|
2690
|
-
}
|
2691
|
-
|
2692
|
-
@include foo;
|
2693
|
-
SCSS
|
2694
|
-
end
|
2695
|
-
|
2696
2851
|
## Errors
|
2697
2852
|
|
2698
2853
|
def test_nested_mixin_def_is_scoped
|
@@ -2901,6 +3056,48 @@ MESSAGE
|
|
2901
3056
|
SCSS
|
2902
3057
|
end
|
2903
3058
|
|
3059
|
+
def test_failed_parent_selector_with_suffix
|
3060
|
+
assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render(<<SCSS)}
|
3061
|
+
Invalid parent selector for "&-bar": "*"
|
3062
|
+
MESSAGE
|
3063
|
+
* {
|
3064
|
+
&-bar {a: b}
|
3065
|
+
}
|
3066
|
+
SCSS
|
3067
|
+
|
3068
|
+
assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render(<<SCSS)}
|
3069
|
+
Invalid parent selector for "&-bar": "[foo=bar]"
|
3070
|
+
MESSAGE
|
3071
|
+
[foo=bar] {
|
3072
|
+
&-bar {a: b}
|
3073
|
+
}
|
3074
|
+
SCSS
|
3075
|
+
|
3076
|
+
assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render(<<SCSS)}
|
3077
|
+
Invalid parent selector for "&-bar": "::nth-child(2n+1)"
|
3078
|
+
MESSAGE
|
3079
|
+
::nth-child(2n+1) {
|
3080
|
+
&-bar {a: b}
|
3081
|
+
}
|
3082
|
+
SCSS
|
3083
|
+
|
3084
|
+
assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render(<<SCSS)}
|
3085
|
+
Invalid parent selector for "&-bar": ":not(.foo)"
|
3086
|
+
MESSAGE
|
3087
|
+
:not(.foo) {
|
3088
|
+
&-bar {a: b}
|
3089
|
+
}
|
3090
|
+
SCSS
|
3091
|
+
|
3092
|
+
assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render(<<SCSS)}
|
3093
|
+
Invalid parent selector for "&-bar": ".foo +"
|
3094
|
+
MESSAGE
|
3095
|
+
.foo + {
|
3096
|
+
&-bar {a: b}
|
3097
|
+
}
|
3098
|
+
SCSS
|
3099
|
+
end
|
3100
|
+
|
2904
3101
|
# Regression
|
2905
3102
|
|
2906
3103
|
def test_loud_comment_in_compressed_mode
|