oreorenasass 3.4.4 → 3.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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