sass 3.3.14 → 3.4.0.rc.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.
- checksums.yaml +4 -4
- data/MIT-LICENSE +1 -1
- data/README.md +5 -5
- data/VERSION +1 -1
- data/VERSION_DATE +1 -1
- data/VERSION_NAME +1 -1
- data/bin/sass +1 -1
- data/bin/scss +1 -1
- data/lib/sass.rb +0 -5
- data/lib/sass/css.rb +1 -3
- data/lib/sass/engine.rb +28 -39
- data/lib/sass/environment.rb +13 -17
- data/lib/sass/error.rb +6 -9
- data/lib/sass/exec.rb +5 -771
- data/lib/sass/exec/base.rb +187 -0
- data/lib/sass/exec/sass_convert.rb +264 -0
- data/lib/sass/exec/sass_scss.rb +419 -0
- data/lib/sass/features.rb +6 -0
- data/lib/sass/importers.rb +0 -1
- data/lib/sass/importers/base.rb +5 -1
- data/lib/sass/importers/filesystem.rb +4 -21
- data/lib/sass/media.rb +1 -4
- data/lib/sass/plugin/compiler.rb +32 -136
- data/lib/sass/script/css_lexer.rb +1 -1
- data/lib/sass/script/functions.rb +363 -39
- data/lib/sass/script/lexer.rb +68 -50
- data/lib/sass/script/parser.rb +29 -14
- data/lib/sass/script/tree.rb +1 -0
- data/lib/sass/script/tree/funcall.rb +1 -1
- data/lib/sass/script/tree/interpolation.rb +19 -1
- data/lib/sass/script/tree/selector.rb +26 -0
- data/lib/sass/script/value.rb +0 -1
- data/lib/sass/script/value/bool.rb +0 -5
- data/lib/sass/script/value/color.rb +32 -12
- data/lib/sass/script/value/helpers.rb +107 -0
- data/lib/sass/script/value/list.rb +0 -15
- data/lib/sass/script/value/null.rb +0 -5
- data/lib/sass/script/value/number.rb +60 -14
- data/lib/sass/script/value/string.rb +53 -9
- data/lib/sass/scss/css_parser.rb +8 -2
- data/lib/sass/scss/parser.rb +175 -319
- data/lib/sass/scss/rx.rb +14 -5
- data/lib/sass/scss/static_parser.rb +298 -1
- data/lib/sass/selector.rb +56 -193
- data/lib/sass/selector/abstract_sequence.rb +28 -13
- data/lib/sass/selector/comma_sequence.rb +91 -12
- data/lib/sass/selector/pseudo.rb +256 -0
- data/lib/sass/selector/sequence.rb +99 -31
- data/lib/sass/selector/simple.rb +14 -25
- data/lib/sass/selector/simple_sequence.rb +101 -37
- data/lib/sass/shared.rb +1 -1
- data/lib/sass/source/map.rb +23 -9
- data/lib/sass/stack.rb +0 -6
- data/lib/sass/supports.rb +1 -1
- data/lib/sass/tree/at_root_node.rb +1 -0
- data/lib/sass/tree/directive_node.rb +7 -1
- data/lib/sass/tree/error_node.rb +18 -0
- data/lib/sass/tree/keyframe_rule_node.rb +15 -0
- data/lib/sass/tree/prop_node.rb +1 -1
- data/lib/sass/tree/rule_node.rb +11 -6
- data/lib/sass/tree/visitors/check_nesting.rb +3 -4
- data/lib/sass/tree/visitors/convert.rb +8 -17
- data/lib/sass/tree/visitors/cssize.rb +12 -24
- data/lib/sass/tree/visitors/deep_copy.rb +5 -0
- data/lib/sass/tree/visitors/perform.rb +43 -28
- data/lib/sass/tree/visitors/set_options.rb +5 -0
- data/lib/sass/tree/visitors/to_css.rb +14 -13
- data/lib/sass/util.rb +94 -90
- data/test/sass/cache_test.rb +1 -1
- data/test/sass/callbacks_test.rb +1 -1
- data/test/sass/compiler_test.rb +5 -14
- data/test/sass/conversion_test.rb +47 -1
- data/test/sass/css2sass_test.rb +3 -3
- data/test/sass/encoding_test.rb +219 -0
- data/test/sass/engine_test.rb +128 -191
- data/test/sass/exec_test.rb +2 -2
- data/test/sass/extend_test.rb +234 -17
- data/test/sass/functions_test.rb +268 -213
- data/test/sass/importer_test.rb +31 -21
- data/test/sass/logger_test.rb +1 -1
- data/test/sass/more_results/more_import.css +1 -1
- data/test/sass/plugin_test.rb +12 -11
- data/test/sass/results/compact.css +1 -1
- data/test/sass/results/complex.css +4 -4
- data/test/sass/results/expanded.css +1 -1
- data/test/sass/results/import.css +1 -1
- data/test/sass/results/import_charset_ibm866.css +2 -2
- data/test/sass/results/mixins.css +17 -17
- data/test/sass/results/nested.css +1 -1
- data/test/sass/results/parent_ref.css +2 -2
- data/test/sass/results/script.css +3 -3
- data/test/sass/results/scss_import.css +1 -1
- data/test/sass/script_conversion_test.rb +7 -4
- data/test/sass/script_test.rb +202 -79
- data/test/sass/scss/css_test.rb +95 -25
- data/test/sass/scss/rx_test.rb +4 -4
- data/test/sass/scss/scss_test.rb +363 -19
- data/test/sass/source_map_test.rb +48 -41
- data/test/sass/superselector_test.rb +191 -0
- data/test/sass/templates/scss_import.scss +2 -1
- data/test/sass/test_helper.rb +1 -1
- data/test/sass/util/multibyte_string_scanner_test.rb +1 -1
- data/test/sass/util/normalized_map_test.rb +1 -1
- data/test/sass/util/subset_map_test.rb +2 -2
- data/test/sass/util_test.rb +1 -1
- data/test/sass/value_helpers_test.rb +3 -3
- data/test/test_helper.rb +2 -2
- metadata +30 -7
- data/lib/sass/importers/deprecated_path.rb +0 -51
- data/lib/sass/script/value/deprecated_false.rb +0 -55
data/test/sass/scss/css_test.rb
CHANGED
@@ -6,7 +6,7 @@ require 'sass/scss/css_parser'
|
|
6
6
|
# These tests just test the parsing of CSS
|
7
7
|
# (both standard and any hacks we intend to support).
|
8
8
|
# Tests of SCSS-specific behavior go in scss_test.rb.
|
9
|
-
class ScssCssTest < Test
|
9
|
+
class ScssCssTest < MiniTest::Test
|
10
10
|
include ScssTestHelper
|
11
11
|
|
12
12
|
def test_basic_scss
|
@@ -499,10 +499,24 @@ SCSS
|
|
499
499
|
|
500
500
|
def test_import_directive
|
501
501
|
assert_parses '@import "foo.css";'
|
502
|
-
assert_parses "@import 'foo.css';"
|
503
502
|
assert_parses '@import url("foo.css");'
|
504
503
|
assert_parses "@import url('foo.css');"
|
505
504
|
assert_parses '@import url(foo.css);'
|
505
|
+
|
506
|
+
assert_equal <<CSS, render(<<SCSS)
|
507
|
+
@import "foo.css";
|
508
|
+
CSS
|
509
|
+
@import 'foo.css';
|
510
|
+
SCSS
|
511
|
+
end
|
512
|
+
|
513
|
+
def test_import_directive_with_backslash_newline
|
514
|
+
assert_equal <<CSS, render(<<SCSS)
|
515
|
+
@import "foobar.css";
|
516
|
+
CSS
|
517
|
+
@import "foo\\
|
518
|
+
bar.css";
|
519
|
+
SCSS
|
506
520
|
end
|
507
521
|
|
508
522
|
def test_string_import_directive_with_media
|
@@ -659,13 +673,10 @@ SCSS
|
|
659
673
|
0% {
|
660
674
|
top: 0;
|
661
675
|
left: 0; }
|
662
|
-
|
663
676
|
30% {
|
664
677
|
top: 50px; }
|
665
|
-
|
666
678
|
68%, 72% {
|
667
679
|
left: 50px; }
|
668
|
-
|
669
680
|
100% {
|
670
681
|
top: 100px;
|
671
682
|
left: 100%; } }
|
@@ -688,6 +699,8 @@ SCSS
|
|
688
699
|
assert_selector_parses('E:not(s)')
|
689
700
|
assert_selector_parses('E:not(s1, s2)')
|
690
701
|
assert_selector_parses('E:matches(s1, s2)')
|
702
|
+
assert_selector_parses('E:has(s1, s2)')
|
703
|
+
assert_selector_parses('E:has(> s1, > s2)')
|
691
704
|
assert_selector_parses('E.warning')
|
692
705
|
assert_selector_parses('E#myid')
|
693
706
|
assert_selector_parses('E[foo]')
|
@@ -738,20 +751,22 @@ SCSS
|
|
738
751
|
assert_selector_parses('E:last-of-type')
|
739
752
|
assert_selector_parses('E:nth-last-of-type(n)')
|
740
753
|
assert_selector_parses('E:only-of-type')
|
741
|
-
assert_selector_parses('E:nth-
|
742
|
-
assert_selector_parses('E:nth-last-
|
743
|
-
assert_selector_parses('E:
|
744
|
-
assert_selector_parses('E:nth-
|
745
|
-
assert_selector_parses('E:nth-last-column(n)')
|
754
|
+
assert_selector_parses('E:nth-child(n of selector)')
|
755
|
+
assert_selector_parses('E:nth-last-child(n of selector)')
|
756
|
+
assert_selector_parses('E:nth-child(n)')
|
757
|
+
assert_selector_parses('E:nth-last-child(n)')
|
746
758
|
assert_selector_parses('E F')
|
747
759
|
assert_selector_parses('E > F')
|
748
760
|
assert_selector_parses('E + F')
|
749
761
|
assert_selector_parses('E ~ F')
|
750
762
|
assert_selector_parses('E /foo/ F')
|
751
|
-
assert_selector_parses('E! > F')
|
763
|
+
silence_warnings {assert_selector_parses('E! > F')}
|
752
764
|
|
753
765
|
assert_selector_parses('E /ns|foo/ F')
|
754
|
-
|
766
|
+
|
767
|
+
# From http://dev.w3.org/csswg/css-scoping-1/
|
768
|
+
assert_selector_parses('E:host(s)')
|
769
|
+
assert_selector_parses('E:host-context(s)')
|
755
770
|
end
|
756
771
|
|
757
772
|
# Taken from http://dev.w3.org/csswg/selectors4/#overview, but without element
|
@@ -760,6 +775,8 @@ SCSS
|
|
760
775
|
assert_selector_parses(':not(s)')
|
761
776
|
assert_selector_parses(':not(s1, s2)')
|
762
777
|
assert_selector_parses(':matches(s1, s2)')
|
778
|
+
assert_selector_parses(':has(s1, s2)')
|
779
|
+
assert_selector_parses(':has(> s1, > s2)')
|
763
780
|
assert_selector_parses('.warning')
|
764
781
|
assert_selector_parses('#myid')
|
765
782
|
assert_selector_parses('[foo]')
|
@@ -810,11 +827,14 @@ SCSS
|
|
810
827
|
assert_selector_parses(':last-of-type')
|
811
828
|
assert_selector_parses(':nth-last-of-type(n)')
|
812
829
|
assert_selector_parses(':only-of-type')
|
813
|
-
assert_selector_parses(':nth-
|
814
|
-
assert_selector_parses(':nth-last-
|
815
|
-
assert_selector_parses(':
|
816
|
-
assert_selector_parses(':nth-
|
817
|
-
|
830
|
+
assert_selector_parses(':nth-child(n of selector)')
|
831
|
+
assert_selector_parses(':nth-last-child(n of selector)')
|
832
|
+
assert_selector_parses(':nth-child(n)')
|
833
|
+
assert_selector_parses(':nth-last-child(n)')
|
834
|
+
|
835
|
+
# From http://dev.w3.org/csswg/css-scoping-1/
|
836
|
+
assert_selector_parses(':host(s)')
|
837
|
+
assert_selector_parses(':host-context(s)')
|
818
838
|
end
|
819
839
|
|
820
840
|
def test_attribute_selectors_with_identifiers
|
@@ -854,10 +874,13 @@ SCSS
|
|
854
874
|
def test_selectors_containing_selectors
|
855
875
|
assert_selector_can_contain_selectors(':not(<sel>)')
|
856
876
|
assert_selector_can_contain_selectors(':current(<sel>)')
|
857
|
-
assert_selector_can_contain_selectors(':nth-
|
858
|
-
assert_selector_can_contain_selectors(':nth-last-
|
859
|
-
assert_selector_can_contain_selectors(':column(<sel>)')
|
877
|
+
assert_selector_can_contain_selectors(':nth-child(n of <sel>)')
|
878
|
+
assert_selector_can_contain_selectors(':nth-last-child(n of <sel>)')
|
860
879
|
assert_selector_can_contain_selectors(':-moz-any(<sel>)')
|
880
|
+
assert_selector_can_contain_selectors(':has(<sel>)')
|
881
|
+
assert_selector_can_contain_selectors(':has(+ <sel>)')
|
882
|
+
assert_selector_can_contain_selectors(':host(<sel>)')
|
883
|
+
assert_selector_can_contain_selectors(':host-context(<sel>)')
|
861
884
|
end
|
862
885
|
|
863
886
|
def assert_selector_can_contain_selectors(sel)
|
@@ -914,11 +937,11 @@ SCSS
|
|
914
937
|
end
|
915
938
|
|
916
939
|
def test_expression_fallback_selectors
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
940
|
+
assert_directive_parses('0%')
|
941
|
+
assert_directive_parses('60%')
|
942
|
+
assert_directive_parses('100%')
|
943
|
+
assert_directive_parses('12px')
|
944
|
+
assert_directive_parses('"foo"')
|
922
945
|
end
|
923
946
|
|
924
947
|
def test_functional_pseudo_selectors
|
@@ -955,6 +978,29 @@ SCSS
|
|
955
978
|
assert_equal "E + F {\n a: b; }\n", render("E+F { a: b;} ")
|
956
979
|
end
|
957
980
|
|
981
|
+
def test_subject_selector_deprecation
|
982
|
+
assert_warning(<<WARNING) {render(".foo .bar! .baz {a: b}")}
|
983
|
+
DEPRECATION WARNING on line 1, column 1:
|
984
|
+
The subject selector operator "!" is deprecated and will be removed in a future release.
|
985
|
+
This operator has been replaced by ":has()" in the CSS spec.
|
986
|
+
For example: .foo .bar:has(.baz)
|
987
|
+
WARNING
|
988
|
+
|
989
|
+
assert_warning(<<WARNING) {render(".foo .bar! > .baz {a: b}")}
|
990
|
+
DEPRECATION WARNING on line 1, column 1:
|
991
|
+
The subject selector operator "!" is deprecated and will be removed in a future release.
|
992
|
+
This operator has been replaced by ":has()" in the CSS spec.
|
993
|
+
For example: .foo .bar:has(> .baz)
|
994
|
+
WARNING
|
995
|
+
|
996
|
+
assert_warning(<<WARNING) {render(".foo .bar! {a: b}")}
|
997
|
+
DEPRECATION WARNING on line 1, column 1:
|
998
|
+
The subject selector operator "!" is deprecated and will be removed in a future release.
|
999
|
+
This operator has been replaced by ":has()" in the CSS spec.
|
1000
|
+
For example: .foo .bar
|
1001
|
+
WARNING
|
1002
|
+
end
|
1003
|
+
|
958
1004
|
## Errors
|
959
1005
|
|
960
1006
|
def test_invalid_directives
|
@@ -1040,6 +1086,18 @@ SCSS
|
|
1040
1086
|
assert_equal 1, e.sass_line
|
1041
1087
|
end
|
1042
1088
|
|
1089
|
+
def test_newline_in_property_value
|
1090
|
+
assert_equal(<<CSS, render(<<SCSS))
|
1091
|
+
.foo {
|
1092
|
+
bar: "bazbang"; }
|
1093
|
+
CSS
|
1094
|
+
.foo {
|
1095
|
+
bar: "baz\\
|
1096
|
+
bang";
|
1097
|
+
}
|
1098
|
+
SCSS
|
1099
|
+
end
|
1100
|
+
|
1043
1101
|
## Regressions
|
1044
1102
|
|
1045
1103
|
def test_very_long_comment_doesnt_take_forever
|
@@ -1135,6 +1193,18 @@ SCSS
|
|
1135
1193
|
#{selector} {
|
1136
1194
|
a: b; }
|
1137
1195
|
SCSS
|
1196
|
+
|
1197
|
+
assert_parses <<SCSS
|
1198
|
+
:not(#{selector}) {
|
1199
|
+
a: b; }
|
1200
|
+
SCSS
|
1201
|
+
end
|
1202
|
+
|
1203
|
+
def assert_directive_parses(param)
|
1204
|
+
assert_parses <<SCSS
|
1205
|
+
@keyframes #{param} {
|
1206
|
+
a: b; }
|
1207
|
+
SCSS
|
1138
1208
|
end
|
1139
1209
|
|
1140
1210
|
def render(scss, options = {})
|
data/test/sass/scss/rx_test.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
require File.dirname(__FILE__) + '/../../test_helper'
|
4
4
|
require 'sass/engine'
|
5
5
|
|
6
|
-
class ScssRxTest < Test
|
6
|
+
class ScssRxTest < MiniTest::Test
|
7
7
|
include Sass::SCSS::RX
|
8
8
|
|
9
9
|
def test_identifiers
|
@@ -26,6 +26,7 @@ class ScssRxTest < Test::Unit::TestCase
|
|
26
26
|
assert_match IDENT, "_foo" # Can put a _ before anything
|
27
27
|
assert_match IDENT, "_\xC3\xBFoo"
|
28
28
|
assert_match IDENT, "_\\f oo"
|
29
|
+
assert_match IDENT, "--foo" # "Custom" identifier
|
29
30
|
|
30
31
|
assert_match IDENT, "foo-bar"
|
31
32
|
assert_match IDENT, "f012-23"
|
@@ -59,7 +60,6 @@ class ScssRxTest < Test::Unit::TestCase
|
|
59
60
|
assert_no_match IDENT, ""
|
60
61
|
assert_no_match IDENT, "1foo"
|
61
62
|
assert_no_match IDENT, "-1foo"
|
62
|
-
assert_no_match IDENT, "--foo"
|
63
63
|
assert_no_match IDENT, "foo bar"
|
64
64
|
assert_no_match IDENT, "foo~bar"
|
65
65
|
|
@@ -144,13 +144,13 @@ class ScssRxTest < Test::Unit::TestCase
|
|
144
144
|
private
|
145
145
|
|
146
146
|
def assert_match(rx, str)
|
147
|
-
|
147
|
+
refute_nil(match = rx.match(str))
|
148
148
|
assert_equal str.size, match[0].size
|
149
149
|
end
|
150
150
|
|
151
151
|
def assert_no_match(rx, str)
|
152
152
|
match = rx.match(str)
|
153
|
-
|
153
|
+
refute_equal str.size, match && match[0].size
|
154
154
|
end
|
155
155
|
|
156
156
|
end
|
data/test/sass/scss/scss_test.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
# -*- coding: utf-8 -*-
|
3
3
|
require File.dirname(__FILE__) + '/test_helper'
|
4
4
|
|
5
|
-
class ScssTest < Test
|
5
|
+
class ScssTest < MiniTest::Test
|
6
6
|
include ScssTestHelper
|
7
7
|
|
8
8
|
## One-Line Comments
|
@@ -115,6 +115,14 @@ SCSS
|
|
115
115
|
end
|
116
116
|
end
|
117
117
|
|
118
|
+
def test_error_directive
|
119
|
+
assert_raise_message(Sass::SyntaxError, "hello world!") {render(<<SCSS)}
|
120
|
+
foo {a: b}
|
121
|
+
@error "hello world!";
|
122
|
+
bar {c: d}
|
123
|
+
SCSS
|
124
|
+
end
|
125
|
+
|
118
126
|
def test_warn_directive
|
119
127
|
expected_warning = <<EXPECTATION
|
120
128
|
WARNING: this is a warning
|
@@ -536,11 +544,17 @@ foo :baz {
|
|
536
544
|
c: d; }
|
537
545
|
foo bang:bop {
|
538
546
|
e: f; }
|
547
|
+
foo ::qux {
|
548
|
+
g: h; }
|
549
|
+
foo zap::fblthp {
|
550
|
+
i: j; }
|
539
551
|
CSS
|
540
552
|
foo {
|
541
553
|
.bar {a: b}
|
542
554
|
:baz {c: d}
|
543
|
-
bang:bop {e: f}
|
555
|
+
bang:bop {e: f}
|
556
|
+
::qux {g: h}
|
557
|
+
zap::fblthp {i: j}}
|
544
558
|
SCSS
|
545
559
|
end
|
546
560
|
|
@@ -645,7 +659,7 @@ SCSS
|
|
645
659
|
end
|
646
660
|
|
647
661
|
def test_parent_selector_with_subject
|
648
|
-
assert_equal <<CSS, render(<<SCSS)
|
662
|
+
silence_warnings {assert_equal <<CSS, render(<<SCSS)}
|
649
663
|
bar foo.baz! .bip {
|
650
664
|
a: b; }
|
651
665
|
|
@@ -799,18 +813,27 @@ SCSS
|
|
799
813
|
def test_no_namespace_properties_without_space_even_when_its_unambiguous
|
800
814
|
render(<<SCSS)
|
801
815
|
foo {
|
802
|
-
bar:
|
816
|
+
bar:baz calc(1 + 2) {
|
803
817
|
bip: bop }}
|
804
818
|
SCSS
|
805
819
|
assert(false, "Expected syntax error")
|
806
820
|
rescue Sass::SyntaxError => e
|
807
|
-
assert_equal
|
808
|
-
Invalid CSS: a space is required between a property and its definition
|
809
|
-
when it has other properties nested beneath it.
|
810
|
-
MESSAGE
|
821
|
+
assert_equal 'Invalid CSS after "bar:baz calc": expected selector, was "(1 + 2)"', e.message
|
811
822
|
assert_equal 2, e.sass_line
|
812
823
|
end
|
813
824
|
|
825
|
+
def test_namespace_properties_without_space_allowed_for_non_identifier
|
826
|
+
assert_equal <<CSS, render(<<SCSS)
|
827
|
+
foo {
|
828
|
+
bar: 1px;
|
829
|
+
bar-bip: bop; }
|
830
|
+
CSS
|
831
|
+
foo {
|
832
|
+
bar:1px {
|
833
|
+
bip: bop }}
|
834
|
+
SCSS
|
835
|
+
end
|
836
|
+
|
814
837
|
## Mixins
|
815
838
|
|
816
839
|
def test_basic_mixins
|
@@ -909,13 +932,10 @@ SCSS
|
|
909
932
|
0% {
|
910
933
|
top: 0;
|
911
934
|
left: 0; }
|
912
|
-
|
913
935
|
30% {
|
914
936
|
top: 50px; }
|
915
|
-
|
916
937
|
68%, 72% {
|
917
938
|
left: 50px; }
|
918
|
-
|
919
939
|
100% {
|
920
940
|
top: 100px;
|
921
941
|
left: 100%; } }
|
@@ -926,7 +946,7 @@ CSS
|
|
926
946
|
|
927
947
|
@include keyframes {
|
928
948
|
0% {top: 0; left: 0}
|
929
|
-
30% {top: 50px}
|
949
|
+
\#{"30%"} {top: 50px}
|
930
950
|
68%, 72% {left: 50px}
|
931
951
|
100% {top: 100px; left: 100%}
|
932
952
|
}
|
@@ -1914,10 +1934,10 @@ SCSS
|
|
1914
1934
|
|
1915
1935
|
def test_basic_selector_interpolation
|
1916
1936
|
assert_equal <<CSS, render(<<SCSS)
|
1917
|
-
foo
|
1937
|
+
foo ab baz {
|
1918
1938
|
a: b; }
|
1919
1939
|
CSS
|
1920
|
-
foo \#{
|
1940
|
+
foo \#{'a' + 'b'} baz {a: b}
|
1921
1941
|
SCSS
|
1922
1942
|
assert_equal <<CSS, render(<<SCSS)
|
1923
1943
|
foo.bar baz {
|
@@ -2043,7 +2063,7 @@ SCSS
|
|
2043
2063
|
end
|
2044
2064
|
|
2045
2065
|
def test_parent_selector_with_parent_and_subject
|
2046
|
-
assert_equal <<CSS, render(<<SCSS)
|
2066
|
+
silence_warnings {assert_equal <<CSS, render(<<SCSS)}
|
2047
2067
|
bar foo.baz! .bip {
|
2048
2068
|
c: d; }
|
2049
2069
|
CSS
|
@@ -2216,6 +2236,69 @@ $domain: "sass-lang.com";
|
|
2216
2236
|
SCSS
|
2217
2237
|
end
|
2218
2238
|
|
2239
|
+
def test_color_interpolation_warning_in_selector
|
2240
|
+
assert_warning(<<WARNING) {assert_equal <<CSS, render(<<SCSS)}
|
2241
|
+
WARNING on line 1, column 4 of #{filename_for_test(:scss)}:
|
2242
|
+
You probably don't mean to use the color value `blue' in interpolation here.
|
2243
|
+
It may end up represented as #0000ff, which will likely produce invalid CSS.
|
2244
|
+
Always quote color names when using them as strings (for example, "blue").
|
2245
|
+
If you really want to use the color value here, use `"" + blue'.
|
2246
|
+
WARNING
|
2247
|
+
fooblue {
|
2248
|
+
a: b; }
|
2249
|
+
CSS
|
2250
|
+
foo\#{blue} {a: b}
|
2251
|
+
SCSS
|
2252
|
+
end
|
2253
|
+
|
2254
|
+
def test_color_interpolation_warning_in_directive
|
2255
|
+
assert_warning(<<WARNING) {assert_equal <<CSS, render(<<SCSS)}
|
2256
|
+
WARNING on line 1, column 12 of #{filename_for_test(:scss)}:
|
2257
|
+
You probably don't mean to use the color value `blue' in interpolation here.
|
2258
|
+
It may end up represented as #0000ff, which will likely produce invalid CSS.
|
2259
|
+
Always quote color names when using them as strings (for example, "blue").
|
2260
|
+
If you really want to use the color value here, use `"" + blue'.
|
2261
|
+
WARNING
|
2262
|
+
@fblthp fooblue {
|
2263
|
+
a: b; }
|
2264
|
+
CSS
|
2265
|
+
@fblthp foo\#{blue} {a: b}
|
2266
|
+
SCSS
|
2267
|
+
end
|
2268
|
+
|
2269
|
+
def test_color_interpolation_warning_in_property_name
|
2270
|
+
assert_warning(<<WARNING) {assert_equal <<CSS, render(<<SCSS)}
|
2271
|
+
WARNING on line 1, column 8 of #{filename_for_test(:scss)}:
|
2272
|
+
You probably don't mean to use the color value `blue' in interpolation here.
|
2273
|
+
It may end up represented as #0000ff, which will likely produce invalid CSS.
|
2274
|
+
Always quote color names when using them as strings (for example, "blue").
|
2275
|
+
If you really want to use the color value here, use `"" + blue'.
|
2276
|
+
WARNING
|
2277
|
+
foo {
|
2278
|
+
a-blue: b; }
|
2279
|
+
CSS
|
2280
|
+
foo {a-\#{blue}: b}
|
2281
|
+
SCSS
|
2282
|
+
end
|
2283
|
+
|
2284
|
+
def test_no_color_interpolation_warning_in_property_value
|
2285
|
+
assert_no_warning {assert_equal <<CSS, render(<<SCSS)}
|
2286
|
+
foo {
|
2287
|
+
a: b-blue; }
|
2288
|
+
CSS
|
2289
|
+
foo {a: b-\#{blue}}
|
2290
|
+
SCSS
|
2291
|
+
end
|
2292
|
+
|
2293
|
+
def test_no_color_interpolation_warning_for_nameless_color
|
2294
|
+
assert_no_warning {assert_equal <<CSS, render(<<SCSS)}
|
2295
|
+
foo-#abcdef {
|
2296
|
+
a: b; }
|
2297
|
+
CSS
|
2298
|
+
foo-\#{#abcdef} {a: b}
|
2299
|
+
SCSS
|
2300
|
+
end
|
2301
|
+
|
2219
2302
|
def test_nested_mixin_def
|
2220
2303
|
assert_equal <<CSS, render(<<SCSS)
|
2221
2304
|
foo {
|
@@ -2878,6 +2961,214 @@ CSS
|
|
2878
2961
|
SCSS
|
2879
2962
|
end
|
2880
2963
|
|
2964
|
+
def test_at_root_without_keyframes_in_keyframe_rule
|
2965
|
+
assert_equal <<CSS, render(<<SCSS)
|
2966
|
+
.foo {
|
2967
|
+
a: b; }
|
2968
|
+
CSS
|
2969
|
+
@keyframes identifier {
|
2970
|
+
0% {
|
2971
|
+
@at-root (without: keyframes) {
|
2972
|
+
.foo {a: b}
|
2973
|
+
}
|
2974
|
+
}
|
2975
|
+
}
|
2976
|
+
SCSS
|
2977
|
+
end
|
2978
|
+
|
2979
|
+
def test_at_root_without_rule_in_keyframe_rule
|
2980
|
+
assert_equal <<CSS, render(<<SCSS)
|
2981
|
+
@keyframes identifier {
|
2982
|
+
0% {
|
2983
|
+
a: b; } }
|
2984
|
+
CSS
|
2985
|
+
@keyframes identifier {
|
2986
|
+
0% {
|
2987
|
+
@at-root (without: rule) {a: b}
|
2988
|
+
}
|
2989
|
+
}
|
2990
|
+
SCSS
|
2991
|
+
end
|
2992
|
+
|
2993
|
+
## Selector Script
|
2994
|
+
|
2995
|
+
def test_selector_script
|
2996
|
+
assert_equal(<<CSS, render(<<SCSS))
|
2997
|
+
.foo .bar {
|
2998
|
+
content: ".foo .bar"; }
|
2999
|
+
CSS
|
3000
|
+
.foo .bar {
|
3001
|
+
content: "\#{&}";
|
3002
|
+
}
|
3003
|
+
SCSS
|
3004
|
+
end
|
3005
|
+
|
3006
|
+
def test_nested_selector_script
|
3007
|
+
assert_equal(<<CSS, render(<<SCSS))
|
3008
|
+
.foo .bar {
|
3009
|
+
content: ".foo .bar"; }
|
3010
|
+
CSS
|
3011
|
+
.foo {
|
3012
|
+
.bar {
|
3013
|
+
content: "\#{&}";
|
3014
|
+
}
|
3015
|
+
}
|
3016
|
+
SCSS
|
3017
|
+
end
|
3018
|
+
|
3019
|
+
def test_nested_selector_script_with_outer_comma_selector
|
3020
|
+
assert_equal(<<CSS, render(<<SCSS))
|
3021
|
+
.foo .baz, .bar .baz {
|
3022
|
+
content: ".foo .baz, .bar .baz"; }
|
3023
|
+
CSS
|
3024
|
+
.foo, .bar {
|
3025
|
+
.baz {
|
3026
|
+
content: "\#{&}";
|
3027
|
+
}
|
3028
|
+
}
|
3029
|
+
SCSS
|
3030
|
+
end
|
3031
|
+
|
3032
|
+
def test_nested_selector_script_with_inner_comma_selector
|
3033
|
+
assert_equal(<<CSS, render(<<SCSS))
|
3034
|
+
.foo .bar, .foo .baz {
|
3035
|
+
content: ".foo .bar, .foo .baz"; }
|
3036
|
+
CSS
|
3037
|
+
.foo {
|
3038
|
+
.bar, .baz {
|
3039
|
+
content: "\#{&}";
|
3040
|
+
}
|
3041
|
+
}
|
3042
|
+
SCSS
|
3043
|
+
end
|
3044
|
+
|
3045
|
+
def test_selector_script_through_mixin
|
3046
|
+
assert_equal(<<CSS, render(<<SCSS))
|
3047
|
+
.foo {
|
3048
|
+
content: ".foo"; }
|
3049
|
+
CSS
|
3050
|
+
@mixin mixin {
|
3051
|
+
content: "\#{&}";
|
3052
|
+
}
|
3053
|
+
|
3054
|
+
.foo {
|
3055
|
+
@include mixin;
|
3056
|
+
}
|
3057
|
+
SCSS
|
3058
|
+
end
|
3059
|
+
|
3060
|
+
def test_selector_script_through_content
|
3061
|
+
assert_equal(<<CSS, render(<<SCSS))
|
3062
|
+
.foo {
|
3063
|
+
content: ".foo"; }
|
3064
|
+
CSS
|
3065
|
+
@mixin mixin {
|
3066
|
+
@content;
|
3067
|
+
}
|
3068
|
+
|
3069
|
+
.foo {
|
3070
|
+
@include mixin {
|
3071
|
+
content: "\#{&}";
|
3072
|
+
}
|
3073
|
+
}
|
3074
|
+
SCSS
|
3075
|
+
end
|
3076
|
+
|
3077
|
+
def test_selector_script_through_function
|
3078
|
+
assert_equal(<<CSS, render(<<SCSS))
|
3079
|
+
.foo {
|
3080
|
+
content: ".foo"; }
|
3081
|
+
CSS
|
3082
|
+
@function fn() {
|
3083
|
+
@return "\#{&}";
|
3084
|
+
}
|
3085
|
+
|
3086
|
+
.foo {
|
3087
|
+
content: fn();
|
3088
|
+
}
|
3089
|
+
SCSS
|
3090
|
+
end
|
3091
|
+
|
3092
|
+
def test_selector_script_through_media
|
3093
|
+
assert_equal(<<CSS, render(<<SCSS))
|
3094
|
+
.foo {
|
3095
|
+
content: "outer"; }
|
3096
|
+
@media screen {
|
3097
|
+
.foo .bar {
|
3098
|
+
content: ".foo .bar"; } }
|
3099
|
+
CSS
|
3100
|
+
.foo {
|
3101
|
+
content: "outer";
|
3102
|
+
@media screen {
|
3103
|
+
.bar {
|
3104
|
+
content: "\#{&}";
|
3105
|
+
}
|
3106
|
+
}
|
3107
|
+
}
|
3108
|
+
SCSS
|
3109
|
+
end
|
3110
|
+
|
3111
|
+
def test_selector_script_save_and_reuse
|
3112
|
+
assert_equal(<<CSS, render(<<SCSS))
|
3113
|
+
.bar {
|
3114
|
+
content: ".foo"; }
|
3115
|
+
CSS
|
3116
|
+
$var: null;
|
3117
|
+
.foo {
|
3118
|
+
$var: & !global;
|
3119
|
+
}
|
3120
|
+
|
3121
|
+
.bar {
|
3122
|
+
content: "\#{$var}";
|
3123
|
+
}
|
3124
|
+
SCSS
|
3125
|
+
end
|
3126
|
+
|
3127
|
+
def test_selector_script_with_at_root
|
3128
|
+
assert_equal(<<CSS, render(<<SCSS))
|
3129
|
+
.foo-bar {
|
3130
|
+
a: b; }
|
3131
|
+
CSS
|
3132
|
+
.foo {
|
3133
|
+
@at-root \#{&}-bar {
|
3134
|
+
a: b;
|
3135
|
+
}
|
3136
|
+
}
|
3137
|
+
SCSS
|
3138
|
+
end
|
3139
|
+
|
3140
|
+
def test_multi_level_at_root_with_inner_selector_script
|
3141
|
+
assert_equal <<CSS, render(<<SCSS)
|
3142
|
+
.bar {
|
3143
|
+
a: b; }
|
3144
|
+
CSS
|
3145
|
+
.foo {
|
3146
|
+
@at-root .bar {
|
3147
|
+
@at-root \#{&} {
|
3148
|
+
a: b;
|
3149
|
+
}
|
3150
|
+
}
|
3151
|
+
}
|
3152
|
+
SCSS
|
3153
|
+
end
|
3154
|
+
|
3155
|
+
def test_at_root_with_at_root_through_mixin
|
3156
|
+
assert_equal(<<CSS, render(<<SCSS))
|
3157
|
+
.bar-baz {
|
3158
|
+
a: b; }
|
3159
|
+
CSS
|
3160
|
+
@mixin foo {
|
3161
|
+
.bar {
|
3162
|
+
@at-root \#{&}-baz {
|
3163
|
+
a: b;
|
3164
|
+
}
|
3165
|
+
}
|
3166
|
+
}
|
3167
|
+
|
3168
|
+
@include foo;
|
3169
|
+
SCSS
|
3170
|
+
end
|
3171
|
+
|
2881
3172
|
# See https://github.com/sass/sass/issues/1294
|
2882
3173
|
def test_extend_top_leveled_by_at_root
|
2883
3174
|
render(<<SCSS)
|
@@ -2924,6 +3215,29 @@ SCSS
|
|
2924
3215
|
|
2925
3216
|
## Errors
|
2926
3217
|
|
3218
|
+
def test_keyframes_rule_outside_of_keyframes
|
3219
|
+
render <<SCSS
|
3220
|
+
0% {
|
3221
|
+
top: 0; }
|
3222
|
+
SCSS
|
3223
|
+
assert(false, "Expected syntax error")
|
3224
|
+
rescue Sass::SyntaxError => e
|
3225
|
+
assert_equal 'Invalid CSS after "": expected selector, was "0%"', e.message
|
3226
|
+
assert_equal 1, e.sass_line
|
3227
|
+
end
|
3228
|
+
|
3229
|
+
def test_selector_rule_in_keyframes
|
3230
|
+
render <<SCSS
|
3231
|
+
@keyframes identifier {
|
3232
|
+
.foo {
|
3233
|
+
top: 0; } }
|
3234
|
+
SCSS
|
3235
|
+
assert(false, "Expected syntax error")
|
3236
|
+
rescue Sass::SyntaxError => e
|
3237
|
+
assert_equal 'Invalid CSS after "": expected keyframes selector (e.g. 10%), was ".foo"', e.message
|
3238
|
+
assert_equal 2, e.sass_line
|
3239
|
+
end
|
3240
|
+
|
2927
3241
|
def test_nested_mixin_def_is_scoped
|
2928
3242
|
render <<SCSS
|
2929
3243
|
foo {
|
@@ -2978,7 +3292,7 @@ foo {
|
|
2978
3292
|
SCSS
|
2979
3293
|
assert(false, "Expected syntax error")
|
2980
3294
|
rescue Sass::SyntaxError => e
|
2981
|
-
assert_equal 'Invalid CSS after " .bar:baz ": expected
|
3295
|
+
assert_equal 'Invalid CSS after " .bar:baz <fail>": expected expression (e.g. 1px, bold), was "; }"', e.message
|
2982
3296
|
assert_equal 2, e.sass_line
|
2983
3297
|
end
|
2984
3298
|
|
@@ -3088,7 +3402,7 @@ SCSS
|
|
3088
3402
|
|
3089
3403
|
def test_parent_in_mid_selector_error
|
3090
3404
|
assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render <<SCSS}
|
3091
|
-
Invalid CSS after "
|
3405
|
+
Invalid CSS after ".foo": expected "{", was "&.bar"
|
3092
3406
|
|
3093
3407
|
"&.bar" may only be used at the beginning of a compound selector.
|
3094
3408
|
MESSAGE
|
@@ -3100,7 +3414,7 @@ SCSS
|
|
3100
3414
|
|
3101
3415
|
def test_parent_after_selector_error
|
3102
3416
|
assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render <<SCSS}
|
3103
|
-
Invalid CSS after "
|
3417
|
+
Invalid CSS after ".foo.bar": expected "{", was "&"
|
3104
3418
|
|
3105
3419
|
"&" may only be used at the beginning of a compound selector.
|
3106
3420
|
MESSAGE
|
@@ -3112,7 +3426,7 @@ SCSS
|
|
3112
3426
|
|
3113
3427
|
def test_double_parent_selector_error
|
3114
3428
|
assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render <<SCSS}
|
3115
|
-
Invalid CSS after "
|
3429
|
+
Invalid CSS after "&": expected "{", was "&"
|
3116
3430
|
|
3117
3431
|
"&" may only be used at the beginning of a compound selector.
|
3118
3432
|
MESSAGE
|
@@ -3182,6 +3496,36 @@ MESSAGE
|
|
3182
3496
|
SCSS
|
3183
3497
|
end
|
3184
3498
|
|
3499
|
+
def test_newline_in_property_value
|
3500
|
+
assert_equal(<<CSS, render(<<SCSS))
|
3501
|
+
.foo {
|
3502
|
+
bar: "bazbang"; }
|
3503
|
+
CSS
|
3504
|
+
.foo {
|
3505
|
+
$var: "baz\\
|
3506
|
+
bang";
|
3507
|
+
bar: $var;
|
3508
|
+
}
|
3509
|
+
SCSS
|
3510
|
+
end
|
3511
|
+
|
3512
|
+
def test_raw_newline_warning
|
3513
|
+
assert_warning(<<MESSAGE.rstrip) {assert_equal(<<CSS, render(<<SCSS))}
|
3514
|
+
DEPRECATION WARNING on line 2, column 9:
|
3515
|
+
Unescaped multiline strings are deprecated and will be removed in a future version of Sass.
|
3516
|
+
To include a newline in a string, use "\\a" or "\\a " as in CSS.
|
3517
|
+
MESSAGE
|
3518
|
+
.foo {
|
3519
|
+
bar: "baz\\a bang"; }
|
3520
|
+
CSS
|
3521
|
+
.foo {
|
3522
|
+
$var: "baz
|
3523
|
+
bang";
|
3524
|
+
bar: $var;
|
3525
|
+
}
|
3526
|
+
SCSS
|
3527
|
+
end
|
3528
|
+
|
3185
3529
|
# Regression
|
3186
3530
|
|
3187
3531
|
def test_top_level_unknown_directive_in_at_root
|