oreorenasass 3.4.4 → 3.4.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (176) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +50 -70
  4. data/Rakefile +5 -26
  5. data/VERSION +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 +12 -19
  10. data/lib/sass/cache_stores/base.rb +2 -2
  11. data/lib/sass/cache_stores/chain.rb +1 -2
  12. data/lib/sass/cache_stores/filesystem.rb +5 -1
  13. data/lib/sass/cache_stores/memory.rb +1 -1
  14. data/lib/sass/cache_stores/null.rb +2 -2
  15. data/lib/sass/callbacks.rb +0 -1
  16. data/lib/sass/css.rb +13 -11
  17. data/lib/sass/engine.rb +173 -424
  18. data/lib/sass/environment.rb +58 -148
  19. data/lib/sass/error.rb +14 -11
  20. data/lib/sass/exec.rb +703 -5
  21. data/lib/sass/importers/base.rb +6 -49
  22. data/lib/sass/importers/filesystem.rb +19 -44
  23. data/lib/sass/logger.rb +4 -1
  24. data/lib/sass/logger/base.rb +4 -2
  25. data/lib/sass/logger/log_level.rb +7 -3
  26. data/lib/sass/media.rb +23 -20
  27. data/lib/sass/plugin.rb +7 -7
  28. data/lib/sass/plugin/compiler.rb +145 -304
  29. data/lib/sass/plugin/configuration.rb +23 -18
  30. data/lib/sass/plugin/merb.rb +1 -1
  31. data/lib/sass/plugin/staleness_checker.rb +3 -3
  32. data/lib/sass/repl.rb +3 -3
  33. data/lib/sass/script.rb +8 -35
  34. data/lib/sass/script/{value/arg_list.rb → arg_list.rb} +25 -9
  35. data/lib/sass/script/bool.rb +18 -0
  36. data/lib/sass/script/color.rb +606 -0
  37. data/lib/sass/script/css_lexer.rb +4 -8
  38. data/lib/sass/script/css_parser.rb +2 -5
  39. data/lib/sass/script/funcall.rb +245 -0
  40. data/lib/sass/script/functions.rb +408 -1491
  41. data/lib/sass/script/interpolation.rb +79 -0
  42. data/lib/sass/script/lexer.rb +68 -172
  43. data/lib/sass/script/list.rb +85 -0
  44. data/lib/sass/script/literal.rb +221 -0
  45. data/lib/sass/script/{tree/node.rb → node.rb} +12 -22
  46. data/lib/sass/script/{value/null.rb → null.rb} +7 -14
  47. data/lib/sass/script/{value/number.rb → number.rb} +75 -152
  48. data/lib/sass/script/{tree/operation.rb → operation.rb} +24 -17
  49. data/lib/sass/script/parser.rb +110 -245
  50. data/lib/sass/script/string.rb +51 -0
  51. data/lib/sass/script/{tree/string_interpolation.rb → string_interpolation.rb} +4 -5
  52. data/lib/sass/script/{tree/unary_operation.rb → unary_operation.rb} +6 -6
  53. data/lib/sass/script/variable.rb +58 -0
  54. data/lib/sass/scss/css_parser.rb +3 -9
  55. data/lib/sass/scss/parser.rb +421 -450
  56. data/lib/sass/scss/rx.rb +11 -19
  57. data/lib/sass/scss/static_parser.rb +7 -321
  58. data/lib/sass/selector.rb +194 -68
  59. data/lib/sass/selector/abstract_sequence.rb +14 -29
  60. data/lib/sass/selector/comma_sequence.rb +25 -108
  61. data/lib/sass/selector/sequence.rb +66 -159
  62. data/lib/sass/selector/simple.rb +25 -23
  63. data/lib/sass/selector/simple_sequence.rb +63 -173
  64. data/lib/sass/shared.rb +1 -1
  65. data/lib/sass/supports.rb +15 -13
  66. data/lib/sass/tree/charset_node.rb +1 -1
  67. data/lib/sass/tree/comment_node.rb +3 -3
  68. data/lib/sass/tree/css_import_node.rb +11 -11
  69. data/lib/sass/tree/debug_node.rb +2 -2
  70. data/lib/sass/tree/directive_node.rb +4 -21
  71. data/lib/sass/tree/each_node.rb +8 -8
  72. data/lib/sass/tree/extend_node.rb +7 -14
  73. data/lib/sass/tree/for_node.rb +4 -4
  74. data/lib/sass/tree/function_node.rb +4 -9
  75. data/lib/sass/tree/if_node.rb +1 -1
  76. data/lib/sass/tree/import_node.rb +5 -4
  77. data/lib/sass/tree/media_node.rb +14 -4
  78. data/lib/sass/tree/mixin_def_node.rb +4 -4
  79. data/lib/sass/tree/mixin_node.rb +8 -21
  80. data/lib/sass/tree/node.rb +12 -54
  81. data/lib/sass/tree/prop_node.rb +20 -39
  82. data/lib/sass/tree/return_node.rb +2 -3
  83. data/lib/sass/tree/root_node.rb +3 -19
  84. data/lib/sass/tree/rule_node.rb +22 -35
  85. data/lib/sass/tree/supports_node.rb +13 -0
  86. data/lib/sass/tree/trace_node.rb +1 -2
  87. data/lib/sass/tree/variable_node.rb +3 -9
  88. data/lib/sass/tree/visitors/base.rb +8 -5
  89. data/lib/sass/tree/visitors/check_nesting.rb +19 -49
  90. data/lib/sass/tree/visitors/convert.rb +56 -74
  91. data/lib/sass/tree/visitors/cssize.rb +74 -202
  92. data/lib/sass/tree/visitors/deep_copy.rb +5 -10
  93. data/lib/sass/tree/visitors/extend.rb +7 -7
  94. data/lib/sass/tree/visitors/perform.rb +185 -278
  95. data/lib/sass/tree/visitors/set_options.rb +6 -20
  96. data/lib/sass/tree/visitors/to_css.rb +81 -234
  97. data/lib/sass/tree/warn_node.rb +2 -2
  98. data/lib/sass/tree/while_node.rb +2 -2
  99. data/lib/sass/util.rb +152 -522
  100. data/lib/sass/util/multibyte_string_scanner.rb +0 -2
  101. data/lib/sass/util/subset_map.rb +3 -4
  102. data/lib/sass/util/test.rb +1 -0
  103. data/lib/sass/version.rb +22 -20
  104. data/test/Gemfile +3 -0
  105. data/test/Gemfile.lock +10 -0
  106. data/test/sass/cache_test.rb +20 -62
  107. data/test/sass/callbacks_test.rb +1 -1
  108. data/test/sass/conversion_test.rb +2 -296
  109. data/test/sass/css2sass_test.rb +4 -23
  110. data/test/sass/engine_test.rb +354 -411
  111. data/test/sass/exec_test.rb +2 -2
  112. data/test/sass/extend_test.rb +145 -324
  113. data/test/sass/functions_test.rb +86 -873
  114. data/test/sass/importer_test.rb +21 -241
  115. data/test/sass/logger_test.rb +1 -1
  116. data/test/sass/more_results/more_import.css +1 -1
  117. data/test/sass/plugin_test.rb +26 -16
  118. data/test/sass/results/compact.css +1 -1
  119. data/test/sass/results/complex.css +4 -4
  120. data/test/sass/results/expanded.css +1 -1
  121. data/test/sass/results/import.css +1 -1
  122. data/test/sass/results/import_charset_ibm866.css +2 -2
  123. data/test/sass/results/mixins.css +17 -17
  124. data/test/sass/results/nested.css +1 -1
  125. data/test/sass/results/parent_ref.css +2 -2
  126. data/test/sass/results/script.css +3 -3
  127. data/test/sass/results/scss_import.css +1 -1
  128. data/test/sass/script_conversion_test.rb +7 -36
  129. data/test/sass/script_test.rb +53 -485
  130. data/test/sass/scss/css_test.rb +28 -143
  131. data/test/sass/scss/rx_test.rb +4 -4
  132. data/test/sass/scss/scss_test.rb +325 -2119
  133. data/test/sass/templates/scss_import.scss +1 -2
  134. data/test/sass/test_helper.rb +1 -1
  135. data/test/sass/util/multibyte_string_scanner_test.rb +1 -1
  136. data/test/sass/util/subset_map_test.rb +2 -2
  137. data/test/sass/util_test.rb +1 -86
  138. data/test/test_helper.rb +8 -37
  139. metadata +19 -66
  140. data/lib/sass/exec/base.rb +0 -187
  141. data/lib/sass/exec/sass_convert.rb +0 -264
  142. data/lib/sass/exec/sass_scss.rb +0 -424
  143. data/lib/sass/features.rb +0 -47
  144. data/lib/sass/script/tree.rb +0 -16
  145. data/lib/sass/script/tree/funcall.rb +0 -306
  146. data/lib/sass/script/tree/interpolation.rb +0 -118
  147. data/lib/sass/script/tree/list_literal.rb +0 -77
  148. data/lib/sass/script/tree/literal.rb +0 -45
  149. data/lib/sass/script/tree/map_literal.rb +0 -64
  150. data/lib/sass/script/tree/selector.rb +0 -26
  151. data/lib/sass/script/tree/variable.rb +0 -57
  152. data/lib/sass/script/value.rb +0 -11
  153. data/lib/sass/script/value/base.rb +0 -240
  154. data/lib/sass/script/value/bool.rb +0 -35
  155. data/lib/sass/script/value/color.rb +0 -680
  156. data/lib/sass/script/value/helpers.rb +0 -262
  157. data/lib/sass/script/value/list.rb +0 -113
  158. data/lib/sass/script/value/map.rb +0 -70
  159. data/lib/sass/script/value/string.rb +0 -97
  160. data/lib/sass/selector/pseudo.rb +0 -256
  161. data/lib/sass/source/map.rb +0 -210
  162. data/lib/sass/source/position.rb +0 -39
  163. data/lib/sass/source/range.rb +0 -41
  164. data/lib/sass/stack.rb +0 -120
  165. data/lib/sass/tree/at_root_node.rb +0 -83
  166. data/lib/sass/tree/error_node.rb +0 -18
  167. data/lib/sass/tree/keyframe_rule_node.rb +0 -15
  168. data/lib/sass/util/cross_platform_random.rb +0 -19
  169. data/lib/sass/util/normalized_map.rb +0 -130
  170. data/lib/sass/util/ordered_hash.rb +0 -192
  171. data/test/sass/compiler_test.rb +0 -232
  172. data/test/sass/encoding_test.rb +0 -219
  173. data/test/sass/source_map_test.rb +0 -977
  174. data/test/sass/superselector_test.rb +0 -191
  175. data/test/sass/util/normalized_map_test.rb +0 -51
  176. data/test/sass/value_helpers_test.rb +0 -179
@@ -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 < MiniTest::Test
9
+ class ScssCssTest < Test::Unit::TestCase
10
10
  include ScssTestHelper
11
11
 
12
12
  def test_basic_scss
@@ -94,7 +94,7 @@ foo {a /*: b; c */: d}
94
94
  SCSS
95
95
  end
96
96
 
97
- def test_crazy_comments
97
+ def test_crazy_comments
98
98
  # http://www.w3.org/Style/CSS/Test/CSS2.1/current/xhtml1/t040109-c17-comments-00-b.xht
99
99
  assert_equal <<CSS, render(<<SCSS)
100
100
  /* This is a CSS comment. */
@@ -499,24 +499,10 @@ SCSS
499
499
 
500
500
  def test_import_directive
501
501
  assert_parses '@import "foo.css";'
502
+ assert_parses "@import 'foo.css';"
502
503
  assert_parses '@import url("foo.css");'
503
504
  assert_parses "@import url('foo.css');"
504
505
  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
520
506
  end
521
507
 
522
508
  def test_string_import_directive_with_media
@@ -587,6 +573,7 @@ SCSS
587
573
  assert_parses <<SCSS
588
574
  @foo bar {
589
575
  a: b; }
576
+
590
577
  @bar baz {
591
578
  c: d; }
592
579
  SCSS
@@ -606,6 +593,7 @@ SCSS
606
593
  assert_equal <<CSS, render(<<SCSS)
607
594
  @foo {
608
595
  a: b; }
596
+
609
597
  @bar {
610
598
  a: b; }
611
599
  CSS
@@ -667,40 +655,15 @@ CSS
667
655
  SCSS
668
656
  end
669
657
 
670
- def test_keyframes
671
- assert_equal <<CSS, render(<<SCSS)
672
- @keyframes identifier {
673
- 0% {
674
- top: 0;
675
- left: 0; }
676
- 30% {
677
- top: 50px; }
678
- 68%, 72% {
679
- left: 50px; }
680
- 100% {
681
- top: 100px;
682
- left: 100%; } }
683
- CSS
684
- @keyframes identifier {
685
- 0% {top: 0; left: 0}
686
- 30% {top: 50px}
687
- 68%, 72% {left: 50px}
688
- 100% {top: 100px; left: 100%}
689
- }
690
- SCSS
691
- end
692
-
693
658
  ## Selectors
694
659
 
695
660
  # Taken from http://dev.w3.org/csswg/selectors4/#overview
696
- def test_summarized_selectors_with_element
661
+ def test_summarized_selectors
697
662
  assert_selector_parses('*')
698
663
  assert_selector_parses('E')
699
664
  assert_selector_parses('E:not(s)')
700
665
  assert_selector_parses('E:not(s1, s2)')
701
666
  assert_selector_parses('E:matches(s1, s2)')
702
- assert_selector_parses('E:has(s1, s2)')
703
- assert_selector_parses('E:has(> s1, > s2)')
704
667
  assert_selector_parses('E.warning')
705
668
  assert_selector_parses('E#myid')
706
669
  assert_selector_parses('E[foo]')
@@ -751,22 +714,20 @@ SCSS
751
714
  assert_selector_parses('E:last-of-type')
752
715
  assert_selector_parses('E:nth-last-of-type(n)')
753
716
  assert_selector_parses('E:only-of-type')
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)')
717
+ assert_selector_parses('E:nth-match(n of selector)')
718
+ assert_selector_parses('E:nth-last-match(n of selector)')
719
+ assert_selector_parses('E:column(selector)')
720
+ assert_selector_parses('E:nth-column(n)')
721
+ assert_selector_parses('E:nth-last-column(n)')
758
722
  assert_selector_parses('E F')
759
723
  assert_selector_parses('E > F')
760
724
  assert_selector_parses('E + F')
761
725
  assert_selector_parses('E ~ F')
762
726
  assert_selector_parses('E /foo/ F')
763
- silence_warnings {assert_selector_parses('E! > F')}
727
+ assert_selector_parses('E! > F')
764
728
 
765
729
  assert_selector_parses('E /ns|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)')
730
+ assert_selector_parses('E /*|foo/ F')
770
731
  end
771
732
 
772
733
  # Taken from http://dev.w3.org/csswg/selectors4/#overview, but without element
@@ -775,8 +736,6 @@ SCSS
775
736
  assert_selector_parses(':not(s)')
776
737
  assert_selector_parses(':not(s1, s2)')
777
738
  assert_selector_parses(':matches(s1, s2)')
778
- assert_selector_parses(':has(s1, s2)')
779
- assert_selector_parses(':has(> s1, > s2)')
780
739
  assert_selector_parses('.warning')
781
740
  assert_selector_parses('#myid')
782
741
  assert_selector_parses('[foo]')
@@ -827,14 +786,11 @@ SCSS
827
786
  assert_selector_parses(':last-of-type')
828
787
  assert_selector_parses(':nth-last-of-type(n)')
829
788
  assert_selector_parses(':only-of-type')
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)')
789
+ assert_selector_parses(':nth-match(n of selector)')
790
+ assert_selector_parses(':nth-last-match(n of selector)')
791
+ assert_selector_parses(':column(selector)')
792
+ assert_selector_parses(':nth-column(n)')
793
+ assert_selector_parses(':nth-last-column(n)')
838
794
  end
839
795
 
840
796
  def test_attribute_selectors_with_identifiers
@@ -874,18 +830,15 @@ SCSS
874
830
  def test_selectors_containing_selectors
875
831
  assert_selector_can_contain_selectors(':not(<sel>)')
876
832
  assert_selector_can_contain_selectors(':current(<sel>)')
877
- assert_selector_can_contain_selectors(':nth-child(n of <sel>)')
878
- assert_selector_can_contain_selectors(':nth-last-child(n of <sel>)')
833
+ assert_selector_can_contain_selectors(':nth-match(n of <sel>)')
834
+ assert_selector_can_contain_selectors(':nth-last-match(n of <sel>)')
835
+ assert_selector_can_contain_selectors(':column(<sel>)')
879
836
  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>)')
884
837
  end
885
838
 
886
839
  def assert_selector_can_contain_selectors(sel)
887
840
  try = lambda {|subsel| assert_selector_parses(sel.gsub('<sel>', subsel))}
888
-
841
+
889
842
  try['foo|bar']
890
843
  try['*|bar']
891
844
 
@@ -937,11 +890,11 @@ SCSS
937
890
  end
938
891
 
939
892
  def test_expression_fallback_selectors
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"')
893
+ assert_selector_parses('0%')
894
+ assert_selector_parses('60%')
895
+ assert_selector_parses('100%')
896
+ assert_selector_parses('12px')
897
+ assert_selector_parses('"foo"')
945
898
  end
946
899
 
947
900
  def test_functional_pseudo_selectors
@@ -978,29 +931,6 @@ SCSS
978
931
  assert_equal "E + F {\n a: b; }\n", render("E+F { a: b;} ")
979
932
  end
980
933
 
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
-
1004
934
  ## Errors
1005
935
 
1006
936
  def test_invalid_directives
@@ -1086,41 +1016,8 @@ SCSS
1086
1016
  assert_equal 1, e.sass_line
1087
1017
  end
1088
1018
 
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
-
1101
1019
  ## Regressions
1102
1020
 
1103
- def test_very_long_comment_doesnt_take_forever
1104
- string = 'asdf' * (100000)
1105
- assert_equal(<<CSS, render(<<SCSS))
1106
- /*
1107
- #{string}
1108
- */
1109
- CSS
1110
- /*
1111
- #{string}
1112
- */
1113
- SCSS
1114
- end
1115
-
1116
- def test_long_unclosed_comment_doesnt_take_forever
1117
- assert_raise_message(Sass::SyntaxError,
1118
- 'Invalid CSS after "/*": expected "/", was "//*************..."') {render(<<SCSS)}
1119
- /*
1120
- //**************************************************************************
1121
- SCSS
1122
- end
1123
-
1124
1021
  def test_double_space_string
1125
1022
  assert_equal(<<CSS, render(<<SCSS))
1126
1023
  .a {
@@ -1193,22 +1090,10 @@ SCSS
1193
1090
  #{selector} {
1194
1091
  a: b; }
1195
1092
  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
1208
1093
  end
1209
1094
 
1210
1095
  def render(scss, options = {})
1211
- tree = Sass::SCSS::CssParser.new(scss, options[:filename], nil).parse
1096
+ tree = Sass::SCSS::CssParser.new(scss, options[:filename]).parse
1212
1097
  tree.options = Sass::Engine::DEFAULT_OPTIONS.merge(options)
1213
1098
  tree.render
1214
1099
  end
@@ -3,7 +3,7 @@
3
3
  require File.dirname(__FILE__) + '/../../test_helper'
4
4
  require 'sass/engine'
5
5
 
6
- class ScssRxTest < MiniTest::Test
6
+ class ScssRxTest < Test::Unit::TestCase
7
7
  include Sass::SCSS::RX
8
8
 
9
9
  def test_identifiers
@@ -26,7 +26,6 @@ class ScssRxTest < MiniTest::Test
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
30
29
 
31
30
  assert_match IDENT, "foo-bar"
32
31
  assert_match IDENT, "f012-23"
@@ -60,6 +59,7 @@ class ScssRxTest < MiniTest::Test
60
59
  assert_no_match IDENT, ""
61
60
  assert_no_match IDENT, "1foo"
62
61
  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 < MiniTest::Test
144
144
  private
145
145
 
146
146
  def assert_match(rx, str)
147
- refute_nil(match = rx.match(str))
147
+ assert_not_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
- refute_equal str.size, match && match[0].size
153
+ assert_not_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 < MiniTest::Test
5
+ class ScssTest < Test::Unit::TestCase
6
6
  include ScssTestHelper
7
7
 
8
8
  ## One-Line Comments
@@ -115,14 +115,6 @@ 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
-
126
118
  def test_warn_directive
127
119
  expected_warning = <<EXPECTATION
128
120
  WARNING: this is a warning
@@ -171,51 +163,6 @@ CSS
171
163
  SCSS
172
164
  end
173
165
 
174
- def test_for_directive_with_same_start_and_end
175
- assert_equal <<CSS, render(<<SCSS)
176
- CSS
177
- .foo {
178
- @for $var from 1 to 1 {a: $var;}
179
- }
180
- SCSS
181
-
182
- assert_equal <<CSS, render(<<SCSS)
183
- .foo {
184
- a: 1; }
185
- CSS
186
- .foo {
187
- @for $var from 1 through 1 {a: $var;}
188
- }
189
- SCSS
190
- end
191
-
192
- def test_decrementing_estfor_directive
193
- assert_equal <<CSS, render(<<SCSS)
194
- .foo {
195
- a: 5;
196
- a: 4;
197
- a: 3;
198
- a: 2;
199
- a: 1; }
200
- CSS
201
- .foo {
202
- @for $var from 5 through 1 {a: $var;}
203
- }
204
- SCSS
205
-
206
- assert_equal <<CSS, render(<<SCSS)
207
- .foo {
208
- a: 5;
209
- a: 4;
210
- a: 3;
211
- a: 2; }
212
- CSS
213
- .foo {
214
- @for $var from 5 to 1 {a: $var;}
215
- }
216
- SCSS
217
- end
218
-
219
166
  def test_if_directive
220
167
  assert_equal <<CSS, render(<<SCSS)
221
168
  foo {
@@ -282,7 +229,7 @@ $i: 1;
282
229
  .foo {
283
230
  @while $i != 5 {
284
231
  a: $i;
285
- $i: $i + 1 !global;
232
+ $i: $i + 1;
286
233
  }
287
234
  }
288
235
  SCSS
@@ -315,31 +262,6 @@ c {
315
262
  SCSS
316
263
  end
317
264
 
318
- def test_destructuring_each_directive
319
- assert_equal <<CSS, render(<<SCSS)
320
- a {
321
- foo: 1px;
322
- bar: 2px;
323
- baz: 3px; }
324
-
325
- c {
326
- foo: "Value is bar";
327
- bar: "Value is baz";
328
- bang: "Value is "; }
329
- CSS
330
- a {
331
- @each $name, $number in (foo: 1px, bar: 2px, baz: 3px) {
332
- \#{$name}: $number;
333
- }
334
- }
335
- c {
336
- @each $key, $value in (foo bar) (bar, baz) bang {
337
- \#{$key}: "Value is \#{$value}";
338
- }
339
- }
340
- SCSS
341
- end
342
-
343
265
  def test_css_import_directive
344
266
  assert_equal "@import url(foo.css);\n", render('@import "foo.css";')
345
267
  assert_equal "@import url(foo.css);\n", render("@import 'foo.css';")
@@ -544,17 +466,11 @@ foo :baz {
544
466
  c: d; }
545
467
  foo bang:bop {
546
468
  e: f; }
547
- foo ::qux {
548
- g: h; }
549
- foo zap::fblthp {
550
- i: j; }
551
469
  CSS
552
470
  foo {
553
471
  .bar {a: b}
554
472
  :baz {c: d}
555
- bang:bop {e: f}
556
- ::qux {g: h}
557
- zap::fblthp {i: j}}
473
+ bang:bop {e: f}}
558
474
  SCSS
559
475
  end
560
476
 
@@ -659,7 +575,7 @@ SCSS
659
575
  end
660
576
 
661
577
  def test_parent_selector_with_subject
662
- silence_warnings {assert_equal <<CSS, render(<<SCSS)}
578
+ assert_equal <<CSS, render(<<SCSS)
663
579
  bar foo.baz! .bip {
664
580
  a: b; }
665
581
 
@@ -674,47 +590,6 @@ foo bar {
674
590
  SCSS
675
591
  end
676
592
 
677
- def test_parent_selector_with_suffix
678
- assert_equal <<CSS, render(<<SCSS)
679
- .foo-bar {
680
- a: b; }
681
- .foo_bar {
682
- c: d; }
683
- .foobar {
684
- e: f; }
685
- .foo123 {
686
- e: f; }
687
-
688
- :hover-suffix {
689
- g: h; }
690
- CSS
691
- .foo {
692
- &-bar {a: b}
693
- &_bar {c: d}
694
- &bar {e: f}
695
- &123 {e: f}
696
- }
697
-
698
- :hover {
699
- &-suffix {g: h}
700
- }
701
- SCSS
702
- end
703
-
704
- def test_unknown_directive_bubbling
705
- assert_equal(<<CSS, render(<<SCSS, :style => :nested))
706
- @fblthp {
707
- .foo .bar {
708
- a: b; } }
709
- CSS
710
- .foo {
711
- @fblthp {
712
- .bar {a: b}
713
- }
714
- }
715
- SCSS
716
- end
717
-
718
593
  ## Namespace Properties
719
594
 
720
595
  def test_namespace_properties
@@ -813,27 +688,18 @@ SCSS
813
688
  def test_no_namespace_properties_without_space_even_when_its_unambiguous
814
689
  render(<<SCSS)
815
690
  foo {
816
- bar:baz calc(1 + 2) {
691
+ bar:1px {
817
692
  bip: bop }}
818
693
  SCSS
819
694
  assert(false, "Expected syntax error")
820
695
  rescue Sass::SyntaxError => e
821
- assert_equal 'Invalid CSS after "bar:baz calc": expected selector, was "(1 + 2)"', e.message
696
+ assert_equal <<MESSAGE, e.message
697
+ Invalid CSS: a space is required between a property and its definition
698
+ when it has other properties nested beneath it.
699
+ MESSAGE
822
700
  assert_equal 2, e.sass_line
823
701
  end
824
702
 
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
-
837
703
  ## Mixins
838
704
 
839
705
  def test_basic_mixins
@@ -926,33 +792,6 @@ CSS
926
792
  SCSS
927
793
  end
928
794
 
929
- def test_keyframes_rules_in_content
930
- assert_equal <<CSS, render(<<SCSS)
931
- @keyframes identifier {
932
- 0% {
933
- top: 0;
934
- left: 0; }
935
- 30% {
936
- top: 50px; }
937
- 68%, 72% {
938
- left: 50px; }
939
- 100% {
940
- top: 100px;
941
- left: 100%; } }
942
- CSS
943
- @mixin keyframes {
944
- @keyframes identifier { @content }
945
- }
946
-
947
- @include keyframes {
948
- 0% {top: 0; left: 0}
949
- \#{"30%"} {top: 50px}
950
- 68%, 72% {left: 50px}
951
- 100% {top: 100px; left: 100%}
952
- }
953
- SCSS
954
- end
955
-
956
795
  ## Functions
957
796
 
958
797
  def test_basic_function
@@ -1142,2101 +981,579 @@ CSS
1142
981
  SCSS
1143
982
  end
1144
983
 
1145
- def test_mixin_var_keyword_args
1146
- assert_equal <<CSS, render(<<SCSS)
1147
- .foo {
1148
- a: 1;
1149
- b: 2;
1150
- c: 3; }
1151
- CSS
1152
- @mixin foo($args...) {
1153
- a: map-get(keywords($args), a);
1154
- b: map-get(keywords($args), b);
1155
- c: map-get(keywords($args), c);
984
+ def test_mixin_var_args_with_keyword
985
+ assert_raise_message(Sass::SyntaxError, "Positional arguments must come before keyword arguments.") {render <<SCSS}
986
+ @mixin foo($a, $b...) {
987
+ a: $a;
988
+ b: $b;
1156
989
  }
1157
990
 
1158
- .foo {@include foo($a: 1, $b: 2, $c: 3)}
991
+ .foo {@include foo($a: 1, 2, 3, 4)}
1159
992
  SCSS
1160
993
  end
1161
994
 
1162
- def test_mixin_empty_var_keyword_args
1163
- assert_equal <<CSS, render(<<SCSS)
1164
- .foo {
1165
- length: 0; }
1166
- CSS
1167
- @mixin foo($args...) {
1168
- length: length(keywords($args));
995
+ def test_mixin_keyword_for_var_arg
996
+ assert_raise_message(Sass::SyntaxError, "Argument $b of mixin foo cannot be used as a named argument.") {render <<SCSS}
997
+ @mixin foo($a, $b...) {
998
+ a: $a;
999
+ b: $b;
1169
1000
  }
1170
1001
 
1171
- .foo {@include foo}
1002
+ .foo {@include foo(1, $b: 2 3 4)}
1172
1003
  SCSS
1173
1004
  end
1174
1005
 
1175
- def test_mixin_map_splat
1176
- assert_equal <<CSS, render(<<SCSS)
1177
- .foo {
1178
- a: 1;
1179
- b: 2;
1180
- c: 3; }
1181
- CSS
1182
- @mixin foo($a, $b, $c) {
1006
+ def test_mixin_keyword_for_unknown_arg_with_var_args
1007
+ assert_raise_message(Sass::SyntaxError, "Mixin foo doesn't have an argument named $c.") {render <<SCSS}
1008
+ @mixin foo($a, $b...) {
1183
1009
  a: $a;
1184
1010
  b: $b;
1185
- c: $c;
1186
1011
  }
1187
1012
 
1188
- .foo {
1189
- $map: (a: 1, b: 2, c: 3);
1190
- @include foo($map...);
1191
- }
1013
+ .foo {@include foo(1, $c: 2 3 4)}
1192
1014
  SCSS
1193
1015
  end
1194
1016
 
1195
- def test_mixin_map_and_list_splat
1017
+ def test_function_var_args
1196
1018
  assert_equal <<CSS, render(<<SCSS)
1197
1019
  .foo {
1198
- a: x;
1199
- b: y;
1200
- c: z;
1201
- d: 1;
1202
- e: 2;
1203
- f: 3; }
1204
- CSS
1205
- @mixin foo($a, $b, $c, $d, $e, $f) {
1206
- a: $a;
1207
- b: $b;
1208
- c: $c;
1209
- d: $d;
1210
- e: $e;
1211
- f: $f;
1020
+ val: "a: 1, b: 2, 3, 4"; }
1021
+ CSS
1022
+ @function foo($a, $b...) {
1023
+ @return "a: \#{$a}, b: \#{$b}";
1212
1024
  }
1213
1025
 
1214
- .foo {
1215
- $list: x y z;
1216
- $map: (d: 1, e: 2, f: 3);
1217
- @include foo($list..., $map...);
1218
- }
1026
+ .foo {val: foo(1, 2, 3, 4)}
1219
1027
  SCSS
1220
1028
  end
1221
1029
 
1222
- def test_mixin_map_splat_takes_precedence_over_pass_through
1030
+ def test_function_empty_var_args
1223
1031
  assert_equal <<CSS, render(<<SCSS)
1224
1032
  .foo {
1225
- a: 1;
1226
- b: 2;
1227
- c: z; }
1033
+ val: "a: 1, b: 0"; }
1228
1034
  CSS
1229
- @mixin foo($args...) {
1230
- $map: (c: z);
1231
- @include bar($args..., $map...);
1232
- }
1233
-
1234
- @mixin bar($a, $b, $c) {
1235
- a: $a;
1236
- b: $b;
1237
- c: $c;
1035
+ @function foo($a, $b...) {
1036
+ @return "a: \#{$a}, b: \#{length($b)}";
1238
1037
  }
1239
1038
 
1240
- .foo {
1241
- @include foo(1, $b: 2, $c: 3);
1242
- }
1039
+ .foo {val: foo(1)}
1243
1040
  SCSS
1244
1041
  end
1245
1042
 
1246
- def test_mixin_list_of_pairs_splat_treated_as_list
1043
+ def test_function_var_args_act_like_list
1247
1044
  assert_equal <<CSS, render(<<SCSS)
1248
1045
  .foo {
1249
- a: a 1;
1250
- b: b 2;
1251
- c: c 3; }
1046
+ val: "a: 3, b: 3"; }
1252
1047
  CSS
1253
- @mixin foo($a, $b, $c) {
1254
- a: $a;
1255
- b: $b;
1256
- c: $c;
1048
+ @function foo($a, $b...) {
1049
+ @return "a: \#{length($b)}, b: \#{nth($b, 2)}";
1257
1050
  }
1258
1051
 
1259
- .foo {
1260
- @include foo((a 1, b 2, c 3)...);
1261
- }
1052
+ .foo {val: foo(1, 2, 3, 4)}
1262
1053
  SCSS
1263
1054
  end
1264
1055
 
1265
- def test_mixin_splat_after_keyword_args
1056
+ def test_function_splat_args
1266
1057
  assert_equal <<CSS, render(<<SCSS)
1267
1058
  .foo {
1268
- a: 1;
1269
- b: 2;
1270
- c: 3; }
1059
+ val: "a: 1, b: 2, c: 3, d: 4"; }
1271
1060
  CSS
1272
- @mixin foo($a, $b, $c) {
1273
- a: 1;
1274
- b: 2;
1275
- c: 3;
1061
+ @function foo($a, $b, $c, $d) {
1062
+ @return "a: \#{$a}, b: \#{$b}, c: \#{$c}, d: \#{$d}";
1276
1063
  }
1277
1064
 
1278
- .foo {
1279
- @include foo(1, $c: 3, 2...);
1280
- }
1065
+ $list: 2, 3, 4;
1066
+ .foo {val: foo(1, $list...)}
1281
1067
  SCSS
1282
1068
  end
1283
1069
 
1284
- def test_mixin_keyword_args_after_splat
1070
+ def test_function_splat_expression
1285
1071
  assert_equal <<CSS, render(<<SCSS)
1286
1072
  .foo {
1287
- a: 1;
1288
- b: 2;
1289
- c: 3; }
1073
+ val: "a: 1, b: 2, c: 3, d: 4"; }
1290
1074
  CSS
1291
- @mixin foo($a, $b, $c) {
1292
- a: 1;
1293
- b: 2;
1294
- c: 3;
1075
+ @function foo($a, $b, $c, $d) {
1076
+ @return "a: \#{$a}, b: \#{$b}, c: \#{$c}, d: \#{$d}";
1295
1077
  }
1296
1078
 
1297
- .foo {
1298
- @include foo(1, 2..., $c: 3);
1299
- }
1079
+ .foo {val: foo(1, (2, 3, 4)...)}
1300
1080
  SCSS
1301
1081
  end
1302
1082
 
1303
- def test_mixin_keyword_splat_after_keyword_args
1083
+ def test_function_splat_args_with_var_args
1304
1084
  assert_equal <<CSS, render(<<SCSS)
1305
1085
  .foo {
1306
- a: 1;
1307
- b: 2;
1308
- c: 3; }
1086
+ val: "a: 1, b: 2, 3, 4"; }
1309
1087
  CSS
1310
- @mixin foo($a, $b, $c) {
1311
- a: 1;
1312
- b: 2;
1313
- c: 3;
1088
+ @function foo($a, $b...) {
1089
+ @return "a: \#{$a}, b: \#{$b}";
1314
1090
  }
1315
1091
 
1316
- .foo {
1317
- @include foo(1, $b: 2, (c: 3)...);
1318
- }
1092
+ $list: 2, 3, 4;
1093
+ .foo {val: foo(1, $list...)}
1319
1094
  SCSS
1320
1095
  end
1321
1096
 
1322
- def test_mixin_triple_keyword_splat_merge
1097
+ def test_function_splat_args_with_var_args_and_normal_args
1323
1098
  assert_equal <<CSS, render(<<SCSS)
1324
1099
  .foo {
1325
- foo: 1;
1326
- bar: 2;
1327
- kwarg: 3;
1328
- a: 3;
1329
- b: 2;
1330
- c: 3; }
1100
+ val: "a: 1, b: 2, c: 3, 4"; }
1331
1101
  CSS
1332
- @mixin foo($foo, $bar, $kwarg, $a, $b, $c) {
1333
- foo: $foo;
1334
- bar: $bar;
1335
- kwarg: $kwarg;
1336
- a: $a;
1337
- b: $b;
1338
- c: $c;
1339
- }
1340
-
1341
- @mixin bar($args...) {
1342
- @include foo($args..., $bar: 2, $a: 2, $b: 2, (kwarg: 3, a: 3, c: 3)...);
1102
+ @function foo($a, $b, $c...) {
1103
+ @return "a: \#{$a}, b: \#{$b}, c: \#{$c}";
1343
1104
  }
1344
1105
 
1345
- .foo {
1346
- @include bar($foo: 1, $a: 1, $b: 1, $c: 1);
1347
- }
1106
+ $list: 2, 3, 4;
1107
+ .foo {val: foo(1, $list...)}
1348
1108
  SCSS
1349
1109
  end
1350
1110
 
1351
- def test_mixin_map_splat_converts_hyphens_and_underscores_for_real_args
1111
+ def test_function_splat_args_with_var_args_preserves_separator
1352
1112
  assert_equal <<CSS, render(<<SCSS)
1353
1113
  .foo {
1354
- a: 1;
1355
- b: 2;
1356
- c: 3;
1357
- d: 4; }
1114
+ val: "a: 1, b: 2 3 4 5"; }
1358
1115
  CSS
1359
- @mixin foo($a-1, $b-2, $c_3, $d_4) {
1360
- a: $a-1;
1361
- b: $b-2;
1362
- c: $c_3;
1363
- d: $d_4;
1116
+ @function foo($a, $b...) {
1117
+ @return "a: \#{$a}, b: \#{$b}";
1364
1118
  }
1365
1119
 
1366
- .foo {
1367
- $map: (a-1: 1, b_2: 2, c-3: 3, d_4: 4);
1368
- @include foo($map...);
1369
- }
1120
+ $list: 3 4 5;
1121
+ .foo {val: foo(1, 2, $list...)}
1370
1122
  SCSS
1371
1123
  end
1372
1124
 
1373
- def test_mixin_map_splat_doesnt_convert_hyphens_and_underscores_for_var_args
1125
+ def test_function_var_and_splat_args_pass_through_keywords
1374
1126
  assert_equal <<CSS, render(<<SCSS)
1375
1127
  .foo {
1376
- a-1: 1;
1377
- b_2: 2;
1378
- c-3: 3;
1379
- d_4: 4; }
1380
- CSS
1381
- @mixin foo($args...) {
1382
- @each $key, $value in keywords($args) {
1383
- \#{$key}: $value;
1384
- }
1128
+ val: "a: 3, b: 1, c: 2"; }
1129
+ CSS
1130
+ @function foo($a...) {
1131
+ @return bar($a...);
1385
1132
  }
1386
1133
 
1387
- .foo {
1388
- $map: (a-1: 1, b_2: 2, c-3: 3, d_4: 4);
1389
- @include foo($map...);
1134
+ @function bar($b, $c, $a) {
1135
+ @return "a: \#{$a}, b: \#{$b}, c: \#{$c}";
1390
1136
  }
1137
+
1138
+ .foo {val: foo(1, $c: 2, $a: 3)}
1391
1139
  SCSS
1392
1140
  end
1393
1141
 
1394
- def test_mixin_conflicting_splat_after_keyword_args
1395
- assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render(<<SCSS)}
1396
- Mixin foo was passed argument $b both by position and by name.
1397
- MESSAGE
1398
- @mixin foo($a, $b, $c) {
1399
- a: 1;
1400
- b: 2;
1401
- c: 3;
1142
+ def test_function_var_args_with_keyword
1143
+ assert_raise_message(Sass::SyntaxError, "Positional arguments must come before keyword arguments.") {render <<SCSS}
1144
+ @function foo($a, $b...) {
1145
+ @return "a: \#{$a}, b: $b";
1402
1146
  }
1403
1147
 
1404
- .foo {
1405
- @include foo(1, $b: 2, 3...);
1406
- }
1148
+ .foo {val: foo($a: 1, 2, 3, 4)}
1407
1149
  SCSS
1408
1150
  end
1409
1151
 
1410
- def test_mixin_keyword_splat_must_have_string_keys
1411
- assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render <<SCSS}
1412
- Variable keyword argument map must have string keys.
1413
- 12 is not a string in (12: 1).
1414
- MESSAGE
1415
- @mixin foo($a) {
1416
- a: $a;
1417
- }
1418
-
1419
- .foo {@include foo((12: 1)...)}
1420
- SCSS
1421
- end
1422
-
1423
- def test_mixin_positional_arg_after_splat
1424
- assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render(<<SCSS)}
1425
- Only keyword arguments may follow variable arguments (...).
1426
- MESSAGE
1427
- @mixin foo($a, $b, $c) {
1428
- a: 1;
1429
- b: 2;
1430
- c: 3;
1431
- }
1432
-
1433
- .foo {
1434
- @include foo(1, 2..., 3);
1435
- }
1436
- SCSS
1437
- end
1438
-
1439
- def test_mixin_var_args_with_keyword
1440
- assert_raise_message(Sass::SyntaxError, "Positional arguments must come before keyword arguments.") {render <<SCSS}
1441
- @mixin foo($a, $b...) {
1442
- a: $a;
1443
- b: $b;
1444
- }
1445
-
1446
- .foo {@include foo($a: 1, 2, 3, 4)}
1447
- SCSS
1448
- end
1449
-
1450
- def test_mixin_keyword_for_var_arg
1451
- assert_raise_message(Sass::SyntaxError, "Argument $b of mixin foo cannot be used as a named argument.") {render <<SCSS}
1452
- @mixin foo($a, $b...) {
1453
- a: $a;
1454
- b: $b;
1455
- }
1456
-
1457
- .foo {@include foo(1, $b: 2 3 4)}
1458
- SCSS
1459
- end
1460
-
1461
- def test_mixin_keyword_for_unknown_arg_with_var_args
1462
- assert_raise_message(Sass::SyntaxError, "Mixin foo doesn't have an argument named $c.") {render <<SCSS}
1463
- @mixin foo($a, $b...) {
1464
- a: $a;
1465
- b: $b;
1466
- }
1467
-
1468
- .foo {@include foo(1, $c: 2 3 4)}
1469
- SCSS
1470
- end
1471
-
1472
- def test_mixin_map_splat_before_list_splat
1473
- assert_raise_message(Sass::SyntaxError, "Variable keyword arguments must be a map (was (2 3)).") {render <<SCSS}
1474
- @mixin foo($a, $b, $c) {
1475
- a: $a;
1476
- b: $b;
1477
- c: $c;
1478
- }
1479
-
1480
- .foo {
1481
- @include foo((a: 1)..., (2 3)...);
1482
- }
1483
- SCSS
1484
- end
1485
-
1486
- def test_mixin_map_splat_with_unknown_keyword
1487
- assert_raise_message(Sass::SyntaxError, "Mixin foo doesn't have an argument named $c.") {render <<SCSS}
1488
- @mixin foo($a, $b) {
1489
- a: $a;
1490
- b: $b;
1491
- }
1492
-
1493
- .foo {
1494
- @include foo(1, 2, (c: 1)...);
1495
- }
1496
- SCSS
1497
- end
1498
-
1499
- def test_mixin_map_splat_with_wrong_type
1500
- assert_raise_message(Sass::SyntaxError, "Variable keyword arguments must be a map (was 12).") {render <<SCSS}
1501
- @mixin foo($a, $b) {
1502
- a: $a;
1503
- b: $b;
1504
- }
1505
-
1506
- .foo {
1507
- @include foo((1, 2)..., 12...);
1508
- }
1509
- SCSS
1510
- end
1511
-
1512
- def test_function_var_args
1513
- assert_equal <<CSS, render(<<SCSS)
1514
- .foo {
1515
- val: "a: 1, b: 2, 3, 4"; }
1516
- CSS
1517
- @function foo($a, $b...) {
1518
- @return "a: \#{$a}, b: \#{$b}";
1519
- }
1520
-
1521
- .foo {val: foo(1, 2, 3, 4)}
1522
- SCSS
1523
- end
1524
-
1525
- def test_function_empty_var_args
1526
- assert_equal <<CSS, render(<<SCSS)
1527
- .foo {
1528
- val: "a: 1, b: 0"; }
1529
- CSS
1530
- @function foo($a, $b...) {
1531
- @return "a: \#{$a}, b: \#{length($b)}";
1532
- }
1533
-
1534
- .foo {val: foo(1)}
1535
- SCSS
1536
- end
1537
-
1538
- def test_function_var_args_act_like_list
1539
- assert_equal <<CSS, render(<<SCSS)
1540
- .foo {
1541
- val: "a: 3, b: 3"; }
1542
- CSS
1543
- @function foo($a, $b...) {
1544
- @return "a: \#{length($b)}, b: \#{nth($b, 2)}";
1545
- }
1546
-
1547
- .foo {val: foo(1, 2, 3, 4)}
1548
- SCSS
1549
- end
1550
-
1551
- def test_function_splat_args
1552
- assert_equal <<CSS, render(<<SCSS)
1553
- .foo {
1554
- val: "a: 1, b: 2, c: 3, d: 4"; }
1555
- CSS
1556
- @function foo($a, $b, $c, $d) {
1557
- @return "a: \#{$a}, b: \#{$b}, c: \#{$c}, d: \#{$d}";
1558
- }
1559
-
1560
- $list: 2, 3, 4;
1561
- .foo {val: foo(1, $list...)}
1562
- SCSS
1563
- end
1564
-
1565
- def test_function_splat_expression
1566
- assert_equal <<CSS, render(<<SCSS)
1567
- .foo {
1568
- val: "a: 1, b: 2, c: 3, d: 4"; }
1569
- CSS
1570
- @function foo($a, $b, $c, $d) {
1571
- @return "a: \#{$a}, b: \#{$b}, c: \#{$c}, d: \#{$d}";
1572
- }
1573
-
1574
- .foo {val: foo(1, (2, 3, 4)...)}
1575
- SCSS
1576
- end
1577
-
1578
- def test_function_splat_args_with_var_args
1579
- assert_equal <<CSS, render(<<SCSS)
1580
- .foo {
1581
- val: "a: 1, b: 2, 3, 4"; }
1582
- CSS
1583
- @function foo($a, $b...) {
1584
- @return "a: \#{$a}, b: \#{$b}";
1585
- }
1586
-
1587
- $list: 2, 3, 4;
1588
- .foo {val: foo(1, $list...)}
1589
- SCSS
1590
- end
1591
-
1592
- def test_function_splat_args_with_var_args_and_normal_args
1593
- assert_equal <<CSS, render(<<SCSS)
1594
- .foo {
1595
- val: "a: 1, b: 2, c: 3, 4"; }
1596
- CSS
1597
- @function foo($a, $b, $c...) {
1598
- @return "a: \#{$a}, b: \#{$b}, c: \#{$c}";
1599
- }
1600
-
1601
- $list: 2, 3, 4;
1602
- .foo {val: foo(1, $list...)}
1603
- SCSS
1604
- end
1605
-
1606
- def test_function_splat_args_with_var_args_preserves_separator
1607
- assert_equal <<CSS, render(<<SCSS)
1608
- .foo {
1609
- val: "a: 1, b: 2 3 4 5"; }
1610
- CSS
1152
+ def test_function_keyword_for_var_arg
1153
+ assert_raise_message(Sass::SyntaxError, "Argument $b of function foo cannot be used as a named argument.") {render <<SCSS}
1611
1154
  @function foo($a, $b...) {
1612
- @return "a: \#{$a}, b: \#{$b}";
1613
- }
1614
-
1615
- $list: 3 4 5;
1616
- .foo {val: foo(1, 2, $list...)}
1617
- SCSS
1618
- end
1619
-
1620
- def test_function_var_and_splat_args_pass_through_keywords
1621
- assert_equal <<CSS, render(<<SCSS)
1622
- .foo {
1623
- val: "a: 3, b: 1, c: 2"; }
1624
- CSS
1625
- @function foo($a...) {
1626
- @return bar($a...);
1627
- }
1628
-
1629
- @function bar($b, $c, $a) {
1630
- @return "a: \#{$a}, b: \#{$b}, c: \#{$c}";
1631
- }
1632
-
1633
- .foo {val: foo(1, $c: 2, $a: 3)}
1634
- SCSS
1635
- end
1636
-
1637
- def test_function_var_keyword_args
1638
- assert_equal <<CSS, render(<<SCSS)
1639
- .foo {
1640
- val: "a: 1, b: 2, c: 3"; }
1641
- CSS
1642
- @function foo($args...) {
1643
- @return "a: \#{map-get(keywords($args), a)}, " +
1644
- "b: \#{map-get(keywords($args), b)}, " +
1645
- "c: \#{map-get(keywords($args), c)}";
1646
- }
1647
-
1648
- .foo {val: foo($a: 1, $b: 2, $c: 3)}
1649
- SCSS
1650
- end
1651
-
1652
- def test_function_empty_var_keyword_args
1653
- assert_equal <<CSS, render(<<SCSS)
1654
- .foo {
1655
- length: 0; }
1656
- CSS
1657
- @function foo($args...) {
1658
- @return length(keywords($args));
1659
- }
1660
-
1661
- .foo {length: foo()}
1662
- SCSS
1663
- end
1664
-
1665
- def test_function_map_splat
1666
- assert_equal <<CSS, render(<<SCSS)
1667
- .foo {
1668
- val: "a: 1, b: 2, c: 3"; }
1669
- CSS
1670
- @function foo($a, $b, $c) {
1671
- @return "a: \#{$a}, b: \#{$b}, c: \#{$c}";
1672
- }
1673
-
1674
- .foo {
1675
- $map: (a: 1, b: 2, c: 3);
1676
- val: foo($map...);
1677
- }
1678
- SCSS
1679
- end
1680
-
1681
- def test_function_map_and_list_splat
1682
- assert_equal <<CSS, render(<<SCSS)
1683
- .foo {
1684
- val: "a: x, b: y, c: z, d: 1, e: 2, f: 3"; }
1685
- CSS
1686
- @function foo($a, $b, $c, $d, $e, $f) {
1687
- @return "a: \#{$a}, b: \#{$b}, c: \#{$c}, d: \#{$d}, e: \#{$e}, f: \#{$f}";
1688
- }
1689
-
1690
- .foo {
1691
- $list: x y z;
1692
- $map: (d: 1, e: 2, f: 3);
1693
- val: foo($list..., $map...);
1694
- }
1695
- SCSS
1696
- end
1697
-
1698
- def test_function_map_splat_takes_precedence_over_pass_through
1699
- assert_equal <<CSS, render(<<SCSS)
1700
- .foo {
1701
- val: "a: 1, b: 2, c: z"; }
1702
- CSS
1703
- @function foo($args...) {
1704
- $map: (c: z);
1705
- @return bar($args..., $map...);
1706
- }
1707
-
1708
- @function bar($a, $b, $c) {
1709
- @return "a: \#{$a}, b: \#{$b}, c: \#{$c}";
1710
- }
1711
-
1712
- .foo {
1713
- val: foo(1, $b: 2, $c: 3);
1714
- }
1715
- SCSS
1716
- end
1717
-
1718
- def test_ruby_function_map_splat_takes_precedence_over_pass_through
1719
- assert_equal <<CSS, render(<<SCSS)
1720
- .foo {
1721
- val: 1 2 3 z; }
1722
- CSS
1723
- @function foo($args...) {
1724
- $map: (val: z);
1725
- @return append($args..., $map...);
1726
- }
1727
-
1728
- .foo {
1729
- val: foo(1 2 3, $val: 4)
1730
- }
1731
- SCSS
1732
- end
1733
-
1734
- def test_function_list_of_pairs_splat_treated_as_list
1735
- assert_equal <<CSS, render(<<SCSS)
1736
- .foo {
1737
- val: "a: a 1, b: b 2, c: c 3"; }
1738
- CSS
1739
- @function foo($a, $b, $c) {
1740
- @return "a: \#{$a}, b: \#{$b}, c: \#{$c}";
1741
- }
1742
-
1743
- .foo {
1744
- val: foo((a 1, b 2, c 3)...);
1745
- }
1746
- SCSS
1747
- end
1748
-
1749
- def test_function_splat_after_keyword_args
1750
- assert_equal <<CSS, render(<<SCSS)
1751
- .foo {
1752
- val: "a: 1, b: 2, c: 3"; }
1753
- CSS
1754
- @function foo($a, $b, $c) {
1755
- @return "a: \#{$a}, b: \#{$b}, c: \#{$c}";
1756
- }
1757
-
1758
- .foo {
1759
- val: foo(1, $c: 3, 2...);
1760
- }
1761
- SCSS
1762
- end
1763
-
1764
- def test_function_keyword_args_after_splat
1765
- assert_equal <<CSS, render(<<SCSS)
1766
- .foo {
1767
- val: "a: 1, b: 2, c: 3"; }
1768
- CSS
1769
- @function foo($a, $b, $c) {
1770
- @return "a: \#{$a}, b: \#{$b}, c: \#{$c}";
1771
- }
1772
-
1773
- .foo {
1774
- val: foo(1, 2..., $c: 3);
1775
- }
1776
- SCSS
1777
- end
1778
-
1779
- def test_function_keyword_splat_after_keyword_args
1780
- assert_equal <<CSS, render(<<SCSS)
1781
- .foo {
1782
- val: "a: 1, b: 2, c: 3"; }
1783
- CSS
1784
- @function foo($a, $b, $c) {
1785
- @return "a: \#{$a}, b: \#{$b}, c: \#{$c}";
1786
- }
1787
-
1788
- .foo {
1789
- val: foo(1, $b: 2, (c: 3)...);
1790
- }
1791
- SCSS
1792
- end
1793
-
1794
- def test_function_triple_keyword_splat_merge
1795
- assert_equal <<CSS, render(<<SCSS)
1796
- .foo {
1797
- val: "foo: 1, bar: 2, kwarg: 3, a: 3, b: 2, c: 3"; }
1798
- CSS
1799
- @function foo($foo, $bar, $kwarg, $a, $b, $c) {
1800
- @return "foo: \#{$foo}, bar: \#{$bar}, kwarg: \#{$kwarg}, a: \#{$a}, b: \#{$b}, c: \#{$c}";
1801
- }
1802
-
1803
- @function bar($args...) {
1804
- @return foo($args..., $bar: 2, $a: 2, $b: 2, (kwarg: 3, a: 3, c: 3)...);
1805
- }
1806
-
1807
- .foo {
1808
- val: bar($foo: 1, $a: 1, $b: 1, $c: 1);
1809
- }
1810
- SCSS
1811
- end
1812
-
1813
- def test_function_conflicting_splat_after_keyword_args
1814
- assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render(<<SCSS)}
1815
- Function foo was passed argument $b both by position and by name.
1816
- MESSAGE
1817
- @function foo($a, $b, $c) {
1818
- @return "a: \#{$a}, b: \#{$b}, c: \#{$c}";
1819
- }
1820
-
1821
- .foo {
1822
- val: foo(1, $b: 2, 3...);
1823
- }
1824
- SCSS
1825
- end
1826
-
1827
- def test_function_positional_arg_after_splat
1828
- assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render(<<SCSS)}
1829
- Only keyword arguments may follow variable arguments (...).
1830
- MESSAGE
1831
- @function foo($a, $b, $c) {
1832
- @return "a: \#{$a}, b: \#{$b}, c: \#{$c}";
1833
- }
1834
-
1835
- .foo {
1836
- val: foo(1, 2..., 3);
1837
- }
1838
- SCSS
1839
- end
1840
-
1841
- def test_function_var_args_with_keyword
1842
- assert_raise_message(Sass::SyntaxError, "Positional arguments must come before keyword arguments.") {render <<SCSS}
1843
- @function foo($a, $b...) {
1844
- @return "a: \#{$a}, b: \#{$b}";
1845
- }
1846
-
1847
- .foo {val: foo($a: 1, 2, 3, 4)}
1848
- SCSS
1849
- end
1850
-
1851
- def test_function_keyword_for_var_arg
1852
- assert_raise_message(Sass::SyntaxError, "Argument $b of function foo cannot be used as a named argument.") {render <<SCSS}
1853
- @function foo($a, $b...) {
1854
- @return "a: \#{$a}, b: \#{$b}";
1855
- }
1856
-
1857
- .foo {val: foo(1, $b: 2 3 4)}
1858
- SCSS
1859
- end
1860
-
1861
- def test_function_keyword_for_unknown_arg_with_var_args
1862
- assert_raise_message(Sass::SyntaxError, "Function foo doesn't have an argument named $c.") {render <<SCSS}
1863
- @function foo($a, $b...) {
1864
- @return "a: \#{$a}, b: \#{length($b)}";
1865
- }
1866
-
1867
- .foo {val: foo(1, $c: 2 3 4)}
1868
- SCSS
1869
- end
1870
-
1871
- def test_function_var_args_passed_to_native
1872
- assert_equal <<CSS, render(<<SCSS)
1873
- .foo {
1874
- val: #102035; }
1875
- CSS
1876
- @function foo($args...) {
1877
- @return adjust-color($args...);
1878
- }
1879
-
1880
- .foo {val: foo(#102030, $blue: 5)}
1881
- SCSS
1882
- end
1883
-
1884
- def test_function_map_splat_before_list_splat
1885
- assert_raise_message(Sass::SyntaxError, "Variable keyword arguments must be a map (was (2 3)).") {render <<SCSS}
1886
- @function foo($a, $b, $c) {
1887
- @return "a: \#{$a}, b: \#{$b}, c: \#{$c}";
1888
- }
1889
-
1890
- .foo {
1891
- val: foo((a: 1)..., (2 3)...);
1892
- }
1893
- SCSS
1894
- end
1895
-
1896
- def test_function_map_splat_with_unknown_keyword
1897
- assert_raise_message(Sass::SyntaxError, "Function foo doesn't have an argument named $c.") {render <<SCSS}
1898
- @function foo($a, $b) {
1899
- @return "a: \#{$a}, b: \#{$b}";
1900
- }
1901
-
1902
- .foo {
1903
- val: foo(1, 2, (c: 1)...);
1904
- }
1905
- SCSS
1906
- end
1907
-
1908
- def test_function_map_splat_with_wrong_type
1909
- assert_raise_message(Sass::SyntaxError, "Variable keyword arguments must be a map (was 12).") {render <<SCSS}
1910
- @function foo($a, $b) {
1911
- @return "a: \#{$a}, b: \#{$b}";
1912
- }
1913
-
1914
- .foo {
1915
- val: foo((1, 2)..., 12...);
1916
- }
1917
- SCSS
1918
- end
1919
-
1920
- def test_function_keyword_splat_must_have_string_keys
1921
- assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render <<SCSS}
1922
- Variable keyword argument map must have string keys.
1923
- 12 is not a string in (12: 1).
1924
- MESSAGE
1925
- @function foo($a) {
1926
- @return $a;
1927
- }
1928
-
1929
- .foo {val: foo((12: 1)...)}
1930
- SCSS
1931
- end
1932
-
1933
- ## Interpolation
1934
-
1935
- def test_basic_selector_interpolation
1936
- assert_equal <<CSS, render(<<SCSS)
1937
- foo ab baz {
1938
- a: b; }
1939
- CSS
1940
- foo \#{'a' + 'b'} baz {a: b}
1941
- SCSS
1942
- assert_equal <<CSS, render(<<SCSS)
1943
- foo.bar baz {
1944
- a: b; }
1945
- CSS
1946
- foo\#{".bar"} baz {a: b}
1947
- SCSS
1948
- assert_equal <<CSS, render(<<SCSS)
1949
- foo.bar baz {
1950
- a: b; }
1951
- CSS
1952
- \#{"foo"}.bar baz {a: b}
1953
- SCSS
1954
- end
1955
-
1956
- def test_selector_only_interpolation
1957
- assert_equal <<CSS, render(<<SCSS)
1958
- foo bar {
1959
- a: b; }
1960
- CSS
1961
- \#{"foo" + " bar"} {a: b}
1962
- SCSS
1963
- end
1964
-
1965
- def test_selector_interpolation_before_element_name
1966
- assert_equal <<CSS, render(<<SCSS)
1967
- foo barbaz {
1968
- a: b; }
1969
- CSS
1970
- \#{"foo" + " bar"}baz {a: b}
1971
- SCSS
1972
- end
1973
-
1974
- def test_selector_interpolation_in_string
1975
- assert_equal <<CSS, render(<<SCSS)
1976
- foo[val="bar foo bar baz"] {
1977
- a: b; }
1978
- CSS
1979
- foo[val="bar \#{"foo" + " bar"} baz"] {a: b}
1980
- SCSS
1981
- end
1982
-
1983
- def test_selector_interpolation_in_pseudoclass
1984
- assert_equal <<CSS, render(<<SCSS)
1985
- foo:nth-child(5n) {
1986
- a: b; }
1987
- CSS
1988
- foo:nth-child(\#{5 + "n"}) {a: b}
1989
- SCSS
1990
- end
1991
-
1992
- def test_selector_interpolation_at_class_begininng
1993
- assert_equal <<CSS, render(<<SCSS)
1994
- .zzz {
1995
- a: b; }
1996
- CSS
1997
- $zzz: zzz;
1998
- .\#{$zzz} { a: b; }
1999
- SCSS
2000
- end
2001
-
2002
- def test_selector_interpolation_at_id_begininng
2003
- assert_equal <<CSS, render(<<SCSS)
2004
- #zzz {
2005
- a: b; }
2006
- CSS
2007
- $zzz: zzz;
2008
- #\#{$zzz} { a: b; }
2009
- SCSS
2010
- end
2011
-
2012
- def test_selector_interpolation_at_pseudo_begininng
2013
- assert_equal <<CSS, render(<<SCSS)
2014
- :zzz::zzz {
2015
- a: b; }
2016
- CSS
2017
- $zzz: zzz;
2018
- :\#{$zzz}::\#{$zzz} { a: b; }
2019
- SCSS
2020
- end
2021
-
2022
- def test_selector_interpolation_at_attr_beginning
2023
- assert_equal <<CSS, render(<<SCSS)
2024
- [zzz=foo] {
2025
- a: b; }
2026
- CSS
2027
- $zzz: zzz;
2028
- [\#{$zzz}=foo] { a: b; }
2029
- SCSS
2030
- end
2031
-
2032
- def test_selector_interpolation_at_attr_end
2033
- assert_equal <<CSS, render(<<SCSS)
2034
- [foo=zzz] {
2035
- a: b; }
2036
- CSS
2037
- $zzz: zzz;
2038
- [foo=\#{$zzz}] { a: b; }
2039
- SCSS
2040
- end
2041
-
2042
- def test_selector_interpolation_at_dashes
2043
- assert_equal <<CSS, render(<<SCSS)
2044
- div {
2045
- -foo-a-b-foo: foo; }
2046
- CSS
2047
- $a : a;
2048
- $b : b;
2049
- div { -foo-\#{$a}-\#{$b}-foo: foo }
2050
- SCSS
2051
- end
2052
-
2053
- def test_selector_interpolation_in_reference_combinator
2054
- assert_equal <<CSS, render(<<SCSS)
2055
- .foo /a/ .bar /b|c/ .baz {
2056
- a: b; }
2057
- CSS
2058
- $a: a;
2059
- $b: b;
2060
- $c: c;
2061
- .foo /\#{$a}/ .bar /\#{$b}|\#{$c}/ .baz {a: b}
2062
- SCSS
2063
- end
2064
-
2065
- def test_parent_selector_with_parent_and_subject
2066
- silence_warnings {assert_equal <<CSS, render(<<SCSS)}
2067
- bar foo.baz! .bip {
2068
- c: d; }
2069
- CSS
2070
- $subject: "!";
2071
- foo {
2072
- bar &.baz\#{$subject} .bip {c: d}}
2073
- SCSS
2074
- end
2075
-
2076
- def test_basic_prop_name_interpolation
2077
- assert_equal <<CSS, render(<<SCSS)
2078
- foo {
2079
- barbazbang: blip; }
2080
- CSS
2081
- foo {bar\#{"baz" + "bang"}: blip}
2082
- SCSS
2083
- assert_equal <<CSS, render(<<SCSS)
2084
- foo {
2085
- bar3: blip; }
2086
- CSS
2087
- foo {bar\#{1 + 2}: blip}
2088
- SCSS
2089
- end
2090
-
2091
- def test_prop_name_only_interpolation
2092
- assert_equal <<CSS, render(<<SCSS)
2093
- foo {
2094
- bazbang: blip; }
2095
- CSS
2096
- foo {\#{"baz" + "bang"}: blip}
2097
- SCSS
2098
- end
2099
-
2100
- def test_directive_interpolation
2101
- assert_equal <<CSS, render(<<SCSS)
2102
- @foo bar12 qux {
2103
- a: b; }
2104
- CSS
2105
- $baz: 12;
2106
- @foo bar\#{$baz} qux {a: b}
2107
- SCSS
2108
- end
2109
-
2110
- def test_media_interpolation
2111
- assert_equal <<CSS, render(<<SCSS)
2112
- @media bar12 {
2113
- a: b; }
2114
- CSS
2115
- $baz: 12;
2116
- @media bar\#{$baz} {a: b}
2117
- SCSS
2118
- end
2119
-
2120
- def test_script_in_media
2121
- assert_equal <<CSS, render(<<SCSS)
2122
- @media screen and (-webkit-min-device-pixel-ratio: 20), only print {
2123
- a: b; }
2124
- CSS
2125
- $media1: screen;
2126
- $media2: print;
2127
- $var: -webkit-min-device-pixel-ratio;
2128
- $val: 20;
2129
- @media \#{$media1} and ($var: $val), only \#{$media2} {a: b}
2130
- SCSS
2131
-
2132
- assert_equal <<CSS, render(<<SCSS)
2133
- @media screen and (-webkit-min-device-pixel-ratio: 13) {
2134
- a: b; }
2135
- CSS
2136
- $vals: 1 2 3;
2137
- @media screen and (-webkit-min-device-pixel-ratio: 5 + 6 + nth($vals, 2)) {a: b}
2138
- SCSS
2139
- end
2140
-
2141
- def test_media_interpolation_with_reparse
2142
- assert_equal <<CSS, render(<<SCSS)
2143
- @media screen and (max-width: 300px) {
2144
- a: b; }
2145
- @media screen and (max-width: 300px) {
2146
- a: b; }
2147
- @media screen and (max-width: 300px) {
2148
- a: b; }
2149
- @media screen and (max-width: 300px), print and (max-width: 300px) {
2150
- a: b; }
2151
- CSS
2152
- $constraint: "(max-width: 300px)";
2153
- $fragment: "nd \#{$constraint}";
2154
- $comma: "een, pri";
2155
- @media screen and \#{$constraint} {a: b}
2156
- @media screen {
2157
- @media \#{$constraint} {a: b}
2158
- }
2159
- @media screen a\#{$fragment} {a: b}
2160
- @media scr\#{$comma}nt {
2161
- @media \#{$constraint} {a: b}
2162
- }
2163
- SCSS
2164
- end
2165
-
2166
- def test_moz_document_interpolation
2167
- assert_equal <<CSS, render(<<SCSS)
2168
- @-moz-document url(http://sass-lang.com/),
2169
- url-prefix(http://sass-lang.com/docs),
2170
- domain(sass-lang.com),
2171
- domain("sass-lang.com") {
2172
- .foo {
2173
- a: b; } }
2174
- CSS
2175
- $domain: "sass-lang.com";
2176
- @-moz-document url(http://\#{$domain}/),
2177
- url-prefix(http://\#{$domain}/docs),
2178
- domain(\#{$domain}),
2179
- \#{domain($domain)} {
2180
- .foo {a: b}
2181
- }
2182
- SCSS
2183
- end
2184
-
2185
- def test_supports_with_expressions
2186
- assert_equal <<CSS, render(<<SCSS)
2187
- @supports (feature1: val) and (feature2: val) or (not (feature23: val4)) {
2188
- foo {
2189
- a: b; } }
2190
- CSS
2191
- $query: "(feature1: val)";
2192
- $feature: feature2;
2193
- $val: val;
2194
- @supports \#{$query} and ($feature: $val) or (not ($feature + 3: $val + 4)) {
2195
- foo {a: b}
2196
- }
2197
- SCSS
2198
- end
2199
-
2200
- def test_supports_bubbling
2201
- assert_equal <<CSS, render(<<SCSS)
2202
- @supports (foo: bar) {
2203
- a {
2204
- b: c; }
2205
- @supports (baz: bang) {
2206
- a {
2207
- d: e; } } }
2208
- CSS
2209
- a {
2210
- @supports (foo: bar) {
2211
- b: c;
2212
- @supports (baz: bang) {
2213
- d: e;
2214
- }
2215
- }
2216
- }
2217
- SCSS
2218
- end
2219
-
2220
- def test_random_directive_interpolation
2221
- assert_equal <<CSS, render(<<SCSS)
2222
- @foo url(http://sass-lang.com/),
2223
- domain("sass-lang.com"),
2224
- "foobarbaz",
2225
- foobarbaz {
2226
- .foo {
2227
- a: b; } }
2228
- CSS
2229
- $domain: "sass-lang.com";
2230
- @foo url(http://\#{$domain}/),
2231
- \#{domain($domain)},
2232
- "foo\#{'ba' + 'r'}baz",
2233
- foo\#{'ba' + 'r'}baz {
2234
- .foo {a: b}
2235
- }
2236
- SCSS
2237
- end
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
-
2302
- def test_nested_mixin_def
2303
- assert_equal <<CSS, render(<<SCSS)
2304
- foo {
2305
- a: b; }
2306
- CSS
2307
- foo {
2308
- @mixin bar {a: b}
2309
- @include bar; }
2310
- SCSS
2311
- end
2312
-
2313
- def test_nested_mixin_shadow
2314
- assert_equal <<CSS, render(<<SCSS)
2315
- foo {
2316
- c: d; }
2317
-
2318
- baz {
2319
- a: b; }
2320
- CSS
2321
- @mixin bar {a: b}
2322
-
2323
- foo {
2324
- @mixin bar {c: d}
2325
- @include bar;
2326
- }
2327
-
2328
- baz {@include bar}
2329
- SCSS
2330
- end
2331
-
2332
- def test_nested_function_def
2333
- assert_equal <<CSS, render(<<SCSS)
2334
- foo {
2335
- a: 1; }
2336
-
2337
- bar {
2338
- b: foo(); }
2339
- CSS
2340
- foo {
2341
- @function foo() {@return 1}
2342
- a: foo(); }
2343
-
2344
- bar {b: foo()}
2345
- SCSS
2346
- end
2347
-
2348
- def test_nested_function_shadow
2349
- assert_equal <<CSS, render(<<SCSS)
2350
- foo {
2351
- a: 2; }
2352
-
2353
- baz {
2354
- b: 1; }
2355
- CSS
2356
- @function foo() {@return 1}
2357
-
2358
- foo {
2359
- @function foo() {@return 2}
2360
- a: foo();
2361
- }
2362
-
2363
- baz {b: foo()}
2364
- SCSS
2365
- end
2366
-
2367
- ## @at-root
2368
-
2369
- def test_simple_at_root
2370
- assert_equal <<CSS, render(<<SCSS)
2371
- .bar {
2372
- a: b; }
2373
- CSS
2374
- .foo {
2375
- @at-root {
2376
- .bar {a: b}
2377
- }
2378
- }
2379
- SCSS
2380
- end
2381
-
2382
- def test_at_root_with_selector
2383
- assert_equal <<CSS, render(<<SCSS)
2384
- .bar {
2385
- a: b; }
2386
- CSS
2387
- .foo {
2388
- @at-root .bar {a: b}
2389
- }
2390
- SCSS
2391
- end
2392
-
2393
- def test_at_root_in_mixin
2394
- assert_equal <<CSS, render(<<SCSS)
2395
- .bar {
2396
- a: b; }
2397
- CSS
2398
- @mixin bar {
2399
- @at-root .bar {a: b}
2400
- }
2401
-
2402
- .foo {
2403
- @include bar;
2404
- }
2405
- SCSS
2406
- end
2407
-
2408
- def test_at_root_in_media
2409
- assert_equal <<CSS, render(<<SCSS)
2410
- @media screen {
2411
- .bar {
2412
- a: b; } }
2413
- CSS
2414
- @media screen {
2415
- .foo {
2416
- @at-root .bar {a: b}
2417
- }
2418
- }
2419
- SCSS
2420
- end
2421
-
2422
- def test_at_root_in_bubbled_media
2423
- assert_equal <<CSS, render(<<SCSS)
2424
- @media screen {
2425
- .bar {
2426
- a: b; } }
2427
- CSS
2428
- .foo {
2429
- @media screen {
2430
- @at-root .bar {a: b}
2431
- }
2432
- }
2433
- SCSS
2434
- end
2435
-
2436
- def test_at_root_in_unknown_directive
2437
- assert_equal <<CSS, render(<<SCSS)
2438
- @fblthp {
2439
- .bar {
2440
- a: b; } }
2441
- CSS
2442
- @fblthp {
2443
- .foo {
2444
- @at-root .bar {a: b}
2445
- }
2446
- }
2447
- SCSS
2448
- end
2449
-
2450
- def test_comments_in_at_root
2451
- assert_equal <<CSS, render(<<SCSS)
2452
- /* foo */
2453
- .bar {
2454
- a: b; }
2455
-
2456
- /* baz */
2457
- CSS
2458
- .foo {
2459
- @at-root {
2460
- /* foo */
2461
- .bar {a: b}
2462
- /* baz */
2463
- }
2464
- }
2465
- SCSS
2466
- end
2467
-
2468
- def test_comments_in_at_root_in_media
2469
- assert_equal <<CSS, render(<<SCSS)
2470
- @media screen {
2471
- /* foo */
2472
- .bar {
2473
- a: b; }
2474
-
2475
- /* baz */ }
2476
- CSS
2477
- @media screen {
2478
- .foo {
2479
- @at-root {
2480
- /* foo */
2481
- .bar {a: b}
2482
- /* baz */
2483
- }
2484
- }
2485
- }
2486
- SCSS
2487
- end
2488
-
2489
- def test_comments_in_at_root_in_unknown_directive
2490
- assert_equal <<CSS, render(<<SCSS)
2491
- @fblthp {
2492
- /* foo */
2493
- .bar {
2494
- a: b; }
2495
-
2496
- /* baz */ }
2497
- CSS
2498
- @fblthp {
2499
- .foo {
2500
- @at-root {
2501
- /* foo */
2502
- .bar {a: b}
2503
- /* baz */
2504
- }
2505
- }
2506
- }
2507
- SCSS
2508
- end
2509
-
2510
- def test_media_directive_in_at_root
2511
- assert_equal <<CSS, render(<<SCSS)
2512
- @media screen {
2513
- .bar {
2514
- a: b; } }
2515
- CSS
2516
- .foo {
2517
- @at-root {
2518
- @media screen {.bar {a: b}}
2519
- }
2520
- }
2521
- SCSS
2522
- end
2523
-
2524
- def test_bubbled_media_directive_in_at_root
2525
- assert_equal <<CSS, render(<<SCSS)
2526
- @media screen {
2527
- .bar .baz {
2528
- a: b; } }
2529
- CSS
2530
- .foo {
2531
- @at-root {
2532
- .bar {
2533
- @media screen {.baz {a: b}}
2534
- }
2535
- }
2536
- }
2537
- SCSS
2538
- end
2539
-
2540
- def test_unknown_directive_in_at_root
2541
- assert_equal <<CSS, render(<<SCSS)
2542
- @fblthp {
2543
- .bar {
2544
- a: b; } }
2545
- CSS
2546
- .foo {
2547
- @at-root {
2548
- @fblthp {.bar {a: b}}
2549
- }
2550
- }
2551
- SCSS
2552
- end
2553
-
2554
- def test_at_root_in_at_root
2555
- assert_equal <<CSS, render(<<SCSS)
2556
- .bar {
2557
- a: b; }
2558
- CSS
2559
- .foo {
2560
- @at-root {
2561
- @at-root .bar {a: b}
2562
- }
2563
- }
2564
- SCSS
2565
- end
2566
-
2567
- def test_at_root_with_parent_ref
2568
- assert_equal <<CSS, render(<<SCSS)
2569
- .foo {
2570
- a: b; }
2571
- CSS
2572
- .foo {
2573
- @at-root & {
2574
- a: b;
2575
- }
2576
- }
2577
- SCSS
2578
- end
2579
-
2580
- def test_multi_level_at_root_with_parent_ref
2581
- assert_equal <<CSS, render(<<SCSS)
2582
- .foo .bar {
2583
- a: b; }
2584
- CSS
2585
- .foo {
2586
- @at-root & {
2587
- .bar {
2588
- @at-root & {
2589
- a: b;
2590
- }
2591
- }
2592
- }
2593
- }
2594
- SCSS
2595
- end
2596
-
2597
- def test_multi_level_at_root_with_inner_parent_ref
2598
- assert_equal <<CSS, render(<<SCSS)
2599
- .bar {
2600
- a: b; }
2601
- CSS
2602
- .foo {
2603
- @at-root .bar {
2604
- @at-root & {
2605
- a: b;
2606
- }
2607
- }
1155
+ @return "a: \#{$a}, b: \#{$b}";
2608
1156
  }
1157
+
1158
+ .foo {val: foo(1, $b: 2 3 4)}
2609
1159
  SCSS
2610
1160
  end
2611
1161
 
2612
- def test_at_root_beneath_comma_selector
2613
- assert_equal(<<CSS, render(<<SCSS))
2614
- .baz {
2615
- a: b; }
2616
- CSS
2617
- .foo, .bar {
2618
- @at-root .baz {
2619
- a: b;
2620
- }
1162
+ def test_function_keyword_for_unknown_arg_with_var_args
1163
+ assert_raise_message(Sass::SyntaxError, "Function foo doesn't have an argument named $c.") {render <<SCSS}
1164
+ @function foo($a, $b...) {
1165
+ @return "a: \#{$a}, b: \#{$b}";
2621
1166
  }
1167
+
1168
+ .foo {val: foo(1, $c: 2 3 4)}
2622
1169
  SCSS
2623
1170
  end
2624
1171
 
2625
- def test_at_root_with_parent_ref_and_class
2626
- assert_equal(<<CSS, render(<<SCSS))
2627
- .foo.bar {
2628
- a: b; }
2629
- CSS
1172
+ def test_function_var_args_passed_to_native
1173
+ assert_equal <<CSS, render(<<SCSS)
2630
1174
  .foo {
2631
- @at-root &.bar {
2632
- a: b;
2633
- }
1175
+ val: #102035; }
1176
+ CSS
1177
+ @function foo($args...) {
1178
+ @return adjust-color($args...);
2634
1179
  }
1180
+
1181
+ .foo {val: foo(#102030, $blue: 5)}
2635
1182
  SCSS
2636
1183
  end
2637
1184
 
2638
- def test_at_root_beneath_comma_selector_with_parent_ref
2639
- assert_equal(<<CSS, render(<<SCSS))
2640
- .foo.baz, .bar.baz {
1185
+ ## Interpolation
1186
+
1187
+ def test_basic_selector_interpolation
1188
+ assert_equal <<CSS, render(<<SCSS)
1189
+ foo 3 baz {
2641
1190
  a: b; }
2642
1191
  CSS
2643
- .foo, .bar {
2644
- @at-root &.baz {
2645
- a: b;
2646
- }
2647
- }
1192
+ foo \#{1 + 2} baz {a: b}
2648
1193
  SCSS
2649
- end
2650
-
2651
- ## @at-root (...)
2652
-
2653
- def test_at_root_without_media
2654
1194
  assert_equal <<CSS, render(<<SCSS)
2655
- .foo .bar {
1195
+ foo.bar baz {
2656
1196
  a: b; }
2657
1197
  CSS
2658
- .foo {
2659
- @media screen {
2660
- @at-root (without: media) {
2661
- .bar {
2662
- a: b;
2663
- }
2664
- }
2665
- }
2666
- }
1198
+ foo\#{".bar"} baz {a: b}
2667
1199
  SCSS
2668
- end
2669
-
2670
- def test_at_root_without_supports
2671
1200
  assert_equal <<CSS, render(<<SCSS)
2672
- .foo .bar {
1201
+ foo.bar baz {
2673
1202
  a: b; }
2674
1203
  CSS
2675
- .foo {
2676
- @supports (foo: bar) {
2677
- @at-root (without: supports) {
2678
- .bar {
2679
- a: b;
2680
- }
2681
- }
2682
- }
2683
- }
1204
+ \#{"foo"}.bar baz {a: b}
2684
1205
  SCSS
2685
1206
  end
2686
1207
 
2687
- def test_at_root_without_rule
1208
+ def test_selector_only_interpolation
2688
1209
  assert_equal <<CSS, render(<<SCSS)
2689
- @media screen {
2690
- .bar {
2691
- a: b; } }
1210
+ foo bar {
1211
+ a: b; }
2692
1212
  CSS
2693
- .foo {
2694
- @media screen {
2695
- @at-root (without: rule) {
2696
- .bar {
2697
- a: b;
2698
- }
2699
- }
2700
- }
2701
- }
1213
+ \#{"foo" + " bar"} {a: b}
2702
1214
  SCSS
2703
1215
  end
2704
1216
 
2705
- def test_at_root_without_unknown_directive
1217
+ def test_selector_interpolation_before_element_name
2706
1218
  assert_equal <<CSS, render(<<SCSS)
2707
- @fblthp {}
2708
- .foo .bar {
1219
+ foo barbaz {
2709
1220
  a: b; }
2710
1221
  CSS
2711
- .foo {
2712
- @fblthp {
2713
- @at-root (without: fblthp) {
2714
- .bar {
2715
- a: b;
2716
- }
2717
- }
2718
- }
2719
- }
1222
+ \#{"foo" + " bar"}baz {a: b}
2720
1223
  SCSS
2721
1224
  end
2722
1225
 
2723
- def test_at_root_without_multiple
1226
+ def test_selector_interpolation_in_string
2724
1227
  assert_equal <<CSS, render(<<SCSS)
2725
- @supports (foo: bar) {
2726
- .bar {
2727
- a: b; } }
1228
+ foo[val="bar foo bar baz"] {
1229
+ a: b; }
2728
1230
  CSS
2729
- .foo {
2730
- @media screen {
2731
- @supports (foo: bar) {
2732
- @at-root (without: media rule) {
2733
- .bar {
2734
- a: b;
2735
- }
2736
- }
2737
- }
2738
- }
2739
- }
1231
+ foo[val="bar \#{"foo" + " bar"} baz"] {a: b}
2740
1232
  SCSS
2741
1233
  end
2742
1234
 
2743
- def test_at_root_without_all
1235
+ def test_selector_interpolation_in_pseudoclass
2744
1236
  assert_equal <<CSS, render(<<SCSS)
2745
- @supports (foo: bar) {
2746
- @fblthp {} }
2747
- .bar {
1237
+ foo:nth-child(5n) {
2748
1238
  a: b; }
2749
1239
  CSS
2750
- .foo {
2751
- @supports (foo: bar) {
2752
- @fblthp {
2753
- @at-root (without: all) {
2754
- .bar {
2755
- a: b;
2756
- }
2757
- }
2758
- }
2759
- }
2760
- }
1240
+ foo:nth-child(\#{5 + "n"}) {a: b}
2761
1241
  SCSS
2762
1242
  end
2763
1243
 
2764
- def test_at_root_with_media
1244
+ def test_selector_interpolation_at_class_begininng
2765
1245
  assert_equal <<CSS, render(<<SCSS)
2766
- @media screen {
2767
- @fblthp {}
2768
- .bar {
2769
- a: b; } }
1246
+ .zzz {
1247
+ a: b; }
2770
1248
  CSS
2771
- .foo {
2772
- @media screen {
2773
- @fblthp {
2774
- @supports (foo: bar) {
2775
- @at-root (with: media) {
2776
- .bar {
2777
- a: b;
2778
- }
2779
- }
2780
- }
2781
- }
2782
- }
2783
- }
1249
+ $zzz: zzz;
1250
+ .\#{$zzz} { a: b; }
2784
1251
  SCSS
2785
1252
  end
2786
1253
 
2787
- def test_at_root_with_rule
1254
+ def test_selector_interpolation_at_id_begininng
2788
1255
  assert_equal <<CSS, render(<<SCSS)
2789
- @media screen {
2790
- @fblthp {} }
2791
- .foo .bar {
1256
+ #zzz {
2792
1257
  a: b; }
2793
1258
  CSS
2794
- .foo {
2795
- @media screen {
2796
- @fblthp {
2797
- @supports (foo: bar) {
2798
- @at-root (with: rule) {
2799
- .bar {
2800
- a: b;
2801
- }
2802
- }
2803
- }
2804
- }
2805
- }
2806
- }
1259
+ $zzz: zzz;
1260
+ #\#{$zzz} { a: b; }
2807
1261
  SCSS
2808
1262
  end
2809
1263
 
2810
- def test_at_root_with_supports
1264
+ def test_selector_interpolation_at_pseudo_begininng
2811
1265
  assert_equal <<CSS, render(<<SCSS)
2812
- @media screen {
2813
- @fblthp {} }
2814
- @supports (foo: bar) {
2815
- .bar {
2816
- a: b; } }
1266
+ :zzz::zzz {
1267
+ a: b; }
2817
1268
  CSS
2818
- .foo {
2819
- @media screen {
2820
- @fblthp {
2821
- @supports (foo: bar) {
2822
- @at-root (with: supports) {
2823
- .bar {
2824
- a: b;
2825
- }
2826
- }
2827
- }
2828
- }
2829
- }
2830
- }
1269
+ $zzz: zzz;
1270
+ :\#{$zzz}::\#{$zzz} { a: b; }
2831
1271
  SCSS
2832
1272
  end
2833
1273
 
2834
- def test_at_root_with_unknown_directive
1274
+ def test_selector_interpolation_at_attr_beginning
2835
1275
  assert_equal <<CSS, render(<<SCSS)
2836
- @media screen {
2837
- @fblthp {} }
2838
- @fblthp {
2839
- .bar {
2840
- a: b; } }
1276
+ [zzz=foo] {
1277
+ a: b; }
2841
1278
  CSS
2842
- .foo {
2843
- @media screen {
2844
- @fblthp {
2845
- @supports (foo: bar) {
2846
- @at-root (with: fblthp) {
2847
- .bar {
2848
- a: b;
2849
- }
2850
- }
2851
- }
2852
- }
2853
- }
2854
- }
1279
+ $zzz: zzz;
1280
+ [\#{$zzz}=foo] { a: b; }
2855
1281
  SCSS
2856
1282
  end
2857
1283
 
2858
- def test_at_root_with_multiple
1284
+ def test_selector_interpolation_at_attr_end
2859
1285
  assert_equal <<CSS, render(<<SCSS)
2860
- @media screen {
2861
- @fblthp {}
2862
- .foo .bar {
2863
- a: b; } }
1286
+ [foo=zzz] {
1287
+ a: b; }
2864
1288
  CSS
2865
- .foo {
2866
- @media screen {
2867
- @fblthp {
2868
- @supports (foo: bar) {
2869
- @at-root (with: media rule) {
2870
- .bar {
2871
- a: b;
2872
- }
2873
- }
2874
- }
2875
- }
2876
- }
2877
- }
1289
+ $zzz: zzz;
1290
+ [foo=\#{$zzz}] { a: b; }
2878
1291
  SCSS
2879
1292
  end
2880
1293
 
2881
- def test_at_root_with_all
1294
+ def test_selector_interpolation_at_dashes
2882
1295
  assert_equal <<CSS, render(<<SCSS)
2883
- @media screen {
2884
- @fblthp {
2885
- @supports (foo: bar) {
2886
- .foo .bar {
2887
- a: b; } } } }
1296
+ div {
1297
+ -foo-a-b-foo: foo; }
2888
1298
  CSS
2889
- .foo {
2890
- @media screen {
2891
- @fblthp {
2892
- @supports (foo: bar) {
2893
- @at-root (with: all) {
2894
- .bar {
2895
- a: b;
2896
- }
2897
- }
2898
- }
2899
- }
2900
- }
2901
- }
1299
+ $a : a;
1300
+ $b : b;
1301
+ div { -foo-\#{$a}-\#{$b}-foo: foo }
2902
1302
  SCSS
2903
1303
  end
2904
1304
 
2905
- def test_at_root_dynamic_values
1305
+ def test_selector_interpolation_in_reference_combinator
2906
1306
  assert_equal <<CSS, render(<<SCSS)
2907
- @media screen {
2908
- .bar {
2909
- a: b; } }
1307
+ .foo /a/ .bar /b|c/ .baz {
1308
+ a: b; }
2910
1309
  CSS
2911
- $key: with;
2912
- $value: media;
2913
- .foo {
2914
- @media screen {
2915
- @at-root ($key: $value) {
2916
- .bar {
2917
- a: b;
2918
- }
2919
- }
2920
- }
2921
- }
1310
+ $a: a;
1311
+ $b: b;
1312
+ $c: c;
1313
+ .foo /\#{$a}/ .bar /\#{$b}|\#{$c}/ .baz {a: b}
2922
1314
  SCSS
2923
1315
  end
2924
1316
 
2925
- def test_at_root_interpolated_query
1317
+ def test_parent_selector_with_parent_and_subject
2926
1318
  assert_equal <<CSS, render(<<SCSS)
2927
- @media screen {
2928
- .bar {
2929
- a: b; } }
1319
+ bar foo.baz! .bip {
1320
+ c: d; }
2930
1321
  CSS
2931
- .foo {
2932
- @media screen {
2933
- @at-root (\#{"with: media"}) {
2934
- .bar {
2935
- a: b;
2936
- }
2937
- }
2938
- }
2939
- }
1322
+ $subject: "!";
1323
+ foo {
1324
+ bar &.baz\#{$subject} .bip {c: d}}
2940
1325
  SCSS
2941
1326
  end
2942
1327
 
2943
- def test_at_root_plus_extend
1328
+ def test_basic_prop_name_interpolation
2944
1329
  assert_equal <<CSS, render(<<SCSS)
2945
- .foo .bar {
2946
- a: b; }
1330
+ foo {
1331
+ barbazbang: blip; }
2947
1332
  CSS
2948
- %base {
2949
- a: b;
2950
- }
2951
-
2952
- .foo {
2953
- @media screen {
2954
- @at-root (without: media) {
2955
- .bar {
2956
- @extend %base;
2957
- }
2958
- }
2959
- }
2960
- }
1333
+ foo {bar\#{"baz" + "bang"}: blip}
2961
1334
  SCSS
2962
- end
2963
-
2964
- def test_at_root_without_keyframes_in_keyframe_rule
2965
1335
  assert_equal <<CSS, render(<<SCSS)
2966
- .foo {
2967
- a: b; }
1336
+ foo {
1337
+ bar3: blip; }
2968
1338
  CSS
2969
- @keyframes identifier {
2970
- 0% {
2971
- @at-root (without: keyframes) {
2972
- .foo {a: b}
2973
- }
2974
- }
2975
- }
1339
+ foo {bar\#{1 + 2}: blip}
2976
1340
  SCSS
2977
1341
  end
2978
1342
 
2979
- def test_at_root_without_rule_in_keyframe_rule
1343
+ def test_prop_name_only_interpolation
2980
1344
  assert_equal <<CSS, render(<<SCSS)
2981
- @keyframes identifier {
2982
- 0% {
2983
- a: b; } }
1345
+ foo {
1346
+ bazbang: blip; }
2984
1347
  CSS
2985
- @keyframes identifier {
2986
- 0% {
2987
- @at-root (without: rule) {a: b}
2988
- }
2989
- }
1348
+ foo {\#{"baz" + "bang"}: blip}
2990
1349
  SCSS
2991
1350
  end
2992
1351
 
2993
- ## Selector Script
2994
-
2995
- def test_selector_script
2996
- assert_equal(<<CSS, render(<<SCSS))
2997
- .foo .bar {
2998
- content: ".foo .bar"; }
1352
+ def test_directive_interpolation
1353
+ assert_equal <<CSS, render(<<SCSS)
1354
+ @foo bar12 qux {
1355
+ a: b; }
2999
1356
  CSS
3000
- .foo .bar {
3001
- content: "\#{&}";
3002
- }
1357
+ $baz: 12;
1358
+ @foo bar\#{$baz} qux {a: b}
3003
1359
  SCSS
3004
1360
  end
3005
1361
 
3006
- def test_nested_selector_script
3007
- assert_equal(<<CSS, render(<<SCSS))
3008
- .foo .bar {
3009
- content: ".foo .bar"; }
1362
+ def test_media_interpolation
1363
+ assert_equal <<CSS, render(<<SCSS)
1364
+ @media bar12 {
1365
+ a: b; }
3010
1366
  CSS
3011
- .foo {
3012
- .bar {
3013
- content: "\#{&}";
3014
- }
3015
- }
1367
+ $baz: 12;
1368
+ @media bar\#{$baz} {a: b}
3016
1369
  SCSS
3017
1370
  end
3018
1371
 
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"; }
1372
+ def test_script_in_media
1373
+ assert_equal <<CSS, render(<<SCSS)
1374
+ @media screen and (-webkit-min-device-pixel-ratio: 20), only print {
1375
+ a: b; }
3023
1376
  CSS
3024
- .foo, .bar {
3025
- .baz {
3026
- content: "\#{&}";
3027
- }
3028
- }
1377
+ $media1: screen;
1378
+ $media2: print;
1379
+ $var: -webkit-min-device-pixel-ratio;
1380
+ $val: 20;
1381
+ @media \#{$media1} and ($var: $val), only \#{$media2} {a: b}
3029
1382
  SCSS
3030
- end
3031
1383
 
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"; }
1384
+ assert_equal <<CSS, render(<<SCSS)
1385
+ @media screen and (-webkit-min-device-pixel-ratio: 13) {
1386
+ a: b; }
3036
1387
  CSS
3037
- .foo {
3038
- .bar, .baz {
3039
- content: "\#{&}";
3040
- }
3041
- }
1388
+ $vals: 1 2 3;
1389
+ @media screen and (-webkit-min-device-pixel-ratio: 5 + 6 + nth($vals, 2)) {a: b}
3042
1390
  SCSS
3043
1391
  end
3044
1392
 
3045
- def test_selector_script_through_mixin
3046
- assert_equal(<<CSS, render(<<SCSS))
3047
- .foo {
3048
- content: ".foo"; }
1393
+ def test_media_interpolation_with_reparse
1394
+ assert_equal <<CSS, render(<<SCSS)
1395
+ @media screen and (max-width: 300px) {
1396
+ a: b; }
1397
+ @media screen and (max-width: 300px) {
1398
+ a: b; }
1399
+ @media screen and (max-width: 300px) {
1400
+ a: b; }
1401
+ @media screen and (max-width: 300px), print and (max-width: 300px) {
1402
+ a: b; }
3049
1403
  CSS
3050
- @mixin mixin {
3051
- content: "\#{&}";
1404
+ $constraint: "(max-width: 300px)";
1405
+ $fragment: "nd \#{$constraint}";
1406
+ $comma: "een, pri";
1407
+ @media screen and \#{$constraint} {a: b}
1408
+ @media screen {
1409
+ @media \#{$constraint} {a: b}
3052
1410
  }
3053
-
3054
- .foo {
3055
- @include mixin;
1411
+ @media screen a\#{$fragment} {a: b}
1412
+ @media scr\#{$comma}nt {
1413
+ @media \#{$constraint} {a: b}
3056
1414
  }
3057
1415
  SCSS
3058
1416
  end
3059
1417
 
3060
- def test_selector_script_through_content
3061
- assert_equal(<<CSS, render(<<SCSS))
3062
- .foo {
3063
- content: ".foo"; }
1418
+ def test_moz_document_interpolation
1419
+ assert_equal <<CSS, render(<<SCSS)
1420
+ @-moz-document url(http://sass-lang.com/),
1421
+ url-prefix(http://sass-lang.com/docs),
1422
+ domain(sass-lang.com),
1423
+ domain("sass-lang.com") {
1424
+ .foo {
1425
+ a: b; } }
3064
1426
  CSS
3065
- @mixin mixin {
3066
- @content;
3067
- }
3068
-
3069
- .foo {
3070
- @include mixin {
3071
- content: "\#{&}";
3072
- }
1427
+ $domain: "sass-lang.com";
1428
+ @-moz-document url(http://\#{$domain}/),
1429
+ url-prefix(http://\#{$domain}/docs),
1430
+ domain(\#{$domain}),
1431
+ \#{domain($domain)} {
1432
+ .foo {a: b}
3073
1433
  }
3074
1434
  SCSS
3075
1435
  end
3076
1436
 
3077
- def test_selector_script_through_function
3078
- assert_equal(<<CSS, render(<<SCSS))
3079
- .foo {
3080
- content: ".foo"; }
1437
+ def test_supports_with_expressions
1438
+ assert_equal <<CSS, render(<<SCSS)
1439
+ @supports (feature1: val) and (feature2: val) or (not (feature23: val4)) {
1440
+ foo {
1441
+ a: b; } }
3081
1442
  CSS
3082
- @function fn() {
3083
- @return "\#{&}";
3084
- }
3085
-
3086
- .foo {
3087
- content: fn();
1443
+ $query: "(feature1: val)";
1444
+ $feature: feature2;
1445
+ $val: val;
1446
+ @supports \#{$query} and ($feature: $val) or (not ($feature + 3: $val + 4)) {
1447
+ foo {a: b}
3088
1448
  }
3089
1449
  SCSS
3090
1450
  end
3091
1451
 
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"; } }
1452
+ def test_supports_bubbling
1453
+ assert_equal <<CSS, render(<<SCSS)
1454
+ @supports (foo: bar) {
1455
+ a {
1456
+ b: c; }
1457
+ @supports (baz: bang) {
1458
+ a {
1459
+ d: e; } } }
3099
1460
  CSS
3100
- .foo {
3101
- content: "outer";
3102
- @media screen {
3103
- .bar {
3104
- content: "\#{&}";
1461
+ a {
1462
+ @supports (foo: bar) {
1463
+ b: c;
1464
+ @supports (baz: bang) {
1465
+ d: e;
3105
1466
  }
3106
1467
  }
3107
1468
  }
3108
1469
  SCSS
3109
1470
  end
3110
1471
 
3111
- def test_selector_script_save_and_reuse
3112
- assert_equal(<<CSS, render(<<SCSS))
3113
- .bar {
3114
- content: ".foo"; }
1472
+ def test_random_directive_interpolation
1473
+ assert_equal <<CSS, render(<<SCSS)
1474
+ @foo url(http://sass-lang.com/),
1475
+ domain("sass-lang.com"),
1476
+ "foobarbaz",
1477
+ foobarbaz {
1478
+ .foo {
1479
+ a: b; } }
3115
1480
  CSS
3116
- $var: null;
3117
- .foo {
3118
- $var: & !global;
3119
- }
3120
-
3121
- .bar {
3122
- content: "\#{$var}";
1481
+ $domain: "sass-lang.com";
1482
+ @foo url(http://\#{$domain}/),
1483
+ \#{domain($domain)},
1484
+ "foo\#{'ba' + 'r'}baz",
1485
+ foo\#{'ba' + 'r'}baz {
1486
+ .foo {a: b}
3123
1487
  }
3124
1488
  SCSS
3125
1489
  end
3126
1490
 
3127
- def test_selector_script_with_at_root
3128
- assert_equal(<<CSS, render(<<SCSS))
3129
- .foo-bar {
1491
+ def test_nested_mixin_def
1492
+ assert_equal <<CSS, render(<<SCSS)
1493
+ foo {
3130
1494
  a: b; }
3131
1495
  CSS
3132
- .foo {
3133
- @at-root \#{&}-bar {
3134
- a: b;
3135
- }
3136
- }
1496
+ foo {
1497
+ @mixin bar {a: b}
1498
+ @include bar; }
3137
1499
  SCSS
3138
1500
  end
3139
1501
 
3140
- def test_multi_level_at_root_with_inner_selector_script
1502
+ def test_nested_mixin_shadow
3141
1503
  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
1504
+ foo {
1505
+ c: d; }
3154
1506
 
3155
- def test_at_root_with_at_root_through_mixin
3156
- assert_equal(<<CSS, render(<<SCSS))
3157
- .bar-baz {
1507
+ baz {
3158
1508
  a: b; }
3159
1509
  CSS
3160
- @mixin foo {
3161
- .bar {
3162
- @at-root \#{&}-baz {
3163
- a: b;
3164
- }
3165
- }
1510
+ @mixin bar {a: b}
1511
+
1512
+ foo {
1513
+ @mixin bar {c: d}
1514
+ @include bar;
3166
1515
  }
3167
1516
 
3168
- @include foo;
1517
+ baz {@include bar}
3169
1518
  SCSS
3170
1519
  end
3171
1520
 
3172
- # See https://github.com/sass/sass/issues/1294
3173
- def test_extend_top_leveled_by_at_root
3174
- render(<<SCSS)
3175
- .span-10 {
3176
- @at-root (without: all) {
3177
- @extend %column;
3178
- }
3179
- }
3180
- SCSS
1521
+ def test_nested_function_def
1522
+ assert_equal <<CSS, render(<<SCSS)
1523
+ foo {
1524
+ a: 1; }
3181
1525
 
3182
- assert(false, "Expected syntax error")
3183
- rescue Sass::SyntaxError => e
3184
- assert_equal "Extend directives may only be used within rules.", e.message
3185
- assert_equal 3, e.sass_line
1526
+ bar {
1527
+ b: foo(); }
1528
+ CSS
1529
+ foo {
1530
+ @function foo() {@return 1}
1531
+ a: foo(); }
1532
+
1533
+ bar {b: foo()}
1534
+ SCSS
3186
1535
  end
3187
1536
 
3188
- def test_at_root_doesnt_always_break_blocks
1537
+ def test_nested_function_shadow
3189
1538
  assert_equal <<CSS, render(<<SCSS)
3190
- .foo {
3191
- a: b; }
1539
+ foo {
1540
+ a: 2; }
3192
1541
 
3193
- @media screen {
3194
- .foo {
3195
- c: d; }
3196
- .bar {
3197
- e: f; } }
1542
+ baz {
1543
+ b: 1; }
3198
1544
  CSS
3199
- %base {
3200
- a: b;
3201
- }
3202
-
3203
- @media screen {
3204
- .foo {
3205
- c: d;
3206
- @at-root (without: media) {
3207
- @extend %base;
3208
- }
3209
- }
1545
+ @function foo() {@return 1}
3210
1546
 
3211
- .bar {e: f}
1547
+ foo {
1548
+ @function foo() {@return 2}
1549
+ a: foo();
3212
1550
  }
3213
- SCSS
3214
- end
3215
1551
 
3216
- ## Errors
3217
-
3218
- def test_keyframes_rule_outside_of_keyframes
3219
- render <<SCSS
3220
- 0% {
3221
- top: 0; }
1552
+ baz {b: foo()}
3222
1553
  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
1554
  end
3228
1555
 
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
1556
+ ## Errors
3240
1557
 
3241
1558
  def test_nested_mixin_def_is_scoped
3242
1559
  render <<SCSS
@@ -3292,7 +1609,7 @@ foo {
3292
1609
  SCSS
3293
1610
  assert(false, "Expected syntax error")
3294
1611
  rescue Sass::SyntaxError => e
3295
- assert_equal 'Invalid CSS after " .bar:baz <fail>": expected expression (e.g. 1px, bold), was "; }"', e.message
1612
+ assert_equal 'Invalid CSS after " .bar:baz ": expected "{", was "<fail>; }"', e.message
3296
1613
  assert_equal 2, e.sass_line
3297
1614
  end
3298
1615
 
@@ -3402,7 +1719,7 @@ SCSS
3402
1719
 
3403
1720
  def test_parent_in_mid_selector_error
3404
1721
  assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render <<SCSS}
3405
- Invalid CSS after ".foo": expected "{", was "&.bar"
1722
+ Invalid CSS after " .foo": expected "{", was "&.bar {a: b}"
3406
1723
 
3407
1724
  "&.bar" may only be used at the beginning of a compound selector.
3408
1725
  MESSAGE
@@ -3414,7 +1731,7 @@ SCSS
3414
1731
 
3415
1732
  def test_parent_after_selector_error
3416
1733
  assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render <<SCSS}
3417
- Invalid CSS after ".foo.bar": expected "{", was "&"
1734
+ Invalid CSS after " .foo.bar": expected "{", was "& {a: b}"
3418
1735
 
3419
1736
  "&" may only be used at the beginning of a compound selector.
3420
1737
  MESSAGE
@@ -3426,7 +1743,7 @@ SCSS
3426
1743
 
3427
1744
  def test_double_parent_selector_error
3428
1745
  assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render <<SCSS}
3429
- Invalid CSS after "&": expected "{", was "&"
1746
+ Invalid CSS after " &": expected "{", was "& {a: b}"
3430
1747
 
3431
1748
  "&" may only be used at the beginning of a compound selector.
3432
1749
  MESSAGE
@@ -3444,101 +1761,8 @@ MESSAGE
3444
1761
  SCSS
3445
1762
  end
3446
1763
 
3447
- def test_failed_parent_selector_with_suffix
3448
- assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render(<<SCSS)}
3449
- Invalid parent selector for "&-bar": "*"
3450
- MESSAGE
3451
- * {
3452
- &-bar {a: b}
3453
- }
3454
- SCSS
3455
-
3456
- assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render(<<SCSS)}
3457
- Invalid parent selector for "&-bar": "[foo=bar]"
3458
- MESSAGE
3459
- [foo=bar] {
3460
- &-bar {a: b}
3461
- }
3462
- SCSS
3463
-
3464
- assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render(<<SCSS)}
3465
- Invalid parent selector for "&-bar": "::nth-child(2n+1)"
3466
- MESSAGE
3467
- ::nth-child(2n+1) {
3468
- &-bar {a: b}
3469
- }
3470
- SCSS
3471
-
3472
- assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render(<<SCSS)}
3473
- Invalid parent selector for "&-bar": ":not(.foo)"
3474
- MESSAGE
3475
- :not(.foo) {
3476
- &-bar {a: b}
3477
- }
3478
- SCSS
3479
-
3480
- assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render(<<SCSS)}
3481
- Invalid parent selector for "&-bar": ".foo +"
3482
- MESSAGE
3483
- .foo + {
3484
- &-bar {a: b}
3485
- }
3486
- SCSS
3487
- end
3488
-
3489
- def test_empty_media_query_error
3490
- assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render(<<SCSS)}
3491
- Invalid CSS after "": expected media query list, was ""
3492
- MESSAGE
3493
- @media \#{""} {
3494
- foo {a: b}
3495
- }
3496
- SCSS
3497
- end
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 of #{filename_for_test :scss}:
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
-
3529
1764
  # Regression
3530
-
3531
- def test_top_level_unknown_directive_in_at_root
3532
- assert_equal(<<CSS, render(<<SCSS))
3533
- @fblthp {
3534
- a: b; }
3535
- CSS
3536
- @at-root {
3537
- @fblthp {a: b}
3538
- }
3539
- SCSS
3540
- end
3541
-
1765
+
3542
1766
  def test_parent_ref_with_newline
3543
1767
  assert_equal(<<CSS, render(<<SCSS))
3544
1768
  a.c
@@ -3550,24 +1774,6 @@ a
3550
1774
  SCSS
3551
1775
  end
3552
1776
 
3553
- def test_parent_ref_in_nested_at_root
3554
- assert_equal(<<CSS, render(<<SCSS))
3555
- #test {
3556
- border: 0; }
3557
- #test:hover {
3558
- display: none; }
3559
- CSS
3560
- a {
3561
- @at-root #test {
3562
- border: 0;
3563
- &:hover{
3564
- display: none;
3565
- }
3566
- }
3567
- }
3568
- SCSS
3569
- end
3570
-
3571
1777
  def test_loud_comment_in_compressed_mode
3572
1778
  assert_equal(<<CSS, render(<<SCSS))
3573
1779
  /*! foo */
@@ -3861,10 +2067,10 @@ SCSS
3861
2067
  }
3862
2068
  .aaa .aaa .aaa {
3863
2069
  background-color: black;
3864
- }
2070
+ }
3865
2071
  .bbb {
3866
2072
  @extend .aaa;
3867
- }
2073
+ }
3868
2074
  .xxx {
3869
2075
  @extend .bbb;
3870
2076
  }
@@ -3875,7 +2081,7 @@ SCSS
3875
2081
  @extend .bbb;
3876
2082
  }
3877
2083
  SCSS
3878
- Sass::SCSS::Parser.new(template, "test.scss", nil).parse
2084
+ Sass::SCSS::Parser.new(template, "test.scss").parse
3879
2085
  end
3880
2086
 
3881
2087
  def test_extend_in_media_in_rule