sass 3.3.14 → 3.4.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +5 -5
  4. data/VERSION +1 -1
  5. data/VERSION_DATE +1 -1
  6. data/VERSION_NAME +1 -1
  7. data/bin/sass +1 -1
  8. data/bin/scss +1 -1
  9. data/lib/sass.rb +0 -5
  10. data/lib/sass/css.rb +1 -3
  11. data/lib/sass/engine.rb +28 -39
  12. data/lib/sass/environment.rb +13 -17
  13. data/lib/sass/error.rb +6 -9
  14. data/lib/sass/exec.rb +5 -771
  15. data/lib/sass/exec/base.rb +187 -0
  16. data/lib/sass/exec/sass_convert.rb +264 -0
  17. data/lib/sass/exec/sass_scss.rb +419 -0
  18. data/lib/sass/features.rb +6 -0
  19. data/lib/sass/importers.rb +0 -1
  20. data/lib/sass/importers/base.rb +5 -1
  21. data/lib/sass/importers/filesystem.rb +4 -21
  22. data/lib/sass/media.rb +1 -4
  23. data/lib/sass/plugin/compiler.rb +32 -136
  24. data/lib/sass/script/css_lexer.rb +1 -1
  25. data/lib/sass/script/functions.rb +363 -39
  26. data/lib/sass/script/lexer.rb +68 -50
  27. data/lib/sass/script/parser.rb +29 -14
  28. data/lib/sass/script/tree.rb +1 -0
  29. data/lib/sass/script/tree/funcall.rb +1 -1
  30. data/lib/sass/script/tree/interpolation.rb +19 -1
  31. data/lib/sass/script/tree/selector.rb +26 -0
  32. data/lib/sass/script/value.rb +0 -1
  33. data/lib/sass/script/value/bool.rb +0 -5
  34. data/lib/sass/script/value/color.rb +32 -12
  35. data/lib/sass/script/value/helpers.rb +107 -0
  36. data/lib/sass/script/value/list.rb +0 -15
  37. data/lib/sass/script/value/null.rb +0 -5
  38. data/lib/sass/script/value/number.rb +60 -14
  39. data/lib/sass/script/value/string.rb +53 -9
  40. data/lib/sass/scss/css_parser.rb +8 -2
  41. data/lib/sass/scss/parser.rb +175 -319
  42. data/lib/sass/scss/rx.rb +14 -5
  43. data/lib/sass/scss/static_parser.rb +298 -1
  44. data/lib/sass/selector.rb +56 -193
  45. data/lib/sass/selector/abstract_sequence.rb +28 -13
  46. data/lib/sass/selector/comma_sequence.rb +91 -12
  47. data/lib/sass/selector/pseudo.rb +256 -0
  48. data/lib/sass/selector/sequence.rb +99 -31
  49. data/lib/sass/selector/simple.rb +14 -25
  50. data/lib/sass/selector/simple_sequence.rb +101 -37
  51. data/lib/sass/shared.rb +1 -1
  52. data/lib/sass/source/map.rb +23 -9
  53. data/lib/sass/stack.rb +0 -6
  54. data/lib/sass/supports.rb +1 -1
  55. data/lib/sass/tree/at_root_node.rb +1 -0
  56. data/lib/sass/tree/directive_node.rb +7 -1
  57. data/lib/sass/tree/error_node.rb +18 -0
  58. data/lib/sass/tree/keyframe_rule_node.rb +15 -0
  59. data/lib/sass/tree/prop_node.rb +1 -1
  60. data/lib/sass/tree/rule_node.rb +11 -6
  61. data/lib/sass/tree/visitors/check_nesting.rb +3 -4
  62. data/lib/sass/tree/visitors/convert.rb +8 -17
  63. data/lib/sass/tree/visitors/cssize.rb +12 -24
  64. data/lib/sass/tree/visitors/deep_copy.rb +5 -0
  65. data/lib/sass/tree/visitors/perform.rb +43 -28
  66. data/lib/sass/tree/visitors/set_options.rb +5 -0
  67. data/lib/sass/tree/visitors/to_css.rb +14 -13
  68. data/lib/sass/util.rb +94 -90
  69. data/test/sass/cache_test.rb +1 -1
  70. data/test/sass/callbacks_test.rb +1 -1
  71. data/test/sass/compiler_test.rb +5 -14
  72. data/test/sass/conversion_test.rb +47 -1
  73. data/test/sass/css2sass_test.rb +3 -3
  74. data/test/sass/encoding_test.rb +219 -0
  75. data/test/sass/engine_test.rb +128 -191
  76. data/test/sass/exec_test.rb +2 -2
  77. data/test/sass/extend_test.rb +234 -17
  78. data/test/sass/functions_test.rb +268 -213
  79. data/test/sass/importer_test.rb +31 -21
  80. data/test/sass/logger_test.rb +1 -1
  81. data/test/sass/more_results/more_import.css +1 -1
  82. data/test/sass/plugin_test.rb +12 -11
  83. data/test/sass/results/compact.css +1 -1
  84. data/test/sass/results/complex.css +4 -4
  85. data/test/sass/results/expanded.css +1 -1
  86. data/test/sass/results/import.css +1 -1
  87. data/test/sass/results/import_charset_ibm866.css +2 -2
  88. data/test/sass/results/mixins.css +17 -17
  89. data/test/sass/results/nested.css +1 -1
  90. data/test/sass/results/parent_ref.css +2 -2
  91. data/test/sass/results/script.css +3 -3
  92. data/test/sass/results/scss_import.css +1 -1
  93. data/test/sass/script_conversion_test.rb +7 -4
  94. data/test/sass/script_test.rb +202 -79
  95. data/test/sass/scss/css_test.rb +95 -25
  96. data/test/sass/scss/rx_test.rb +4 -4
  97. data/test/sass/scss/scss_test.rb +363 -19
  98. data/test/sass/source_map_test.rb +48 -41
  99. data/test/sass/superselector_test.rb +191 -0
  100. data/test/sass/templates/scss_import.scss +2 -1
  101. data/test/sass/test_helper.rb +1 -1
  102. data/test/sass/util/multibyte_string_scanner_test.rb +1 -1
  103. data/test/sass/util/normalized_map_test.rb +1 -1
  104. data/test/sass/util/subset_map_test.rb +2 -2
  105. data/test/sass/util_test.rb +1 -1
  106. data/test/sass/value_helpers_test.rb +3 -3
  107. data/test/test_helper.rb +2 -2
  108. metadata +30 -7
  109. data/lib/sass/importers/deprecated_path.rb +0 -51
  110. data/lib/sass/script/value/deprecated_false.rb +0 -55
@@ -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::Unit::TestCase
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-match(n of selector)')
742
- assert_selector_parses('E:nth-last-match(n of selector)')
743
- assert_selector_parses('E:column(selector)')
744
- assert_selector_parses('E:nth-column(n)')
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
- assert_selector_parses('E /*|foo/ F')
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-match(n of selector)')
814
- assert_selector_parses(':nth-last-match(n of selector)')
815
- assert_selector_parses(':column(selector)')
816
- assert_selector_parses(':nth-column(n)')
817
- assert_selector_parses(':nth-last-column(n)')
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-match(n of <sel>)')
858
- assert_selector_can_contain_selectors(':nth-last-match(n of <sel>)')
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
- assert_selector_parses('0%')
918
- assert_selector_parses('60%')
919
- assert_selector_parses('100%')
920
- assert_selector_parses('12px')
921
- assert_selector_parses('"foo"')
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 = {})
@@ -3,7 +3,7 @@
3
3
  require File.dirname(__FILE__) + '/../../test_helper'
4
4
  require 'sass/engine'
5
5
 
6
- class ScssRxTest < Test::Unit::TestCase
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
- assert_not_nil(match = rx.match(str))
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
- assert_not_equal str.size, match && match[0].size
153
+ refute_equal str.size, match && match[0].size
154
154
  end
155
155
 
156
156
  end
@@ -2,7 +2,7 @@
2
2
  # -*- coding: utf-8 -*-
3
3
  require File.dirname(__FILE__) + '/test_helper'
4
4
 
5
- class ScssTest < Test::Unit::TestCase
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:1px {
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 <<MESSAGE, e.message
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 3 baz {
1937
+ foo ab baz {
1918
1938
  a: b; }
1919
1939
  CSS
1920
- foo \#{1 + 2} baz {a: b}
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 "{", was "<fail>; }"', e.message
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 " .foo": expected "{", was "&.bar {a: b}"
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 " .foo.bar": expected "{", was "& {a: b}"
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 " &": expected "{", was "& {a: b}"
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