sass 3.5.2 → 3.7.4

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