xass 0.1.0
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.
- checksums.yaml +7 -0
- data/.yardopts +11 -0
- data/CONTRIBUTING +3 -0
- data/MIT-LICENSE +20 -0
- data/README.md +201 -0
- data/Rakefile +349 -0
- data/VERSION +1 -0
- data/VERSION_NAME +1 -0
- data/bin/push +13 -0
- data/bin/sass +13 -0
- data/bin/sass-convert +12 -0
- data/bin/scss +13 -0
- data/extra/update_watch.rb +13 -0
- data/init.rb +18 -0
- data/lib/sass/cache_stores/base.rb +88 -0
- data/lib/sass/cache_stores/chain.rb +33 -0
- data/lib/sass/cache_stores/filesystem.rb +64 -0
- data/lib/sass/cache_stores/memory.rb +47 -0
- data/lib/sass/cache_stores/null.rb +25 -0
- data/lib/sass/cache_stores.rb +15 -0
- data/lib/sass/callbacks.rb +66 -0
- data/lib/sass/css.rb +409 -0
- data/lib/sass/engine.rb +930 -0
- data/lib/sass/environment.rb +101 -0
- data/lib/sass/error.rb +201 -0
- data/lib/sass/exec.rb +707 -0
- data/lib/sass/importers/base.rb +139 -0
- data/lib/sass/importers/filesystem.rb +186 -0
- data/lib/sass/importers.rb +22 -0
- data/lib/sass/logger/base.rb +32 -0
- data/lib/sass/logger/log_level.rb +49 -0
- data/lib/sass/logger.rb +15 -0
- data/lib/sass/media.rb +213 -0
- data/lib/sass/plugin/compiler.rb +406 -0
- data/lib/sass/plugin/configuration.rb +123 -0
- data/lib/sass/plugin/generic.rb +15 -0
- data/lib/sass/plugin/merb.rb +48 -0
- data/lib/sass/plugin/rack.rb +60 -0
- data/lib/sass/plugin/rails.rb +47 -0
- data/lib/sass/plugin/staleness_checker.rb +199 -0
- data/lib/sass/plugin.rb +133 -0
- data/lib/sass/railtie.rb +10 -0
- data/lib/sass/repl.rb +57 -0
- data/lib/sass/root.rb +7 -0
- data/lib/sass/script/arg_list.rb +52 -0
- data/lib/sass/script/bool.rb +18 -0
- data/lib/sass/script/color.rb +606 -0
- data/lib/sass/script/css_lexer.rb +29 -0
- data/lib/sass/script/css_parser.rb +31 -0
- data/lib/sass/script/funcall.rb +245 -0
- data/lib/sass/script/functions.rb +1543 -0
- data/lib/sass/script/interpolation.rb +79 -0
- data/lib/sass/script/lexer.rb +345 -0
- data/lib/sass/script/list.rb +85 -0
- data/lib/sass/script/literal.rb +221 -0
- data/lib/sass/script/node.rb +99 -0
- data/lib/sass/script/null.rb +37 -0
- data/lib/sass/script/number.rb +453 -0
- data/lib/sass/script/operation.rb +110 -0
- data/lib/sass/script/parser.rb +502 -0
- data/lib/sass/script/string.rb +51 -0
- data/lib/sass/script/string_interpolation.rb +103 -0
- data/lib/sass/script/unary_operation.rb +69 -0
- data/lib/sass/script/variable.rb +58 -0
- data/lib/sass/script.rb +39 -0
- data/lib/sass/scss/css_parser.rb +36 -0
- data/lib/sass/scss/parser.rb +1180 -0
- data/lib/sass/scss/rx.rb +133 -0
- data/lib/sass/scss/script_lexer.rb +15 -0
- data/lib/sass/scss/script_parser.rb +25 -0
- data/lib/sass/scss/static_parser.rb +54 -0
- data/lib/sass/scss.rb +16 -0
- data/lib/sass/selector/abstract_sequence.rb +94 -0
- data/lib/sass/selector/comma_sequence.rb +92 -0
- data/lib/sass/selector/sequence.rb +507 -0
- data/lib/sass/selector/simple.rb +119 -0
- data/lib/sass/selector/simple_sequence.rb +215 -0
- data/lib/sass/selector.rb +452 -0
- data/lib/sass/shared.rb +76 -0
- data/lib/sass/supports.rb +229 -0
- data/lib/sass/tree/charset_node.rb +22 -0
- data/lib/sass/tree/comment_node.rb +82 -0
- data/lib/sass/tree/content_node.rb +9 -0
- data/lib/sass/tree/css_import_node.rb +60 -0
- data/lib/sass/tree/debug_node.rb +18 -0
- data/lib/sass/tree/directive_node.rb +42 -0
- data/lib/sass/tree/each_node.rb +24 -0
- data/lib/sass/tree/extend_node.rb +36 -0
- data/lib/sass/tree/for_node.rb +36 -0
- data/lib/sass/tree/function_node.rb +34 -0
- data/lib/sass/tree/if_node.rb +52 -0
- data/lib/sass/tree/import_node.rb +75 -0
- data/lib/sass/tree/media_node.rb +58 -0
- data/lib/sass/tree/mixin_def_node.rb +38 -0
- data/lib/sass/tree/mixin_node.rb +39 -0
- data/lib/sass/tree/node.rb +196 -0
- data/lib/sass/tree/prop_node.rb +152 -0
- data/lib/sass/tree/return_node.rb +18 -0
- data/lib/sass/tree/root_node.rb +78 -0
- data/lib/sass/tree/rule_node.rb +132 -0
- data/lib/sass/tree/supports_node.rb +51 -0
- data/lib/sass/tree/trace_node.rb +32 -0
- data/lib/sass/tree/variable_node.rb +30 -0
- data/lib/sass/tree/visitors/base.rb +75 -0
- data/lib/sass/tree/visitors/check_nesting.rb +147 -0
- data/lib/sass/tree/visitors/convert.rb +316 -0
- data/lib/sass/tree/visitors/cssize.rb +241 -0
- data/lib/sass/tree/visitors/deep_copy.rb +102 -0
- data/lib/sass/tree/visitors/extend.rb +68 -0
- data/lib/sass/tree/visitors/perform.rb +446 -0
- data/lib/sass/tree/visitors/set_options.rb +125 -0
- data/lib/sass/tree/visitors/to_css.rb +228 -0
- data/lib/sass/tree/warn_node.rb +18 -0
- data/lib/sass/tree/while_node.rb +18 -0
- data/lib/sass/util/multibyte_string_scanner.rb +155 -0
- data/lib/sass/util/subset_map.rb +109 -0
- data/lib/sass/util/test.rb +10 -0
- data/lib/sass/util.rb +948 -0
- data/lib/sass/version.rb +126 -0
- data/lib/sass.rb +95 -0
- data/rails/init.rb +1 -0
- data/test/Gemfile +3 -0
- data/test/Gemfile.lock +10 -0
- data/test/sass/cache_test.rb +89 -0
- data/test/sass/callbacks_test.rb +61 -0
- data/test/sass/conversion_test.rb +1760 -0
- data/test/sass/css2sass_test.rb +458 -0
- data/test/sass/data/hsl-rgb.txt +319 -0
- data/test/sass/engine_test.rb +3244 -0
- data/test/sass/exec_test.rb +86 -0
- data/test/sass/extend_test.rb +1482 -0
- data/test/sass/fixtures/test_staleness_check_across_importers.css +1 -0
- data/test/sass/fixtures/test_staleness_check_across_importers.scss +1 -0
- data/test/sass/functions_test.rb +1139 -0
- data/test/sass/importer_test.rb +192 -0
- data/test/sass/logger_test.rb +58 -0
- data/test/sass/mock_importer.rb +49 -0
- data/test/sass/more_results/more1.css +9 -0
- data/test/sass/more_results/more1_with_line_comments.css +26 -0
- data/test/sass/more_results/more_import.css +29 -0
- data/test/sass/more_templates/_more_partial.sass +2 -0
- data/test/sass/more_templates/more1.sass +23 -0
- data/test/sass/more_templates/more_import.sass +11 -0
- data/test/sass/plugin_test.rb +564 -0
- data/test/sass/results/alt.css +4 -0
- data/test/sass/results/basic.css +9 -0
- data/test/sass/results/cached_import_option.css +3 -0
- data/test/sass/results/compact.css +5 -0
- data/test/sass/results/complex.css +86 -0
- data/test/sass/results/compressed.css +1 -0
- data/test/sass/results/expanded.css +19 -0
- data/test/sass/results/filename_fn.css +3 -0
- data/test/sass/results/if.css +3 -0
- data/test/sass/results/import.css +31 -0
- data/test/sass/results/import_charset.css +5 -0
- data/test/sass/results/import_charset_1_8.css +5 -0
- data/test/sass/results/import_charset_ibm866.css +5 -0
- data/test/sass/results/import_content.css +1 -0
- data/test/sass/results/line_numbers.css +49 -0
- data/test/sass/results/mixins.css +95 -0
- data/test/sass/results/multiline.css +24 -0
- data/test/sass/results/nested.css +22 -0
- data/test/sass/results/options.css +1 -0
- data/test/sass/results/parent_ref.css +13 -0
- data/test/sass/results/script.css +16 -0
- data/test/sass/results/scss_import.css +31 -0
- data/test/sass/results/scss_importee.css +2 -0
- data/test/sass/results/subdir/nested_subdir/nested_subdir.css +1 -0
- data/test/sass/results/subdir/subdir.css +3 -0
- data/test/sass/results/units.css +11 -0
- data/test/sass/results/warn.css +0 -0
- data/test/sass/results/warn_imported.css +0 -0
- data/test/sass/script_conversion_test.rb +299 -0
- data/test/sass/script_test.rb +622 -0
- data/test/sass/scss/css_test.rb +1100 -0
- data/test/sass/scss/rx_test.rb +156 -0
- data/test/sass/scss/scss_test.rb +2106 -0
- data/test/sass/scss/test_helper.rb +37 -0
- data/test/sass/templates/_cached_import_option_partial.scss +1 -0
- data/test/sass/templates/_double_import_loop2.sass +1 -0
- data/test/sass/templates/_filename_fn_import.scss +11 -0
- data/test/sass/templates/_imported_charset_ibm866.sass +4 -0
- data/test/sass/templates/_imported_charset_utf8.sass +4 -0
- data/test/sass/templates/_imported_content.sass +3 -0
- data/test/sass/templates/_partial.sass +2 -0
- data/test/sass/templates/_same_name_different_partiality.scss +1 -0
- data/test/sass/templates/alt.sass +16 -0
- data/test/sass/templates/basic.sass +23 -0
- data/test/sass/templates/bork1.sass +2 -0
- data/test/sass/templates/bork2.sass +2 -0
- data/test/sass/templates/bork3.sass +2 -0
- data/test/sass/templates/bork4.sass +2 -0
- data/test/sass/templates/bork5.sass +3 -0
- data/test/sass/templates/cached_import_option.scss +3 -0
- data/test/sass/templates/compact.sass +17 -0
- data/test/sass/templates/complex.sass +305 -0
- data/test/sass/templates/compressed.sass +15 -0
- data/test/sass/templates/double_import_loop1.sass +1 -0
- data/test/sass/templates/expanded.sass +17 -0
- data/test/sass/templates/filename_fn.scss +18 -0
- data/test/sass/templates/if.sass +11 -0
- data/test/sass/templates/import.sass +12 -0
- data/test/sass/templates/import_charset.sass +9 -0
- data/test/sass/templates/import_charset_1_8.sass +6 -0
- data/test/sass/templates/import_charset_ibm866.sass +11 -0
- data/test/sass/templates/import_content.sass +4 -0
- data/test/sass/templates/importee.less +2 -0
- data/test/sass/templates/importee.sass +19 -0
- data/test/sass/templates/line_numbers.sass +13 -0
- data/test/sass/templates/mixin_bork.sass +5 -0
- data/test/sass/templates/mixins.sass +76 -0
- data/test/sass/templates/multiline.sass +20 -0
- data/test/sass/templates/nested.sass +25 -0
- data/test/sass/templates/nested_bork1.sass +2 -0
- data/test/sass/templates/nested_bork2.sass +2 -0
- data/test/sass/templates/nested_bork3.sass +2 -0
- data/test/sass/templates/nested_bork4.sass +2 -0
- data/test/sass/templates/nested_import.sass +2 -0
- data/test/sass/templates/nested_mixin_bork.sass +6 -0
- data/test/sass/templates/options.sass +2 -0
- data/test/sass/templates/parent_ref.sass +25 -0
- data/test/sass/templates/same_name_different_ext.sass +2 -0
- data/test/sass/templates/same_name_different_ext.scss +1 -0
- data/test/sass/templates/same_name_different_partiality.scss +1 -0
- data/test/sass/templates/script.sass +101 -0
- data/test/sass/templates/scss_import.scss +11 -0
- data/test/sass/templates/scss_importee.scss +1 -0
- data/test/sass/templates/single_import_loop.sass +1 -0
- data/test/sass/templates/subdir/import_up1.scss +1 -0
- data/test/sass/templates/subdir/import_up2.scss +1 -0
- data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +2 -0
- data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +3 -0
- data/test/sass/templates/subdir/subdir.sass +6 -0
- data/test/sass/templates/units.sass +11 -0
- data/test/sass/templates/warn.sass +3 -0
- data/test/sass/templates/warn_imported.sass +4 -0
- data/test/sass/test_helper.rb +8 -0
- data/test/sass/util/multibyte_string_scanner_test.rb +147 -0
- data/test/sass/util/subset_map_test.rb +91 -0
- data/test/sass/util_test.rb +382 -0
- data/test/test_helper.rb +80 -0
- metadata +354 -0
|
@@ -0,0 +1,2106 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
require File.dirname(__FILE__) + '/test_helper'
|
|
4
|
+
|
|
5
|
+
class ScssTest < Test::Unit::TestCase
|
|
6
|
+
include ScssTestHelper
|
|
7
|
+
|
|
8
|
+
## One-Line Comments
|
|
9
|
+
|
|
10
|
+
def test_one_line_comments
|
|
11
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
12
|
+
.foo {
|
|
13
|
+
baz: bang; }
|
|
14
|
+
CSS
|
|
15
|
+
.foo {// bar: baz;}
|
|
16
|
+
baz: bang; //}
|
|
17
|
+
}
|
|
18
|
+
SCSS
|
|
19
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
20
|
+
.foo bar[val="//"] {
|
|
21
|
+
baz: bang; }
|
|
22
|
+
CSS
|
|
23
|
+
.foo bar[val="//"] {
|
|
24
|
+
baz: bang; //}
|
|
25
|
+
}
|
|
26
|
+
SCSS
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
## Script
|
|
30
|
+
|
|
31
|
+
def test_variables
|
|
32
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
33
|
+
blat {
|
|
34
|
+
a: foo; }
|
|
35
|
+
CSS
|
|
36
|
+
$var: foo;
|
|
37
|
+
|
|
38
|
+
blat {a: $var}
|
|
39
|
+
SCSS
|
|
40
|
+
|
|
41
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
42
|
+
foo {
|
|
43
|
+
a: 2;
|
|
44
|
+
b: 6; }
|
|
45
|
+
CSS
|
|
46
|
+
foo {
|
|
47
|
+
$var: 2;
|
|
48
|
+
$another-var: 4;
|
|
49
|
+
a: $var;
|
|
50
|
+
b: $var + $another-var;}
|
|
51
|
+
SCSS
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def test_unicode_variables
|
|
55
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
56
|
+
blat {
|
|
57
|
+
a: foo; }
|
|
58
|
+
CSS
|
|
59
|
+
$vär: foo;
|
|
60
|
+
|
|
61
|
+
blat {a: $vär}
|
|
62
|
+
SCSS
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def test_guard_assign
|
|
66
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
67
|
+
foo {
|
|
68
|
+
a: 1; }
|
|
69
|
+
CSS
|
|
70
|
+
$var: 1;
|
|
71
|
+
$var: 2 !default;
|
|
72
|
+
|
|
73
|
+
foo {a: $var}
|
|
74
|
+
SCSS
|
|
75
|
+
|
|
76
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
77
|
+
foo {
|
|
78
|
+
a: 2; }
|
|
79
|
+
CSS
|
|
80
|
+
$var: 2 !default;
|
|
81
|
+
|
|
82
|
+
foo {a: $var}
|
|
83
|
+
SCSS
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def test_sass_script
|
|
87
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
88
|
+
foo {
|
|
89
|
+
a: 3;
|
|
90
|
+
b: -1;
|
|
91
|
+
c: foobar;
|
|
92
|
+
d: 12px; }
|
|
93
|
+
CSS
|
|
94
|
+
foo {
|
|
95
|
+
a: 1 + 2;
|
|
96
|
+
b: 1 - 2;
|
|
97
|
+
c: foo + bar;
|
|
98
|
+
d: floor(12.3px); }
|
|
99
|
+
SCSS
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def test_debug_directive
|
|
103
|
+
assert_warning "test_debug_directive_inline.scss:2 DEBUG: hello world!" do
|
|
104
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
105
|
+
foo {
|
|
106
|
+
a: b; }
|
|
107
|
+
|
|
108
|
+
bar {
|
|
109
|
+
c: d; }
|
|
110
|
+
CSS
|
|
111
|
+
foo {a: b}
|
|
112
|
+
@debug "hello world!";
|
|
113
|
+
bar {c: d}
|
|
114
|
+
SCSS
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def test_warn_directive
|
|
119
|
+
expected_warning = <<EXPECTATION
|
|
120
|
+
WARNING: this is a warning
|
|
121
|
+
on line 2 of test_warn_directive_inline.scss
|
|
122
|
+
|
|
123
|
+
WARNING: this is a mixin
|
|
124
|
+
on line 1 of test_warn_directive_inline.scss, in `foo'
|
|
125
|
+
from line 3 of test_warn_directive_inline.scss
|
|
126
|
+
EXPECTATION
|
|
127
|
+
assert_warning expected_warning do
|
|
128
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
129
|
+
bar {
|
|
130
|
+
c: d; }
|
|
131
|
+
CSS
|
|
132
|
+
@mixin foo { @warn "this is a mixin";}
|
|
133
|
+
@warn "this is a warning";
|
|
134
|
+
bar {c: d; @include foo;}
|
|
135
|
+
SCSS
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def test_for_directive
|
|
140
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
141
|
+
.foo {
|
|
142
|
+
a: 1;
|
|
143
|
+
a: 2;
|
|
144
|
+
a: 3;
|
|
145
|
+
a: 4; }
|
|
146
|
+
CSS
|
|
147
|
+
.foo {
|
|
148
|
+
@for $var from 1 to 5 {a: $var;}
|
|
149
|
+
}
|
|
150
|
+
SCSS
|
|
151
|
+
|
|
152
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
153
|
+
.foo {
|
|
154
|
+
a: 1;
|
|
155
|
+
a: 2;
|
|
156
|
+
a: 3;
|
|
157
|
+
a: 4;
|
|
158
|
+
a: 5; }
|
|
159
|
+
CSS
|
|
160
|
+
.foo {
|
|
161
|
+
@for $var from 1 through 5 {a: $var;}
|
|
162
|
+
}
|
|
163
|
+
SCSS
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def test_if_directive
|
|
167
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
168
|
+
foo {
|
|
169
|
+
a: b; }
|
|
170
|
+
CSS
|
|
171
|
+
@if "foo" == "foo" {foo {a: b}}
|
|
172
|
+
@if "foo" != "foo" {bar {a: b}}
|
|
173
|
+
SCSS
|
|
174
|
+
|
|
175
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
176
|
+
bar {
|
|
177
|
+
a: b; }
|
|
178
|
+
CSS
|
|
179
|
+
@if "foo" != "foo" {foo {a: b}}
|
|
180
|
+
@else if "foo" == "foo" {bar {a: b}}
|
|
181
|
+
@else if true {baz {a: b}}
|
|
182
|
+
SCSS
|
|
183
|
+
|
|
184
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
185
|
+
bar {
|
|
186
|
+
a: b; }
|
|
187
|
+
CSS
|
|
188
|
+
@if "foo" != "foo" {foo {a: b}}
|
|
189
|
+
@else {bar {a: b}}
|
|
190
|
+
SCSS
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def test_comment_after_if_directive
|
|
194
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
195
|
+
foo {
|
|
196
|
+
a: b;
|
|
197
|
+
/* This is a comment */
|
|
198
|
+
c: d; }
|
|
199
|
+
CSS
|
|
200
|
+
foo {
|
|
201
|
+
@if true {a: b}
|
|
202
|
+
/* This is a comment */
|
|
203
|
+
c: d }
|
|
204
|
+
SCSS
|
|
205
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
206
|
+
foo {
|
|
207
|
+
a: b;
|
|
208
|
+
/* This is a comment */
|
|
209
|
+
c: d; }
|
|
210
|
+
CSS
|
|
211
|
+
foo {
|
|
212
|
+
@if true {a: b}
|
|
213
|
+
@else {x: y}
|
|
214
|
+
/* This is a comment */
|
|
215
|
+
c: d }
|
|
216
|
+
SCSS
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def test_while_directive
|
|
220
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
221
|
+
.foo {
|
|
222
|
+
a: 1;
|
|
223
|
+
a: 2;
|
|
224
|
+
a: 3;
|
|
225
|
+
a: 4; }
|
|
226
|
+
CSS
|
|
227
|
+
$i: 1;
|
|
228
|
+
|
|
229
|
+
.foo {
|
|
230
|
+
@while $i != 5 {
|
|
231
|
+
a: $i;
|
|
232
|
+
$i: $i + 1;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
SCSS
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def test_each_directive
|
|
239
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
240
|
+
a {
|
|
241
|
+
b: 1px;
|
|
242
|
+
b: 2px;
|
|
243
|
+
b: 3px;
|
|
244
|
+
b: 4px; }
|
|
245
|
+
|
|
246
|
+
c {
|
|
247
|
+
d: foo;
|
|
248
|
+
d: bar;
|
|
249
|
+
d: baz;
|
|
250
|
+
d: bang; }
|
|
251
|
+
CSS
|
|
252
|
+
a {
|
|
253
|
+
@each $number in 1px 2px 3px 4px {
|
|
254
|
+
b: $number;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
c {
|
|
258
|
+
@each $str in foo, bar, baz, bang {
|
|
259
|
+
d: $str;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
SCSS
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
def test_css_import_directive
|
|
266
|
+
assert_equal "@import url(foo.css);\n", render('@import "foo.css";')
|
|
267
|
+
assert_equal "@import url(foo.css);\n", render("@import 'foo.css';")
|
|
268
|
+
assert_equal "@import url(\"foo.css\");\n", render('@import url("foo.css");')
|
|
269
|
+
assert_equal "@import url(\"foo.css\");\n", render('@import url("foo.css");')
|
|
270
|
+
assert_equal "@import url(foo.css);\n", render('@import url(foo.css);')
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
def test_css_string_import_directive_with_media
|
|
274
|
+
assert_parses '@import "foo.css" screen;'
|
|
275
|
+
assert_parses '@import "foo.css" screen, print;'
|
|
276
|
+
assert_parses '@import "foo.css" screen, print and (foo: 0);'
|
|
277
|
+
assert_parses '@import "foo.css" screen, only print, screen and (foo: 0);'
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
def test_css_url_import_directive_with_media
|
|
281
|
+
assert_parses '@import url("foo.css") screen;'
|
|
282
|
+
assert_parses '@import url("foo.css") screen, print;'
|
|
283
|
+
assert_parses '@import url("foo.css") screen, print and (foo: 0);'
|
|
284
|
+
assert_parses '@import url("foo.css") screen, only print, screen and (foo: 0);'
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
def test_media_import
|
|
288
|
+
assert_equal("@import \"./fonts.sass\" all;\n", render("@import \"./fonts.sass\" all;"))
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
def test_dynamic_media_import
|
|
292
|
+
assert_equal(<<CSS, render(<<SCSS))
|
|
293
|
+
@import "foo" print and (-webkit-min-device-pixel-ratio-foo: 25);
|
|
294
|
+
CSS
|
|
295
|
+
$media: print;
|
|
296
|
+
$key: -webkit-min-device-pixel-ratio;
|
|
297
|
+
$value: 20;
|
|
298
|
+
@import "foo" \#{$media} and ($key + "-foo": $value + 5);
|
|
299
|
+
SCSS
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
def test_http_import
|
|
303
|
+
assert_equal("@import \"http://fonts.googleapis.com/css?family=Droid+Sans\";\n",
|
|
304
|
+
render("@import \"http://fonts.googleapis.com/css?family=Droid+Sans\";"))
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
def test_protocol_relative_import
|
|
308
|
+
assert_equal("@import \"//fonts.googleapis.com/css?family=Droid+Sans\";\n",
|
|
309
|
+
render("@import \"//fonts.googleapis.com/css?family=Droid+Sans\";"))
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
def test_import_with_interpolation
|
|
313
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
314
|
+
@import url("http://fonts.googleapis.com/css?family=Droid+Sans");
|
|
315
|
+
CSS
|
|
316
|
+
$family: unquote("Droid+Sans");
|
|
317
|
+
@import url("http://fonts.googleapis.com/css?family=\#{$family}");
|
|
318
|
+
SCSS
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
def test_url_import
|
|
322
|
+
assert_equal("@import url(fonts.sass);\n", render("@import url(fonts.sass);"))
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
def test_css_import_doesnt_move_through_comments
|
|
326
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
327
|
+
/* Comment 1 */
|
|
328
|
+
@import url("foo.css");
|
|
329
|
+
/* Comment 2 */
|
|
330
|
+
@import url("bar.css");
|
|
331
|
+
CSS
|
|
332
|
+
/* Comment 1 */
|
|
333
|
+
@import url("foo.css");
|
|
334
|
+
|
|
335
|
+
/* Comment 2 */
|
|
336
|
+
@import url("bar.css");
|
|
337
|
+
SCSS
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
def test_css_import_movement_stops_at_comments
|
|
341
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
342
|
+
/* Comment 1 */
|
|
343
|
+
@import url("foo.css");
|
|
344
|
+
/* Comment 2 */
|
|
345
|
+
@import url("bar.css");
|
|
346
|
+
.foo {
|
|
347
|
+
a: b; }
|
|
348
|
+
|
|
349
|
+
/* Comment 3 */
|
|
350
|
+
CSS
|
|
351
|
+
/* Comment 1 */
|
|
352
|
+
@import url("foo.css");
|
|
353
|
+
|
|
354
|
+
/* Comment 2 */
|
|
355
|
+
|
|
356
|
+
.foo {a: b}
|
|
357
|
+
|
|
358
|
+
/* Comment 3 */
|
|
359
|
+
@import url("bar.css");
|
|
360
|
+
SCSS
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
def test_block_comment_in_script
|
|
364
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
365
|
+
foo {
|
|
366
|
+
a: 1bar; }
|
|
367
|
+
CSS
|
|
368
|
+
foo {a: 1 + /* flang */ bar}
|
|
369
|
+
SCSS
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
def test_line_comment_in_script
|
|
373
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
374
|
+
foo {
|
|
375
|
+
a: 1blang; }
|
|
376
|
+
CSS
|
|
377
|
+
foo {a: 1 + // flang }
|
|
378
|
+
blang }
|
|
379
|
+
SCSS
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
## Nested Rules
|
|
383
|
+
|
|
384
|
+
def test_nested_rules
|
|
385
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
386
|
+
foo bar {
|
|
387
|
+
a: b; }
|
|
388
|
+
CSS
|
|
389
|
+
foo {bar {a: b}}
|
|
390
|
+
SCSS
|
|
391
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
392
|
+
foo bar {
|
|
393
|
+
a: b; }
|
|
394
|
+
foo baz {
|
|
395
|
+
b: c; }
|
|
396
|
+
CSS
|
|
397
|
+
foo {
|
|
398
|
+
bar {a: b}
|
|
399
|
+
baz {b: c}}
|
|
400
|
+
SCSS
|
|
401
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
402
|
+
foo bar baz {
|
|
403
|
+
a: b; }
|
|
404
|
+
foo bang bip {
|
|
405
|
+
a: b; }
|
|
406
|
+
CSS
|
|
407
|
+
foo {
|
|
408
|
+
bar {baz {a: b}}
|
|
409
|
+
bang {bip {a: b}}}
|
|
410
|
+
SCSS
|
|
411
|
+
end
|
|
412
|
+
|
|
413
|
+
def test_nested_rules_with_declarations
|
|
414
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
415
|
+
foo {
|
|
416
|
+
a: b; }
|
|
417
|
+
foo bar {
|
|
418
|
+
c: d; }
|
|
419
|
+
CSS
|
|
420
|
+
foo {
|
|
421
|
+
a: b;
|
|
422
|
+
bar {c: d}}
|
|
423
|
+
SCSS
|
|
424
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
425
|
+
foo {
|
|
426
|
+
a: b; }
|
|
427
|
+
foo bar {
|
|
428
|
+
c: d; }
|
|
429
|
+
CSS
|
|
430
|
+
foo {
|
|
431
|
+
bar {c: d}
|
|
432
|
+
a: b}
|
|
433
|
+
SCSS
|
|
434
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
435
|
+
foo {
|
|
436
|
+
ump: nump;
|
|
437
|
+
grump: clump; }
|
|
438
|
+
foo bar {
|
|
439
|
+
blat: bang;
|
|
440
|
+
habit: rabbit; }
|
|
441
|
+
foo bar baz {
|
|
442
|
+
a: b; }
|
|
443
|
+
foo bar bip {
|
|
444
|
+
c: d; }
|
|
445
|
+
foo bibble bap {
|
|
446
|
+
e: f; }
|
|
447
|
+
CSS
|
|
448
|
+
foo {
|
|
449
|
+
ump: nump;
|
|
450
|
+
grump: clump;
|
|
451
|
+
bar {
|
|
452
|
+
blat: bang;
|
|
453
|
+
habit: rabbit;
|
|
454
|
+
baz {a: b}
|
|
455
|
+
bip {c: d}}
|
|
456
|
+
bibble {
|
|
457
|
+
bap {e: f}}}
|
|
458
|
+
SCSS
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
def test_nested_rules_with_fancy_selectors
|
|
462
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
463
|
+
foo .bar {
|
|
464
|
+
a: b; }
|
|
465
|
+
foo :baz {
|
|
466
|
+
c: d; }
|
|
467
|
+
foo bang:bop {
|
|
468
|
+
e: f; }
|
|
469
|
+
CSS
|
|
470
|
+
foo {
|
|
471
|
+
.bar {a: b}
|
|
472
|
+
:baz {c: d}
|
|
473
|
+
bang:bop {e: f}}
|
|
474
|
+
SCSS
|
|
475
|
+
end
|
|
476
|
+
|
|
477
|
+
def test_almost_ambiguous_nested_rules_and_declarations
|
|
478
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
479
|
+
foo {
|
|
480
|
+
bar: baz bang bop biddle woo look at all these elems; }
|
|
481
|
+
foo bar:baz:bang:bop:biddle:woo:look:at:all:these:pseudoclasses {
|
|
482
|
+
a: b; }
|
|
483
|
+
foo bar:baz bang bop biddle woo look at all these elems {
|
|
484
|
+
a: b; }
|
|
485
|
+
CSS
|
|
486
|
+
foo {
|
|
487
|
+
bar:baz:bang:bop:biddle:woo:look:at:all:these:pseudoclasses {a: b};
|
|
488
|
+
bar:baz bang bop biddle woo look at all these elems {a: b};
|
|
489
|
+
bar:baz bang bop biddle woo look at all these elems; }
|
|
490
|
+
SCSS
|
|
491
|
+
end
|
|
492
|
+
|
|
493
|
+
def test_newlines_in_selectors
|
|
494
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
495
|
+
foo
|
|
496
|
+
bar {
|
|
497
|
+
a: b; }
|
|
498
|
+
CSS
|
|
499
|
+
foo
|
|
500
|
+
bar {a: b}
|
|
501
|
+
SCSS
|
|
502
|
+
|
|
503
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
504
|
+
foo baz,
|
|
505
|
+
foo bang,
|
|
506
|
+
bar baz,
|
|
507
|
+
bar bang {
|
|
508
|
+
a: b; }
|
|
509
|
+
CSS
|
|
510
|
+
foo,
|
|
511
|
+
bar {
|
|
512
|
+
baz,
|
|
513
|
+
bang {a: b}}
|
|
514
|
+
SCSS
|
|
515
|
+
|
|
516
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
517
|
+
foo
|
|
518
|
+
bar baz
|
|
519
|
+
bang {
|
|
520
|
+
a: b; }
|
|
521
|
+
foo
|
|
522
|
+
bar bip bop {
|
|
523
|
+
c: d; }
|
|
524
|
+
CSS
|
|
525
|
+
foo
|
|
526
|
+
bar {
|
|
527
|
+
baz
|
|
528
|
+
bang {a: b}
|
|
529
|
+
|
|
530
|
+
bip bop {c: d}}
|
|
531
|
+
SCSS
|
|
532
|
+
|
|
533
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
534
|
+
foo bang, foo bip
|
|
535
|
+
bop, bar
|
|
536
|
+
baz bang, bar
|
|
537
|
+
baz bip
|
|
538
|
+
bop {
|
|
539
|
+
a: b; }
|
|
540
|
+
CSS
|
|
541
|
+
foo, bar
|
|
542
|
+
baz {
|
|
543
|
+
bang, bip
|
|
544
|
+
bop {a: b}}
|
|
545
|
+
SCSS
|
|
546
|
+
end
|
|
547
|
+
|
|
548
|
+
def test_trailing_comma_in_selector
|
|
549
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
550
|
+
#foo #bar,
|
|
551
|
+
#baz #boom {
|
|
552
|
+
a: b; }
|
|
553
|
+
|
|
554
|
+
#bip #bop {
|
|
555
|
+
c: d; }
|
|
556
|
+
CSS
|
|
557
|
+
#foo #bar,,
|
|
558
|
+
,#baz #boom, {a: b}
|
|
559
|
+
|
|
560
|
+
#bip #bop, ,, {c: d}
|
|
561
|
+
SCSS
|
|
562
|
+
end
|
|
563
|
+
|
|
564
|
+
def test_parent_selectors
|
|
565
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
566
|
+
foo:hover {
|
|
567
|
+
a: b; }
|
|
568
|
+
bar foo.baz {
|
|
569
|
+
c: d; }
|
|
570
|
+
CSS
|
|
571
|
+
foo {
|
|
572
|
+
&:hover {a: b}
|
|
573
|
+
bar &.baz {c: d}}
|
|
574
|
+
SCSS
|
|
575
|
+
end
|
|
576
|
+
|
|
577
|
+
def test_parent_selector_with_subject
|
|
578
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
579
|
+
bar foo.baz! .bip {
|
|
580
|
+
a: b; }
|
|
581
|
+
|
|
582
|
+
bar foo bar.baz! .bip {
|
|
583
|
+
c: d; }
|
|
584
|
+
CSS
|
|
585
|
+
foo {
|
|
586
|
+
bar &.baz! .bip {a: b}}
|
|
587
|
+
|
|
588
|
+
foo bar {
|
|
589
|
+
bar &.baz! .bip {c: d}}
|
|
590
|
+
SCSS
|
|
591
|
+
end
|
|
592
|
+
|
|
593
|
+
## Namespace Properties
|
|
594
|
+
|
|
595
|
+
def test_namespace_properties
|
|
596
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
597
|
+
foo {
|
|
598
|
+
bar: baz;
|
|
599
|
+
bang-bip: 1px;
|
|
600
|
+
bang-bop: bar; }
|
|
601
|
+
CSS
|
|
602
|
+
foo {
|
|
603
|
+
bar: baz;
|
|
604
|
+
bang: {
|
|
605
|
+
bip: 1px;
|
|
606
|
+
bop: bar;}}
|
|
607
|
+
SCSS
|
|
608
|
+
end
|
|
609
|
+
|
|
610
|
+
def test_several_namespace_properties
|
|
611
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
612
|
+
foo {
|
|
613
|
+
bar: baz;
|
|
614
|
+
bang-bip: 1px;
|
|
615
|
+
bang-bop: bar;
|
|
616
|
+
buzz-fram: "foo";
|
|
617
|
+
buzz-frum: moo; }
|
|
618
|
+
CSS
|
|
619
|
+
foo {
|
|
620
|
+
bar: baz;
|
|
621
|
+
bang: {
|
|
622
|
+
bip: 1px;
|
|
623
|
+
bop: bar;}
|
|
624
|
+
buzz: {
|
|
625
|
+
fram: "foo";
|
|
626
|
+
frum: moo;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
SCSS
|
|
630
|
+
end
|
|
631
|
+
|
|
632
|
+
def test_nested_namespace_properties
|
|
633
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
634
|
+
foo {
|
|
635
|
+
bar: baz;
|
|
636
|
+
bang-bip: 1px;
|
|
637
|
+
bang-bop: bar;
|
|
638
|
+
bang-blat-baf: bort; }
|
|
639
|
+
CSS
|
|
640
|
+
foo {
|
|
641
|
+
bar: baz;
|
|
642
|
+
bang: {
|
|
643
|
+
bip: 1px;
|
|
644
|
+
bop: bar;
|
|
645
|
+
blat:{baf:bort}}}
|
|
646
|
+
SCSS
|
|
647
|
+
end
|
|
648
|
+
|
|
649
|
+
def test_namespace_properties_with_value
|
|
650
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
651
|
+
foo {
|
|
652
|
+
bar: baz;
|
|
653
|
+
bar-bip: bop;
|
|
654
|
+
bar-bing: bop; }
|
|
655
|
+
CSS
|
|
656
|
+
foo {
|
|
657
|
+
bar: baz {
|
|
658
|
+
bip: bop;
|
|
659
|
+
bing: bop; }}
|
|
660
|
+
SCSS
|
|
661
|
+
end
|
|
662
|
+
|
|
663
|
+
def test_namespace_properties_with_script_value
|
|
664
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
665
|
+
foo {
|
|
666
|
+
bar: bazbang;
|
|
667
|
+
bar-bip: bop;
|
|
668
|
+
bar-bing: bop; }
|
|
669
|
+
CSS
|
|
670
|
+
foo {
|
|
671
|
+
bar: baz + bang {
|
|
672
|
+
bip: bop;
|
|
673
|
+
bing: bop; }}
|
|
674
|
+
SCSS
|
|
675
|
+
end
|
|
676
|
+
|
|
677
|
+
def test_no_namespace_properties_without_space
|
|
678
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
679
|
+
foo bar:baz {
|
|
680
|
+
bip: bop; }
|
|
681
|
+
CSS
|
|
682
|
+
foo {
|
|
683
|
+
bar:baz {
|
|
684
|
+
bip: bop }}
|
|
685
|
+
SCSS
|
|
686
|
+
end
|
|
687
|
+
|
|
688
|
+
def test_no_namespace_properties_without_space_even_when_its_unambiguous
|
|
689
|
+
render(<<SCSS)
|
|
690
|
+
foo {
|
|
691
|
+
bar:1px {
|
|
692
|
+
bip: bop }}
|
|
693
|
+
SCSS
|
|
694
|
+
assert(false, "Expected syntax error")
|
|
695
|
+
rescue Sass::SyntaxError => e
|
|
696
|
+
assert_equal <<MESSAGE, e.message
|
|
697
|
+
Invalid CSS: a space is required between a property and its definition
|
|
698
|
+
when it has other properties nested beneath it.
|
|
699
|
+
MESSAGE
|
|
700
|
+
assert_equal 2, e.sass_line
|
|
701
|
+
end
|
|
702
|
+
|
|
703
|
+
## Mixins
|
|
704
|
+
|
|
705
|
+
def test_basic_mixins
|
|
706
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
707
|
+
.foo {
|
|
708
|
+
a: b; }
|
|
709
|
+
CSS
|
|
710
|
+
@mixin foo {
|
|
711
|
+
.foo {a: b}}
|
|
712
|
+
|
|
713
|
+
@include foo;
|
|
714
|
+
SCSS
|
|
715
|
+
|
|
716
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
717
|
+
bar {
|
|
718
|
+
c: d; }
|
|
719
|
+
bar .foo {
|
|
720
|
+
a: b; }
|
|
721
|
+
CSS
|
|
722
|
+
@mixin foo {
|
|
723
|
+
.foo {a: b}}
|
|
724
|
+
|
|
725
|
+
bar {
|
|
726
|
+
@include foo;
|
|
727
|
+
c: d; }
|
|
728
|
+
SCSS
|
|
729
|
+
|
|
730
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
731
|
+
bar {
|
|
732
|
+
a: b;
|
|
733
|
+
c: d; }
|
|
734
|
+
CSS
|
|
735
|
+
@mixin foo {a: b}
|
|
736
|
+
|
|
737
|
+
bar {
|
|
738
|
+
@include foo;
|
|
739
|
+
c: d; }
|
|
740
|
+
SCSS
|
|
741
|
+
end
|
|
742
|
+
|
|
743
|
+
def test_mixins_with_empty_args
|
|
744
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
745
|
+
.foo {
|
|
746
|
+
a: b; }
|
|
747
|
+
CSS
|
|
748
|
+
@mixin foo() {a: b}
|
|
749
|
+
|
|
750
|
+
.foo {@include foo();}
|
|
751
|
+
SCSS
|
|
752
|
+
|
|
753
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
754
|
+
.foo {
|
|
755
|
+
a: b; }
|
|
756
|
+
CSS
|
|
757
|
+
@mixin foo() {a: b}
|
|
758
|
+
|
|
759
|
+
.foo {@include foo;}
|
|
760
|
+
SCSS
|
|
761
|
+
|
|
762
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
763
|
+
.foo {
|
|
764
|
+
a: b; }
|
|
765
|
+
CSS
|
|
766
|
+
@mixin foo {a: b}
|
|
767
|
+
|
|
768
|
+
.foo {@include foo();}
|
|
769
|
+
SCSS
|
|
770
|
+
end
|
|
771
|
+
|
|
772
|
+
def test_mixins_with_args
|
|
773
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
774
|
+
.foo {
|
|
775
|
+
a: bar; }
|
|
776
|
+
CSS
|
|
777
|
+
@mixin foo($a) {a: $a}
|
|
778
|
+
|
|
779
|
+
.foo {@include foo(bar)}
|
|
780
|
+
SCSS
|
|
781
|
+
|
|
782
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
783
|
+
.foo {
|
|
784
|
+
a: bar;
|
|
785
|
+
b: 12px; }
|
|
786
|
+
CSS
|
|
787
|
+
@mixin foo($a, $b) {
|
|
788
|
+
a: $a;
|
|
789
|
+
b: $b; }
|
|
790
|
+
|
|
791
|
+
.foo {@include foo(bar, 12px)}
|
|
792
|
+
SCSS
|
|
793
|
+
end
|
|
794
|
+
|
|
795
|
+
## Functions
|
|
796
|
+
|
|
797
|
+
def test_basic_function
|
|
798
|
+
assert_equal(<<CSS, render(<<SASS))
|
|
799
|
+
bar {
|
|
800
|
+
a: 3; }
|
|
801
|
+
CSS
|
|
802
|
+
@function foo() {
|
|
803
|
+
@return 1 + 2;
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
bar {
|
|
807
|
+
a: foo();
|
|
808
|
+
}
|
|
809
|
+
SASS
|
|
810
|
+
end
|
|
811
|
+
|
|
812
|
+
def test_function_args
|
|
813
|
+
assert_equal(<<CSS, render(<<SASS))
|
|
814
|
+
bar {
|
|
815
|
+
a: 3; }
|
|
816
|
+
CSS
|
|
817
|
+
@function plus($var1, $var2) {
|
|
818
|
+
@return $var1 + $var2;
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
bar {
|
|
822
|
+
a: plus(1, 2);
|
|
823
|
+
}
|
|
824
|
+
SASS
|
|
825
|
+
end
|
|
826
|
+
|
|
827
|
+
## Var Args
|
|
828
|
+
|
|
829
|
+
def test_mixin_var_args
|
|
830
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
831
|
+
.foo {
|
|
832
|
+
a: 1;
|
|
833
|
+
b: 2, 3, 4; }
|
|
834
|
+
CSS
|
|
835
|
+
@mixin foo($a, $b...) {
|
|
836
|
+
a: $a;
|
|
837
|
+
b: $b;
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
.foo {@include foo(1, 2, 3, 4)}
|
|
841
|
+
SCSS
|
|
842
|
+
end
|
|
843
|
+
|
|
844
|
+
def test_mixin_empty_var_args
|
|
845
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
846
|
+
.foo {
|
|
847
|
+
a: 1;
|
|
848
|
+
b: 0; }
|
|
849
|
+
CSS
|
|
850
|
+
@mixin foo($a, $b...) {
|
|
851
|
+
a: $a;
|
|
852
|
+
b: length($b);
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
.foo {@include foo(1)}
|
|
856
|
+
SCSS
|
|
857
|
+
end
|
|
858
|
+
|
|
859
|
+
def test_mixin_var_args_act_like_list
|
|
860
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
861
|
+
.foo {
|
|
862
|
+
a: 3;
|
|
863
|
+
b: 3; }
|
|
864
|
+
CSS
|
|
865
|
+
@mixin foo($a, $b...) {
|
|
866
|
+
a: length($b);
|
|
867
|
+
b: nth($b, 2);
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
.foo {@include foo(1, 2, 3, 4)}
|
|
871
|
+
SCSS
|
|
872
|
+
end
|
|
873
|
+
|
|
874
|
+
def test_mixin_splat_args
|
|
875
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
876
|
+
.foo {
|
|
877
|
+
a: 1;
|
|
878
|
+
b: 2;
|
|
879
|
+
c: 3;
|
|
880
|
+
d: 4; }
|
|
881
|
+
CSS
|
|
882
|
+
@mixin foo($a, $b, $c, $d) {
|
|
883
|
+
a: $a;
|
|
884
|
+
b: $b;
|
|
885
|
+
c: $c;
|
|
886
|
+
d: $d;
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
$list: 2, 3, 4;
|
|
890
|
+
.foo {@include foo(1, $list...)}
|
|
891
|
+
SCSS
|
|
892
|
+
end
|
|
893
|
+
|
|
894
|
+
def test_mixin_splat_expression
|
|
895
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
896
|
+
.foo {
|
|
897
|
+
a: 1;
|
|
898
|
+
b: 2;
|
|
899
|
+
c: 3;
|
|
900
|
+
d: 4; }
|
|
901
|
+
CSS
|
|
902
|
+
@mixin foo($a, $b, $c, $d) {
|
|
903
|
+
a: $a;
|
|
904
|
+
b: $b;
|
|
905
|
+
c: $c;
|
|
906
|
+
d: $d;
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
.foo {@include foo(1, (2, 3, 4)...)}
|
|
910
|
+
SCSS
|
|
911
|
+
end
|
|
912
|
+
|
|
913
|
+
def test_mixin_splat_args_with_var_args
|
|
914
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
915
|
+
.foo {
|
|
916
|
+
a: 1;
|
|
917
|
+
b: 2, 3, 4; }
|
|
918
|
+
CSS
|
|
919
|
+
@mixin foo($a, $b...) {
|
|
920
|
+
a: $a;
|
|
921
|
+
b: $b;
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
$list: 2, 3, 4;
|
|
925
|
+
.foo {@include foo(1, $list...)}
|
|
926
|
+
SCSS
|
|
927
|
+
end
|
|
928
|
+
|
|
929
|
+
def test_mixin_splat_args_with_var_args_and_normal_args
|
|
930
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
931
|
+
.foo {
|
|
932
|
+
a: 1;
|
|
933
|
+
b: 2;
|
|
934
|
+
c: 3, 4; }
|
|
935
|
+
CSS
|
|
936
|
+
@mixin foo($a, $b, $c...) {
|
|
937
|
+
a: $a;
|
|
938
|
+
b: $b;
|
|
939
|
+
c: $c;
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
$list: 2, 3, 4;
|
|
943
|
+
.foo {@include foo(1, $list...)}
|
|
944
|
+
SCSS
|
|
945
|
+
end
|
|
946
|
+
|
|
947
|
+
def test_mixin_splat_args_with_var_args_preserves_separator
|
|
948
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
949
|
+
.foo {
|
|
950
|
+
a: 1;
|
|
951
|
+
b: 2 3 4 5; }
|
|
952
|
+
CSS
|
|
953
|
+
@mixin foo($a, $b...) {
|
|
954
|
+
a: $a;
|
|
955
|
+
b: $b;
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
$list: 3 4 5;
|
|
959
|
+
.foo {@include foo(1, 2, $list...)}
|
|
960
|
+
SCSS
|
|
961
|
+
end
|
|
962
|
+
|
|
963
|
+
def test_mixin_var_and_splat_args_pass_through_keywords
|
|
964
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
965
|
+
.foo {
|
|
966
|
+
a: 3;
|
|
967
|
+
b: 1;
|
|
968
|
+
c: 2; }
|
|
969
|
+
CSS
|
|
970
|
+
@mixin foo($a...) {
|
|
971
|
+
@include bar($a...);
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
@mixin bar($b, $c, $a) {
|
|
975
|
+
a: $a;
|
|
976
|
+
b: $b;
|
|
977
|
+
c: $c;
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
.foo {@include foo(1, $c: 2, $a: 3)}
|
|
981
|
+
SCSS
|
|
982
|
+
end
|
|
983
|
+
|
|
984
|
+
def test_mixin_var_args_with_keyword
|
|
985
|
+
assert_raise_message(Sass::SyntaxError, "Positional arguments must come before keyword arguments.") {render <<SCSS}
|
|
986
|
+
@mixin foo($a, $b...) {
|
|
987
|
+
a: $a;
|
|
988
|
+
b: $b;
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
.foo {@include foo($a: 1, 2, 3, 4)}
|
|
992
|
+
SCSS
|
|
993
|
+
end
|
|
994
|
+
|
|
995
|
+
def test_mixin_keyword_for_var_arg
|
|
996
|
+
assert_raise_message(Sass::SyntaxError, "Argument $b of mixin foo cannot be used as a named argument.") {render <<SCSS}
|
|
997
|
+
@mixin foo($a, $b...) {
|
|
998
|
+
a: $a;
|
|
999
|
+
b: $b;
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
.foo {@include foo(1, $b: 2 3 4)}
|
|
1003
|
+
SCSS
|
|
1004
|
+
end
|
|
1005
|
+
|
|
1006
|
+
def test_mixin_keyword_for_unknown_arg_with_var_args
|
|
1007
|
+
assert_raise_message(Sass::SyntaxError, "Mixin foo doesn't have an argument named $c.") {render <<SCSS}
|
|
1008
|
+
@mixin foo($a, $b...) {
|
|
1009
|
+
a: $a;
|
|
1010
|
+
b: $b;
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
.foo {@include foo(1, $c: 2 3 4)}
|
|
1014
|
+
SCSS
|
|
1015
|
+
end
|
|
1016
|
+
|
|
1017
|
+
def test_function_var_args
|
|
1018
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1019
|
+
.foo {
|
|
1020
|
+
val: "a: 1, b: 2, 3, 4"; }
|
|
1021
|
+
CSS
|
|
1022
|
+
@function foo($a, $b...) {
|
|
1023
|
+
@return "a: \#{$a}, b: \#{$b}";
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
.foo {val: foo(1, 2, 3, 4)}
|
|
1027
|
+
SCSS
|
|
1028
|
+
end
|
|
1029
|
+
|
|
1030
|
+
def test_function_empty_var_args
|
|
1031
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1032
|
+
.foo {
|
|
1033
|
+
val: "a: 1, b: 0"; }
|
|
1034
|
+
CSS
|
|
1035
|
+
@function foo($a, $b...) {
|
|
1036
|
+
@return "a: \#{$a}, b: \#{length($b)}";
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
.foo {val: foo(1)}
|
|
1040
|
+
SCSS
|
|
1041
|
+
end
|
|
1042
|
+
|
|
1043
|
+
def test_function_var_args_act_like_list
|
|
1044
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1045
|
+
.foo {
|
|
1046
|
+
val: "a: 3, b: 3"; }
|
|
1047
|
+
CSS
|
|
1048
|
+
@function foo($a, $b...) {
|
|
1049
|
+
@return "a: \#{length($b)}, b: \#{nth($b, 2)}";
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
.foo {val: foo(1, 2, 3, 4)}
|
|
1053
|
+
SCSS
|
|
1054
|
+
end
|
|
1055
|
+
|
|
1056
|
+
def test_function_splat_args
|
|
1057
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1058
|
+
.foo {
|
|
1059
|
+
val: "a: 1, b: 2, c: 3, d: 4"; }
|
|
1060
|
+
CSS
|
|
1061
|
+
@function foo($a, $b, $c, $d) {
|
|
1062
|
+
@return "a: \#{$a}, b: \#{$b}, c: \#{$c}, d: \#{$d}";
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
$list: 2, 3, 4;
|
|
1066
|
+
.foo {val: foo(1, $list...)}
|
|
1067
|
+
SCSS
|
|
1068
|
+
end
|
|
1069
|
+
|
|
1070
|
+
def test_function_splat_expression
|
|
1071
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1072
|
+
.foo {
|
|
1073
|
+
val: "a: 1, b: 2, c: 3, d: 4"; }
|
|
1074
|
+
CSS
|
|
1075
|
+
@function foo($a, $b, $c, $d) {
|
|
1076
|
+
@return "a: \#{$a}, b: \#{$b}, c: \#{$c}, d: \#{$d}";
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
.foo {val: foo(1, (2, 3, 4)...)}
|
|
1080
|
+
SCSS
|
|
1081
|
+
end
|
|
1082
|
+
|
|
1083
|
+
def test_function_splat_args_with_var_args
|
|
1084
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1085
|
+
.foo {
|
|
1086
|
+
val: "a: 1, b: 2, 3, 4"; }
|
|
1087
|
+
CSS
|
|
1088
|
+
@function foo($a, $b...) {
|
|
1089
|
+
@return "a: \#{$a}, b: \#{$b}";
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
$list: 2, 3, 4;
|
|
1093
|
+
.foo {val: foo(1, $list...)}
|
|
1094
|
+
SCSS
|
|
1095
|
+
end
|
|
1096
|
+
|
|
1097
|
+
def test_function_splat_args_with_var_args_and_normal_args
|
|
1098
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1099
|
+
.foo {
|
|
1100
|
+
val: "a: 1, b: 2, c: 3, 4"; }
|
|
1101
|
+
CSS
|
|
1102
|
+
@function foo($a, $b, $c...) {
|
|
1103
|
+
@return "a: \#{$a}, b: \#{$b}, c: \#{$c}";
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
$list: 2, 3, 4;
|
|
1107
|
+
.foo {val: foo(1, $list...)}
|
|
1108
|
+
SCSS
|
|
1109
|
+
end
|
|
1110
|
+
|
|
1111
|
+
def test_function_splat_args_with_var_args_preserves_separator
|
|
1112
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1113
|
+
.foo {
|
|
1114
|
+
val: "a: 1, b: 2 3 4 5"; }
|
|
1115
|
+
CSS
|
|
1116
|
+
@function foo($a, $b...) {
|
|
1117
|
+
@return "a: \#{$a}, b: \#{$b}";
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
$list: 3 4 5;
|
|
1121
|
+
.foo {val: foo(1, 2, $list...)}
|
|
1122
|
+
SCSS
|
|
1123
|
+
end
|
|
1124
|
+
|
|
1125
|
+
def test_function_var_and_splat_args_pass_through_keywords
|
|
1126
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1127
|
+
.foo {
|
|
1128
|
+
val: "a: 3, b: 1, c: 2"; }
|
|
1129
|
+
CSS
|
|
1130
|
+
@function foo($a...) {
|
|
1131
|
+
@return bar($a...);
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
@function bar($b, $c, $a) {
|
|
1135
|
+
@return "a: \#{$a}, b: \#{$b}, c: \#{$c}";
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
.foo {val: foo(1, $c: 2, $a: 3)}
|
|
1139
|
+
SCSS
|
|
1140
|
+
end
|
|
1141
|
+
|
|
1142
|
+
def test_function_var_args_with_keyword
|
|
1143
|
+
assert_raise_message(Sass::SyntaxError, "Positional arguments must come before keyword arguments.") {render <<SCSS}
|
|
1144
|
+
@function foo($a, $b...) {
|
|
1145
|
+
@return "a: \#{$a}, b: $b";
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
.foo {val: foo($a: 1, 2, 3, 4)}
|
|
1149
|
+
SCSS
|
|
1150
|
+
end
|
|
1151
|
+
|
|
1152
|
+
def test_function_keyword_for_var_arg
|
|
1153
|
+
assert_raise_message(Sass::SyntaxError, "Argument $b of function foo cannot be used as a named argument.") {render <<SCSS}
|
|
1154
|
+
@function foo($a, $b...) {
|
|
1155
|
+
@return "a: \#{$a}, b: \#{$b}";
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
.foo {val: foo(1, $b: 2 3 4)}
|
|
1159
|
+
SCSS
|
|
1160
|
+
end
|
|
1161
|
+
|
|
1162
|
+
def test_function_keyword_for_unknown_arg_with_var_args
|
|
1163
|
+
assert_raise_message(Sass::SyntaxError, "Function foo doesn't have an argument named $c.") {render <<SCSS}
|
|
1164
|
+
@function foo($a, $b...) {
|
|
1165
|
+
@return "a: \#{$a}, b: \#{$b}";
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
.foo {val: foo(1, $c: 2 3 4)}
|
|
1169
|
+
SCSS
|
|
1170
|
+
end
|
|
1171
|
+
|
|
1172
|
+
def test_function_var_args_passed_to_native
|
|
1173
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1174
|
+
.foo {
|
|
1175
|
+
val: #102035; }
|
|
1176
|
+
CSS
|
|
1177
|
+
@function foo($args...) {
|
|
1178
|
+
@return adjust-color($args...);
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
.foo {val: foo(#102030, $blue: 5)}
|
|
1182
|
+
SCSS
|
|
1183
|
+
end
|
|
1184
|
+
|
|
1185
|
+
## Interpolation
|
|
1186
|
+
|
|
1187
|
+
def test_basic_selector_interpolation
|
|
1188
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1189
|
+
foo 3 baz {
|
|
1190
|
+
a: b; }
|
|
1191
|
+
CSS
|
|
1192
|
+
foo \#{1 + 2} baz {a: b}
|
|
1193
|
+
SCSS
|
|
1194
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1195
|
+
foo.bar baz {
|
|
1196
|
+
a: b; }
|
|
1197
|
+
CSS
|
|
1198
|
+
foo\#{".bar"} baz {a: b}
|
|
1199
|
+
SCSS
|
|
1200
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1201
|
+
foo.bar baz {
|
|
1202
|
+
a: b; }
|
|
1203
|
+
CSS
|
|
1204
|
+
\#{"foo"}.bar baz {a: b}
|
|
1205
|
+
SCSS
|
|
1206
|
+
end
|
|
1207
|
+
|
|
1208
|
+
def test_selector_only_interpolation
|
|
1209
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1210
|
+
foo bar {
|
|
1211
|
+
a: b; }
|
|
1212
|
+
CSS
|
|
1213
|
+
\#{"foo" + " bar"} {a: b}
|
|
1214
|
+
SCSS
|
|
1215
|
+
end
|
|
1216
|
+
|
|
1217
|
+
def test_selector_interpolation_before_element_name
|
|
1218
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1219
|
+
foo barbaz {
|
|
1220
|
+
a: b; }
|
|
1221
|
+
CSS
|
|
1222
|
+
\#{"foo" + " bar"}baz {a: b}
|
|
1223
|
+
SCSS
|
|
1224
|
+
end
|
|
1225
|
+
|
|
1226
|
+
def test_selector_interpolation_in_string
|
|
1227
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1228
|
+
foo[val="bar foo bar baz"] {
|
|
1229
|
+
a: b; }
|
|
1230
|
+
CSS
|
|
1231
|
+
foo[val="bar \#{"foo" + " bar"} baz"] {a: b}
|
|
1232
|
+
SCSS
|
|
1233
|
+
end
|
|
1234
|
+
|
|
1235
|
+
def test_selector_interpolation_in_pseudoclass
|
|
1236
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1237
|
+
foo:nth-child(5n) {
|
|
1238
|
+
a: b; }
|
|
1239
|
+
CSS
|
|
1240
|
+
foo:nth-child(\#{5 + "n"}) {a: b}
|
|
1241
|
+
SCSS
|
|
1242
|
+
end
|
|
1243
|
+
|
|
1244
|
+
def test_selector_interpolation_at_class_begininng
|
|
1245
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1246
|
+
.zzz {
|
|
1247
|
+
a: b; }
|
|
1248
|
+
CSS
|
|
1249
|
+
$zzz: zzz;
|
|
1250
|
+
.\#{$zzz} { a: b; }
|
|
1251
|
+
SCSS
|
|
1252
|
+
end
|
|
1253
|
+
|
|
1254
|
+
def test_selector_interpolation_at_id_begininng
|
|
1255
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1256
|
+
#zzz {
|
|
1257
|
+
a: b; }
|
|
1258
|
+
CSS
|
|
1259
|
+
$zzz: zzz;
|
|
1260
|
+
#\#{$zzz} { a: b; }
|
|
1261
|
+
SCSS
|
|
1262
|
+
end
|
|
1263
|
+
|
|
1264
|
+
def test_selector_interpolation_at_pseudo_begininng
|
|
1265
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1266
|
+
:zzz::zzz {
|
|
1267
|
+
a: b; }
|
|
1268
|
+
CSS
|
|
1269
|
+
$zzz: zzz;
|
|
1270
|
+
:\#{$zzz}::\#{$zzz} { a: b; }
|
|
1271
|
+
SCSS
|
|
1272
|
+
end
|
|
1273
|
+
|
|
1274
|
+
def test_selector_interpolation_at_attr_beginning
|
|
1275
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1276
|
+
[zzz=foo] {
|
|
1277
|
+
a: b; }
|
|
1278
|
+
CSS
|
|
1279
|
+
$zzz: zzz;
|
|
1280
|
+
[\#{$zzz}=foo] { a: b; }
|
|
1281
|
+
SCSS
|
|
1282
|
+
end
|
|
1283
|
+
|
|
1284
|
+
def test_selector_interpolation_at_attr_end
|
|
1285
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1286
|
+
[foo=zzz] {
|
|
1287
|
+
a: b; }
|
|
1288
|
+
CSS
|
|
1289
|
+
$zzz: zzz;
|
|
1290
|
+
[foo=\#{$zzz}] { a: b; }
|
|
1291
|
+
SCSS
|
|
1292
|
+
end
|
|
1293
|
+
|
|
1294
|
+
def test_selector_interpolation_at_dashes
|
|
1295
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1296
|
+
div {
|
|
1297
|
+
-foo-a-b-foo: foo; }
|
|
1298
|
+
CSS
|
|
1299
|
+
$a : a;
|
|
1300
|
+
$b : b;
|
|
1301
|
+
div { -foo-\#{$a}-\#{$b}-foo: foo }
|
|
1302
|
+
SCSS
|
|
1303
|
+
end
|
|
1304
|
+
|
|
1305
|
+
def test_selector_interpolation_in_reference_combinator
|
|
1306
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1307
|
+
.foo /a/ .bar /b|c/ .baz {
|
|
1308
|
+
a: b; }
|
|
1309
|
+
CSS
|
|
1310
|
+
$a: a;
|
|
1311
|
+
$b: b;
|
|
1312
|
+
$c: c;
|
|
1313
|
+
.foo /\#{$a}/ .bar /\#{$b}|\#{$c}/ .baz {a: b}
|
|
1314
|
+
SCSS
|
|
1315
|
+
end
|
|
1316
|
+
|
|
1317
|
+
def test_parent_selector_with_parent_and_subject
|
|
1318
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1319
|
+
bar foo.baz! .bip {
|
|
1320
|
+
c: d; }
|
|
1321
|
+
CSS
|
|
1322
|
+
$subject: "!";
|
|
1323
|
+
foo {
|
|
1324
|
+
bar &.baz\#{$subject} .bip {c: d}}
|
|
1325
|
+
SCSS
|
|
1326
|
+
end
|
|
1327
|
+
|
|
1328
|
+
def test_basic_prop_name_interpolation
|
|
1329
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1330
|
+
foo {
|
|
1331
|
+
barbazbang: blip; }
|
|
1332
|
+
CSS
|
|
1333
|
+
foo {bar\#{"baz" + "bang"}: blip}
|
|
1334
|
+
SCSS
|
|
1335
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1336
|
+
foo {
|
|
1337
|
+
bar3: blip; }
|
|
1338
|
+
CSS
|
|
1339
|
+
foo {bar\#{1 + 2}: blip}
|
|
1340
|
+
SCSS
|
|
1341
|
+
end
|
|
1342
|
+
|
|
1343
|
+
def test_prop_name_only_interpolation
|
|
1344
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1345
|
+
foo {
|
|
1346
|
+
bazbang: blip; }
|
|
1347
|
+
CSS
|
|
1348
|
+
foo {\#{"baz" + "bang"}: blip}
|
|
1349
|
+
SCSS
|
|
1350
|
+
end
|
|
1351
|
+
|
|
1352
|
+
def test_directive_interpolation
|
|
1353
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1354
|
+
@foo bar12 qux {
|
|
1355
|
+
a: b; }
|
|
1356
|
+
CSS
|
|
1357
|
+
$baz: 12;
|
|
1358
|
+
@foo bar\#{$baz} qux {a: b}
|
|
1359
|
+
SCSS
|
|
1360
|
+
end
|
|
1361
|
+
|
|
1362
|
+
def test_media_interpolation
|
|
1363
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1364
|
+
@media bar12 {
|
|
1365
|
+
a: b; }
|
|
1366
|
+
CSS
|
|
1367
|
+
$baz: 12;
|
|
1368
|
+
@media bar\#{$baz} {a: b}
|
|
1369
|
+
SCSS
|
|
1370
|
+
end
|
|
1371
|
+
|
|
1372
|
+
def test_script_in_media
|
|
1373
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1374
|
+
@media screen and (-webkit-min-device-pixel-ratio: 20), only print {
|
|
1375
|
+
a: b; }
|
|
1376
|
+
CSS
|
|
1377
|
+
$media1: screen;
|
|
1378
|
+
$media2: print;
|
|
1379
|
+
$var: -webkit-min-device-pixel-ratio;
|
|
1380
|
+
$val: 20;
|
|
1381
|
+
@media \#{$media1} and ($var: $val), only \#{$media2} {a: b}
|
|
1382
|
+
SCSS
|
|
1383
|
+
|
|
1384
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1385
|
+
@media screen and (-webkit-min-device-pixel-ratio: 13) {
|
|
1386
|
+
a: b; }
|
|
1387
|
+
CSS
|
|
1388
|
+
$vals: 1 2 3;
|
|
1389
|
+
@media screen and (-webkit-min-device-pixel-ratio: 5 + 6 + nth($vals, 2)) {a: b}
|
|
1390
|
+
SCSS
|
|
1391
|
+
end
|
|
1392
|
+
|
|
1393
|
+
def test_media_interpolation_with_reparse
|
|
1394
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1395
|
+
@media screen and (max-width: 300px) {
|
|
1396
|
+
a: b; }
|
|
1397
|
+
@media screen and (max-width: 300px) {
|
|
1398
|
+
a: b; }
|
|
1399
|
+
@media screen and (max-width: 300px) {
|
|
1400
|
+
a: b; }
|
|
1401
|
+
@media screen and (max-width: 300px), print and (max-width: 300px) {
|
|
1402
|
+
a: b; }
|
|
1403
|
+
CSS
|
|
1404
|
+
$constraint: "(max-width: 300px)";
|
|
1405
|
+
$fragment: "nd \#{$constraint}";
|
|
1406
|
+
$comma: "een, pri";
|
|
1407
|
+
@media screen and \#{$constraint} {a: b}
|
|
1408
|
+
@media screen {
|
|
1409
|
+
@media \#{$constraint} {a: b}
|
|
1410
|
+
}
|
|
1411
|
+
@media screen a\#{$fragment} {a: b}
|
|
1412
|
+
@media scr\#{$comma}nt {
|
|
1413
|
+
@media \#{$constraint} {a: b}
|
|
1414
|
+
}
|
|
1415
|
+
SCSS
|
|
1416
|
+
end
|
|
1417
|
+
|
|
1418
|
+
def test_moz_document_interpolation
|
|
1419
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1420
|
+
@-moz-document url(http://sass-lang.com/),
|
|
1421
|
+
url-prefix(http://sass-lang.com/docs),
|
|
1422
|
+
domain(sass-lang.com),
|
|
1423
|
+
domain("sass-lang.com") {
|
|
1424
|
+
.foo {
|
|
1425
|
+
a: b; } }
|
|
1426
|
+
CSS
|
|
1427
|
+
$domain: "sass-lang.com";
|
|
1428
|
+
@-moz-document url(http://\#{$domain}/),
|
|
1429
|
+
url-prefix(http://\#{$domain}/docs),
|
|
1430
|
+
domain(\#{$domain}),
|
|
1431
|
+
\#{domain($domain)} {
|
|
1432
|
+
.foo {a: b}
|
|
1433
|
+
}
|
|
1434
|
+
SCSS
|
|
1435
|
+
end
|
|
1436
|
+
|
|
1437
|
+
def test_supports_with_expressions
|
|
1438
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1439
|
+
@supports (feature1: val) and (feature2: val) or (not (feature23: val4)) {
|
|
1440
|
+
foo {
|
|
1441
|
+
a: b; } }
|
|
1442
|
+
CSS
|
|
1443
|
+
$query: "(feature1: val)";
|
|
1444
|
+
$feature: feature2;
|
|
1445
|
+
$val: val;
|
|
1446
|
+
@supports \#{$query} and ($feature: $val) or (not ($feature + 3: $val + 4)) {
|
|
1447
|
+
foo {a: b}
|
|
1448
|
+
}
|
|
1449
|
+
SCSS
|
|
1450
|
+
end
|
|
1451
|
+
|
|
1452
|
+
def test_supports_bubbling
|
|
1453
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1454
|
+
@supports (foo: bar) {
|
|
1455
|
+
a {
|
|
1456
|
+
b: c; }
|
|
1457
|
+
@supports (baz: bang) {
|
|
1458
|
+
a {
|
|
1459
|
+
d: e; } } }
|
|
1460
|
+
CSS
|
|
1461
|
+
a {
|
|
1462
|
+
@supports (foo: bar) {
|
|
1463
|
+
b: c;
|
|
1464
|
+
@supports (baz: bang) {
|
|
1465
|
+
d: e;
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
SCSS
|
|
1470
|
+
end
|
|
1471
|
+
|
|
1472
|
+
def test_random_directive_interpolation
|
|
1473
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1474
|
+
@foo url(http://sass-lang.com/),
|
|
1475
|
+
domain("sass-lang.com"),
|
|
1476
|
+
"foobarbaz",
|
|
1477
|
+
foobarbaz {
|
|
1478
|
+
.foo {
|
|
1479
|
+
a: b; } }
|
|
1480
|
+
CSS
|
|
1481
|
+
$domain: "sass-lang.com";
|
|
1482
|
+
@foo url(http://\#{$domain}/),
|
|
1483
|
+
\#{domain($domain)},
|
|
1484
|
+
"foo\#{'ba' + 'r'}baz",
|
|
1485
|
+
foo\#{'ba' + 'r'}baz {
|
|
1486
|
+
.foo {a: b}
|
|
1487
|
+
}
|
|
1488
|
+
SCSS
|
|
1489
|
+
end
|
|
1490
|
+
|
|
1491
|
+
def test_nested_mixin_def
|
|
1492
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1493
|
+
foo {
|
|
1494
|
+
a: b; }
|
|
1495
|
+
CSS
|
|
1496
|
+
foo {
|
|
1497
|
+
@mixin bar {a: b}
|
|
1498
|
+
@include bar; }
|
|
1499
|
+
SCSS
|
|
1500
|
+
end
|
|
1501
|
+
|
|
1502
|
+
def test_nested_mixin_shadow
|
|
1503
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1504
|
+
foo {
|
|
1505
|
+
c: d; }
|
|
1506
|
+
|
|
1507
|
+
baz {
|
|
1508
|
+
a: b; }
|
|
1509
|
+
CSS
|
|
1510
|
+
@mixin bar {a: b}
|
|
1511
|
+
|
|
1512
|
+
foo {
|
|
1513
|
+
@mixin bar {c: d}
|
|
1514
|
+
@include bar;
|
|
1515
|
+
}
|
|
1516
|
+
|
|
1517
|
+
baz {@include bar}
|
|
1518
|
+
SCSS
|
|
1519
|
+
end
|
|
1520
|
+
|
|
1521
|
+
def test_nested_function_def
|
|
1522
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1523
|
+
foo {
|
|
1524
|
+
a: 1; }
|
|
1525
|
+
|
|
1526
|
+
bar {
|
|
1527
|
+
b: foo(); }
|
|
1528
|
+
CSS
|
|
1529
|
+
foo {
|
|
1530
|
+
@function foo() {@return 1}
|
|
1531
|
+
a: foo(); }
|
|
1532
|
+
|
|
1533
|
+
bar {b: foo()}
|
|
1534
|
+
SCSS
|
|
1535
|
+
end
|
|
1536
|
+
|
|
1537
|
+
def test_nested_function_shadow
|
|
1538
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1539
|
+
foo {
|
|
1540
|
+
a: 2; }
|
|
1541
|
+
|
|
1542
|
+
baz {
|
|
1543
|
+
b: 1; }
|
|
1544
|
+
CSS
|
|
1545
|
+
@function foo() {@return 1}
|
|
1546
|
+
|
|
1547
|
+
foo {
|
|
1548
|
+
@function foo() {@return 2}
|
|
1549
|
+
a: foo();
|
|
1550
|
+
}
|
|
1551
|
+
|
|
1552
|
+
baz {b: foo()}
|
|
1553
|
+
SCSS
|
|
1554
|
+
end
|
|
1555
|
+
|
|
1556
|
+
## Errors
|
|
1557
|
+
|
|
1558
|
+
def test_nested_mixin_def_is_scoped
|
|
1559
|
+
render <<SCSS
|
|
1560
|
+
foo {
|
|
1561
|
+
@mixin bar {a: b}}
|
|
1562
|
+
bar {@include bar}
|
|
1563
|
+
SCSS
|
|
1564
|
+
assert(false, "Expected syntax error")
|
|
1565
|
+
rescue Sass::SyntaxError => e
|
|
1566
|
+
assert_equal "Undefined mixin 'bar'.", e.message
|
|
1567
|
+
assert_equal 3, e.sass_line
|
|
1568
|
+
end
|
|
1569
|
+
|
|
1570
|
+
def test_rules_beneath_properties
|
|
1571
|
+
render <<SCSS
|
|
1572
|
+
foo {
|
|
1573
|
+
bar: {
|
|
1574
|
+
baz {
|
|
1575
|
+
bang: bop }}}
|
|
1576
|
+
SCSS
|
|
1577
|
+
assert(false, "Expected syntax error")
|
|
1578
|
+
rescue Sass::SyntaxError => e
|
|
1579
|
+
assert_equal 'Illegal nesting: Only properties may be nested beneath properties.', e.message
|
|
1580
|
+
assert_equal 3, e.sass_line
|
|
1581
|
+
end
|
|
1582
|
+
|
|
1583
|
+
def test_uses_property_exception_with_star_hack
|
|
1584
|
+
render <<SCSS
|
|
1585
|
+
foo {
|
|
1586
|
+
*bar:baz [fail]; }
|
|
1587
|
+
SCSS
|
|
1588
|
+
assert(false, "Expected syntax error")
|
|
1589
|
+
rescue Sass::SyntaxError => e
|
|
1590
|
+
assert_equal 'Invalid CSS after " *bar:baz ": expected ";", was "[fail]; }"', e.message
|
|
1591
|
+
assert_equal 2, e.sass_line
|
|
1592
|
+
end
|
|
1593
|
+
|
|
1594
|
+
def test_uses_property_exception_with_colon_hack
|
|
1595
|
+
render <<SCSS
|
|
1596
|
+
foo {
|
|
1597
|
+
:bar:baz [fail]; }
|
|
1598
|
+
SCSS
|
|
1599
|
+
assert(false, "Expected syntax error")
|
|
1600
|
+
rescue Sass::SyntaxError => e
|
|
1601
|
+
assert_equal 'Invalid CSS after " :bar:baz ": expected ";", was "[fail]; }"', e.message
|
|
1602
|
+
assert_equal 2, e.sass_line
|
|
1603
|
+
end
|
|
1604
|
+
|
|
1605
|
+
def test_uses_rule_exception_with_dot_hack
|
|
1606
|
+
render <<SCSS
|
|
1607
|
+
foo {
|
|
1608
|
+
.bar:baz <fail>; }
|
|
1609
|
+
SCSS
|
|
1610
|
+
assert(false, "Expected syntax error")
|
|
1611
|
+
rescue Sass::SyntaxError => e
|
|
1612
|
+
assert_equal 'Invalid CSS after " .bar:baz ": expected "{", was "<fail>; }"', e.message
|
|
1613
|
+
assert_equal 2, e.sass_line
|
|
1614
|
+
end
|
|
1615
|
+
|
|
1616
|
+
def test_uses_property_exception_with_space_after_name
|
|
1617
|
+
render <<SCSS
|
|
1618
|
+
foo {
|
|
1619
|
+
bar: baz [fail]; }
|
|
1620
|
+
SCSS
|
|
1621
|
+
assert(false, "Expected syntax error")
|
|
1622
|
+
rescue Sass::SyntaxError => e
|
|
1623
|
+
assert_equal 'Invalid CSS after " bar: baz ": expected ";", was "[fail]; }"', e.message
|
|
1624
|
+
assert_equal 2, e.sass_line
|
|
1625
|
+
end
|
|
1626
|
+
|
|
1627
|
+
def test_uses_property_exception_with_non_identifier_after_name
|
|
1628
|
+
render <<SCSS
|
|
1629
|
+
foo {
|
|
1630
|
+
bar:1px [fail]; }
|
|
1631
|
+
SCSS
|
|
1632
|
+
assert(false, "Expected syntax error")
|
|
1633
|
+
rescue Sass::SyntaxError => e
|
|
1634
|
+
assert_equal 'Invalid CSS after " bar:1px ": expected ";", was "[fail]; }"', e.message
|
|
1635
|
+
assert_equal 2, e.sass_line
|
|
1636
|
+
end
|
|
1637
|
+
|
|
1638
|
+
def test_uses_property_exception_when_followed_by_open_bracket
|
|
1639
|
+
render <<SCSS
|
|
1640
|
+
foo {
|
|
1641
|
+
bar:{baz: .fail} }
|
|
1642
|
+
SCSS
|
|
1643
|
+
assert(false, "Expected syntax error")
|
|
1644
|
+
rescue Sass::SyntaxError => e
|
|
1645
|
+
assert_equal 'Invalid CSS after " bar:{baz: ": expected expression (e.g. 1px, bold), was ".fail} }"', e.message
|
|
1646
|
+
assert_equal 2, e.sass_line
|
|
1647
|
+
end
|
|
1648
|
+
|
|
1649
|
+
def test_script_error
|
|
1650
|
+
render <<SCSS
|
|
1651
|
+
foo {
|
|
1652
|
+
bar: "baz" * * }
|
|
1653
|
+
SCSS
|
|
1654
|
+
assert(false, "Expected syntax error")
|
|
1655
|
+
rescue Sass::SyntaxError => e
|
|
1656
|
+
assert_equal 'Invalid CSS after " bar: "baz" * ": expected expression (e.g. 1px, bold), was "* }"', e.message
|
|
1657
|
+
assert_equal 2, e.sass_line
|
|
1658
|
+
end
|
|
1659
|
+
|
|
1660
|
+
def test_multiline_script_syntax_error
|
|
1661
|
+
render <<SCSS
|
|
1662
|
+
foo {
|
|
1663
|
+
bar:
|
|
1664
|
+
"baz" * * }
|
|
1665
|
+
SCSS
|
|
1666
|
+
assert(false, "Expected syntax error")
|
|
1667
|
+
rescue Sass::SyntaxError => e
|
|
1668
|
+
assert_equal 'Invalid CSS after " "baz" * ": expected expression (e.g. 1px, bold), was "* }"', e.message
|
|
1669
|
+
assert_equal 3, e.sass_line
|
|
1670
|
+
end
|
|
1671
|
+
|
|
1672
|
+
def test_multiline_script_runtime_error
|
|
1673
|
+
render <<SCSS
|
|
1674
|
+
foo {
|
|
1675
|
+
bar: "baz" +
|
|
1676
|
+
"bar" +
|
|
1677
|
+
$bang }
|
|
1678
|
+
SCSS
|
|
1679
|
+
assert(false, "Expected syntax error")
|
|
1680
|
+
rescue Sass::SyntaxError => e
|
|
1681
|
+
assert_equal "Undefined variable: \"$bang\".", e.message
|
|
1682
|
+
assert_equal 4, e.sass_line
|
|
1683
|
+
end
|
|
1684
|
+
|
|
1685
|
+
def test_post_multiline_script_runtime_error
|
|
1686
|
+
render <<SCSS
|
|
1687
|
+
foo {
|
|
1688
|
+
bar: "baz" +
|
|
1689
|
+
"bar" +
|
|
1690
|
+
"baz";
|
|
1691
|
+
bip: $bop; }
|
|
1692
|
+
SCSS
|
|
1693
|
+
assert(false, "Expected syntax error")
|
|
1694
|
+
rescue Sass::SyntaxError => e
|
|
1695
|
+
assert_equal "Undefined variable: \"$bop\".", e.message
|
|
1696
|
+
assert_equal 5, e.sass_line
|
|
1697
|
+
end
|
|
1698
|
+
|
|
1699
|
+
def test_multiline_property_runtime_error
|
|
1700
|
+
render <<SCSS
|
|
1701
|
+
foo {
|
|
1702
|
+
bar: baz
|
|
1703
|
+
bar
|
|
1704
|
+
\#{$bang} }
|
|
1705
|
+
SCSS
|
|
1706
|
+
assert(false, "Expected syntax error")
|
|
1707
|
+
rescue Sass::SyntaxError => e
|
|
1708
|
+
assert_equal "Undefined variable: \"$bang\".", e.message
|
|
1709
|
+
assert_equal 4, e.sass_line
|
|
1710
|
+
end
|
|
1711
|
+
|
|
1712
|
+
def test_post_resolution_selector_error
|
|
1713
|
+
render "\n\nfoo \#{\") bar\"} {a: b}"
|
|
1714
|
+
assert(false, "Expected syntax error")
|
|
1715
|
+
rescue Sass::SyntaxError => e
|
|
1716
|
+
assert_equal 'Invalid CSS after "foo ": expected selector, was ") bar"', e.message
|
|
1717
|
+
assert_equal 3, e.sass_line
|
|
1718
|
+
end
|
|
1719
|
+
|
|
1720
|
+
def test_parent_in_mid_selector_error
|
|
1721
|
+
assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render <<SCSS}
|
|
1722
|
+
Invalid CSS after " .foo": expected "{", was "&.bar {a: b}"
|
|
1723
|
+
|
|
1724
|
+
"&.bar" may only be used at the beginning of a compound selector.
|
|
1725
|
+
MESSAGE
|
|
1726
|
+
flim {
|
|
1727
|
+
.foo&.bar {a: b}
|
|
1728
|
+
}
|
|
1729
|
+
SCSS
|
|
1730
|
+
end
|
|
1731
|
+
|
|
1732
|
+
def test_parent_after_selector_error
|
|
1733
|
+
assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render <<SCSS}
|
|
1734
|
+
Invalid CSS after " .foo.bar": expected "{", was "& {a: b}"
|
|
1735
|
+
|
|
1736
|
+
"&" may only be used at the beginning of a compound selector.
|
|
1737
|
+
MESSAGE
|
|
1738
|
+
flim {
|
|
1739
|
+
.foo.bar& {a: b}
|
|
1740
|
+
}
|
|
1741
|
+
SCSS
|
|
1742
|
+
end
|
|
1743
|
+
|
|
1744
|
+
def test_double_parent_selector_error
|
|
1745
|
+
assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render <<SCSS}
|
|
1746
|
+
Invalid CSS after " &": expected "{", was "& {a: b}"
|
|
1747
|
+
|
|
1748
|
+
"&" may only be used at the beginning of a compound selector.
|
|
1749
|
+
MESSAGE
|
|
1750
|
+
flim {
|
|
1751
|
+
&& {a: b}
|
|
1752
|
+
}
|
|
1753
|
+
SCSS
|
|
1754
|
+
end
|
|
1755
|
+
|
|
1756
|
+
def test_no_lonely_else
|
|
1757
|
+
assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render <<SCSS}
|
|
1758
|
+
Invalid CSS: @else must come after @if
|
|
1759
|
+
MESSAGE
|
|
1760
|
+
@else {foo: bar}
|
|
1761
|
+
SCSS
|
|
1762
|
+
end
|
|
1763
|
+
|
|
1764
|
+
# Regression
|
|
1765
|
+
|
|
1766
|
+
def test_parent_ref_with_newline
|
|
1767
|
+
assert_equal(<<CSS, render(<<SCSS))
|
|
1768
|
+
a.c
|
|
1769
|
+
, b.c {
|
|
1770
|
+
x: y; }
|
|
1771
|
+
CSS
|
|
1772
|
+
a
|
|
1773
|
+
, b {&.c {x: y}}
|
|
1774
|
+
SCSS
|
|
1775
|
+
end
|
|
1776
|
+
|
|
1777
|
+
def test_loud_comment_in_compressed_mode
|
|
1778
|
+
assert_equal(<<CSS, render(<<SCSS))
|
|
1779
|
+
/*! foo */
|
|
1780
|
+
CSS
|
|
1781
|
+
/*! foo */
|
|
1782
|
+
SCSS
|
|
1783
|
+
end
|
|
1784
|
+
|
|
1785
|
+
def test_parsing_decimals_followed_by_comments_doesnt_take_forever
|
|
1786
|
+
assert_equal(<<CSS, render(<<SCSS))
|
|
1787
|
+
.foo {
|
|
1788
|
+
padding: 4.21053% 4.21053% 5.63158%; }
|
|
1789
|
+
CSS
|
|
1790
|
+
.foo {
|
|
1791
|
+
padding: 4.21052631578947% 4.21052631578947% 5.631578947368421% /**/
|
|
1792
|
+
}
|
|
1793
|
+
SCSS
|
|
1794
|
+
end
|
|
1795
|
+
|
|
1796
|
+
def test_parsing_many_numbers_doesnt_take_forever
|
|
1797
|
+
values = ["80% 90%"] * 1000
|
|
1798
|
+
assert_equal(<<CSS, render(<<SCSS))
|
|
1799
|
+
.foo {
|
|
1800
|
+
padding: #{values.join(', ')}; }
|
|
1801
|
+
CSS
|
|
1802
|
+
.foo {
|
|
1803
|
+
padding: #{values.join(', ')};
|
|
1804
|
+
}
|
|
1805
|
+
SCSS
|
|
1806
|
+
end
|
|
1807
|
+
|
|
1808
|
+
def test_import_comments_in_imports
|
|
1809
|
+
assert_equal(<<CSS, render(<<SCSS))
|
|
1810
|
+
@import url(foo.css);
|
|
1811
|
+
@import url(bar.css);
|
|
1812
|
+
@import url(baz.css);
|
|
1813
|
+
CSS
|
|
1814
|
+
@import "foo.css", // this is a comment
|
|
1815
|
+
"bar.css", /* this is another comment */
|
|
1816
|
+
"baz.css"; // this is a third comment
|
|
1817
|
+
SCSS
|
|
1818
|
+
end
|
|
1819
|
+
|
|
1820
|
+
def test_reference_combinator_with_parent_ref
|
|
1821
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1822
|
+
a /foo/ b {
|
|
1823
|
+
c: d; }
|
|
1824
|
+
CSS
|
|
1825
|
+
a {& /foo/ b {c: d}}
|
|
1826
|
+
SCSS
|
|
1827
|
+
end
|
|
1828
|
+
|
|
1829
|
+
def test_newline_selector_rendered_multiple_times
|
|
1830
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1831
|
+
form input,
|
|
1832
|
+
form select {
|
|
1833
|
+
color: white; }
|
|
1834
|
+
|
|
1835
|
+
form input,
|
|
1836
|
+
form select {
|
|
1837
|
+
color: white; }
|
|
1838
|
+
CSS
|
|
1839
|
+
@for $i from 1 through 2 {
|
|
1840
|
+
form {
|
|
1841
|
+
input,
|
|
1842
|
+
select {
|
|
1843
|
+
color: white;
|
|
1844
|
+
}
|
|
1845
|
+
}
|
|
1846
|
+
}
|
|
1847
|
+
SCSS
|
|
1848
|
+
end
|
|
1849
|
+
|
|
1850
|
+
def test_prop_name_interpolation_after_hyphen
|
|
1851
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1852
|
+
a {
|
|
1853
|
+
-foo-bar: b; }
|
|
1854
|
+
CSS
|
|
1855
|
+
a { -\#{"foo"}-bar: b; }
|
|
1856
|
+
SCSS
|
|
1857
|
+
end
|
|
1858
|
+
|
|
1859
|
+
def test_star_plus_and_parent
|
|
1860
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1861
|
+
* + html foo {
|
|
1862
|
+
a: b; }
|
|
1863
|
+
CSS
|
|
1864
|
+
foo {*+html & {a: b}}
|
|
1865
|
+
SCSS
|
|
1866
|
+
end
|
|
1867
|
+
|
|
1868
|
+
def test_weird_added_space
|
|
1869
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1870
|
+
foo {
|
|
1871
|
+
bar: -moz-bip; }
|
|
1872
|
+
CSS
|
|
1873
|
+
$value : bip;
|
|
1874
|
+
|
|
1875
|
+
foo {
|
|
1876
|
+
bar: -moz-\#{$value};
|
|
1877
|
+
}
|
|
1878
|
+
SCSS
|
|
1879
|
+
end
|
|
1880
|
+
|
|
1881
|
+
def test_interpolation_with_bracket_on_next_line
|
|
1882
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1883
|
+
a.foo b {
|
|
1884
|
+
color: red; }
|
|
1885
|
+
CSS
|
|
1886
|
+
a.\#{"foo"} b
|
|
1887
|
+
{color: red}
|
|
1888
|
+
SCSS
|
|
1889
|
+
end
|
|
1890
|
+
|
|
1891
|
+
def test_extra_comma_in_mixin_arglist_error
|
|
1892
|
+
assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render <<SCSS}
|
|
1893
|
+
Invalid CSS after "...clude foo(bar, ": expected mixin argument, was ");"
|
|
1894
|
+
MESSAGE
|
|
1895
|
+
@mixin foo($a1, $a2) {
|
|
1896
|
+
baz: $a1 $a2;
|
|
1897
|
+
}
|
|
1898
|
+
|
|
1899
|
+
.bar {
|
|
1900
|
+
@include foo(bar, );
|
|
1901
|
+
}
|
|
1902
|
+
SCSS
|
|
1903
|
+
end
|
|
1904
|
+
|
|
1905
|
+
def test_interpolation
|
|
1906
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1907
|
+
ul li#foo a span.label {
|
|
1908
|
+
foo: bar; }
|
|
1909
|
+
CSS
|
|
1910
|
+
$bar : "#foo";
|
|
1911
|
+
ul li\#{$bar} a span.label { foo: bar; }
|
|
1912
|
+
SCSS
|
|
1913
|
+
end
|
|
1914
|
+
|
|
1915
|
+
def test_mixin_with_keyword_args
|
|
1916
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1917
|
+
.mixed {
|
|
1918
|
+
required: foo;
|
|
1919
|
+
arg1: default-val1;
|
|
1920
|
+
arg2: non-default-val2; }
|
|
1921
|
+
CSS
|
|
1922
|
+
@mixin a-mixin($required, $arg1: default-val1, $arg2: default-val2) {
|
|
1923
|
+
required: $required;
|
|
1924
|
+
arg1: $arg1;
|
|
1925
|
+
arg2: $arg2;
|
|
1926
|
+
}
|
|
1927
|
+
.mixed { @include a-mixin(foo, $arg2: non-default-val2); }
|
|
1928
|
+
SCSS
|
|
1929
|
+
end
|
|
1930
|
+
|
|
1931
|
+
def test_passing_required_args_as_a_keyword_arg
|
|
1932
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1933
|
+
.mixed {
|
|
1934
|
+
required: foo;
|
|
1935
|
+
arg1: default-val1;
|
|
1936
|
+
arg2: default-val2; }
|
|
1937
|
+
CSS
|
|
1938
|
+
@mixin a-mixin($required, $arg1: default-val1, $arg2: default-val2) {
|
|
1939
|
+
required: $required;
|
|
1940
|
+
arg1: $arg1;
|
|
1941
|
+
arg2: $arg2; }
|
|
1942
|
+
.mixed { @include a-mixin($required: foo); }
|
|
1943
|
+
SCSS
|
|
1944
|
+
end
|
|
1945
|
+
|
|
1946
|
+
def test_passing_all_as_keyword_args_in_opposite_order
|
|
1947
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1948
|
+
.mixed {
|
|
1949
|
+
required: foo;
|
|
1950
|
+
arg1: non-default-val1;
|
|
1951
|
+
arg2: non-default-val2; }
|
|
1952
|
+
CSS
|
|
1953
|
+
@mixin a-mixin($required, $arg1: default-val1, $arg2: default-val2) {
|
|
1954
|
+
required: $required;
|
|
1955
|
+
arg1: $arg1;
|
|
1956
|
+
arg2: $arg2; }
|
|
1957
|
+
.mixed { @include a-mixin($arg2: non-default-val2, $arg1: non-default-val1, $required: foo); }
|
|
1958
|
+
SCSS
|
|
1959
|
+
end
|
|
1960
|
+
|
|
1961
|
+
def test_keyword_args_in_functions
|
|
1962
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
1963
|
+
.keyed {
|
|
1964
|
+
color: rgba(170, 119, 204, 0.4); }
|
|
1965
|
+
CSS
|
|
1966
|
+
.keyed { color: rgba($color: #a7c, $alpha: 0.4) }
|
|
1967
|
+
SCSS
|
|
1968
|
+
end
|
|
1969
|
+
|
|
1970
|
+
def test_unknown_keyword_arg_raises_error
|
|
1971
|
+
assert_raise_message(Sass::SyntaxError, "Mixin a doesn't have an argument named $c.") {render <<SCSS}
|
|
1972
|
+
@mixin a($b: 1) { a: $b; }
|
|
1973
|
+
div { @include a(1, $c: 3); }
|
|
1974
|
+
SCSS
|
|
1975
|
+
end
|
|
1976
|
+
|
|
1977
|
+
|
|
1978
|
+
def test_newlines_removed_from_selectors_when_compressed
|
|
1979
|
+
assert_equal <<CSS, render(<<SCSS, :style => :compressed)
|
|
1980
|
+
z a,z b{display:block}
|
|
1981
|
+
CSS
|
|
1982
|
+
a
|
|
1983
|
+
, b {
|
|
1984
|
+
z & {
|
|
1985
|
+
display: block;
|
|
1986
|
+
}
|
|
1987
|
+
}
|
|
1988
|
+
SCSS
|
|
1989
|
+
end
|
|
1990
|
+
|
|
1991
|
+
def test_if_error_line
|
|
1992
|
+
assert_raise_line(2) {render(<<SCSS)}
|
|
1993
|
+
@if true {foo: bar}
|
|
1994
|
+
}
|
|
1995
|
+
SCSS
|
|
1996
|
+
end
|
|
1997
|
+
|
|
1998
|
+
def test_multiline_var
|
|
1999
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
2000
|
+
foo {
|
|
2001
|
+
a: 3;
|
|
2002
|
+
b: false;
|
|
2003
|
+
c: a b c; }
|
|
2004
|
+
CSS
|
|
2005
|
+
foo {
|
|
2006
|
+
$var1: 1 +
|
|
2007
|
+
2;
|
|
2008
|
+
$var2: true and
|
|
2009
|
+
false;
|
|
2010
|
+
$var3: a b
|
|
2011
|
+
c;
|
|
2012
|
+
a: $var1;
|
|
2013
|
+
b: $var2;
|
|
2014
|
+
c: $var3; }
|
|
2015
|
+
SCSS
|
|
2016
|
+
end
|
|
2017
|
+
|
|
2018
|
+
def test_mixin_content
|
|
2019
|
+
assert_equal <<CSS, render(<<SASS)
|
|
2020
|
+
.parent {
|
|
2021
|
+
background-color: red;
|
|
2022
|
+
border-color: red; }
|
|
2023
|
+
.parent .child {
|
|
2024
|
+
background-color: yellow;
|
|
2025
|
+
color: blue;
|
|
2026
|
+
border-color: yellow; }
|
|
2027
|
+
CSS
|
|
2028
|
+
$color: blue;
|
|
2029
|
+
@mixin context($class, $color: red) {
|
|
2030
|
+
.\#{$class} {
|
|
2031
|
+
background-color: $color;
|
|
2032
|
+
@content;
|
|
2033
|
+
border-color: $color;
|
|
2034
|
+
}
|
|
2035
|
+
}
|
|
2036
|
+
@include context(parent) {
|
|
2037
|
+
@include context(child, $color: yellow) {
|
|
2038
|
+
color: $color;
|
|
2039
|
+
}
|
|
2040
|
+
}
|
|
2041
|
+
SASS
|
|
2042
|
+
end
|
|
2043
|
+
|
|
2044
|
+
def test_empty_content
|
|
2045
|
+
assert_equal <<CSS, render(<<SCSS)
|
|
2046
|
+
a {
|
|
2047
|
+
b: c; }
|
|
2048
|
+
CSS
|
|
2049
|
+
@mixin foo { @content }
|
|
2050
|
+
a { b: c; @include foo {} }
|
|
2051
|
+
SCSS
|
|
2052
|
+
end
|
|
2053
|
+
|
|
2054
|
+
def test_options_passed_to_script
|
|
2055
|
+
assert_equal <<CSS, render(<<SCSS, :style => :compressed)
|
|
2056
|
+
foo{color:#000}
|
|
2057
|
+
CSS
|
|
2058
|
+
foo {color: darken(black, 10%)}
|
|
2059
|
+
SCSS
|
|
2060
|
+
end
|
|
2061
|
+
|
|
2062
|
+
# ref: https://github.com/nex3/sass/issues/104
|
|
2063
|
+
def test_no_buffer_overflow
|
|
2064
|
+
template = render <<SCSS
|
|
2065
|
+
.aaa {
|
|
2066
|
+
background-color: white;
|
|
2067
|
+
}
|
|
2068
|
+
.aaa .aaa .aaa {
|
|
2069
|
+
background-color: black;
|
|
2070
|
+
}
|
|
2071
|
+
.bbb {
|
|
2072
|
+
@extend .aaa;
|
|
2073
|
+
}
|
|
2074
|
+
.xxx {
|
|
2075
|
+
@extend .bbb;
|
|
2076
|
+
}
|
|
2077
|
+
.yyy {
|
|
2078
|
+
@extend .bbb;
|
|
2079
|
+
}
|
|
2080
|
+
.zzz {
|
|
2081
|
+
@extend .bbb;
|
|
2082
|
+
}
|
|
2083
|
+
SCSS
|
|
2084
|
+
Sass::SCSS::Parser.new(template, "test.scss").parse
|
|
2085
|
+
end
|
|
2086
|
+
|
|
2087
|
+
def test_extend_in_media_in_rule
|
|
2088
|
+
assert_equal(<<CSS, render(<<SCSS))
|
|
2089
|
+
@media screen {
|
|
2090
|
+
.foo {
|
|
2091
|
+
a: b; } }
|
|
2092
|
+
CSS
|
|
2093
|
+
.foo {
|
|
2094
|
+
@media screen {
|
|
2095
|
+
@extend %bar;
|
|
2096
|
+
}
|
|
2097
|
+
}
|
|
2098
|
+
|
|
2099
|
+
@media screen {
|
|
2100
|
+
%bar {
|
|
2101
|
+
a: b;
|
|
2102
|
+
}
|
|
2103
|
+
}
|
|
2104
|
+
SCSS
|
|
2105
|
+
end
|
|
2106
|
+
end
|