sass 3.4.25 → 3.7.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (237) hide show
  1. checksums.yaml +4 -4
  2. data/CODE_OF_CONDUCT.md +1 -1
  3. data/CONTRIBUTING.md +3 -3
  4. data/README.md +17 -9
  5. data/VERSION +1 -1
  6. data/VERSION_DATE +1 -1
  7. data/VERSION_NAME +1 -1
  8. data/extra/sass-spec-ref.sh +9 -1
  9. data/lib/sass.rb +0 -7
  10. data/lib/sass/cache_stores/filesystem.rb +1 -1
  11. data/lib/sass/css.rb +1 -2
  12. data/lib/sass/engine.rb +39 -29
  13. data/lib/sass/environment.rb +26 -5
  14. data/lib/sass/error.rb +2 -2
  15. data/lib/sass/exec/base.rb +2 -13
  16. data/lib/sass/exec/sass_scss.rb +1 -5
  17. data/lib/sass/features.rb +1 -0
  18. data/lib/sass/importers/filesystem.rb +6 -4
  19. data/lib/sass/logger/base.rb +11 -0
  20. data/lib/sass/plugin/compiler.rb +20 -50
  21. data/lib/sass/plugin/configuration.rb +2 -2
  22. data/lib/sass/railtie.rb +1 -1
  23. data/lib/sass/script/css_parser.rb +4 -1
  24. data/lib/sass/script/functions.rb +308 -81
  25. data/lib/sass/script/lexer.rb +63 -9
  26. data/lib/sass/script/parser.rb +287 -118
  27. data/lib/sass/script/tree/funcall.rb +35 -34
  28. data/lib/sass/script/tree/interpolation.rb +0 -3
  29. data/lib/sass/script/tree/list_literal.rb +23 -8
  30. data/lib/sass/script/tree/map_literal.rb +2 -2
  31. data/lib/sass/script/tree/node.rb +0 -8
  32. data/lib/sass/script/tree/operation.rb +1 -8
  33. data/lib/sass/script/value.rb +2 -0
  34. data/lib/sass/script/value/arg_list.rb +1 -1
  35. data/lib/sass/script/value/base.rb +17 -0
  36. data/lib/sass/script/value/callable.rb +25 -0
  37. data/lib/sass/script/value/color.rb +8 -2
  38. data/lib/sass/script/value/function.rb +19 -0
  39. data/lib/sass/script/value/helpers.rb +37 -11
  40. data/lib/sass/script/value/list.rb +35 -14
  41. data/lib/sass/script/value/map.rb +2 -2
  42. data/lib/sass/script/value/number.rb +3 -2
  43. data/lib/sass/scss/css_parser.rb +6 -1
  44. data/lib/sass/scss/parser.rb +145 -56
  45. data/lib/sass/scss/rx.rb +5 -11
  46. data/lib/sass/scss/static_parser.rb +20 -42
  47. data/lib/sass/selector.rb +4 -0
  48. data/lib/sass/selector/abstract_sequence.rb +7 -6
  49. data/lib/sass/selector/comma_sequence.rb +9 -5
  50. data/lib/sass/selector/pseudo.rb +20 -3
  51. data/lib/sass/selector/sequence.rb +35 -10
  52. data/lib/sass/selector/simple.rb +9 -2
  53. data/lib/sass/selector/simple_sequence.rb +8 -4
  54. data/lib/sass/source/map.rb +2 -6
  55. data/lib/sass/stack.rb +21 -1
  56. data/lib/sass/tree/charset_node.rb +1 -1
  57. data/lib/sass/tree/prop_node.rb +45 -53
  58. data/lib/sass/tree/rule_node.rb +6 -8
  59. data/lib/sass/tree/visitors/check_nesting.rb +1 -1
  60. data/lib/sass/tree/visitors/convert.rb +2 -3
  61. data/lib/sass/tree/visitors/cssize.rb +4 -15
  62. data/lib/sass/tree/visitors/deep_copy.rb +1 -1
  63. data/lib/sass/tree/visitors/extend.rb +2 -8
  64. data/lib/sass/tree/visitors/perform.rb +23 -15
  65. data/lib/sass/tree/visitors/set_options.rb +1 -1
  66. data/lib/sass/tree/visitors/to_css.rb +49 -22
  67. data/lib/sass/util.rb +72 -310
  68. data/lib/sass/util/multibyte_string_scanner.rb +127 -131
  69. data/lib/sass/util/normalized_map.rb +1 -8
  70. data/lib/sass/version.rb +0 -4
  71. metadata +55 -202
  72. data/Rakefile +0 -453
  73. data/lib/sass/script/css_variable_warning.rb +0 -52
  74. data/lib/sass/util/cross_platform_random.rb +0 -19
  75. data/lib/sass/util/ordered_hash.rb +0 -192
  76. data/test/sass-spec.yml +0 -3
  77. data/test/sass/cache_test.rb +0 -131
  78. data/test/sass/callbacks_test.rb +0 -61
  79. data/test/sass/compiler_test.rb +0 -236
  80. data/test/sass/conversion_test.rb +0 -2188
  81. data/test/sass/css2sass_test.rb +0 -526
  82. data/test/sass/css_variable_test.rb +0 -132
  83. data/test/sass/data/hsl-rgb.txt +0 -319
  84. data/test/sass/encoding_test.rb +0 -219
  85. data/test/sass/engine_test.rb +0 -3447
  86. data/test/sass/exec_test.rb +0 -96
  87. data/test/sass/extend_test.rb +0 -1733
  88. data/test/sass/fixtures/test_staleness_check_across_importers.css +0 -1
  89. data/test/sass/fixtures/test_staleness_check_across_importers.scss +0 -1
  90. data/test/sass/functions_test.rb +0 -1977
  91. data/test/sass/importer_test.rb +0 -421
  92. data/test/sass/logger_test.rb +0 -58
  93. data/test/sass/mock_importer.rb +0 -49
  94. data/test/sass/more_results/more1.css +0 -9
  95. data/test/sass/more_results/more1_with_line_comments.css +0 -26
  96. data/test/sass/more_results/more_import.css +0 -29
  97. data/test/sass/more_templates/_more_partial.sass +0 -2
  98. data/test/sass/more_templates/more1.sass +0 -23
  99. data/test/sass/more_templates/more_import.sass +0 -11
  100. data/test/sass/plugin_test.rb +0 -556
  101. data/test/sass/results/alt.css +0 -4
  102. data/test/sass/results/basic.css +0 -9
  103. data/test/sass/results/cached_import_option.css +0 -3
  104. data/test/sass/results/compact.css +0 -5
  105. data/test/sass/results/complex.css +0 -86
  106. data/test/sass/results/compressed.css +0 -1
  107. data/test/sass/results/expanded.css +0 -19
  108. data/test/sass/results/filename_fn.css +0 -3
  109. data/test/sass/results/if.css +0 -3
  110. data/test/sass/results/import.css +0 -31
  111. data/test/sass/results/import_charset.css +0 -5
  112. data/test/sass/results/import_charset_1_8.css +0 -5
  113. data/test/sass/results/import_charset_ibm866.css +0 -5
  114. data/test/sass/results/import_content.css +0 -1
  115. data/test/sass/results/line_numbers.css +0 -49
  116. data/test/sass/results/mixins.css +0 -95
  117. data/test/sass/results/multiline.css +0 -24
  118. data/test/sass/results/nested.css +0 -22
  119. data/test/sass/results/options.css +0 -1
  120. data/test/sass/results/parent_ref.css +0 -13
  121. data/test/sass/results/script.css +0 -16
  122. data/test/sass/results/scss_import.css +0 -31
  123. data/test/sass/results/scss_importee.css +0 -2
  124. data/test/sass/results/subdir/nested_subdir/nested_subdir.css +0 -1
  125. data/test/sass/results/subdir/subdir.css +0 -3
  126. data/test/sass/results/units.css +0 -11
  127. data/test/sass/results/warn.css +0 -0
  128. data/test/sass/results/warn_imported.css +0 -0
  129. data/test/sass/script_conversion_test.rb +0 -357
  130. data/test/sass/script_test.rb +0 -1431
  131. data/test/sass/scss/css_test.rb +0 -1281
  132. data/test/sass/scss/rx_test.rb +0 -160
  133. data/test/sass/scss/scss_test.rb +0 -4205
  134. data/test/sass/scss/test_helper.rb +0 -37
  135. data/test/sass/source_map_test.rb +0 -1055
  136. data/test/sass/superselector_test.rb +0 -210
  137. data/test/sass/templates/_cached_import_option_partial.scss +0 -1
  138. data/test/sass/templates/_double_import_loop2.sass +0 -1
  139. data/test/sass/templates/_filename_fn_import.scss +0 -11
  140. data/test/sass/templates/_imported_charset_ibm866.sass +0 -4
  141. data/test/sass/templates/_imported_charset_utf8.sass +0 -4
  142. data/test/sass/templates/_imported_content.sass +0 -3
  143. data/test/sass/templates/_partial.sass +0 -2
  144. data/test/sass/templates/_same_name_different_partiality.scss +0 -1
  145. data/test/sass/templates/alt.sass +0 -16
  146. data/test/sass/templates/basic.sass +0 -23
  147. data/test/sass/templates/bork1.sass +0 -2
  148. data/test/sass/templates/bork2.sass +0 -2
  149. data/test/sass/templates/bork3.sass +0 -2
  150. data/test/sass/templates/bork4.sass +0 -2
  151. data/test/sass/templates/bork5.sass +0 -3
  152. data/test/sass/templates/cached_import_option.scss +0 -3
  153. data/test/sass/templates/compact.sass +0 -17
  154. data/test/sass/templates/complex.sass +0 -305
  155. data/test/sass/templates/compressed.sass +0 -15
  156. data/test/sass/templates/double_import_loop1.sass +0 -1
  157. data/test/sass/templates/expanded.sass +0 -17
  158. data/test/sass/templates/filename_fn.scss +0 -18
  159. data/test/sass/templates/if.sass +0 -11
  160. data/test/sass/templates/import.sass +0 -12
  161. data/test/sass/templates/import_charset.sass +0 -9
  162. data/test/sass/templates/import_charset_1_8.sass +0 -6
  163. data/test/sass/templates/import_charset_ibm866.sass +0 -11
  164. data/test/sass/templates/import_content.sass +0 -4
  165. data/test/sass/templates/importee.less +0 -2
  166. data/test/sass/templates/importee.sass +0 -19
  167. data/test/sass/templates/line_numbers.sass +0 -13
  168. data/test/sass/templates/mixin_bork.sass +0 -5
  169. data/test/sass/templates/mixins.sass +0 -76
  170. data/test/sass/templates/multiline.sass +0 -20
  171. data/test/sass/templates/nested.sass +0 -25
  172. data/test/sass/templates/nested_bork1.sass +0 -2
  173. data/test/sass/templates/nested_bork2.sass +0 -2
  174. data/test/sass/templates/nested_bork3.sass +0 -2
  175. data/test/sass/templates/nested_bork4.sass +0 -2
  176. data/test/sass/templates/nested_import.sass +0 -2
  177. data/test/sass/templates/nested_mixin_bork.sass +0 -6
  178. data/test/sass/templates/options.sass +0 -2
  179. data/test/sass/templates/parent_ref.sass +0 -25
  180. data/test/sass/templates/same_name_different_ext.sass +0 -2
  181. data/test/sass/templates/same_name_different_ext.scss +0 -1
  182. data/test/sass/templates/same_name_different_partiality.scss +0 -1
  183. data/test/sass/templates/script.sass +0 -101
  184. data/test/sass/templates/scss_import.scss +0 -12
  185. data/test/sass/templates/scss_importee.scss +0 -1
  186. data/test/sass/templates/single_import_loop.sass +0 -1
  187. data/test/sass/templates/subdir/import_up1.scss +0 -1
  188. data/test/sass/templates/subdir/import_up2.scss +0 -1
  189. data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +0 -2
  190. data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +0 -3
  191. data/test/sass/templates/subdir/subdir.sass +0 -6
  192. data/test/sass/templates/units.sass +0 -11
  193. data/test/sass/templates/warn.sass +0 -3
  194. data/test/sass/templates/warn_imported.sass +0 -4
  195. data/test/sass/test_helper.rb +0 -8
  196. data/test/sass/util/multibyte_string_scanner_test.rb +0 -155
  197. data/test/sass/util/normalized_map_test.rb +0 -51
  198. data/test/sass/util/subset_map_test.rb +0 -91
  199. data/test/sass/util_test.rb +0 -438
  200. data/test/sass/value_helpers_test.rb +0 -179
  201. data/test/test_helper.rb +0 -110
  202. data/vendor/listen/CHANGELOG.md +0 -1
  203. data/vendor/listen/CONTRIBUTING.md +0 -38
  204. data/vendor/listen/Gemfile +0 -20
  205. data/vendor/listen/Guardfile +0 -8
  206. data/vendor/listen/LICENSE +0 -20
  207. data/vendor/listen/README.md +0 -349
  208. data/vendor/listen/Rakefile +0 -5
  209. data/vendor/listen/Vagrantfile +0 -96
  210. data/vendor/listen/lib/listen.rb +0 -54
  211. data/vendor/listen/lib/listen/adapter.rb +0 -327
  212. data/vendor/listen/lib/listen/adapters/bsd.rb +0 -75
  213. data/vendor/listen/lib/listen/adapters/darwin.rb +0 -48
  214. data/vendor/listen/lib/listen/adapters/linux.rb +0 -81
  215. data/vendor/listen/lib/listen/adapters/polling.rb +0 -58
  216. data/vendor/listen/lib/listen/adapters/windows.rb +0 -91
  217. data/vendor/listen/lib/listen/directory_record.rb +0 -406
  218. data/vendor/listen/lib/listen/listener.rb +0 -323
  219. data/vendor/listen/lib/listen/turnstile.rb +0 -32
  220. data/vendor/listen/lib/listen/version.rb +0 -3
  221. data/vendor/listen/listen.gemspec +0 -28
  222. data/vendor/listen/spec/listen/adapter_spec.rb +0 -149
  223. data/vendor/listen/spec/listen/adapters/bsd_spec.rb +0 -36
  224. data/vendor/listen/spec/listen/adapters/darwin_spec.rb +0 -37
  225. data/vendor/listen/spec/listen/adapters/linux_spec.rb +0 -47
  226. data/vendor/listen/spec/listen/adapters/polling_spec.rb +0 -68
  227. data/vendor/listen/spec/listen/adapters/windows_spec.rb +0 -30
  228. data/vendor/listen/spec/listen/directory_record_spec.rb +0 -1250
  229. data/vendor/listen/spec/listen/listener_spec.rb +0 -258
  230. data/vendor/listen/spec/listen/turnstile_spec.rb +0 -56
  231. data/vendor/listen/spec/listen_spec.rb +0 -67
  232. data/vendor/listen/spec/spec_helper.rb +0 -25
  233. data/vendor/listen/spec/support/adapter_helper.rb +0 -666
  234. data/vendor/listen/spec/support/directory_record_helper.rb +0 -57
  235. data/vendor/listen/spec/support/fixtures_helper.rb +0 -29
  236. data/vendor/listen/spec/support/listeners_helper.rb +0 -179
  237. data/vendor/listen/spec/support/platform_helper.rb +0 -15
@@ -1,160 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # -*- coding: utf-8 -*-
3
- require File.dirname(__FILE__) + '/../../test_helper'
4
- require 'sass/engine'
5
-
6
- class ScssRxTest < MiniTest::Test
7
- include Sass::SCSS::RX
8
-
9
- def test_identifiers
10
- assert_match IDENT, "foo"
11
- assert_match IDENT, "\xC3\xBFoo" # Initial char can be nonascii
12
- assert_match IDENT, "\\123abcoo" # Initial char can be unicode escape
13
- assert_match IDENT, "\\f oo" # Unicode escapes can be followed by whitespace
14
- assert_match IDENT, "\\fa\too"
15
- assert_match IDENT, "\\ff2\roo"
16
- assert_match IDENT, "\\f13a\foo"
17
- assert_match IDENT, "\\f13abcoo"
18
- assert_match IDENT, "\\ oo" # Initial char can be a plain escape as well
19
- assert_match IDENT, "\\~oo"
20
- assert_match IDENT, "\\\\oo"
21
- assert_match IDENT, "\\{oo"
22
- assert_match IDENT, "\\\xC3\xBFoo"
23
- assert_match IDENT, "-foo" # Can put a - before anything
24
- assert_match IDENT, "-\xC3\xBFoo"
25
- assert_match IDENT, "-\\f oo"
26
- assert_match IDENT, "_foo" # Can put a _ before anything
27
- assert_match IDENT, "_\xC3\xBFoo"
28
- assert_match IDENT, "_\\f oo"
29
- assert_match IDENT, "--foo" # "Custom" identifier
30
-
31
- assert_match IDENT, "foo-bar"
32
- assert_match IDENT, "f012-23"
33
- assert_match IDENT, "foo_-_bar"
34
- assert_match IDENT, "f012_23"
35
-
36
- # http://www.w3.org/Style/CSS/Test/CSS2.1/current/xhtml1/escapes-003.xht
37
- assert_match IDENT, "c\\lass"
38
- # http://www.w3.org/Style/CSS/Test/CSS2.1/current/xhtml1/escapes-004.xht
39
- assert_match IDENT, "c\\00006Cas\\000073"
40
- # http://www.w3.org/Style/CSS/Test/CSS2.1/current/xhtml1/ident-001.xht
41
- assert_match IDENT, "IdE6n-3t0_6"
42
- # http://www.w3.org/Style/CSS/Test/CSS2.1/current/xhtml1/ident-006.xht
43
- assert_match IDENT, "\\6000ident"
44
- # http://www.w3.org/Style/CSS/Test/CSS2.1/current/xhtml1/ident-007.xht
45
- assert_match IDENT, "iden\\6000t\\6000"
46
- # http://www.w3.org/Style/CSS/Test/CSS2.1/current/xhtml1/ident-013.xht
47
- assert_match IDENT, "\\-ident"
48
- end
49
-
50
- def test_underscores_in_identifiers
51
- assert_match IDENT, "foo_bar"
52
- assert_match IDENT, "_\xC3\xBFfoo"
53
- assert_match IDENT, "__foo"
54
- assert_match IDENT, "_1foo"
55
- assert_match IDENT, "-_foo"
56
- assert_match IDENT, "_-foo"
57
- end
58
-
59
- def test_invalid_identifiers
60
- assert_no_match IDENT, ""
61
- assert_no_match IDENT, "1foo"
62
- assert_no_match IDENT, "-1foo"
63
- assert_no_match IDENT, "foo bar"
64
- assert_no_match IDENT, "foo~bar"
65
-
66
- # http://www.w3.org/Style/CSS/Test/CSS2.1/current/xhtml1/escapes-008.xht
67
- assert_no_match IDENT, "c\\06C ass"
68
- assert_no_match IDENT, "back\\67\n round"
69
- end
70
-
71
- def test_double_quote_strings
72
- assert_match STRING, '"foo bar"'
73
- assert_match STRING, '"foo\\\nbar"'
74
- assert_match STRING, "\"\\\"\""
75
- assert_match STRING, '"\t !#$%&(-~()*+,-./0123456789~"'
76
- end
77
-
78
- def test_single_quote_strings
79
- assert_match STRING, "'foo bar'"
80
- assert_match STRING, "'foo\\\nbar'"
81
- assert_match STRING, "'\\''"
82
- assert_match STRING, "'\t !#\$%&(-~()*+,-./0123456789~'"
83
- end
84
-
85
- def test_invalid_strings
86
- assert_no_match STRING, "\"foo\nbar\""
87
- assert_no_match STRING, "\"foo\"bar\""
88
- assert_no_match STRING, "'foo\nbar'"
89
- assert_no_match STRING, "'foo'bar'"
90
- end
91
-
92
- def test_uri
93
- assert_match URI, 'url("foo bar)")'
94
- assert_match URI, "url('foo bar)')"
95
- assert_match URI, 'url( "foo bar)" )'
96
- assert_match URI, "url(#\\%&**+,-./0123456789~)"
97
- end
98
-
99
- def test_invalid_uri
100
- assert_no_match URI, 'url(foo)bar)'
101
- end
102
-
103
- def test_unicode_range
104
- assert_match UNICODERANGE, 'U+00-Ff'
105
- assert_match UNICODERANGE, 'u+980-9FF'
106
- assert_match UNICODERANGE, 'U+9aF??'
107
- assert_match UNICODERANGE, 'U+??'
108
- end
109
-
110
- def test_escape_empty_ident
111
- assert_equal "", Sass::SCSS::RX.escape_ident("")
112
- end
113
-
114
- def test_escape_just_prefix_ident
115
- assert_equal "\\-", Sass::SCSS::RX.escape_ident("-")
116
- assert_equal "\\_", Sass::SCSS::RX.escape_ident("_")
117
- end
118
-
119
- def test_escape_plain_ident
120
- assert_equal "foo", Sass::SCSS::RX.escape_ident("foo")
121
- assert_equal "foo-1bar", Sass::SCSS::RX.escape_ident("foo-1bar")
122
- assert_equal "-foo-bar", Sass::SCSS::RX.escape_ident("-foo-bar")
123
- assert_equal "f2oo_bar", Sass::SCSS::RX.escape_ident("f2oo_bar")
124
- assert_equal "_foo_bar", Sass::SCSS::RX.escape_ident("_foo_bar")
125
- end
126
-
127
- def test_escape_initial_funky_ident
128
- assert_equal "\\000035foo", Sass::SCSS::RX.escape_ident("5foo")
129
- assert_equal "-\\000035foo", Sass::SCSS::RX.escape_ident("-5foo")
130
- assert_equal "_\\000035foo", Sass::SCSS::RX.escape_ident("_5foo")
131
-
132
- assert_equal "\\&foo", Sass::SCSS::RX.escape_ident("&foo")
133
- assert_equal "-\\&foo", Sass::SCSS::RX.escape_ident("-&foo")
134
-
135
- assert_equal "-\\ foo", Sass::SCSS::RX.escape_ident("- foo")
136
- end
137
-
138
- def test_escape_mid_funky_ident
139
- assert_equal "foo\\&bar", Sass::SCSS::RX.escape_ident("foo&bar")
140
- assert_equal "foo\\ \\ bar", Sass::SCSS::RX.escape_ident("foo bar")
141
- assert_equal "foo\\00007fbar", Sass::SCSS::RX.escape_ident("foo\177bar")
142
- end
143
-
144
- def test_no_static_hyphenated_units
145
- assert_no_match STATIC_VALUE, "20px-20px"
146
- end
147
-
148
- private
149
-
150
- def assert_match(rx, str)
151
- refute_nil(match = rx.match(str))
152
- assert_equal str.size, match[0].size
153
- end
154
-
155
- def assert_no_match(rx, str)
156
- match = rx.match(str)
157
- refute_equal str.size, match && match[0].size
158
- end
159
-
160
- end
@@ -1,4205 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # -*- coding: utf-8 -*-
3
- require File.dirname(__FILE__) + '/test_helper'
4
-
5
- class ScssTest < MiniTest::Test
6
- include ScssTestHelper
7
-
8
- ## One-Line Comments
9
-
10
- def test_one_line_comments
11
- assert_equal <<CSS, render(<<SCSS)
12
- .foo {
13
- baz: bang; }
14
- CSS
15
- .foo {// bar: baz;}
16
- baz: bang; //}
17
- }
18
- SCSS
19
- assert_equal <<CSS, render(<<SCSS)
20
- .foo bar[val="//"] {
21
- baz: bang; }
22
- CSS
23
- .foo bar[val="//"] {
24
- baz: bang; //}
25
- }
26
- SCSS
27
- end
28
-
29
- ## Script
30
-
31
- def test_variables
32
- assert_equal <<CSS, render(<<SCSS)
33
- blat {
34
- a: foo; }
35
- CSS
36
- $var: foo;
37
-
38
- blat {a: $var}
39
- SCSS
40
-
41
- assert_equal <<CSS, render(<<SCSS)
42
- foo {
43
- a: 2;
44
- b: 6; }
45
- CSS
46
- foo {
47
- $var: 2;
48
- $another-var: 4;
49
- a: $var;
50
- b: $var + $another-var;}
51
- SCSS
52
- end
53
-
54
- def test_unicode_variables
55
- assert_equal <<CSS, render(<<SCSS)
56
- blat {
57
- a: foo; }
58
- CSS
59
- $vär: foo;
60
-
61
- blat {a: $vär}
62
- SCSS
63
- end
64
-
65
- def test_guard_assign
66
- assert_equal <<CSS, render(<<SCSS)
67
- foo {
68
- a: 1; }
69
- CSS
70
- $var: 1;
71
- $var: 2 !default;
72
-
73
- foo {a: $var}
74
- SCSS
75
-
76
- assert_equal <<CSS, render(<<SCSS)
77
- foo {
78
- a: 2; }
79
- CSS
80
- $var: 2 !default;
81
-
82
- foo {a: $var}
83
- SCSS
84
- end
85
-
86
- def test_sass_script
87
- assert_equal <<CSS, render(<<SCSS)
88
- foo {
89
- a: 3;
90
- b: -1;
91
- c: foobar;
92
- d: 12px; }
93
- CSS
94
- foo {
95
- a: 1 + 2;
96
- b: 1 - 2;
97
- c: foo + bar;
98
- d: floor(12.3px); }
99
- SCSS
100
- end
101
-
102
- def test_debug_directive
103
- assert_warning "test_debug_directive_inline.scss:2 DEBUG: hello world!" do
104
- assert_equal <<CSS, render(<<SCSS)
105
- foo {
106
- a: b; }
107
-
108
- bar {
109
- c: d; }
110
- CSS
111
- foo {a: b}
112
- @debug "hello world!";
113
- bar {c: d}
114
- SCSS
115
- end
116
- end
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
- def test_warn_directive
127
- expected_warning = <<EXPECTATION
128
- WARNING: this is a warning
129
- on line 2 of test_warn_directive_inline.scss
130
-
131
- WARNING: this is a mixin
132
- on line 1 of test_warn_directive_inline.scss, in `foo'
133
- from line 3 of test_warn_directive_inline.scss
134
- EXPECTATION
135
- assert_warning expected_warning do
136
- assert_equal <<CSS, render(<<SCSS)
137
- bar {
138
- c: d; }
139
- CSS
140
- @mixin foo { @warn "this is a mixin";}
141
- @warn "this is a warning";
142
- bar {c: d; @include foo;}
143
- SCSS
144
- end
145
- end
146
-
147
- def test_for_directive
148
- assert_equal <<CSS, render(<<SCSS)
149
- .foo {
150
- a: 1;
151
- a: 2;
152
- a: 3;
153
- a: 4; }
154
- CSS
155
- .foo {
156
- @for $var from 1 to 5 {a: $var;}
157
- }
158
- SCSS
159
-
160
- assert_equal <<CSS, render(<<SCSS)
161
- .foo {
162
- a: 1;
163
- a: 2;
164
- a: 3;
165
- a: 4;
166
- a: 5; }
167
- CSS
168
- .foo {
169
- @for $var from 1 through 5 {a: $var;}
170
- }
171
- SCSS
172
- end
173
-
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
- def test_if_directive
220
- assert_equal <<CSS, render(<<SCSS)
221
- foo {
222
- a: b; }
223
- CSS
224
- @if "foo" == "foo" {foo {a: b}}
225
- @if "foo" != "foo" {bar {a: b}}
226
- SCSS
227
-
228
- assert_equal <<CSS, render(<<SCSS)
229
- bar {
230
- a: b; }
231
- CSS
232
- @if "foo" != "foo" {foo {a: b}}
233
- @else if "foo" == "foo" {bar {a: b}}
234
- @else if true {baz {a: b}}
235
- SCSS
236
-
237
- assert_equal <<CSS, render(<<SCSS)
238
- bar {
239
- a: b; }
240
- CSS
241
- @if "foo" != "foo" {foo {a: b}}
242
- @else {bar {a: b}}
243
- SCSS
244
- end
245
-
246
- def test_comment_after_if_directive
247
- assert_equal <<CSS, render(<<SCSS)
248
- foo {
249
- a: b;
250
- /* This is a comment */
251
- c: d; }
252
- CSS
253
- foo {
254
- @if true {a: b}
255
- /* This is a comment */
256
- c: d }
257
- SCSS
258
- assert_equal <<CSS, render(<<SCSS)
259
- foo {
260
- a: b;
261
- /* This is a comment */
262
- c: d; }
263
- CSS
264
- foo {
265
- @if true {a: b}
266
- @else {x: y}
267
- /* This is a comment */
268
- c: d }
269
- SCSS
270
- end
271
-
272
- def test_while_directive
273
- assert_equal <<CSS, render(<<SCSS)
274
- .foo {
275
- a: 1;
276
- a: 2;
277
- a: 3;
278
- a: 4; }
279
- CSS
280
- $i: 1;
281
-
282
- .foo {
283
- @while $i != 5 {
284
- a: $i;
285
- $i: $i + 1 !global;
286
- }
287
- }
288
- SCSS
289
- end
290
-
291
- def test_each_directive
292
- assert_equal <<CSS, render(<<SCSS)
293
- a {
294
- b: 1px;
295
- b: 2px;
296
- b: 3px;
297
- b: 4px; }
298
-
299
- c {
300
- d: foo;
301
- d: bar;
302
- d: baz;
303
- d: bang; }
304
- CSS
305
- a {
306
- @each $number in 1px 2px 3px 4px {
307
- b: $number;
308
- }
309
- }
310
- c {
311
- @each $str in foo, bar, baz, bang {
312
- d: $str;
313
- }
314
- }
315
- SCSS
316
- end
317
-
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
- def test_css_import_directive
344
- assert_equal "@import url(foo.css);\n", render('@import "foo.css";')
345
- assert_equal "@import url(foo.css);\n", render("@import 'foo.css';")
346
- assert_equal "@import url(\"foo.css\");\n", render('@import url("foo.css");')
347
- assert_equal "@import url(\"foo.css\");\n", render('@import url("foo.css");')
348
- assert_equal "@import url(foo.css);\n", render('@import url(foo.css);')
349
- end
350
-
351
- def test_css_string_import_directive_with_media
352
- assert_parses '@import "foo.css" screen;'
353
- assert_parses '@import "foo.css" screen, print;'
354
- assert_parses '@import "foo.css" screen, print and (foo: 0);'
355
- assert_parses '@import "foo.css" screen, only print, screen and (foo: 0);'
356
- end
357
-
358
- def test_css_url_import_directive_with_media
359
- assert_parses '@import url("foo.css") screen;'
360
- assert_parses '@import url("foo.css") screen, print;'
361
- assert_parses '@import url("foo.css") screen, print and (foo: 0);'
362
- assert_parses '@import url("foo.css") screen, only print, screen and (foo: 0);'
363
- end
364
-
365
- def test_media_import
366
- assert_equal("@import \"./fonts.sass\" all;\n", render("@import \"./fonts.sass\" all;"))
367
- end
368
-
369
- def test_dynamic_media_import
370
- assert_equal(<<CSS, render(<<SCSS))
371
- @import "foo" print and (-webkit-min-device-pixel-ratio-foo: 25);
372
- CSS
373
- $media: print;
374
- $key: -webkit-min-device-pixel-ratio;
375
- $value: 20;
376
- @import "foo" \#{$media} and ($key + "-foo": $value + 5);
377
- SCSS
378
- end
379
-
380
- def test_http_import
381
- assert_equal("@import \"http://fonts.googleapis.com/css?family=Droid+Sans\";\n",
382
- render("@import \"http://fonts.googleapis.com/css?family=Droid+Sans\";"))
383
- end
384
-
385
- def test_protocol_relative_import
386
- assert_equal("@import \"//fonts.googleapis.com/css?family=Droid+Sans\";\n",
387
- render("@import \"//fonts.googleapis.com/css?family=Droid+Sans\";"))
388
- end
389
-
390
- def test_import_with_interpolation
391
- assert_equal <<CSS, render(<<SCSS)
392
- @import url("http://fonts.googleapis.com/css?family=Droid+Sans");
393
- CSS
394
- $family: unquote("Droid+Sans");
395
- @import url("http://fonts.googleapis.com/css?family=\#{$family}");
396
- SCSS
397
- end
398
-
399
- def test_url_import
400
- assert_equal("@import url(fonts.sass);\n", render("@import url(fonts.sass);"))
401
- end
402
-
403
- def test_css_import_doesnt_move_through_comments
404
- assert_equal <<CSS, render(<<SCSS)
405
- /* Comment 1 */
406
- @import url("foo.css");
407
- /* Comment 2 */
408
- @import url("bar.css");
409
- CSS
410
- /* Comment 1 */
411
- @import url("foo.css");
412
-
413
- /* Comment 2 */
414
- @import url("bar.css");
415
- SCSS
416
- end
417
-
418
- def test_css_import_movement_stops_at_comments
419
- assert_equal <<CSS, render(<<SCSS)
420
- /* Comment 1 */
421
- @import url("foo.css");
422
- /* Comment 2 */
423
- @import url("bar.css");
424
- .foo {
425
- a: b; }
426
-
427
- /* Comment 3 */
428
- CSS
429
- /* Comment 1 */
430
- @import url("foo.css");
431
-
432
- /* Comment 2 */
433
-
434
- .foo {a: b}
435
-
436
- /* Comment 3 */
437
- @import url("bar.css");
438
- SCSS
439
- end
440
-
441
- def test_block_comment_in_script
442
- assert_equal <<CSS, render(<<SCSS)
443
- foo {
444
- a: 1bar; }
445
- CSS
446
- foo {a: 1 + /* flang */ bar}
447
- SCSS
448
- end
449
-
450
- def test_line_comment_in_script
451
- assert_equal <<CSS, render(<<SCSS)
452
- foo {
453
- a: 1blang; }
454
- CSS
455
- foo {a: 1 + // flang }
456
- blang }
457
- SCSS
458
- end
459
-
460
- def test_static_hyphenated_unit
461
- assert_equal <<CSS, render(<<SCSS)
462
- foo {
463
- a: 0px; }
464
- CSS
465
- foo {a: 10px-10px }
466
- SCSS
467
- end
468
-
469
- ## Nested Rules
470
-
471
- def test_nested_rules
472
- assert_equal <<CSS, render(<<SCSS)
473
- foo bar {
474
- a: b; }
475
- CSS
476
- foo {bar {a: b}}
477
- SCSS
478
- assert_equal <<CSS, render(<<SCSS)
479
- foo bar {
480
- a: b; }
481
- foo baz {
482
- b: c; }
483
- CSS
484
- foo {
485
- bar {a: b}
486
- baz {b: c}}
487
- SCSS
488
- assert_equal <<CSS, render(<<SCSS)
489
- foo bar baz {
490
- a: b; }
491
- foo bang bip {
492
- a: b; }
493
- CSS
494
- foo {
495
- bar {baz {a: b}}
496
- bang {bip {a: b}}}
497
- SCSS
498
- end
499
-
500
- def test_nested_rules_with_declarations
501
- assert_equal <<CSS, render(<<SCSS)
502
- foo {
503
- a: b; }
504
- foo bar {
505
- c: d; }
506
- CSS
507
- foo {
508
- a: b;
509
- bar {c: d}}
510
- SCSS
511
- assert_equal <<CSS, render(<<SCSS)
512
- foo {
513
- a: b; }
514
- foo bar {
515
- c: d; }
516
- CSS
517
- foo {
518
- bar {c: d}
519
- a: b}
520
- SCSS
521
- assert_equal <<CSS, render(<<SCSS)
522
- foo {
523
- ump: nump;
524
- grump: clump; }
525
- foo bar {
526
- blat: bang;
527
- habit: rabbit; }
528
- foo bar baz {
529
- a: b; }
530
- foo bar bip {
531
- c: d; }
532
- foo bibble bap {
533
- e: f; }
534
- CSS
535
- foo {
536
- ump: nump;
537
- grump: clump;
538
- bar {
539
- blat: bang;
540
- habit: rabbit;
541
- baz {a: b}
542
- bip {c: d}}
543
- bibble {
544
- bap {e: f}}}
545
- SCSS
546
- end
547
-
548
- def test_nested_rules_with_fancy_selectors
549
- assert_equal <<CSS, render(<<SCSS)
550
- foo .bar {
551
- a: b; }
552
- foo :baz {
553
- c: d; }
554
- foo bang:bop {
555
- e: f; }
556
- foo ::qux {
557
- g: h; }
558
- foo zap::fblthp {
559
- i: j; }
560
- CSS
561
- foo {
562
- .bar {a: b}
563
- :baz {c: d}
564
- bang:bop {e: f}
565
- ::qux {g: h}
566
- zap::fblthp {i: j}}
567
- SCSS
568
- end
569
-
570
- def test_almost_ambiguous_nested_rules_and_declarations
571
- assert_equal <<CSS, render(<<SCSS)
572
- foo {
573
- bar: baz bang bop biddle woo look at all these elems; }
574
- foo bar:baz:bang:bop:biddle:woo:look:at:all:these:pseudoclasses {
575
- a: b; }
576
- foo bar:baz bang bop biddle woo look at all these elems {
577
- a: b; }
578
- CSS
579
- foo {
580
- bar:baz:bang:bop:biddle:woo:look:at:all:these:pseudoclasses {a: b};
581
- bar:baz bang bop biddle woo look at all these elems {a: b};
582
- bar:baz bang bop biddle woo look at all these elems; }
583
- SCSS
584
- end
585
-
586
- def test_newlines_in_selectors
587
- assert_equal <<CSS, render(<<SCSS)
588
- foo
589
- bar {
590
- a: b; }
591
- CSS
592
- foo
593
- bar {a: b}
594
- SCSS
595
-
596
- assert_equal <<CSS, render(<<SCSS)
597
- foo baz,
598
- foo bang,
599
- bar baz,
600
- bar bang {
601
- a: b; }
602
- CSS
603
- foo,
604
- bar {
605
- baz,
606
- bang {a: b}}
607
- SCSS
608
-
609
- assert_equal <<CSS, render(<<SCSS)
610
- foo
611
- bar baz
612
- bang {
613
- a: b; }
614
- foo
615
- bar bip bop {
616
- c: d; }
617
- CSS
618
- foo
619
- bar {
620
- baz
621
- bang {a: b}
622
-
623
- bip bop {c: d}}
624
- SCSS
625
-
626
- assert_equal <<CSS, render(<<SCSS)
627
- foo bang, foo bip
628
- bop, bar
629
- baz bang, bar
630
- baz bip
631
- bop {
632
- a: b; }
633
- CSS
634
- foo, bar
635
- baz {
636
- bang, bip
637
- bop {a: b}}
638
- SCSS
639
- end
640
-
641
- def test_trailing_comma_in_selector
642
- assert_equal <<CSS, render(<<SCSS)
643
- #foo #bar,
644
- #baz #boom {
645
- a: b; }
646
-
647
- #bip #bop {
648
- c: d; }
649
- CSS
650
- #foo #bar,,
651
- ,#baz #boom, {a: b}
652
-
653
- #bip #bop, ,, {c: d}
654
- SCSS
655
- end
656
-
657
- def test_parent_selectors
658
- assert_equal <<CSS, render(<<SCSS)
659
- foo:hover {
660
- a: b; }
661
- bar foo.baz {
662
- c: d; }
663
- CSS
664
- foo {
665
- &:hover {a: b}
666
- bar &.baz {c: d}}
667
- SCSS
668
- end
669
-
670
- def test_parent_selector_with_subject
671
- silence_warnings {assert_equal <<CSS, render(<<SCSS)}
672
- bar foo.baz! .bip {
673
- a: b; }
674
-
675
- bar foo bar.baz! .bip {
676
- c: d; }
677
- CSS
678
- foo {
679
- bar &.baz! .bip {a: b}}
680
-
681
- foo bar {
682
- bar &.baz! .bip {c: d}}
683
- SCSS
684
- end
685
-
686
- def test_parent_selector_with_suffix
687
- assert_equal <<CSS, render(<<SCSS)
688
- .foo-bar {
689
- a: b; }
690
- .foo_bar {
691
- c: d; }
692
- .foobar {
693
- e: f; }
694
- .foo123 {
695
- e: f; }
696
-
697
- :hover-suffix {
698
- g: h; }
699
- CSS
700
- .foo {
701
- &-bar {a: b}
702
- &_bar {c: d}
703
- &bar {e: f}
704
- &123 {e: f}
705
- }
706
-
707
- :hover {
708
- &-suffix {g: h}
709
- }
710
- SCSS
711
- end
712
-
713
- def test_unknown_directive_bubbling
714
- assert_equal(<<CSS, render(<<SCSS, :style => :nested))
715
- @fblthp {
716
- .foo .bar {
717
- a: b; } }
718
- CSS
719
- .foo {
720
- @fblthp {
721
- .bar {a: b}
722
- }
723
- }
724
- SCSS
725
- end
726
-
727
- def test_keyframe_bubbling
728
- assert_equal(<<CSS, render(<<SCSS, :style => :nested))
729
- @keyframes spin {
730
- 0% {
731
- transform: rotate(0deg); } }
732
- @-webkit-keyframes spin {
733
- 0% {
734
- transform: rotate(0deg); } }
735
- CSS
736
- .foo {
737
- @keyframes spin {
738
- 0% {transform: rotate(0deg)}
739
- }
740
- @-webkit-keyframes spin {
741
- 0% {transform: rotate(0deg)}
742
- }
743
- }
744
- SCSS
745
- end
746
-
747
- ## Namespace Properties
748
-
749
- def test_namespace_properties
750
- assert_equal <<CSS, render(<<SCSS)
751
- foo {
752
- bar: baz;
753
- bang-bip: 1px;
754
- bang-bop: bar; }
755
- CSS
756
- foo {
757
- bar: baz;
758
- bang: {
759
- bip: 1px;
760
- bop: bar;}}
761
- SCSS
762
- end
763
-
764
- def test_several_namespace_properties
765
- assert_equal <<CSS, render(<<SCSS)
766
- foo {
767
- bar: baz;
768
- bang-bip: 1px;
769
- bang-bop: bar;
770
- buzz-fram: "foo";
771
- buzz-frum: moo; }
772
- CSS
773
- foo {
774
- bar: baz;
775
- bang: {
776
- bip: 1px;
777
- bop: bar;}
778
- buzz: {
779
- fram: "foo";
780
- frum: moo;
781
- }
782
- }
783
- SCSS
784
- end
785
-
786
- def test_nested_namespace_properties
787
- assert_equal <<CSS, render(<<SCSS)
788
- foo {
789
- bar: baz;
790
- bang-bip: 1px;
791
- bang-bop: bar;
792
- bang-blat-baf: bort; }
793
- CSS
794
- foo {
795
- bar: baz;
796
- bang: {
797
- bip: 1px;
798
- bop: bar;
799
- blat:{baf:bort}}}
800
- SCSS
801
- end
802
-
803
- def test_namespace_properties_with_value
804
- assert_equal <<CSS, render(<<SCSS)
805
- foo {
806
- bar: baz;
807
- bar-bip: bop;
808
- bar-bing: bop; }
809
- CSS
810
- foo {
811
- bar: baz {
812
- bip: bop;
813
- bing: bop; }}
814
- SCSS
815
- end
816
-
817
- def test_namespace_properties_with_script_value
818
- assert_equal <<CSS, render(<<SCSS)
819
- foo {
820
- bar: bazbang;
821
- bar-bip: bop;
822
- bar-bing: bop; }
823
- CSS
824
- foo {
825
- bar: baz + bang {
826
- bip: bop;
827
- bing: bop; }}
828
- SCSS
829
- end
830
-
831
- def test_no_namespace_properties_without_space
832
- assert_equal <<CSS, render(<<SCSS)
833
- foo bar:baz {
834
- bip: bop; }
835
- CSS
836
- foo {
837
- bar:baz {
838
- bip: bop }}
839
- SCSS
840
- end
841
-
842
- def test_no_namespace_properties_without_space_even_when_its_unambiguous
843
- render(<<SCSS)
844
- foo {
845
- bar:baz calc(1 + 2) {
846
- bip: bop }}
847
- SCSS
848
- assert(false, "Expected syntax error")
849
- rescue Sass::SyntaxError => e
850
- assert_equal 'Invalid CSS after "bar:baz calc": expected selector, was "(1 + 2)"', e.message
851
- assert_equal 2, e.sass_line
852
- end
853
-
854
- def test_namespace_properties_without_space_allowed_for_non_identifier
855
- assert_equal <<CSS, render(<<SCSS)
856
- foo {
857
- bar: 1px;
858
- bar-bip: bop; }
859
- CSS
860
- foo {
861
- bar:1px {
862
- bip: bop }}
863
- SCSS
864
- end
865
-
866
- ## Mixins
867
-
868
- def test_basic_mixins
869
- assert_equal <<CSS, render(<<SCSS)
870
- .foo {
871
- a: b; }
872
- CSS
873
- @mixin foo {
874
- .foo {a: b}}
875
-
876
- @include foo;
877
- SCSS
878
-
879
- assert_equal <<CSS, render(<<SCSS)
880
- bar {
881
- c: d; }
882
- bar .foo {
883
- a: b; }
884
- CSS
885
- @mixin foo {
886
- .foo {a: b}}
887
-
888
- bar {
889
- @include foo;
890
- c: d; }
891
- SCSS
892
-
893
- assert_equal <<CSS, render(<<SCSS)
894
- bar {
895
- a: b;
896
- c: d; }
897
- CSS
898
- @mixin foo {a: b}
899
-
900
- bar {
901
- @include foo;
902
- c: d; }
903
- SCSS
904
- end
905
-
906
- def test_mixins_with_empty_args
907
- assert_equal <<CSS, render(<<SCSS)
908
- .foo {
909
- a: b; }
910
- CSS
911
- @mixin foo() {a: b}
912
-
913
- .foo {@include foo();}
914
- SCSS
915
-
916
- assert_equal <<CSS, render(<<SCSS)
917
- .foo {
918
- a: b; }
919
- CSS
920
- @mixin foo() {a: b}
921
-
922
- .foo {@include foo;}
923
- SCSS
924
-
925
- assert_equal <<CSS, render(<<SCSS)
926
- .foo {
927
- a: b; }
928
- CSS
929
- @mixin foo {a: b}
930
-
931
- .foo {@include foo();}
932
- SCSS
933
- end
934
-
935
- def test_mixins_with_args
936
- assert_equal <<CSS, render(<<SCSS)
937
- .foo {
938
- a: bar; }
939
- CSS
940
- @mixin foo($a) {a: $a}
941
-
942
- .foo {@include foo(bar)}
943
- SCSS
944
-
945
- assert_equal <<CSS, render(<<SCSS)
946
- .foo {
947
- a: bar;
948
- b: 12px; }
949
- CSS
950
- @mixin foo($a, $b) {
951
- a: $a;
952
- b: $b; }
953
-
954
- .foo {@include foo(bar, 12px)}
955
- SCSS
956
- end
957
-
958
- def test_keyframes_rules_in_content
959
- assert_equal <<CSS, render(<<SCSS)
960
- @keyframes identifier {
961
- 0% {
962
- top: 0;
963
- left: 0; }
964
- 30% {
965
- top: 50px; }
966
- 68%, 72% {
967
- left: 50px; }
968
- 100% {
969
- top: 100px;
970
- left: 100%; } }
971
- CSS
972
- @mixin keyframes {
973
- @keyframes identifier { @content }
974
- }
975
-
976
- @include keyframes {
977
- 0% {top: 0; left: 0}
978
- \#{"30%"} {top: 50px}
979
- 68%, 72% {left: 50px}
980
- 100% {top: 100px; left: 100%}
981
- }
982
- SCSS
983
- end
984
-
985
- ## Functions
986
-
987
- def test_basic_function
988
- assert_equal(<<CSS, render(<<SASS))
989
- bar {
990
- a: 3; }
991
- CSS
992
- @function foo() {
993
- @return 1 + 2;
994
- }
995
-
996
- bar {
997
- a: foo();
998
- }
999
- SASS
1000
- end
1001
-
1002
- def test_function_args
1003
- assert_equal(<<CSS, render(<<SASS))
1004
- bar {
1005
- a: 3; }
1006
- CSS
1007
- @function plus($var1, $var2) {
1008
- @return $var1 + $var2;
1009
- }
1010
-
1011
- bar {
1012
- a: plus(1, 2);
1013
- }
1014
- SASS
1015
- end
1016
-
1017
- def test_disallowed_function_names
1018
- Sass::Deprecation.allow_double_warnings do
1019
- assert_warning(<<WARNING) {render(<<SCSS)}
1020
- DEPRECATION WARNING on line 1 of test_disallowed_function_names_inline.scss:
1021
- Naming a function "calc" is disallowed and will be an error in future versions of Sass.
1022
- This name conflicts with an existing CSS function with special parse rules.
1023
- WARNING
1024
- @function calc() {}
1025
- SCSS
1026
-
1027
- assert_warning(<<WARNING) {render(<<SCSS)}
1028
- DEPRECATION WARNING on line 1 of test_disallowed_function_names_inline.scss:
1029
- Naming a function "-my-calc" is disallowed and will be an error in future versions of Sass.
1030
- This name conflicts with an existing CSS function with special parse rules.
1031
- WARNING
1032
- @function -my-calc() {}
1033
- SCSS
1034
-
1035
- assert_warning(<<WARNING) {render(<<SCSS)}
1036
- DEPRECATION WARNING on line 1 of test_disallowed_function_names_inline.scss:
1037
- Naming a function "element" is disallowed and will be an error in future versions of Sass.
1038
- This name conflicts with an existing CSS function with special parse rules.
1039
- WARNING
1040
- @function element() {}
1041
- SCSS
1042
-
1043
- assert_warning(<<WARNING) {render(<<SCSS)}
1044
- DEPRECATION WARNING on line 1 of test_disallowed_function_names_inline.scss:
1045
- Naming a function "-my-element" is disallowed and will be an error in future versions of Sass.
1046
- This name conflicts with an existing CSS function with special parse rules.
1047
- WARNING
1048
- @function -my-element() {}
1049
- SCSS
1050
-
1051
- assert_warning(<<WARNING) {render(<<SCSS)}
1052
- DEPRECATION WARNING on line 1 of test_disallowed_function_names_inline.scss:
1053
- Naming a function "expression" is disallowed and will be an error in future versions of Sass.
1054
- This name conflicts with an existing CSS function with special parse rules.
1055
- WARNING
1056
- @function expression() {}
1057
- SCSS
1058
-
1059
- assert_warning(<<WARNING) {render(<<SCSS)}
1060
- DEPRECATION WARNING on line 1 of test_disallowed_function_names_inline.scss:
1061
- Naming a function "url" is disallowed and will be an error in future versions of Sass.
1062
- This name conflicts with an existing CSS function with special parse rules.
1063
- WARNING
1064
- @function url() {}
1065
- SCSS
1066
- end
1067
- end
1068
-
1069
- def test_allowed_function_names
1070
- assert_no_warning {assert_equal(<<CSS, render(<<SCSS))}
1071
- .a {
1072
- b: c; }
1073
- CSS
1074
- @function -my-expression() {@return c}
1075
-
1076
- .a {b: -my-expression()}
1077
- SCSS
1078
-
1079
- assert_no_warning {assert_equal(<<CSS, render(<<SCSS))}
1080
- .a {
1081
- b: c; }
1082
- CSS
1083
- @function -my-url() {@return c}
1084
-
1085
- .a {b: -my-url()}
1086
- SCSS
1087
- end
1088
-
1089
- ## Var Args
1090
-
1091
- def test_mixin_var_args
1092
- assert_equal <<CSS, render(<<SCSS)
1093
- .foo {
1094
- a: 1;
1095
- b: 2, 3, 4; }
1096
- CSS
1097
- @mixin foo($a, $b...) {
1098
- a: $a;
1099
- b: $b;
1100
- }
1101
-
1102
- .foo {@include foo(1, 2, 3, 4)}
1103
- SCSS
1104
- end
1105
-
1106
- def test_mixin_empty_var_args
1107
- assert_equal <<CSS, render(<<SCSS)
1108
- .foo {
1109
- a: 1;
1110
- b: 0; }
1111
- CSS
1112
- @mixin foo($a, $b...) {
1113
- a: $a;
1114
- b: length($b);
1115
- }
1116
-
1117
- .foo {@include foo(1)}
1118
- SCSS
1119
- end
1120
-
1121
- def test_mixin_var_args_act_like_list
1122
- assert_equal <<CSS, render(<<SCSS)
1123
- .foo {
1124
- a: 3;
1125
- b: 3; }
1126
- CSS
1127
- @mixin foo($a, $b...) {
1128
- a: length($b);
1129
- b: nth($b, 2);
1130
- }
1131
-
1132
- .foo {@include foo(1, 2, 3, 4)}
1133
- SCSS
1134
- end
1135
-
1136
- def test_mixin_splat_args
1137
- assert_equal <<CSS, render(<<SCSS)
1138
- .foo {
1139
- a: 1;
1140
- b: 2;
1141
- c: 3;
1142
- d: 4; }
1143
- CSS
1144
- @mixin foo($a, $b, $c, $d) {
1145
- a: $a;
1146
- b: $b;
1147
- c: $c;
1148
- d: $d;
1149
- }
1150
-
1151
- $list: 2, 3, 4;
1152
- .foo {@include foo(1, $list...)}
1153
- SCSS
1154
- end
1155
-
1156
- def test_mixin_splat_expression
1157
- assert_equal <<CSS, render(<<SCSS)
1158
- .foo {
1159
- a: 1;
1160
- b: 2;
1161
- c: 3;
1162
- d: 4; }
1163
- CSS
1164
- @mixin foo($a, $b, $c, $d) {
1165
- a: $a;
1166
- b: $b;
1167
- c: $c;
1168
- d: $d;
1169
- }
1170
-
1171
- .foo {@include foo(1, (2, 3, 4)...)}
1172
- SCSS
1173
- end
1174
-
1175
- def test_mixin_splat_args_with_var_args
1176
- assert_equal <<CSS, render(<<SCSS)
1177
- .foo {
1178
- a: 1;
1179
- b: 2, 3, 4; }
1180
- CSS
1181
- @mixin foo($a, $b...) {
1182
- a: $a;
1183
- b: $b;
1184
- }
1185
-
1186
- $list: 2, 3, 4;
1187
- .foo {@include foo(1, $list...)}
1188
- SCSS
1189
- end
1190
-
1191
- def test_mixin_splat_args_with_var_args_and_normal_args
1192
- assert_equal <<CSS, render(<<SCSS)
1193
- .foo {
1194
- a: 1;
1195
- b: 2;
1196
- c: 3, 4; }
1197
- CSS
1198
- @mixin foo($a, $b, $c...) {
1199
- a: $a;
1200
- b: $b;
1201
- c: $c;
1202
- }
1203
-
1204
- $list: 2, 3, 4;
1205
- .foo {@include foo(1, $list...)}
1206
- SCSS
1207
- end
1208
-
1209
- def test_mixin_splat_args_with_var_args_preserves_separator
1210
- assert_equal <<CSS, render(<<SCSS)
1211
- .foo {
1212
- a: 1;
1213
- b: 2 3 4 5; }
1214
- CSS
1215
- @mixin foo($a, $b...) {
1216
- a: $a;
1217
- b: $b;
1218
- }
1219
-
1220
- $list: 3 4 5;
1221
- .foo {@include foo(1, 2, $list...)}
1222
- SCSS
1223
- end
1224
-
1225
- def test_mixin_var_and_splat_args_pass_through_keywords
1226
- assert_equal <<CSS, render(<<SCSS)
1227
- .foo {
1228
- a: 3;
1229
- b: 1;
1230
- c: 2; }
1231
- CSS
1232
- @mixin foo($a...) {
1233
- @include bar($a...);
1234
- }
1235
-
1236
- @mixin bar($b, $c, $a) {
1237
- a: $a;
1238
- b: $b;
1239
- c: $c;
1240
- }
1241
-
1242
- .foo {@include foo(1, $c: 2, $a: 3)}
1243
- SCSS
1244
- end
1245
-
1246
- def test_mixin_var_keyword_args
1247
- assert_equal <<CSS, render(<<SCSS)
1248
- .foo {
1249
- a: 1;
1250
- b: 2;
1251
- c: 3; }
1252
- CSS
1253
- @mixin foo($args...) {
1254
- a: map-get(keywords($args), a);
1255
- b: map-get(keywords($args), b);
1256
- c: map-get(keywords($args), c);
1257
- }
1258
-
1259
- .foo {@include foo($a: 1, $b: 2, $c: 3)}
1260
- SCSS
1261
- end
1262
-
1263
- def test_mixin_empty_var_keyword_args
1264
- assert_equal <<CSS, render(<<SCSS)
1265
- .foo {
1266
- length: 0; }
1267
- CSS
1268
- @mixin foo($args...) {
1269
- length: length(keywords($args));
1270
- }
1271
-
1272
- .foo {@include foo}
1273
- SCSS
1274
- end
1275
-
1276
- def test_mixin_map_splat
1277
- assert_equal <<CSS, render(<<SCSS)
1278
- .foo {
1279
- a: 1;
1280
- b: 2;
1281
- c: 3; }
1282
- CSS
1283
- @mixin foo($a, $b, $c) {
1284
- a: $a;
1285
- b: $b;
1286
- c: $c;
1287
- }
1288
-
1289
- .foo {
1290
- $map: (a: 1, b: 2, c: 3);
1291
- @include foo($map...);
1292
- }
1293
- SCSS
1294
- end
1295
-
1296
- def test_mixin_map_and_list_splat
1297
- assert_equal <<CSS, render(<<SCSS)
1298
- .foo {
1299
- a: x;
1300
- b: y;
1301
- c: z;
1302
- d: 1;
1303
- e: 2;
1304
- f: 3; }
1305
- CSS
1306
- @mixin foo($a, $b, $c, $d, $e, $f) {
1307
- a: $a;
1308
- b: $b;
1309
- c: $c;
1310
- d: $d;
1311
- e: $e;
1312
- f: $f;
1313
- }
1314
-
1315
- .foo {
1316
- $list: x y z;
1317
- $map: (d: 1, e: 2, f: 3);
1318
- @include foo($list..., $map...);
1319
- }
1320
- SCSS
1321
- end
1322
-
1323
- def test_mixin_map_splat_takes_precedence_over_pass_through
1324
- assert_equal <<CSS, render(<<SCSS)
1325
- .foo {
1326
- a: 1;
1327
- b: 2;
1328
- c: z; }
1329
- CSS
1330
- @mixin foo($args...) {
1331
- $map: (c: z);
1332
- @include bar($args..., $map...);
1333
- }
1334
-
1335
- @mixin bar($a, $b, $c) {
1336
- a: $a;
1337
- b: $b;
1338
- c: $c;
1339
- }
1340
-
1341
- .foo {
1342
- @include foo(1, $b: 2, $c: 3);
1343
- }
1344
- SCSS
1345
- end
1346
-
1347
- def test_mixin_list_of_pairs_splat_treated_as_list
1348
- assert_equal <<CSS, render(<<SCSS)
1349
- .foo {
1350
- a: a 1;
1351
- b: b 2;
1352
- c: c 3; }
1353
- CSS
1354
- @mixin foo($a, $b, $c) {
1355
- a: $a;
1356
- b: $b;
1357
- c: $c;
1358
- }
1359
-
1360
- .foo {
1361
- @include foo((a 1, b 2, c 3)...);
1362
- }
1363
- SCSS
1364
- end
1365
-
1366
- def test_mixin_splat_after_keyword_args
1367
- assert_equal <<CSS, render(<<SCSS)
1368
- .foo {
1369
- a: 1;
1370
- b: 2;
1371
- c: 3; }
1372
- CSS
1373
- @mixin foo($a, $b, $c) {
1374
- a: 1;
1375
- b: 2;
1376
- c: 3;
1377
- }
1378
-
1379
- .foo {
1380
- @include foo(1, $c: 3, 2...);
1381
- }
1382
- SCSS
1383
- end
1384
-
1385
- def test_mixin_keyword_args_after_splat
1386
- assert_equal <<CSS, render(<<SCSS)
1387
- .foo {
1388
- a: 1;
1389
- b: 2;
1390
- c: 3; }
1391
- CSS
1392
- @mixin foo($a, $b, $c) {
1393
- a: 1;
1394
- b: 2;
1395
- c: 3;
1396
- }
1397
-
1398
- .foo {
1399
- @include foo(1, 2..., $c: 3);
1400
- }
1401
- SCSS
1402
- end
1403
-
1404
- def test_mixin_keyword_splat_after_keyword_args
1405
- assert_equal <<CSS, render(<<SCSS)
1406
- .foo {
1407
- a: 1;
1408
- b: 2;
1409
- c: 3; }
1410
- CSS
1411
- @mixin foo($a, $b, $c) {
1412
- a: 1;
1413
- b: 2;
1414
- c: 3;
1415
- }
1416
-
1417
- .foo {
1418
- @include foo(1, $b: 2, (c: 3)...);
1419
- }
1420
- SCSS
1421
- end
1422
-
1423
- def test_mixin_triple_keyword_splat_merge
1424
- assert_equal <<CSS, render(<<SCSS)
1425
- .foo {
1426
- foo: 1;
1427
- bar: 2;
1428
- kwarg: 3;
1429
- a: 3;
1430
- b: 2;
1431
- c: 3; }
1432
- CSS
1433
- @mixin foo($foo, $bar, $kwarg, $a, $b, $c) {
1434
- foo: $foo;
1435
- bar: $bar;
1436
- kwarg: $kwarg;
1437
- a: $a;
1438
- b: $b;
1439
- c: $c;
1440
- }
1441
-
1442
- @mixin bar($args...) {
1443
- @include foo($args..., $bar: 2, $a: 2, $b: 2, (kwarg: 3, a: 3, c: 3)...);
1444
- }
1445
-
1446
- .foo {
1447
- @include bar($foo: 1, $a: 1, $b: 1, $c: 1);
1448
- }
1449
- SCSS
1450
- end
1451
-
1452
- def test_mixin_map_splat_converts_hyphens_and_underscores_for_real_args
1453
- assert_equal <<CSS, render(<<SCSS)
1454
- .foo {
1455
- a: 1;
1456
- b: 2;
1457
- c: 3;
1458
- d: 4; }
1459
- CSS
1460
- @mixin foo($a-1, $b-2, $c_3, $d_4) {
1461
- a: $a-1;
1462
- b: $b-2;
1463
- c: $c_3;
1464
- d: $d_4;
1465
- }
1466
-
1467
- .foo {
1468
- $map: (a-1: 1, b_2: 2, c-3: 3, d_4: 4);
1469
- @include foo($map...);
1470
- }
1471
- SCSS
1472
- end
1473
-
1474
- def test_mixin_map_splat_doesnt_convert_hyphens_and_underscores_for_var_args
1475
- assert_equal <<CSS, render(<<SCSS)
1476
- .foo {
1477
- a-1: 1;
1478
- b_2: 2;
1479
- c-3: 3;
1480
- d_4: 4; }
1481
- CSS
1482
- @mixin foo($args...) {
1483
- @each $key, $value in keywords($args) {
1484
- \#{$key}: $value;
1485
- }
1486
- }
1487
-
1488
- .foo {
1489
- $map: (a-1: 1, b_2: 2, c-3: 3, d_4: 4);
1490
- @include foo($map...);
1491
- }
1492
- SCSS
1493
- end
1494
-
1495
- def test_mixin_conflicting_splat_after_keyword_args
1496
- assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render(<<SCSS)}
1497
- Mixin foo was passed argument $b both by position and by name.
1498
- MESSAGE
1499
- @mixin foo($a, $b, $c) {
1500
- a: 1;
1501
- b: 2;
1502
- c: 3;
1503
- }
1504
-
1505
- .foo {
1506
- @include foo(1, $b: 2, 3...);
1507
- }
1508
- SCSS
1509
- end
1510
-
1511
- def test_mixin_keyword_splat_must_have_string_keys
1512
- assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render <<SCSS}
1513
- Variable keyword argument map must have string keys.
1514
- 12 is not a string in (12: 1).
1515
- MESSAGE
1516
- @mixin foo($a) {
1517
- a: $a;
1518
- }
1519
-
1520
- .foo {@include foo((12: 1)...)}
1521
- SCSS
1522
- end
1523
-
1524
- def test_mixin_positional_arg_after_splat
1525
- assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render(<<SCSS)}
1526
- Only keyword arguments may follow variable arguments (...).
1527
- MESSAGE
1528
- @mixin foo($a, $b, $c) {
1529
- a: 1;
1530
- b: 2;
1531
- c: 3;
1532
- }
1533
-
1534
- .foo {
1535
- @include foo(1, 2..., 3);
1536
- }
1537
- SCSS
1538
- end
1539
-
1540
- def test_mixin_var_args_with_keyword
1541
- assert_raise_message(Sass::SyntaxError, "Positional arguments must come before keyword arguments.") {render <<SCSS}
1542
- @mixin foo($a, $b...) {
1543
- a: $a;
1544
- b: $b;
1545
- }
1546
-
1547
- .foo {@include foo($a: 1, 2, 3, 4)}
1548
- SCSS
1549
- end
1550
-
1551
- def test_mixin_keyword_for_var_arg
1552
- assert_raise_message(Sass::SyntaxError, "Argument $b of mixin foo cannot be used as a named argument.") {render <<SCSS}
1553
- @mixin foo($a, $b...) {
1554
- a: $a;
1555
- b: $b;
1556
- }
1557
-
1558
- .foo {@include foo(1, $b: 2 3 4)}
1559
- SCSS
1560
- end
1561
-
1562
- def test_mixin_keyword_for_unknown_arg_with_var_args
1563
- assert_raise_message(Sass::SyntaxError, "Mixin foo doesn't have an argument named $c.") {render <<SCSS}
1564
- @mixin foo($a, $b...) {
1565
- a: $a;
1566
- b: $b;
1567
- }
1568
-
1569
- .foo {@include foo(1, $c: 2 3 4)}
1570
- SCSS
1571
- end
1572
-
1573
- def test_mixin_map_splat_before_list_splat
1574
- assert_raise_message(Sass::SyntaxError, "Variable keyword arguments must be a map (was (2 3)).") {render <<SCSS}
1575
- @mixin foo($a, $b, $c) {
1576
- a: $a;
1577
- b: $b;
1578
- c: $c;
1579
- }
1580
-
1581
- .foo {
1582
- @include foo((a: 1)..., (2 3)...);
1583
- }
1584
- SCSS
1585
- end
1586
-
1587
- def test_mixin_map_splat_with_unknown_keyword
1588
- assert_raise_message(Sass::SyntaxError, "Mixin foo doesn't have an argument named $c.") {render <<SCSS}
1589
- @mixin foo($a, $b) {
1590
- a: $a;
1591
- b: $b;
1592
- }
1593
-
1594
- .foo {
1595
- @include foo(1, 2, (c: 1)...);
1596
- }
1597
- SCSS
1598
- end
1599
-
1600
- def test_mixin_map_splat_with_wrong_type
1601
- assert_raise_message(Sass::SyntaxError, "Variable keyword arguments must be a map (was 12).") {render <<SCSS}
1602
- @mixin foo($a, $b) {
1603
- a: $a;
1604
- b: $b;
1605
- }
1606
-
1607
- .foo {
1608
- @include foo((1, 2)..., 12...);
1609
- }
1610
- SCSS
1611
- end
1612
-
1613
- def test_mixin_splat_too_many_args
1614
- assert_warning(<<WARNING) {render <<SCSS}
1615
- WARNING: Mixin foo takes 2 arguments but 4 were passed.
1616
- on line 2 of #{filename_for_test(:scss)}
1617
- This will be an error in future versions of Sass.
1618
- WARNING
1619
- @mixin foo($a, $b) {}
1620
- @include foo((1, 2, 3, 4)...);
1621
- SCSS
1622
- end
1623
-
1624
- def test_function_var_args
1625
- assert_equal <<CSS, render(<<SCSS)
1626
- .foo {
1627
- val: "a: 1, b: 2, 3, 4"; }
1628
- CSS
1629
- @function foo($a, $b...) {
1630
- @return "a: \#{$a}, b: \#{$b}";
1631
- }
1632
-
1633
- .foo {val: foo(1, 2, 3, 4)}
1634
- SCSS
1635
- end
1636
-
1637
- def test_function_empty_var_args
1638
- assert_equal <<CSS, render(<<SCSS)
1639
- .foo {
1640
- val: "a: 1, b: 0"; }
1641
- CSS
1642
- @function foo($a, $b...) {
1643
- @return "a: \#{$a}, b: \#{length($b)}";
1644
- }
1645
-
1646
- .foo {val: foo(1)}
1647
- SCSS
1648
- end
1649
-
1650
- def test_function_var_args_act_like_list
1651
- assert_equal <<CSS, render(<<SCSS)
1652
- .foo {
1653
- val: "a: 3, b: 3"; }
1654
- CSS
1655
- @function foo($a, $b...) {
1656
- @return "a: \#{length($b)}, b: \#{nth($b, 2)}";
1657
- }
1658
-
1659
- .foo {val: foo(1, 2, 3, 4)}
1660
- SCSS
1661
- end
1662
-
1663
- def test_function_splat_args
1664
- assert_equal <<CSS, render(<<SCSS)
1665
- .foo {
1666
- val: "a: 1, b: 2, c: 3, d: 4"; }
1667
- CSS
1668
- @function foo($a, $b, $c, $d) {
1669
- @return "a: \#{$a}, b: \#{$b}, c: \#{$c}, d: \#{$d}";
1670
- }
1671
-
1672
- $list: 2, 3, 4;
1673
- .foo {val: foo(1, $list...)}
1674
- SCSS
1675
- end
1676
-
1677
- def test_function_splat_expression
1678
- assert_equal <<CSS, render(<<SCSS)
1679
- .foo {
1680
- val: "a: 1, b: 2, c: 3, d: 4"; }
1681
- CSS
1682
- @function foo($a, $b, $c, $d) {
1683
- @return "a: \#{$a}, b: \#{$b}, c: \#{$c}, d: \#{$d}";
1684
- }
1685
-
1686
- .foo {val: foo(1, (2, 3, 4)...)}
1687
- SCSS
1688
- end
1689
-
1690
- def test_function_splat_args_with_var_args
1691
- assert_equal <<CSS, render(<<SCSS)
1692
- .foo {
1693
- val: "a: 1, b: 2, 3, 4"; }
1694
- CSS
1695
- @function foo($a, $b...) {
1696
- @return "a: \#{$a}, b: \#{$b}";
1697
- }
1698
-
1699
- $list: 2, 3, 4;
1700
- .foo {val: foo(1, $list...)}
1701
- SCSS
1702
- end
1703
-
1704
- def test_function_splat_args_with_var_args_and_normal_args
1705
- assert_equal <<CSS, render(<<SCSS)
1706
- .foo {
1707
- val: "a: 1, b: 2, c: 3, 4"; }
1708
- CSS
1709
- @function foo($a, $b, $c...) {
1710
- @return "a: \#{$a}, b: \#{$b}, c: \#{$c}";
1711
- }
1712
-
1713
- $list: 2, 3, 4;
1714
- .foo {val: foo(1, $list...)}
1715
- SCSS
1716
- end
1717
-
1718
- def test_function_splat_args_with_var_args_preserves_separator
1719
- assert_equal <<CSS, render(<<SCSS)
1720
- .foo {
1721
- val: "a: 1, b: 2 3 4 5"; }
1722
- CSS
1723
- @function foo($a, $b...) {
1724
- @return "a: \#{$a}, b: \#{$b}";
1725
- }
1726
-
1727
- $list: 3 4 5;
1728
- .foo {val: foo(1, 2, $list...)}
1729
- SCSS
1730
- end
1731
-
1732
- def test_function_var_and_splat_args_pass_through_keywords
1733
- assert_equal <<CSS, render(<<SCSS)
1734
- .foo {
1735
- val: "a: 3, b: 1, c: 2"; }
1736
- CSS
1737
- @function foo($a...) {
1738
- @return bar($a...);
1739
- }
1740
-
1741
- @function bar($b, $c, $a) {
1742
- @return "a: \#{$a}, b: \#{$b}, c: \#{$c}";
1743
- }
1744
-
1745
- .foo {val: foo(1, $c: 2, $a: 3)}
1746
- SCSS
1747
- end
1748
-
1749
- def test_function_var_keyword_args
1750
- assert_equal <<CSS, render(<<SCSS)
1751
- .foo {
1752
- val: "a: 1, b: 2, c: 3"; }
1753
- CSS
1754
- @function foo($args...) {
1755
- @return "a: \#{map-get(keywords($args), a)}, " +
1756
- "b: \#{map-get(keywords($args), b)}, " +
1757
- "c: \#{map-get(keywords($args), c)}";
1758
- }
1759
-
1760
- .foo {val: foo($a: 1, $b: 2, $c: 3)}
1761
- SCSS
1762
- end
1763
-
1764
- def test_function_empty_var_keyword_args
1765
- assert_equal <<CSS, render(<<SCSS)
1766
- .foo {
1767
- length: 0; }
1768
- CSS
1769
- @function foo($args...) {
1770
- @return length(keywords($args));
1771
- }
1772
-
1773
- .foo {length: foo()}
1774
- SCSS
1775
- end
1776
-
1777
- def test_function_map_splat
1778
- assert_equal <<CSS, render(<<SCSS)
1779
- .foo {
1780
- val: "a: 1, b: 2, c: 3"; }
1781
- CSS
1782
- @function foo($a, $b, $c) {
1783
- @return "a: \#{$a}, b: \#{$b}, c: \#{$c}";
1784
- }
1785
-
1786
- .foo {
1787
- $map: (a: 1, b: 2, c: 3);
1788
- val: foo($map...);
1789
- }
1790
- SCSS
1791
- end
1792
-
1793
- def test_function_map_and_list_splat
1794
- assert_equal <<CSS, render(<<SCSS)
1795
- .foo {
1796
- val: "a: x, b: y, c: z, d: 1, e: 2, f: 3"; }
1797
- CSS
1798
- @function foo($a, $b, $c, $d, $e, $f) {
1799
- @return "a: \#{$a}, b: \#{$b}, c: \#{$c}, d: \#{$d}, e: \#{$e}, f: \#{$f}";
1800
- }
1801
-
1802
- .foo {
1803
- $list: x y z;
1804
- $map: (d: 1, e: 2, f: 3);
1805
- val: foo($list..., $map...);
1806
- }
1807
- SCSS
1808
- end
1809
-
1810
- def test_function_map_splat_takes_precedence_over_pass_through
1811
- assert_equal <<CSS, render(<<SCSS)
1812
- .foo {
1813
- val: "a: 1, b: 2, c: z"; }
1814
- CSS
1815
- @function foo($args...) {
1816
- $map: (c: z);
1817
- @return bar($args..., $map...);
1818
- }
1819
-
1820
- @function bar($a, $b, $c) {
1821
- @return "a: \#{$a}, b: \#{$b}, c: \#{$c}";
1822
- }
1823
-
1824
- .foo {
1825
- val: foo(1, $b: 2, $c: 3);
1826
- }
1827
- SCSS
1828
- end
1829
-
1830
- def test_ruby_function_map_splat_takes_precedence_over_pass_through
1831
- assert_equal <<CSS, render(<<SCSS)
1832
- .foo {
1833
- val: 1 2 3 z; }
1834
- CSS
1835
- @function foo($args...) {
1836
- $map: (val: z);
1837
- @return append($args..., $map...);
1838
- }
1839
-
1840
- .foo {
1841
- val: foo(1 2 3, $val: 4)
1842
- }
1843
- SCSS
1844
- end
1845
-
1846
- def test_function_list_of_pairs_splat_treated_as_list
1847
- assert_equal <<CSS, render(<<SCSS)
1848
- .foo {
1849
- val: "a: a 1, b: b 2, c: c 3"; }
1850
- CSS
1851
- @function foo($a, $b, $c) {
1852
- @return "a: \#{$a}, b: \#{$b}, c: \#{$c}";
1853
- }
1854
-
1855
- .foo {
1856
- val: foo((a 1, b 2, c 3)...);
1857
- }
1858
- SCSS
1859
- end
1860
-
1861
- def test_function_splat_after_keyword_args
1862
- assert_equal <<CSS, render(<<SCSS)
1863
- .foo {
1864
- val: "a: 1, b: 2, c: 3"; }
1865
- CSS
1866
- @function foo($a, $b, $c) {
1867
- @return "a: \#{$a}, b: \#{$b}, c: \#{$c}";
1868
- }
1869
-
1870
- .foo {
1871
- val: foo(1, $c: 3, 2...);
1872
- }
1873
- SCSS
1874
- end
1875
-
1876
- def test_function_keyword_args_after_splat
1877
- assert_equal <<CSS, render(<<SCSS)
1878
- .foo {
1879
- val: "a: 1, b: 2, c: 3"; }
1880
- CSS
1881
- @function foo($a, $b, $c) {
1882
- @return "a: \#{$a}, b: \#{$b}, c: \#{$c}";
1883
- }
1884
-
1885
- .foo {
1886
- val: foo(1, 2..., $c: 3);
1887
- }
1888
- SCSS
1889
- end
1890
-
1891
- def test_function_keyword_splat_after_keyword_args
1892
- assert_equal <<CSS, render(<<SCSS)
1893
- .foo {
1894
- val: "a: 1, b: 2, c: 3"; }
1895
- CSS
1896
- @function foo($a, $b, $c) {
1897
- @return "a: \#{$a}, b: \#{$b}, c: \#{$c}";
1898
- }
1899
-
1900
- .foo {
1901
- val: foo(1, $b: 2, (c: 3)...);
1902
- }
1903
- SCSS
1904
- end
1905
-
1906
- def test_function_triple_keyword_splat_merge
1907
- assert_equal <<CSS, render(<<SCSS)
1908
- .foo {
1909
- val: "foo: 1, bar: 2, kwarg: 3, a: 3, b: 2, c: 3"; }
1910
- CSS
1911
- @function foo($foo, $bar, $kwarg, $a, $b, $c) {
1912
- @return "foo: \#{$foo}, bar: \#{$bar}, kwarg: \#{$kwarg}, a: \#{$a}, b: \#{$b}, c: \#{$c}";
1913
- }
1914
-
1915
- @function bar($args...) {
1916
- @return foo($args..., $bar: 2, $a: 2, $b: 2, (kwarg: 3, a: 3, c: 3)...);
1917
- }
1918
-
1919
- .foo {
1920
- val: bar($foo: 1, $a: 1, $b: 1, $c: 1);
1921
- }
1922
- SCSS
1923
- end
1924
-
1925
- def test_function_conflicting_splat_after_keyword_args
1926
- assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render(<<SCSS)}
1927
- Function foo was passed argument $b both by position and by name.
1928
- MESSAGE
1929
- @function foo($a, $b, $c) {
1930
- @return "a: \#{$a}, b: \#{$b}, c: \#{$c}";
1931
- }
1932
-
1933
- .foo {
1934
- val: foo(1, $b: 2, 3...);
1935
- }
1936
- SCSS
1937
- end
1938
-
1939
- def test_function_positional_arg_after_splat
1940
- assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render(<<SCSS)}
1941
- Only keyword arguments may follow variable arguments (...).
1942
- MESSAGE
1943
- @function foo($a, $b, $c) {
1944
- @return "a: \#{$a}, b: \#{$b}, c: \#{$c}";
1945
- }
1946
-
1947
- .foo {
1948
- val: foo(1, 2..., 3);
1949
- }
1950
- SCSS
1951
- end
1952
-
1953
- def test_function_var_args_with_keyword
1954
- assert_raise_message(Sass::SyntaxError, "Positional arguments must come before keyword arguments.") {render <<SCSS}
1955
- @function foo($a, $b...) {
1956
- @return "a: \#{$a}, b: \#{$b}";
1957
- }
1958
-
1959
- .foo {val: foo($a: 1, 2, 3, 4)}
1960
- SCSS
1961
- end
1962
-
1963
- def test_function_keyword_for_var_arg
1964
- assert_raise_message(Sass::SyntaxError, "Argument $b of function foo cannot be used as a named argument.") {render <<SCSS}
1965
- @function foo($a, $b...) {
1966
- @return "a: \#{$a}, b: \#{$b}";
1967
- }
1968
-
1969
- .foo {val: foo(1, $b: 2 3 4)}
1970
- SCSS
1971
- end
1972
-
1973
- def test_function_keyword_for_unknown_arg_with_var_args
1974
- assert_raise_message(Sass::SyntaxError, "Function foo doesn't have an argument named $c.") {render <<SCSS}
1975
- @function foo($a, $b...) {
1976
- @return "a: \#{$a}, b: \#{length($b)}";
1977
- }
1978
-
1979
- .foo {val: foo(1, $c: 2 3 4)}
1980
- SCSS
1981
- end
1982
-
1983
- def test_function_var_args_passed_to_native
1984
- assert_equal <<CSS, render(<<SCSS)
1985
- .foo {
1986
- val: #102035; }
1987
- CSS
1988
- @function foo($args...) {
1989
- @return adjust-color($args...);
1990
- }
1991
-
1992
- .foo {val: foo(#102030, $blue: 5)}
1993
- SCSS
1994
- end
1995
-
1996
- def test_function_map_splat_before_list_splat
1997
- assert_raise_message(Sass::SyntaxError, "Variable keyword arguments must be a map (was (2 3)).") {render <<SCSS}
1998
- @function foo($a, $b, $c) {
1999
- @return "a: \#{$a}, b: \#{$b}, c: \#{$c}";
2000
- }
2001
-
2002
- .foo {
2003
- val: foo((a: 1)..., (2 3)...);
2004
- }
2005
- SCSS
2006
- end
2007
-
2008
- def test_function_map_splat_with_unknown_keyword
2009
- assert_raise_message(Sass::SyntaxError, "Function foo doesn't have an argument named $c.") {render <<SCSS}
2010
- @function foo($a, $b) {
2011
- @return "a: \#{$a}, b: \#{$b}";
2012
- }
2013
-
2014
- .foo {
2015
- val: foo(1, 2, (c: 1)...);
2016
- }
2017
- SCSS
2018
- end
2019
-
2020
- def test_function_map_splat_with_wrong_type
2021
- assert_raise_message(Sass::SyntaxError, "Variable keyword arguments must be a map (was 12).") {render <<SCSS}
2022
- @function foo($a, $b) {
2023
- @return "a: \#{$a}, b: \#{$b}";
2024
- }
2025
-
2026
- .foo {
2027
- val: foo((1, 2)..., 12...);
2028
- }
2029
- SCSS
2030
- end
2031
-
2032
- def test_function_keyword_splat_must_have_string_keys
2033
- assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render <<SCSS}
2034
- Variable keyword argument map must have string keys.
2035
- 12 is not a string in (12: 1).
2036
- MESSAGE
2037
- @function foo($a) {
2038
- @return $a;
2039
- }
2040
-
2041
- .foo {val: foo((12: 1)...)}
2042
- SCSS
2043
- end
2044
-
2045
- def test_function_splat_too_many_args
2046
- assert_warning(<<WARNING) {render <<SCSS}
2047
- WARNING: Function foo takes 2 arguments but 4 were passed.
2048
- on line 2 of #{filename_for_test(:scss)}
2049
- This will be an error in future versions of Sass.
2050
- WARNING
2051
- @function foo($a, $b) {@return null}
2052
- $var: foo((1, 2, 3, 4)...);
2053
- SCSS
2054
- end
2055
-
2056
- ## Interpolation
2057
-
2058
- def test_basic_selector_interpolation
2059
- assert_equal <<CSS, render(<<SCSS)
2060
- foo ab baz {
2061
- a: b; }
2062
- CSS
2063
- foo \#{'a' + 'b'} baz {a: b}
2064
- SCSS
2065
- assert_equal <<CSS, render(<<SCSS)
2066
- foo.bar baz {
2067
- a: b; }
2068
- CSS
2069
- foo\#{".bar"} baz {a: b}
2070
- SCSS
2071
- assert_equal <<CSS, render(<<SCSS)
2072
- foo.bar baz {
2073
- a: b; }
2074
- CSS
2075
- \#{"foo"}.bar baz {a: b}
2076
- SCSS
2077
- end
2078
-
2079
- def test_selector_only_interpolation
2080
- assert_equal <<CSS, render(<<SCSS)
2081
- foo bar {
2082
- a: b; }
2083
- CSS
2084
- \#{"foo" + " bar"} {a: b}
2085
- SCSS
2086
- end
2087
-
2088
- def test_selector_interpolation_before_element_name
2089
- assert_equal <<CSS, render(<<SCSS)
2090
- foo barbaz {
2091
- a: b; }
2092
- CSS
2093
- \#{"foo" + " bar"}baz {a: b}
2094
- SCSS
2095
- end
2096
-
2097
- def test_selector_interpolation_in_string
2098
- assert_equal <<CSS, render(<<SCSS)
2099
- foo[val="bar foo bar baz"] {
2100
- a: b; }
2101
- CSS
2102
- foo[val="bar \#{"foo" + " bar"} baz"] {a: b}
2103
- SCSS
2104
- end
2105
-
2106
- def test_selector_interpolation_in_pseudoclass
2107
- assert_equal <<CSS, render(<<SCSS)
2108
- foo:nth-child(5n) {
2109
- a: b; }
2110
- CSS
2111
- foo:nth-child(\#{5 + "n"}) {a: b}
2112
- SCSS
2113
- end
2114
-
2115
- def test_selector_interpolation_at_class_begininng
2116
- assert_equal <<CSS, render(<<SCSS)
2117
- .zzz {
2118
- a: b; }
2119
- CSS
2120
- $zzz: zzz;
2121
- .\#{$zzz} { a: b; }
2122
- SCSS
2123
- end
2124
-
2125
- def test_selector_interpolation_at_id_begininng
2126
- assert_equal <<CSS, render(<<SCSS)
2127
- #zzz {
2128
- a: b; }
2129
- CSS
2130
- $zzz: zzz;
2131
- #\#{$zzz} { a: b; }
2132
- SCSS
2133
- end
2134
-
2135
- def test_selector_interpolation_at_pseudo_begininng
2136
- assert_equal <<CSS, render(<<SCSS)
2137
- :zzz::zzz {
2138
- a: b; }
2139
- CSS
2140
- $zzz: zzz;
2141
- :\#{$zzz}::\#{$zzz} { a: b; }
2142
- SCSS
2143
- end
2144
-
2145
- def test_selector_interpolation_at_attr_beginning
2146
- assert_equal <<CSS, render(<<SCSS)
2147
- [zzz=foo] {
2148
- a: b; }
2149
- CSS
2150
- $zzz: zzz;
2151
- [\#{$zzz}=foo] { a: b; }
2152
- SCSS
2153
- end
2154
-
2155
- def test_selector_interpolation_at_attr_end
2156
- assert_equal <<CSS, render(<<SCSS)
2157
- [foo=zzz] {
2158
- a: b; }
2159
- CSS
2160
- $zzz: zzz;
2161
- [foo=\#{$zzz}] { a: b; }
2162
- SCSS
2163
- end
2164
-
2165
- def test_selector_interpolation_at_dashes
2166
- assert_equal <<CSS, render(<<SCSS)
2167
- div {
2168
- -foo-a-b-foo: foo; }
2169
- CSS
2170
- $a : a;
2171
- $b : b;
2172
- div { -foo-\#{$a}-\#{$b}-foo: foo }
2173
- SCSS
2174
- end
2175
-
2176
- def test_selector_interpolation_in_reference_combinator
2177
- silence_warnings {assert_equal <<CSS, render(<<SCSS)}
2178
- .foo /a/ .bar /b|c/ .baz {
2179
- a: b; }
2180
- CSS
2181
- $a: a;
2182
- $b: b;
2183
- $c: c;
2184
- .foo /\#{$a}/ .bar /\#{$b}|\#{$c}/ .baz {a: b}
2185
- SCSS
2186
- end
2187
-
2188
- def test_parent_selector_with_parent_and_subject
2189
- silence_warnings {assert_equal <<CSS, render(<<SCSS)}
2190
- bar foo.baz! .bip {
2191
- c: d; }
2192
- CSS
2193
- $subject: "!";
2194
- foo {
2195
- bar &.baz\#{$subject} .bip {c: d}}
2196
- SCSS
2197
- end
2198
-
2199
- def test_basic_prop_name_interpolation
2200
- assert_equal <<CSS, render(<<SCSS)
2201
- foo {
2202
- barbazbang: blip; }
2203
- CSS
2204
- foo {bar\#{"baz" + "bang"}: blip}
2205
- SCSS
2206
- assert_equal <<CSS, render(<<SCSS)
2207
- foo {
2208
- bar3: blip; }
2209
- CSS
2210
- foo {bar\#{1 + 2}: blip}
2211
- SCSS
2212
- end
2213
-
2214
- def test_prop_name_only_interpolation
2215
- assert_equal <<CSS, render(<<SCSS)
2216
- foo {
2217
- bazbang: blip; }
2218
- CSS
2219
- foo {\#{"baz" + "bang"}: blip}
2220
- SCSS
2221
- end
2222
-
2223
- def test_directive_interpolation
2224
- assert_equal <<CSS, render(<<SCSS)
2225
- @foo bar12 qux {
2226
- a: b; }
2227
- CSS
2228
- $baz: 12;
2229
- @foo bar\#{$baz} qux {a: b}
2230
- SCSS
2231
- end
2232
-
2233
- def test_media_interpolation
2234
- assert_equal <<CSS, render(<<SCSS)
2235
- @media bar12 {
2236
- a: b; }
2237
- CSS
2238
- $baz: 12;
2239
- @media bar\#{$baz} {a: b}
2240
- SCSS
2241
- end
2242
-
2243
- def test_script_in_media
2244
- assert_equal <<CSS, render(<<SCSS)
2245
- @media screen and (-webkit-min-device-pixel-ratio: 20), only print {
2246
- a: b; }
2247
- CSS
2248
- $media1: screen;
2249
- $media2: print;
2250
- $var: -webkit-min-device-pixel-ratio;
2251
- $val: 20;
2252
- @media \#{$media1} and ($var: $val), only \#{$media2} {a: b}
2253
- SCSS
2254
-
2255
- assert_equal <<CSS, render(<<SCSS)
2256
- @media screen and (-webkit-min-device-pixel-ratio: 13) {
2257
- a: b; }
2258
- CSS
2259
- $vals: 1 2 3;
2260
- @media screen and (-webkit-min-device-pixel-ratio: 5 + 6 + nth($vals, 2)) {a: b}
2261
- SCSS
2262
- end
2263
-
2264
- def test_media_interpolation_with_reparse
2265
- assert_equal <<CSS, render(<<SCSS)
2266
- @media screen and (max-width: 300px) {
2267
- a: b; }
2268
- @media screen and (max-width: 300px) {
2269
- a: b; }
2270
- @media screen and (max-width: 300px) {
2271
- a: b; }
2272
- @media screen and (max-width: 300px), print and (max-width: 300px) {
2273
- a: b; }
2274
- CSS
2275
- $constraint: "(max-width: 300px)";
2276
- $fragment: "nd \#{$constraint}";
2277
- $comma: "een, pri";
2278
- @media screen and \#{$constraint} {a: b}
2279
- @media screen {
2280
- @media \#{$constraint} {a: b}
2281
- }
2282
- @media screen a\#{$fragment} {a: b}
2283
- @media scr\#{$comma}nt {
2284
- @media \#{$constraint} {a: b}
2285
- }
2286
- SCSS
2287
- end
2288
-
2289
- def test_moz_document_interpolation
2290
- assert_equal <<CSS, render(<<SCSS)
2291
- @-moz-document url(http://sass-lang.com/),
2292
- url-prefix(http://sass-lang.com/docs),
2293
- domain(sass-lang.com),
2294
- domain("sass-lang.com") {
2295
- .foo {
2296
- a: b; } }
2297
- CSS
2298
- $domain: "sass-lang.com";
2299
- @-moz-document url(http://\#{$domain}/),
2300
- url-prefix(http://\#{$domain}/docs),
2301
- domain(\#{$domain}),
2302
- \#{domain($domain)} {
2303
- .foo {a: b}
2304
- }
2305
- SCSS
2306
- end
2307
-
2308
- def test_supports_with_expressions
2309
- assert_equal <<CSS, render(<<SCSS)
2310
- @supports ((feature1: val) and (feature2: val)) or (not (feature23: val4)) {
2311
- foo {
2312
- a: b; } }
2313
- CSS
2314
- $query: "(feature1: val)";
2315
- $feature: feature2;
2316
- $val: val;
2317
- @supports (\#{$query} and ($feature: $val)) or (not ($feature + 3: $val + 4)) {
2318
- foo {a: b}
2319
- }
2320
- SCSS
2321
- end
2322
-
2323
- def test_supports_bubbling
2324
- assert_equal <<CSS, render(<<SCSS)
2325
- @supports (foo: bar) {
2326
- a {
2327
- b: c; }
2328
- @supports (baz: bang) {
2329
- a {
2330
- d: e; } } }
2331
- CSS
2332
- a {
2333
- @supports (foo: bar) {
2334
- b: c;
2335
- @supports (baz: bang) {
2336
- d: e;
2337
- }
2338
- }
2339
- }
2340
- SCSS
2341
- end
2342
-
2343
- def test_random_directive_interpolation
2344
- assert_equal <<CSS, render(<<SCSS)
2345
- @foo url(http://sass-lang.com/),
2346
- domain("sass-lang.com"),
2347
- "foobarbaz",
2348
- foobarbaz {
2349
- .foo {
2350
- a: b; } }
2351
- CSS
2352
- $domain: "sass-lang.com";
2353
- @foo url(http://\#{$domain}/),
2354
- \#{domain($domain)},
2355
- "foo\#{'ba' + 'r'}baz",
2356
- foo\#{'ba' + 'r'}baz {
2357
- .foo {a: b}
2358
- }
2359
- SCSS
2360
- end
2361
-
2362
- def test_color_interpolation_warning_in_selector
2363
- assert_warning(<<WARNING) {assert_equal <<CSS, render(<<SCSS)}
2364
- WARNING on line 1, column 4 of #{filename_for_test(:scss)}:
2365
- You probably don't mean to use the color value `blue' in interpolation here.
2366
- It may end up represented as #0000ff, which will likely produce invalid CSS.
2367
- Always quote color names when using them as strings (for example, "blue").
2368
- If you really want to use the color value here, use `"" + blue'.
2369
- WARNING
2370
- fooblue {
2371
- a: b; }
2372
- CSS
2373
- foo\#{blue} {a: b}
2374
- SCSS
2375
- end
2376
-
2377
- def test_color_interpolation_warning_in_directive
2378
- assert_warning(<<WARNING) {assert_equal <<CSS, render(<<SCSS)}
2379
- WARNING on line 1, column 12 of #{filename_for_test(:scss)}:
2380
- You probably don't mean to use the color value `blue' in interpolation here.
2381
- It may end up represented as #0000ff, which will likely produce invalid CSS.
2382
- Always quote color names when using them as strings (for example, "blue").
2383
- If you really want to use the color value here, use `"" + blue'.
2384
- WARNING
2385
- @fblthp fooblue {
2386
- a: b; }
2387
- CSS
2388
- @fblthp foo\#{blue} {a: b}
2389
- SCSS
2390
- end
2391
-
2392
- def test_color_interpolation_warning_in_property_name
2393
- assert_warning(<<WARNING) {assert_equal <<CSS, render(<<SCSS)}
2394
- WARNING on line 1, column 8 of #{filename_for_test(:scss)}:
2395
- You probably don't mean to use the color value `blue' in interpolation here.
2396
- It may end up represented as #0000ff, which will likely produce invalid CSS.
2397
- Always quote color names when using them as strings (for example, "blue").
2398
- If you really want to use the color value here, use `"" + blue'.
2399
- WARNING
2400
- foo {
2401
- a-blue: b; }
2402
- CSS
2403
- foo {a-\#{blue}: b}
2404
- SCSS
2405
- end
2406
-
2407
- def test_no_color_interpolation_warning_in_property_value
2408
- assert_no_warning {assert_equal <<CSS, render(<<SCSS)}
2409
- foo {
2410
- a: b-blue; }
2411
- CSS
2412
- foo {a: b-\#{blue}}
2413
- SCSS
2414
- end
2415
-
2416
- def test_no_color_interpolation_warning_for_nameless_color
2417
- assert_no_warning {assert_equal <<CSS, render(<<SCSS)}
2418
- foo-#abcdef {
2419
- a: b; }
2420
- CSS
2421
- foo-\#{#abcdef} {a: b}
2422
- SCSS
2423
- end
2424
-
2425
- def test_nested_mixin_def
2426
- assert_equal <<CSS, render(<<SCSS)
2427
- foo {
2428
- a: b; }
2429
- CSS
2430
- foo {
2431
- @mixin bar {a: b}
2432
- @include bar; }
2433
- SCSS
2434
- end
2435
-
2436
- def test_nested_mixin_shadow
2437
- assert_equal <<CSS, render(<<SCSS)
2438
- foo {
2439
- c: d; }
2440
-
2441
- baz {
2442
- a: b; }
2443
- CSS
2444
- @mixin bar {a: b}
2445
-
2446
- foo {
2447
- @mixin bar {c: d}
2448
- @include bar;
2449
- }
2450
-
2451
- baz {@include bar}
2452
- SCSS
2453
- end
2454
-
2455
- def test_nested_function_def
2456
- assert_equal <<CSS, render(<<SCSS)
2457
- foo {
2458
- a: 1; }
2459
-
2460
- bar {
2461
- b: foo(); }
2462
- CSS
2463
- foo {
2464
- @function foo() {@return 1}
2465
- a: foo(); }
2466
-
2467
- bar {b: foo()}
2468
- SCSS
2469
- end
2470
-
2471
- def test_nested_function_shadow
2472
- assert_equal <<CSS, render(<<SCSS)
2473
- foo {
2474
- a: 2; }
2475
-
2476
- baz {
2477
- b: 1; }
2478
- CSS
2479
- @function foo() {@return 1}
2480
-
2481
- foo {
2482
- @function foo() {@return 2}
2483
- a: foo();
2484
- }
2485
-
2486
- baz {b: foo()}
2487
- SCSS
2488
- end
2489
-
2490
- ## @at-root
2491
-
2492
- def test_simple_at_root
2493
- assert_equal <<CSS, render(<<SCSS)
2494
- .bar {
2495
- a: b; }
2496
- CSS
2497
- .foo {
2498
- @at-root {
2499
- .bar {a: b}
2500
- }
2501
- }
2502
- SCSS
2503
- end
2504
-
2505
- def test_at_root_with_selector
2506
- assert_equal <<CSS, render(<<SCSS)
2507
- .bar {
2508
- a: b; }
2509
- CSS
2510
- .foo {
2511
- @at-root .bar {a: b}
2512
- }
2513
- SCSS
2514
- end
2515
-
2516
- def test_at_root_in_mixin
2517
- assert_equal <<CSS, render(<<SCSS)
2518
- .bar {
2519
- a: b; }
2520
- CSS
2521
- @mixin bar {
2522
- @at-root .bar {a: b}
2523
- }
2524
-
2525
- .foo {
2526
- @include bar;
2527
- }
2528
- SCSS
2529
- end
2530
-
2531
- def test_at_root_in_media
2532
- assert_equal <<CSS, render(<<SCSS)
2533
- @media screen {
2534
- .bar {
2535
- a: b; } }
2536
- CSS
2537
- @media screen {
2538
- .foo {
2539
- @at-root .bar {a: b}
2540
- }
2541
- }
2542
- SCSS
2543
- end
2544
-
2545
- def test_at_root_in_bubbled_media
2546
- assert_equal <<CSS, render(<<SCSS)
2547
- @media screen {
2548
- .bar {
2549
- a: b; } }
2550
- CSS
2551
- .foo {
2552
- @media screen {
2553
- @at-root .bar {a: b}
2554
- }
2555
- }
2556
- SCSS
2557
- end
2558
-
2559
- def test_at_root_in_unknown_directive
2560
- assert_equal <<CSS, render(<<SCSS)
2561
- @fblthp {
2562
- .bar {
2563
- a: b; } }
2564
- CSS
2565
- @fblthp {
2566
- .foo {
2567
- @at-root .bar {a: b}
2568
- }
2569
- }
2570
- SCSS
2571
- end
2572
-
2573
- def test_comments_in_at_root
2574
- assert_equal <<CSS, render(<<SCSS)
2575
- /* foo */
2576
- .bar {
2577
- a: b; }
2578
-
2579
- /* baz */
2580
- CSS
2581
- .foo {
2582
- @at-root {
2583
- /* foo */
2584
- .bar {a: b}
2585
- /* baz */
2586
- }
2587
- }
2588
- SCSS
2589
- end
2590
-
2591
- def test_comments_in_at_root_in_media
2592
- assert_equal <<CSS, render(<<SCSS)
2593
- @media screen {
2594
- /* foo */
2595
- .bar {
2596
- a: b; }
2597
-
2598
- /* baz */ }
2599
- CSS
2600
- @media screen {
2601
- .foo {
2602
- @at-root {
2603
- /* foo */
2604
- .bar {a: b}
2605
- /* baz */
2606
- }
2607
- }
2608
- }
2609
- SCSS
2610
- end
2611
-
2612
- def test_comments_in_at_root_in_unknown_directive
2613
- assert_equal <<CSS, render(<<SCSS)
2614
- @fblthp {
2615
- /* foo */
2616
- .bar {
2617
- a: b; }
2618
-
2619
- /* baz */ }
2620
- CSS
2621
- @fblthp {
2622
- .foo {
2623
- @at-root {
2624
- /* foo */
2625
- .bar {a: b}
2626
- /* baz */
2627
- }
2628
- }
2629
- }
2630
- SCSS
2631
- end
2632
-
2633
- def test_media_directive_in_at_root
2634
- assert_equal <<CSS, render(<<SCSS)
2635
- @media screen {
2636
- .bar {
2637
- a: b; } }
2638
- CSS
2639
- .foo {
2640
- @at-root {
2641
- @media screen {.bar {a: b}}
2642
- }
2643
- }
2644
- SCSS
2645
- end
2646
-
2647
- def test_bubbled_media_directive_in_at_root
2648
- assert_equal <<CSS, render(<<SCSS)
2649
- @media screen {
2650
- .bar .baz {
2651
- a: b; } }
2652
- CSS
2653
- .foo {
2654
- @at-root {
2655
- .bar {
2656
- @media screen {.baz {a: b}}
2657
- }
2658
- }
2659
- }
2660
- SCSS
2661
- end
2662
-
2663
- def test_unknown_directive_in_at_root
2664
- assert_equal <<CSS, render(<<SCSS)
2665
- @fblthp {
2666
- .bar {
2667
- a: b; } }
2668
- CSS
2669
- .foo {
2670
- @at-root {
2671
- @fblthp {.bar {a: b}}
2672
- }
2673
- }
2674
- SCSS
2675
- end
2676
-
2677
- def test_at_root_in_at_root
2678
- assert_equal <<CSS, render(<<SCSS)
2679
- .bar {
2680
- a: b; }
2681
- CSS
2682
- .foo {
2683
- @at-root {
2684
- @at-root .bar {a: b}
2685
- }
2686
- }
2687
- SCSS
2688
- end
2689
-
2690
- def test_at_root_with_parent_ref
2691
- assert_equal <<CSS, render(<<SCSS)
2692
- .foo {
2693
- a: b; }
2694
- CSS
2695
- .foo {
2696
- @at-root & {
2697
- a: b;
2698
- }
2699
- }
2700
- SCSS
2701
- end
2702
-
2703
- def test_multi_level_at_root_with_parent_ref
2704
- assert_equal <<CSS, render(<<SCSS)
2705
- .foo .bar {
2706
- a: b; }
2707
- CSS
2708
- .foo {
2709
- @at-root & {
2710
- .bar {
2711
- @at-root & {
2712
- a: b;
2713
- }
2714
- }
2715
- }
2716
- }
2717
- SCSS
2718
- end
2719
-
2720
- def test_multi_level_at_root_with_inner_parent_ref
2721
- assert_equal <<CSS, render(<<SCSS)
2722
- .bar {
2723
- a: b; }
2724
- CSS
2725
- .foo {
2726
- @at-root .bar {
2727
- @at-root & {
2728
- a: b;
2729
- }
2730
- }
2731
- }
2732
- SCSS
2733
- end
2734
-
2735
- def test_at_root_beneath_comma_selector
2736
- assert_equal(<<CSS, render(<<SCSS))
2737
- .baz {
2738
- a: b; }
2739
- CSS
2740
- .foo, .bar {
2741
- @at-root .baz {
2742
- a: b;
2743
- }
2744
- }
2745
- SCSS
2746
- end
2747
-
2748
- def test_at_root_with_parent_ref_and_class
2749
- assert_equal(<<CSS, render(<<SCSS))
2750
- .foo.bar {
2751
- a: b; }
2752
- CSS
2753
- .foo {
2754
- @at-root &.bar {
2755
- a: b;
2756
- }
2757
- }
2758
- SCSS
2759
- end
2760
-
2761
- def test_at_root_beneath_comma_selector_with_parent_ref
2762
- assert_equal(<<CSS, render(<<SCSS))
2763
- .foo.baz, .bar.baz {
2764
- a: b; }
2765
- CSS
2766
- .foo, .bar {
2767
- @at-root &.baz {
2768
- a: b;
2769
- }
2770
- }
2771
- SCSS
2772
- end
2773
-
2774
- ## @at-root (...)
2775
-
2776
- def test_at_root_without_media
2777
- assert_equal <<CSS, render(<<SCSS)
2778
- .foo .bar {
2779
- a: b; }
2780
- CSS
2781
- .foo {
2782
- @media screen {
2783
- @at-root (without: media) {
2784
- .bar {
2785
- a: b;
2786
- }
2787
- }
2788
- }
2789
- }
2790
- SCSS
2791
- end
2792
-
2793
- def test_at_root_without_supports
2794
- assert_equal <<CSS, render(<<SCSS)
2795
- .foo .bar {
2796
- a: b; }
2797
- CSS
2798
- .foo {
2799
- @supports (foo: bar) {
2800
- @at-root (without: supports) {
2801
- .bar {
2802
- a: b;
2803
- }
2804
- }
2805
- }
2806
- }
2807
- SCSS
2808
- end
2809
-
2810
- def test_at_root_without_rule
2811
- assert_equal <<CSS, render(<<SCSS)
2812
- @media screen {
2813
- .bar {
2814
- a: b; } }
2815
- CSS
2816
- .foo {
2817
- @media screen {
2818
- @at-root (without: rule) {
2819
- .bar {
2820
- a: b;
2821
- }
2822
- }
2823
- }
2824
- }
2825
- SCSS
2826
- end
2827
-
2828
- def test_at_root_without_unknown_directive
2829
- assert_equal <<CSS, render(<<SCSS)
2830
- @fblthp {}
2831
- .foo .bar {
2832
- a: b; }
2833
- CSS
2834
- .foo {
2835
- @fblthp {
2836
- @at-root (without: fblthp) {
2837
- .bar {
2838
- a: b;
2839
- }
2840
- }
2841
- }
2842
- }
2843
- SCSS
2844
- end
2845
-
2846
- def test_at_root_without_multiple
2847
- assert_equal <<CSS, render(<<SCSS)
2848
- @supports (foo: bar) {
2849
- .bar {
2850
- a: b; } }
2851
- CSS
2852
- .foo {
2853
- @media screen {
2854
- @supports (foo: bar) {
2855
- @at-root (without: media rule) {
2856
- .bar {
2857
- a: b;
2858
- }
2859
- }
2860
- }
2861
- }
2862
- }
2863
- SCSS
2864
- end
2865
-
2866
- def test_at_root_without_all
2867
- assert_equal <<CSS, render(<<SCSS)
2868
- @supports (foo: bar) {
2869
- @fblthp {} }
2870
- .bar {
2871
- a: b; }
2872
- CSS
2873
- .foo {
2874
- @supports (foo: bar) {
2875
- @fblthp {
2876
- @at-root (without: all) {
2877
- .bar {
2878
- a: b;
2879
- }
2880
- }
2881
- }
2882
- }
2883
- }
2884
- SCSS
2885
- end
2886
-
2887
- def test_at_root_with_media
2888
- assert_equal <<CSS, render(<<SCSS)
2889
- @media screen {
2890
- @fblthp {}
2891
- .bar {
2892
- a: b; } }
2893
- CSS
2894
- .foo {
2895
- @media screen {
2896
- @fblthp {
2897
- @supports (foo: bar) {
2898
- @at-root (with: media) {
2899
- .bar {
2900
- a: b;
2901
- }
2902
- }
2903
- }
2904
- }
2905
- }
2906
- }
2907
- SCSS
2908
- end
2909
-
2910
- def test_at_root_with_rule
2911
- assert_equal <<CSS, render(<<SCSS)
2912
- @media screen {
2913
- @fblthp {} }
2914
- .foo .bar {
2915
- a: b; }
2916
- CSS
2917
- .foo {
2918
- @media screen {
2919
- @fblthp {
2920
- @supports (foo: bar) {
2921
- @at-root (with: rule) {
2922
- .bar {
2923
- a: b;
2924
- }
2925
- }
2926
- }
2927
- }
2928
- }
2929
- }
2930
- SCSS
2931
- end
2932
-
2933
- def test_at_root_with_supports
2934
- assert_equal <<CSS, render(<<SCSS)
2935
- @media screen {
2936
- @fblthp {} }
2937
- @supports (foo: bar) {
2938
- .bar {
2939
- a: b; } }
2940
- CSS
2941
- .foo {
2942
- @media screen {
2943
- @fblthp {
2944
- @supports (foo: bar) {
2945
- @at-root (with: supports) {
2946
- .bar {
2947
- a: b;
2948
- }
2949
- }
2950
- }
2951
- }
2952
- }
2953
- }
2954
- SCSS
2955
- end
2956
-
2957
- def test_at_root_with_unknown_directive
2958
- assert_equal <<CSS, render(<<SCSS)
2959
- @media screen {
2960
- @fblthp {} }
2961
- @fblthp {
2962
- .bar {
2963
- a: b; } }
2964
- CSS
2965
- .foo {
2966
- @media screen {
2967
- @fblthp {
2968
- @supports (foo: bar) {
2969
- @at-root (with: fblthp) {
2970
- .bar {
2971
- a: b;
2972
- }
2973
- }
2974
- }
2975
- }
2976
- }
2977
- }
2978
- SCSS
2979
- end
2980
-
2981
- def test_at_root_with_multiple
2982
- assert_equal <<CSS, render(<<SCSS)
2983
- @media screen {
2984
- @fblthp {}
2985
- .foo .bar {
2986
- a: b; } }
2987
- CSS
2988
- .foo {
2989
- @media screen {
2990
- @fblthp {
2991
- @supports (foo: bar) {
2992
- @at-root (with: media rule) {
2993
- .bar {
2994
- a: b;
2995
- }
2996
- }
2997
- }
2998
- }
2999
- }
3000
- }
3001
- SCSS
3002
- end
3003
-
3004
- def test_at_root_with_all
3005
- assert_equal <<CSS, render(<<SCSS)
3006
- @media screen {
3007
- @fblthp {
3008
- @supports (foo: bar) {
3009
- .foo .bar {
3010
- a: b; } } } }
3011
- CSS
3012
- .foo {
3013
- @media screen {
3014
- @fblthp {
3015
- @supports (foo: bar) {
3016
- @at-root (with: all) {
3017
- .bar {
3018
- a: b;
3019
- }
3020
- }
3021
- }
3022
- }
3023
- }
3024
- }
3025
- SCSS
3026
- end
3027
-
3028
- def test_at_root_dynamic_values
3029
- assert_equal <<CSS, render(<<SCSS)
3030
- @media screen {
3031
- .bar {
3032
- a: b; } }
3033
- CSS
3034
- $key: with;
3035
- $value: media;
3036
- .foo {
3037
- @media screen {
3038
- @at-root ($key: $value) {
3039
- .bar {
3040
- a: b;
3041
- }
3042
- }
3043
- }
3044
- }
3045
- SCSS
3046
- end
3047
-
3048
- def test_at_root_interpolated_query
3049
- assert_equal <<CSS, render(<<SCSS)
3050
- @media screen {
3051
- .bar {
3052
- a: b; } }
3053
- CSS
3054
- .foo {
3055
- @media screen {
3056
- @at-root (\#{"with: media"}) {
3057
- .bar {
3058
- a: b;
3059
- }
3060
- }
3061
- }
3062
- }
3063
- SCSS
3064
- end
3065
-
3066
- def test_at_root_plus_extend
3067
- assert_equal <<CSS, render(<<SCSS)
3068
- .foo .bar {
3069
- a: b; }
3070
- CSS
3071
- %base {
3072
- a: b;
3073
- }
3074
-
3075
- .foo {
3076
- @media screen {
3077
- @at-root (without: media) {
3078
- .bar {
3079
- @extend %base;
3080
- }
3081
- }
3082
- }
3083
- }
3084
- SCSS
3085
- end
3086
-
3087
- def test_at_root_without_keyframes_in_keyframe_rule
3088
- assert_equal <<CSS, render(<<SCSS)
3089
- .foo {
3090
- a: b; }
3091
- CSS
3092
- @keyframes identifier {
3093
- 0% {
3094
- @at-root (without: keyframes) {
3095
- .foo {a: b}
3096
- }
3097
- }
3098
- }
3099
- SCSS
3100
- end
3101
-
3102
- def test_at_root_without_rule_in_keyframe_rule
3103
- assert_equal <<CSS, render(<<SCSS)
3104
- @keyframes identifier {
3105
- 0% {
3106
- a: b; } }
3107
- CSS
3108
- @keyframes identifier {
3109
- 0% {
3110
- @at-root (without: rule) {a: b}
3111
- }
3112
- }
3113
- SCSS
3114
- end
3115
-
3116
- ## Selector Script
3117
-
3118
- def test_selector_script
3119
- assert_equal(<<CSS, render(<<SCSS))
3120
- .foo .bar {
3121
- content: ".foo .bar"; }
3122
- CSS
3123
- .foo .bar {
3124
- content: "\#{&}";
3125
- }
3126
- SCSS
3127
- end
3128
-
3129
- def test_nested_selector_script
3130
- assert_equal(<<CSS, render(<<SCSS))
3131
- .foo .bar {
3132
- content: ".foo .bar"; }
3133
- CSS
3134
- .foo {
3135
- .bar {
3136
- content: "\#{&}";
3137
- }
3138
- }
3139
- SCSS
3140
- end
3141
-
3142
- def test_nested_selector_script_with_outer_comma_selector
3143
- assert_equal(<<CSS, render(<<SCSS))
3144
- .foo .baz, .bar .baz {
3145
- content: ".foo .baz, .bar .baz"; }
3146
- CSS
3147
- .foo, .bar {
3148
- .baz {
3149
- content: "\#{&}";
3150
- }
3151
- }
3152
- SCSS
3153
- end
3154
-
3155
- def test_nested_selector_script_with_inner_comma_selector
3156
- assert_equal(<<CSS, render(<<SCSS))
3157
- .foo .bar, .foo .baz {
3158
- content: ".foo .bar, .foo .baz"; }
3159
- CSS
3160
- .foo {
3161
- .bar, .baz {
3162
- content: "\#{&}";
3163
- }
3164
- }
3165
- SCSS
3166
- end
3167
-
3168
- def test_selector_script_through_mixin
3169
- assert_equal(<<CSS, render(<<SCSS))
3170
- .foo {
3171
- content: ".foo"; }
3172
- CSS
3173
- @mixin mixin {
3174
- content: "\#{&}";
3175
- }
3176
-
3177
- .foo {
3178
- @include mixin;
3179
- }
3180
- SCSS
3181
- end
3182
-
3183
- def test_selector_script_through_content
3184
- assert_equal(<<CSS, render(<<SCSS))
3185
- .foo {
3186
- content: ".foo"; }
3187
- CSS
3188
- @mixin mixin {
3189
- @content;
3190
- }
3191
-
3192
- .foo {
3193
- @include mixin {
3194
- content: "\#{&}";
3195
- }
3196
- }
3197
- SCSS
3198
- end
3199
-
3200
- def test_selector_script_through_function
3201
- assert_equal(<<CSS, render(<<SCSS))
3202
- .foo {
3203
- content: ".foo"; }
3204
- CSS
3205
- @function fn() {
3206
- @return "\#{&}";
3207
- }
3208
-
3209
- .foo {
3210
- content: fn();
3211
- }
3212
- SCSS
3213
- end
3214
-
3215
- def test_selector_script_through_media
3216
- assert_equal(<<CSS, render(<<SCSS))
3217
- .foo {
3218
- content: "outer"; }
3219
- @media screen {
3220
- .foo .bar {
3221
- content: ".foo .bar"; } }
3222
- CSS
3223
- .foo {
3224
- content: "outer";
3225
- @media screen {
3226
- .bar {
3227
- content: "\#{&}";
3228
- }
3229
- }
3230
- }
3231
- SCSS
3232
- end
3233
-
3234
- def test_selector_script_save_and_reuse
3235
- assert_equal(<<CSS, render(<<SCSS))
3236
- .bar {
3237
- content: ".foo"; }
3238
- CSS
3239
- $var: null;
3240
- .foo {
3241
- $var: & !global;
3242
- }
3243
-
3244
- .bar {
3245
- content: "\#{$var}";
3246
- }
3247
- SCSS
3248
- end
3249
-
3250
- def test_selector_script_with_at_root
3251
- assert_equal(<<CSS, render(<<SCSS))
3252
- .foo-bar {
3253
- a: b; }
3254
- CSS
3255
- .foo {
3256
- @at-root \#{&}-bar {
3257
- a: b;
3258
- }
3259
- }
3260
- SCSS
3261
- end
3262
-
3263
- def test_multi_level_at_root_with_inner_selector_script
3264
- assert_equal <<CSS, render(<<SCSS)
3265
- .bar {
3266
- a: b; }
3267
- CSS
3268
- .foo {
3269
- @at-root .bar {
3270
- @at-root \#{&} {
3271
- a: b;
3272
- }
3273
- }
3274
- }
3275
- SCSS
3276
- end
3277
-
3278
- def test_at_root_with_at_root_through_mixin
3279
- assert_equal(<<CSS, render(<<SCSS))
3280
- .bar-baz {
3281
- a: b; }
3282
- CSS
3283
- @mixin foo {
3284
- .bar {
3285
- @at-root \#{&}-baz {
3286
- a: b;
3287
- }
3288
- }
3289
- }
3290
-
3291
- @include foo;
3292
- SCSS
3293
- end
3294
-
3295
- # See https://github.com/sass/sass/issues/1294
3296
- def test_extend_top_leveled_by_at_root
3297
- render(<<SCSS)
3298
- .span-10 {
3299
- @at-root (without: all) {
3300
- @extend %column;
3301
- }
3302
- }
3303
- SCSS
3304
-
3305
- assert(false, "Expected syntax error")
3306
- rescue Sass::SyntaxError => e
3307
- assert_equal "Extend directives may only be used within rules.", e.message
3308
- assert_equal 3, e.sass_line
3309
- end
3310
-
3311
- def test_at_root_doesnt_always_break_blocks
3312
- assert_equal <<CSS, render(<<SCSS)
3313
- .foo {
3314
- a: b; }
3315
-
3316
- @media screen {
3317
- .foo {
3318
- c: d; }
3319
- .bar {
3320
- e: f; } }
3321
- CSS
3322
- %base {
3323
- a: b;
3324
- }
3325
-
3326
- @media screen {
3327
- .foo {
3328
- c: d;
3329
- @at-root (without: media) {
3330
- @extend %base;
3331
- }
3332
- }
3333
-
3334
- .bar {e: f}
3335
- }
3336
- SCSS
3337
- end
3338
-
3339
- ## Errors
3340
-
3341
- def test_keyframes_rule_outside_of_keyframes
3342
- render <<SCSS
3343
- 0% {
3344
- top: 0; }
3345
- SCSS
3346
- assert(false, "Expected syntax error")
3347
- rescue Sass::SyntaxError => e
3348
- assert_equal 'Invalid CSS after "": expected selector, was "0%"', e.message
3349
- assert_equal 1, e.sass_line
3350
- end
3351
-
3352
- def test_selector_rule_in_keyframes
3353
- render <<SCSS
3354
- @keyframes identifier {
3355
- .foo {
3356
- top: 0; } }
3357
- SCSS
3358
- assert(false, "Expected syntax error")
3359
- rescue Sass::SyntaxError => e
3360
- assert_equal 'Invalid CSS after "": expected keyframes selector (e.g. 10%), was ".foo"', e.message
3361
- assert_equal 2, e.sass_line
3362
- end
3363
-
3364
- def test_nested_mixin_def_is_scoped
3365
- render <<SCSS
3366
- foo {
3367
- @mixin bar {a: b}}
3368
- bar {@include bar}
3369
- SCSS
3370
- assert(false, "Expected syntax error")
3371
- rescue Sass::SyntaxError => e
3372
- assert_equal "Undefined mixin 'bar'.", e.message
3373
- assert_equal 3, e.sass_line
3374
- end
3375
-
3376
- def test_rules_beneath_properties
3377
- render <<SCSS
3378
- foo {
3379
- bar: {
3380
- baz {
3381
- bang: bop }}}
3382
- SCSS
3383
- assert(false, "Expected syntax error")
3384
- rescue Sass::SyntaxError => e
3385
- assert_equal 'Illegal nesting: Only properties may be nested beneath properties.', e.message
3386
- assert_equal 3, e.sass_line
3387
- end
3388
-
3389
- def test_uses_property_exception_with_star_hack
3390
- render <<SCSS
3391
- foo {
3392
- *bar:baz [fail]; }
3393
- SCSS
3394
- assert(false, "Expected syntax error")
3395
- rescue Sass::SyntaxError => e
3396
- assert_equal 'Invalid CSS after " *bar:baz ": expected ";", was "[fail]; }"', e.message
3397
- assert_equal 2, e.sass_line
3398
- end
3399
-
3400
- def test_uses_property_exception_with_colon_hack
3401
- render <<SCSS
3402
- foo {
3403
- :bar:baz [fail]; }
3404
- SCSS
3405
- assert(false, "Expected syntax error")
3406
- rescue Sass::SyntaxError => e
3407
- assert_equal 'Invalid CSS after " :bar:baz ": expected ";", was "[fail]; }"', e.message
3408
- assert_equal 2, e.sass_line
3409
- end
3410
-
3411
- def test_uses_rule_exception_with_dot_hack
3412
- render <<SCSS
3413
- foo {
3414
- .bar:baz <fail>; }
3415
- SCSS
3416
- assert(false, "Expected syntax error")
3417
- rescue Sass::SyntaxError => e
3418
- assert_equal 'Invalid CSS after " .bar:baz <fail>": expected expression (e.g. 1px, bold), was "; }"', e.message
3419
- assert_equal 2, e.sass_line
3420
- end
3421
-
3422
- def test_uses_property_exception_with_space_after_name
3423
- render <<SCSS
3424
- foo {
3425
- bar: baz [fail]; }
3426
- SCSS
3427
- assert(false, "Expected syntax error")
3428
- rescue Sass::SyntaxError => e
3429
- assert_equal 'Invalid CSS after " bar: baz ": expected ";", was "[fail]; }"', e.message
3430
- assert_equal 2, e.sass_line
3431
- end
3432
-
3433
- def test_uses_property_exception_with_non_identifier_after_name
3434
- render <<SCSS
3435
- foo {
3436
- bar:1px [fail]; }
3437
- SCSS
3438
- assert(false, "Expected syntax error")
3439
- rescue Sass::SyntaxError => e
3440
- assert_equal 'Invalid CSS after " bar:1px ": expected ";", was "[fail]; }"', e.message
3441
- assert_equal 2, e.sass_line
3442
- end
3443
-
3444
- def test_uses_property_exception_when_followed_by_open_bracket
3445
- render <<SCSS
3446
- foo {
3447
- bar:{baz: .fail} }
3448
- SCSS
3449
- assert(false, "Expected syntax error")
3450
- rescue Sass::SyntaxError => e
3451
- assert_equal 'Invalid CSS after " bar:{baz: ": expected expression (e.g. 1px, bold), was ".fail} }"', e.message
3452
- assert_equal 2, e.sass_line
3453
- end
3454
-
3455
- def test_script_error
3456
- render <<SCSS
3457
- foo {
3458
- bar: "baz" * * }
3459
- SCSS
3460
- assert(false, "Expected syntax error")
3461
- rescue Sass::SyntaxError => e
3462
- assert_equal 'Invalid CSS after " bar: "baz" * ": expected expression (e.g. 1px, bold), was "* }"', e.message
3463
- assert_equal 2, e.sass_line
3464
- end
3465
-
3466
- def test_multiline_script_syntax_error
3467
- render <<SCSS
3468
- foo {
3469
- bar:
3470
- "baz" * * }
3471
- SCSS
3472
- assert(false, "Expected syntax error")
3473
- rescue Sass::SyntaxError => e
3474
- assert_equal 'Invalid CSS after " "baz" * ": expected expression (e.g. 1px, bold), was "* }"', e.message
3475
- assert_equal 3, e.sass_line
3476
- end
3477
-
3478
- def test_multiline_script_runtime_error
3479
- render <<SCSS
3480
- foo {
3481
- bar: "baz" +
3482
- "bar" +
3483
- $bang }
3484
- SCSS
3485
- assert(false, "Expected syntax error")
3486
- rescue Sass::SyntaxError => e
3487
- assert_equal "Undefined variable: \"$bang\".", e.message
3488
- assert_equal 4, e.sass_line
3489
- end
3490
-
3491
- def test_post_multiline_script_runtime_error
3492
- render <<SCSS
3493
- foo {
3494
- bar: "baz" +
3495
- "bar" +
3496
- "baz";
3497
- bip: $bop; }
3498
- SCSS
3499
- assert(false, "Expected syntax error")
3500
- rescue Sass::SyntaxError => e
3501
- assert_equal "Undefined variable: \"$bop\".", e.message
3502
- assert_equal 5, e.sass_line
3503
- end
3504
-
3505
- def test_multiline_property_runtime_error
3506
- render <<SCSS
3507
- foo {
3508
- bar: baz
3509
- bar
3510
- \#{$bang} }
3511
- SCSS
3512
- assert(false, "Expected syntax error")
3513
- rescue Sass::SyntaxError => e
3514
- assert_equal "Undefined variable: \"$bang\".", e.message
3515
- assert_equal 4, e.sass_line
3516
- end
3517
-
3518
- def test_post_resolution_selector_error
3519
- render "\n\nfoo \#{\") bar\"} {a: b}"
3520
- assert(false, "Expected syntax error")
3521
- rescue Sass::SyntaxError => e
3522
- assert_equal 'Invalid CSS after "foo ": expected selector, was ") bar"', e.message
3523
- assert_equal 3, e.sass_line
3524
- end
3525
-
3526
- def test_parent_in_mid_selector_error
3527
- assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render <<SCSS}
3528
- Invalid CSS after ".foo": expected "{", was "&.bar"
3529
-
3530
- "&.bar" may only be used at the beginning of a compound selector.
3531
- MESSAGE
3532
- flim {
3533
- .foo&.bar {a: b}
3534
- }
3535
- SCSS
3536
- end
3537
-
3538
- def test_parent_after_selector_error
3539
- assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render <<SCSS}
3540
- Invalid CSS after ".foo.bar": expected "{", was "&"
3541
-
3542
- "&" may only be used at the beginning of a compound selector.
3543
- MESSAGE
3544
- flim {
3545
- .foo.bar& {a: b}
3546
- }
3547
- SCSS
3548
- end
3549
-
3550
- def test_double_parent_selector_error
3551
- assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render <<SCSS}
3552
- Invalid CSS after "&": expected "{", was "&"
3553
-
3554
- "&" may only be used at the beginning of a compound selector.
3555
- MESSAGE
3556
- flim {
3557
- && {a: b}
3558
- }
3559
- SCSS
3560
- end
3561
-
3562
- def test_no_lonely_else
3563
- assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render <<SCSS}
3564
- Invalid CSS: @else must come after @if
3565
- MESSAGE
3566
- @else {foo: bar}
3567
- SCSS
3568
- end
3569
-
3570
- def test_failed_parent_selector_with_suffix
3571
- assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render(<<SCSS)}
3572
- Invalid parent selector for "&-bar": "*"
3573
- MESSAGE
3574
- * {
3575
- &-bar {a: b}
3576
- }
3577
- SCSS
3578
-
3579
- assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render(<<SCSS)}
3580
- Invalid parent selector for "&-bar": "[foo=bar]"
3581
- MESSAGE
3582
- [foo=bar] {
3583
- &-bar {a: b}
3584
- }
3585
- SCSS
3586
-
3587
- assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render(<<SCSS)}
3588
- Invalid parent selector for "&-bar": "::nth-child(2n+1)"
3589
- MESSAGE
3590
- ::nth-child(2n+1) {
3591
- &-bar {a: b}
3592
- }
3593
- SCSS
3594
-
3595
- assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render(<<SCSS)}
3596
- Invalid parent selector for "&-bar": ":not(.foo)"
3597
- MESSAGE
3598
- :not(.foo) {
3599
- &-bar {a: b}
3600
- }
3601
- SCSS
3602
-
3603
- assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render(<<SCSS)}
3604
- Invalid parent selector for "&-bar": ".foo +"
3605
- MESSAGE
3606
- .foo + {
3607
- &-bar {a: b}
3608
- }
3609
- SCSS
3610
- end
3611
-
3612
- def test_empty_media_query_error
3613
- assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render(<<SCSS)}
3614
- Invalid CSS after "": expected media query list, was ""
3615
- MESSAGE
3616
- @media \#{""} {
3617
- foo {a: b}
3618
- }
3619
- SCSS
3620
- end
3621
-
3622
- def test_newline_in_property_value
3623
- assert_equal(<<CSS, render(<<SCSS))
3624
- .foo {
3625
- bar: "bazbang"; }
3626
- CSS
3627
- .foo {
3628
- $var: "baz\\
3629
- bang";
3630
- bar: $var;
3631
- }
3632
- SCSS
3633
- end
3634
-
3635
- def test_raw_newline_warning
3636
- assert_warning(<<MESSAGE.rstrip) {assert_equal(<<CSS, render(<<SCSS))}
3637
- DEPRECATION WARNING on line 2, column 9 of #{filename_for_test :scss}:
3638
- Unescaped multiline strings are deprecated and will be removed in a future version of Sass.
3639
- To include a newline in a string, use "\\a" or "\\a " as in CSS.
3640
- MESSAGE
3641
- .foo {
3642
- bar: "baz\\a bang"; }
3643
- CSS
3644
- .foo {
3645
- $var: "baz
3646
- bang";
3647
- bar: $var;
3648
- }
3649
- SCSS
3650
- end
3651
-
3652
- # Regression
3653
-
3654
- # Regression test for #2031.
3655
- def test_no_interpolation_warning_in_nested_selector
3656
- assert_no_warning {assert_equal(<<CSS, render(<<SCSS))}
3657
- z a:b(n+1) {
3658
- x: y; }
3659
- CSS
3660
- z {
3661
- a:b(n+\#{1}) {
3662
- x: y;
3663
- }
3664
- }
3665
- SCSS
3666
- end
3667
-
3668
- # Ensures that the fix for #2031 doesn't hide legitimate warnings.
3669
- def test_interpolation_warning_in_selector_like_property
3670
- assert_warning(<<WARNING) {assert_equal(<<CSS, render(<<SCSS))}
3671
- DEPRECATION WARNING on line 2 of #{filename_for_test :scss}:
3672
- \#{} interpolation near operators will be simplified in a future version of Sass.
3673
- To preserve the current behavior, use quotes:
3674
-
3675
- unquote("n+1")
3676
-
3677
- You can use the sass-convert command to automatically fix most cases.
3678
- WARNING
3679
- z {
3680
- a: b(n+1); }
3681
- CSS
3682
- z {
3683
- a:b(n+\#{1});
3684
- }
3685
- SCSS
3686
- end
3687
-
3688
- def test_escape_in_selector
3689
- assert_equal(<<CSS, render(".\\!foo {a: b}"))
3690
- .\\!foo {
3691
- a: b; }
3692
- CSS
3693
- end
3694
-
3695
- def test_for_directive_with_float_bounds
3696
- assert_equal(<<CSS, render(<<SCSS))
3697
- .a {
3698
- b: 0;
3699
- b: 1;
3700
- b: 2;
3701
- b: 3;
3702
- b: 4;
3703
- b: 5; }
3704
- CSS
3705
- .a {
3706
- @for $i from 0.0 through 5.0 {b: $i}
3707
- }
3708
- SCSS
3709
-
3710
- assert_raise_message(Sass::SyntaxError, "0.5 is not an integer.") {render(<<SCSS)}
3711
- .a {
3712
- @for $i from 0.5 through 5.0 {b: $i}
3713
- }
3714
- SCSS
3715
-
3716
- assert_raise_message(Sass::SyntaxError, "5.5 is not an integer.") {render(<<SCSS)}
3717
- .a {
3718
- @for $i from 0.0 through 5.5 {b: $i}
3719
- }
3720
- SCSS
3721
- end
3722
-
3723
- def test_parent_selector_in_function_pseudo_selector
3724
- assert_equal <<CSS, render(<<SCSS)
3725
- .bar:not(.foo) {
3726
- a: b; }
3727
-
3728
- .qux:nth-child(2n of .baz .bang) {
3729
- c: d; }
3730
- CSS
3731
- .foo {
3732
- .bar:not(&) {a: b}
3733
- }
3734
-
3735
- .baz .bang {
3736
- .qux:nth-child(2n of &) {c: d}
3737
- }
3738
- SCSS
3739
- end
3740
-
3741
- def test_parent_selector_in_and_out_of_function_pseudo_selector
3742
- # Regression test for https://github.com/sass/sass/issues/1464#issuecomment-70352288
3743
- assert_equal(<<CSS, render(<<SCSS))
3744
- .a:not(.a-b) {
3745
- x: y; }
3746
- CSS
3747
- .a {
3748
- &:not(&-b) {
3749
- x: y;
3750
- }
3751
- }
3752
- SCSS
3753
-
3754
- assert_equal(<<CSS, render(<<SCSS))
3755
- .a:nth-child(2n of .a-b) {
3756
- x: y; }
3757
- CSS
3758
- .a {
3759
- &:nth-child(2n of &-b) {
3760
- x: y;
3761
- }
3762
- }
3763
- SCSS
3764
- end
3765
-
3766
- def test_attribute_selector_in_selector_pseudoclass
3767
- # Even though this is plain CSS, it only failed when given to the SCSS
3768
- # parser.
3769
- assert_equal(<<CSS, render(<<SCSS))
3770
- [href^='http://'] {
3771
- color: red; }
3772
- CSS
3773
- [href^='http://'] {
3774
- color: red;
3775
- }
3776
- SCSS
3777
- end
3778
-
3779
- def test_top_level_unknown_directive_in_at_root
3780
- assert_equal(<<CSS, render(<<SCSS))
3781
- @fblthp {
3782
- a: b; }
3783
- CSS
3784
- @at-root {
3785
- @fblthp {a: b}
3786
- }
3787
- SCSS
3788
- end
3789
-
3790
- def test_parent_ref_with_newline
3791
- assert_equal(<<CSS, render(<<SCSS))
3792
- a.c
3793
- , b.c {
3794
- x: y; }
3795
- CSS
3796
- a
3797
- , b {&.c {x: y}}
3798
- SCSS
3799
- end
3800
-
3801
- def test_parent_ref_in_nested_at_root
3802
- assert_equal(<<CSS, render(<<SCSS))
3803
- #test {
3804
- border: 0; }
3805
- #test:hover {
3806
- display: none; }
3807
- CSS
3808
- a {
3809
- @at-root #test {
3810
- border: 0;
3811
- &:hover{
3812
- display: none;
3813
- }
3814
- }
3815
- }
3816
- SCSS
3817
- end
3818
-
3819
- def test_loud_comment_in_compressed_mode
3820
- assert_equal(<<CSS, render(<<SCSS))
3821
- /*! foo */
3822
- CSS
3823
- /*! foo */
3824
- SCSS
3825
- end
3826
-
3827
- def test_parsing_decimals_followed_by_comments_doesnt_take_forever
3828
- assert_equal(<<CSS, render(<<SCSS))
3829
- .foo {
3830
- padding: 4.21053% 4.21053% 5.63158%; }
3831
- CSS
3832
- .foo {
3833
- padding: 4.21052631578947% 4.21052631578947% 5.631578947368421% /**/
3834
- }
3835
- SCSS
3836
- end
3837
-
3838
- def test_parsing_many_numbers_doesnt_take_forever
3839
- values = ["80% 90%"] * 1000
3840
- assert_equal(<<CSS, render(<<SCSS))
3841
- .foo {
3842
- padding: #{values.join(', ')}; }
3843
- CSS
3844
- .foo {
3845
- padding: #{values.join(', ')};
3846
- }
3847
- SCSS
3848
- end
3849
-
3850
- def test_import_comments_in_imports
3851
- assert_equal(<<CSS, render(<<SCSS))
3852
- @import url(foo.css);
3853
- @import url(bar.css);
3854
- @import url(baz.css);
3855
- CSS
3856
- @import "foo.css", // this is a comment
3857
- "bar.css", /* this is another comment */
3858
- "baz.css"; // this is a third comment
3859
- SCSS
3860
- end
3861
-
3862
- def test_reference_combinator_with_parent_ref
3863
- silence_warnings {assert_equal <<CSS, render(<<SCSS)}
3864
- a /foo/ b {
3865
- c: d; }
3866
- CSS
3867
- a {& /foo/ b {c: d}}
3868
- SCSS
3869
- end
3870
-
3871
- def test_reference_combinator_warning
3872
- assert_warning(<<WARNING) {assert_equal <<CSS, render(<<SCSS)}
3873
- DEPRECATION WARNING on line 1, column 8 of test_reference_combinator_warning_inline.scss:
3874
- The reference combinator /foo/ is deprecated and will be removed in a future release.
3875
- WARNING
3876
- a /foo/ b {
3877
- c: d; }
3878
- CSS
3879
- a {& /foo/ b {c: d}}
3880
- SCSS
3881
- end
3882
-
3883
- def test_newline_selector_rendered_multiple_times
3884
- assert_equal <<CSS, render(<<SCSS)
3885
- form input,
3886
- form select {
3887
- color: white; }
3888
-
3889
- form input,
3890
- form select {
3891
- color: white; }
3892
- CSS
3893
- @for $i from 1 through 2 {
3894
- form {
3895
- input,
3896
- select {
3897
- color: white;
3898
- }
3899
- }
3900
- }
3901
- SCSS
3902
- end
3903
-
3904
- def test_prop_name_interpolation_after_hyphen
3905
- assert_equal <<CSS, render(<<SCSS)
3906
- a {
3907
- -foo-bar: b; }
3908
- CSS
3909
- a { -\#{"foo"}-bar: b; }
3910
- SCSS
3911
- end
3912
-
3913
- def test_star_plus_and_parent
3914
- assert_equal <<CSS, render(<<SCSS)
3915
- * + html foo {
3916
- a: b; }
3917
- CSS
3918
- foo {*+html & {a: b}}
3919
- SCSS
3920
- end
3921
-
3922
- def test_weird_added_space
3923
- assert_equal <<CSS, render(<<SCSS)
3924
- foo {
3925
- bar: -moz-bip; }
3926
- CSS
3927
- $value : bip;
3928
-
3929
- foo {
3930
- bar: -moz-\#{$value};
3931
- }
3932
- SCSS
3933
- end
3934
-
3935
- def test_interpolation_with_bracket_on_next_line
3936
- assert_equal <<CSS, render(<<SCSS)
3937
- a.foo b {
3938
- color: red; }
3939
- CSS
3940
- a.\#{"foo"} b
3941
- {color: red}
3942
- SCSS
3943
- end
3944
-
3945
- def test_extra_comma_in_mixin_arglist_error
3946
- assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render <<SCSS}
3947
- Invalid CSS after "...clude foo(bar, ": expected mixin argument, was ");"
3948
- MESSAGE
3949
- @mixin foo($a1, $a2) {
3950
- baz: $a1 $a2;
3951
- }
3952
-
3953
- .bar {
3954
- @include foo(bar, );
3955
- }
3956
- SCSS
3957
- end
3958
-
3959
- def test_interpolation
3960
- assert_equal <<CSS, render(<<SCSS)
3961
- ul li#foo a span.label {
3962
- foo: bar; }
3963
- CSS
3964
- $bar : "#foo";
3965
- ul li\#{$bar} a span.label { foo: bar; }
3966
- SCSS
3967
- end
3968
-
3969
- def test_mixin_with_keyword_args
3970
- assert_equal <<CSS, render(<<SCSS)
3971
- .mixed {
3972
- required: foo;
3973
- arg1: default-val1;
3974
- arg2: non-default-val2; }
3975
- CSS
3976
- @mixin a-mixin($required, $arg1: default-val1, $arg2: default-val2) {
3977
- required: $required;
3978
- arg1: $arg1;
3979
- arg2: $arg2;
3980
- }
3981
- .mixed { @include a-mixin(foo, $arg2: non-default-val2); }
3982
- SCSS
3983
- end
3984
-
3985
- def test_keyword_arg_scope
3986
- assert_equal <<CSS, render(<<SCSS)
3987
- .mixed {
3988
- arg1: default;
3989
- arg2: non-default; }
3990
- CSS
3991
- $arg1: default;
3992
- $arg2: default;
3993
- @mixin a-mixin($arg1: $arg1, $arg2: $arg2) {
3994
- arg1: $arg1;
3995
- arg2: $arg2;
3996
- }
3997
- .mixed { @include a-mixin($arg2: non-default); }
3998
- SCSS
3999
- end
4000
-
4001
- def test_passing_required_args_as_a_keyword_arg
4002
- assert_equal <<CSS, render(<<SCSS)
4003
- .mixed {
4004
- required: foo;
4005
- arg1: default-val1;
4006
- arg2: default-val2; }
4007
- CSS
4008
- @mixin a-mixin($required, $arg1: default-val1, $arg2: default-val2) {
4009
- required: $required;
4010
- arg1: $arg1;
4011
- arg2: $arg2; }
4012
- .mixed { @include a-mixin($required: foo); }
4013
- SCSS
4014
- end
4015
-
4016
- def test_passing_all_as_keyword_args_in_opposite_order
4017
- assert_equal <<CSS, render(<<SCSS)
4018
- .mixed {
4019
- required: foo;
4020
- arg1: non-default-val1;
4021
- arg2: non-default-val2; }
4022
- CSS
4023
- @mixin a-mixin($required, $arg1: default-val1, $arg2: default-val2) {
4024
- required: $required;
4025
- arg1: $arg1;
4026
- arg2: $arg2; }
4027
- .mixed { @include a-mixin($arg2: non-default-val2, $arg1: non-default-val1, $required: foo); }
4028
- SCSS
4029
- end
4030
-
4031
- def test_keyword_args_in_functions
4032
- assert_equal <<CSS, render(<<SCSS)
4033
- .keyed {
4034
- color: rgba(170, 119, 204, 0.4); }
4035
- CSS
4036
- .keyed { color: rgba($color: #a7c, $alpha: 0.4) }
4037
- SCSS
4038
- end
4039
-
4040
- def test_unknown_keyword_arg_raises_error
4041
- assert_raise_message(Sass::SyntaxError, "Mixin a doesn't have an argument named $c.") {render <<SCSS}
4042
- @mixin a($b: 1) { a: $b; }
4043
- div { @include a(1, $c: 3); }
4044
- SCSS
4045
- end
4046
-
4047
-
4048
- def test_newlines_removed_from_selectors_when_compressed
4049
- assert_equal <<CSS, render(<<SCSS, :style => :compressed)
4050
- z a,z b{display:block}
4051
- CSS
4052
- a
4053
- , b {
4054
- z & {
4055
- display: block;
4056
- }
4057
- }
4058
- SCSS
4059
- end
4060
-
4061
- def test_if_error_line
4062
- assert_raise_line(2) {render(<<SCSS)}
4063
- @if true {foo: bar}
4064
- }
4065
- SCSS
4066
- end
4067
-
4068
- def test_multiline_var
4069
- assert_equal <<CSS, render(<<SCSS)
4070
- foo {
4071
- a: 3;
4072
- b: false;
4073
- c: a b c; }
4074
- CSS
4075
- foo {
4076
- $var1: 1 +
4077
- 2;
4078
- $var2: true and
4079
- false;
4080
- $var3: a b
4081
- c;
4082
- a: $var1;
4083
- b: $var2;
4084
- c: $var3; }
4085
- SCSS
4086
- end
4087
-
4088
- def test_mixin_content
4089
- assert_equal <<CSS, render(<<SASS)
4090
- .parent {
4091
- background-color: red;
4092
- border-color: red; }
4093
- .parent .child {
4094
- background-color: yellow;
4095
- color: blue;
4096
- border-color: yellow; }
4097
- CSS
4098
- $color: blue;
4099
- @mixin context($class, $color: red) {
4100
- .\#{$class} {
4101
- background-color: $color;
4102
- @content;
4103
- border-color: $color;
4104
- }
4105
- }
4106
- @include context(parent) {
4107
- @include context(child, $color: yellow) {
4108
- color: $color;
4109
- }
4110
- }
4111
- SASS
4112
- end
4113
-
4114
- def test_empty_content
4115
- assert_equal <<CSS, render(<<SCSS)
4116
- a {
4117
- b: c; }
4118
- CSS
4119
- @mixin foo { @content }
4120
- a { b: c; @include foo {} }
4121
- SCSS
4122
- end
4123
-
4124
- def test_options_passed_to_script
4125
- assert_equal <<CSS, render(<<SCSS, :style => :compressed)
4126
- foo{color:#000}
4127
- CSS
4128
- foo {color: darken(black, 10%)}
4129
- SCSS
4130
- end
4131
-
4132
- # ref: https://github.com/nex3/sass/issues/104
4133
- def test_no_buffer_overflow
4134
- template = render <<SCSS
4135
- .aaa {
4136
- background-color: white;
4137
- }
4138
- .aaa .aaa .aaa {
4139
- background-color: black;
4140
- }
4141
- .bbb {
4142
- @extend .aaa;
4143
- }
4144
- .xxx {
4145
- @extend .bbb;
4146
- }
4147
- .yyy {
4148
- @extend .bbb;
4149
- }
4150
- .zzz {
4151
- @extend .bbb;
4152
- }
4153
- SCSS
4154
- Sass::SCSS::Parser.new(template, "test.scss", nil).parse
4155
- end
4156
-
4157
- def test_extend_in_media_in_rule
4158
- assert_equal(<<CSS, render(<<SCSS))
4159
- @media screen {
4160
- .foo {
4161
- a: b; } }
4162
- CSS
4163
- .foo {
4164
- @media screen {
4165
- @extend %bar;
4166
- }
4167
- }
4168
-
4169
- @media screen {
4170
- %bar {
4171
- a: b;
4172
- }
4173
- }
4174
- SCSS
4175
- end
4176
-
4177
- def test_import_with_supports_clause_interp
4178
- assert_equal(<<CSS, render(<<'SASS', :style => :compressed))
4179
- @import url("fallback-layout.css") supports(not (display: flex))
4180
- CSS
4181
- $display-type: flex;
4182
- @import url("fallback-layout.css") supports(not (display: #{$display-type}));
4183
- SASS
4184
- end
4185
-
4186
- def test_import_with_supports_clause
4187
- assert_equal(<<CSS, render(<<SASS, :style => :compressed))
4188
- @import url("fallback-layout.css") supports(not (display: flex));.foo{bar:baz}
4189
- CSS
4190
- @import url("fallback-layout.css") supports(not (display: flex));
4191
- .foo { bar: baz; }
4192
- SASS
4193
- end
4194
-
4195
- def test_crlf
4196
- # Attempt to reproduce https://github.com/sass/sass/issues/1985
4197
- assert_equal(<<CSS, render(<<SCSS))
4198
- p {
4199
- margin: 0; }
4200
- CSS
4201
- p {\r\n margin: 0;\r\n}
4202
- SCSS
4203
- end
4204
-
4205
- end