sass 3.4.24 → 3.7.4

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