haml-edge 2.3.179 → 2.3.180
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.
- data/EDGE_GEM_VERSION +1 -1
- data/README.md +88 -149
- data/VERSION +1 -1
- data/bin/css2sass +7 -1
- data/bin/sass-convert +7 -0
- data/lib/haml/exec.rb +95 -22
- data/lib/haml/template.rb +1 -1
- data/lib/haml/util.rb +50 -0
- data/lib/sass.rb +1 -1
- data/lib/sass/css.rb +38 -210
- data/lib/sass/engine.rb +121 -47
- data/lib/sass/files.rb +28 -19
- data/lib/sass/plugin.rb +32 -43
- data/lib/sass/repl.rb +1 -1
- data/lib/sass/script.rb +25 -6
- data/lib/sass/script/bool.rb +1 -0
- data/lib/sass/script/color.rb +2 -2
- data/lib/sass/script/css_lexer.rb +22 -0
- data/lib/sass/script/css_parser.rb +28 -0
- data/lib/sass/script/funcall.rb +17 -9
- data/lib/sass/script/functions.rb +46 -1
- data/lib/sass/script/interpolation.rb +42 -0
- data/lib/sass/script/lexer.rb +142 -34
- data/lib/sass/script/literal.rb +28 -12
- data/lib/sass/script/node.rb +57 -1
- data/lib/sass/script/number.rb +18 -3
- data/lib/sass/script/operation.rb +44 -8
- data/lib/sass/script/parser.rb +149 -24
- data/lib/sass/script/string.rb +50 -2
- data/lib/sass/script/unary_operation.rb +25 -10
- data/lib/sass/script/variable.rb +20 -11
- data/lib/sass/scss.rb +14 -0
- data/lib/sass/scss/css_parser.rb +39 -0
- data/lib/sass/scss/parser.rb +683 -0
- data/lib/sass/scss/rx.rb +112 -0
- data/lib/sass/scss/script_lexer.rb +13 -0
- data/lib/sass/scss/script_parser.rb +25 -0
- data/lib/sass/tree/comment_node.rb +58 -16
- data/lib/sass/tree/debug_node.rb +7 -2
- data/lib/sass/tree/directive_node.rb +38 -34
- data/lib/sass/tree/for_node.rb +6 -0
- data/lib/sass/tree/if_node.rb +13 -0
- data/lib/sass/tree/import_node.rb +26 -7
- data/lib/sass/tree/mixin_def_node.rb +18 -0
- data/lib/sass/tree/mixin_node.rb +16 -1
- data/lib/sass/tree/node.rb +98 -27
- data/lib/sass/tree/prop_node.rb +97 -20
- data/lib/sass/tree/root_node.rb +37 -0
- data/lib/sass/tree/rule_node.rb +88 -60
- data/lib/sass/tree/variable_node.rb +9 -5
- data/lib/sass/tree/while_node.rb +4 -0
- data/test/haml/results/filters.xhtml +1 -1
- data/test/haml/util_test.rb +28 -0
- data/test/sass/conversion_test.rb +884 -0
- data/test/sass/css2sass_test.rb +46 -21
- data/test/sass/engine_test.rb +680 -160
- data/test/sass/functions_test.rb +27 -0
- data/test/sass/more_results/more_import.css +1 -1
- data/test/sass/more_templates/more_import.sass +3 -3
- data/test/sass/plugin_test.rb +28 -8
- data/test/sass/results/compact.css +1 -1
- data/test/sass/results/complex.css +5 -5
- data/test/sass/results/compressed.css +1 -1
- data/test/sass/results/expanded.css +1 -1
- data/test/sass/results/import.css +3 -1
- data/test/sass/results/mixins.css +12 -12
- data/test/sass/results/nested.css +1 -1
- data/test/sass/results/parent_ref.css +4 -4
- data/test/sass/results/script.css +3 -3
- data/test/sass/results/scss_import.css +15 -0
- data/test/sass/results/scss_importee.css +2 -0
- data/test/sass/script_conversion_test.rb +153 -0
- data/test/sass/script_test.rb +44 -54
- data/test/sass/scss/css_test.rb +811 -0
- data/test/sass/scss/rx_test.rb +156 -0
- data/test/sass/scss/scss_test.rb +871 -0
- data/test/sass/scss/test_helper.rb +37 -0
- data/test/sass/templates/alt.sass +2 -2
- data/test/sass/templates/bork1.sass +1 -1
- data/test/sass/templates/import.sass +4 -4
- data/test/sass/templates/importee.sass +3 -3
- data/test/sass/templates/line_numbers.sass +1 -1
- data/test/sass/templates/mixins.sass +2 -2
- data/test/sass/templates/nested_mixin_bork.sass +1 -1
- data/test/sass/templates/options.sass +1 -1
- data/test/sass/templates/parent_ref.sass +2 -2
- data/test/sass/templates/script.sass +69 -69
- data/test/sass/templates/scss_import.scss +10 -0
- data/test/sass/templates/scss_importee.scss +1 -0
- data/test/sass/templates/units.sass +10 -10
- data/test/test_helper.rb +4 -4
- metadata +27 -2
data/test/sass/script_test.rb
CHANGED
@@ -92,11 +92,9 @@ class SassScriptTest < Test::Unit::TestCase
|
|
92
92
|
end
|
93
93
|
|
94
94
|
def test_implicit_strings
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
assert_equal Sass::Script::String.new("foo/bar"), eval("foo/bar")
|
99
|
-
end
|
95
|
+
assert_equal Sass::Script::String.new("foo"), eval("foo")
|
96
|
+
assert_equal Sass::Script::String.new("foo bar"), eval("foo bar")
|
97
|
+
assert_equal Sass::Script::String.new("foo/bar"), eval("foo/bar")
|
100
98
|
end
|
101
99
|
|
102
100
|
def test_interpolation
|
@@ -130,50 +128,14 @@ foo \#{"\\\#{" + "baz"} bang
|
|
130
128
|
SASS
|
131
129
|
end
|
132
130
|
|
133
|
-
def test_implicit_string_warning
|
134
|
-
assert_warning(<<WARN) {eval("foo")}
|
135
|
-
DEPRECATION WARNING:
|
136
|
-
On line 1, character 1 of 'test_implicit_string_warning_inline.sass'
|
137
|
-
Implicit strings have been deprecated and will be removed in version 3.0.
|
138
|
-
'foo' was not quoted. Please add double quotes (e.g. "foo").
|
139
|
-
WARN
|
140
|
-
assert_warning(<<WARN) {eval("1 + foo")}
|
141
|
-
DEPRECATION WARNING:
|
142
|
-
On line 1, character 5 of 'test_implicit_string_warning_inline.sass'
|
143
|
-
Implicit strings have been deprecated and will be removed in version 3.0.
|
144
|
-
'foo' was not quoted. Please add double quotes (e.g. "foo").
|
145
|
-
WARN
|
146
|
-
assert_warning(<<WARN) {render("@if 1 + foo")}
|
147
|
-
DEPRECATION WARNING:
|
148
|
-
On line 1, character 9 of 'test_implicit_string_warning_inline.sass'
|
149
|
-
Implicit strings have been deprecated and will be removed in version 3.0.
|
150
|
-
'foo' was not quoted. Please add double quotes (e.g. "foo").
|
151
|
-
WARN
|
152
|
-
|
153
|
-
# Regression
|
154
|
-
assert_warning(<<WARN) {render("@if if")}
|
155
|
-
DEPRECATION WARNING:
|
156
|
-
On line 1, character 5 of 'test_implicit_string_warning_inline.sass'
|
157
|
-
Implicit strings have been deprecated and will be removed in version 3.0.
|
158
|
-
'if' was not quoted. Please add double quotes (e.g. "if").
|
159
|
-
WARN
|
160
|
-
end
|
161
|
-
|
162
131
|
def test_inaccessible_functions
|
163
|
-
|
164
|
-
DEPRECATION WARNING:
|
165
|
-
On line 2, character 6 of 'test_inaccessible_functions_inline.sass'
|
166
|
-
Implicit strings have been deprecated and will be removed in version 3.0.
|
167
|
-
'to_s' was not quoted. Please add double quotes (e.g. "to_s").
|
168
|
-
WARN
|
169
|
-
assert_equal "send(to_s)", resolve("send(to_s)", :line => 2)
|
170
|
-
end
|
132
|
+
assert_equal "send(to_s)", resolve("send(to_s)", :line => 2)
|
171
133
|
assert_equal "public_instance_methods()", resolve("public_instance_methods()")
|
172
134
|
end
|
173
135
|
|
174
136
|
def test_default_functions
|
175
137
|
assert_equal "url(12)", resolve("url(12)")
|
176
|
-
assert_equal 'blam(foo)', resolve('blam("foo")')
|
138
|
+
assert_equal 'blam("foo")', resolve('blam("foo")')
|
177
139
|
end
|
178
140
|
|
179
141
|
def test_function_results_have_options
|
@@ -182,7 +144,7 @@ WARN
|
|
182
144
|
end
|
183
145
|
|
184
146
|
def test_hyphenated_variables
|
185
|
-
assert_equal("a-b", resolve("
|
147
|
+
assert_equal("a-b", resolve("$a-b", {}, env("a-b" => Sass::Script::String.new("a-b"))))
|
186
148
|
end
|
187
149
|
|
188
150
|
def test_ruby_equality
|
@@ -220,27 +182,27 @@ WARN
|
|
220
182
|
assert_equal "2", resolve("1 + 1")
|
221
183
|
assert_equal "0", resolve("1 - 1")
|
222
184
|
assert_equal "8", resolve("2 * 4")
|
223
|
-
assert_equal "0.5", resolve("2 / 4")
|
224
|
-
assert_equal "2", resolve("4 / 2")
|
185
|
+
assert_equal "0.5", resolve("(2 / 4)")
|
186
|
+
assert_equal "2", resolve("(4 / 2)")
|
225
187
|
|
226
188
|
assert_equal "-1", resolve("-1")
|
227
189
|
end
|
228
190
|
|
229
191
|
def test_string_ops
|
230
|
-
assert_equal "foo bar", resolve('"foo" "bar"')
|
192
|
+
assert_equal '"foo" "bar"', resolve('"foo" "bar"')
|
231
193
|
assert_equal "true 1", resolve('true 1')
|
232
|
-
assert_equal "foo, bar", resolve("'foo' , 'bar'")
|
194
|
+
assert_equal '"foo", "bar"', resolve("'foo' , 'bar'")
|
233
195
|
assert_equal "true, 1", resolve('true , 1')
|
234
196
|
assert_equal "foobar", resolve('"foo" + "bar"')
|
235
197
|
assert_equal "true1", resolve('true + 1')
|
236
|
-
assert_equal "foo-bar", resolve("'foo' - 'bar'")
|
198
|
+
assert_equal '"foo"-"bar"', resolve("'foo' - 'bar'")
|
237
199
|
assert_equal "true-1", resolve('true - 1')
|
238
|
-
assert_equal "foo/bar", resolve('"foo" / "bar"')
|
200
|
+
assert_equal '"foo"/"bar"', resolve('"foo" / "bar"')
|
239
201
|
assert_equal "true/1", resolve('true / 1')
|
240
202
|
|
241
|
-
assert_equal "
|
203
|
+
assert_equal '-"bar"', resolve("- 'bar'")
|
242
204
|
assert_equal "-true", resolve('- true')
|
243
|
-
assert_equal "
|
205
|
+
assert_equal '/"bar"', resolve('/ "bar"')
|
244
206
|
assert_equal "/true", resolve('/ true')
|
245
207
|
end
|
246
208
|
|
@@ -260,7 +222,7 @@ WARN
|
|
260
222
|
end
|
261
223
|
|
262
224
|
def test_equals
|
263
|
-
assert_equal("true", resolve('"foo" ==
|
225
|
+
assert_equal("true", resolve('"foo" == $foo', {},
|
264
226
|
env("foo" => Sass::Script::String.new("foo"))))
|
265
227
|
assert_equal "true", resolve("1 == 1.0")
|
266
228
|
assert_equal "true", resolve("false != true")
|
@@ -295,6 +257,33 @@ WARN
|
|
295
257
|
assert_equal "Options defined!", resolve("assert_options('bar' + 'baz')")
|
296
258
|
end
|
297
259
|
|
260
|
+
def test_slash_compiles_literally_when_left_alone
|
261
|
+
assert_equal "1px/2px", resolve("1px/2px")
|
262
|
+
assert_equal "1px/2px/3px/4px", resolve("1px/2px/3px/4px")
|
263
|
+
|
264
|
+
assert_equal "1px/2px redpx bluepx", resolve("1px/2px redpx bluepx")
|
265
|
+
assert_equal "foo 1px/2px/3px bar", resolve("foo 1px/2px/3px bar")
|
266
|
+
end
|
267
|
+
|
268
|
+
def test_slash_divides_with_parens
|
269
|
+
assert_equal "0.5", resolve("(1px/2px)")
|
270
|
+
assert_equal "0.5", resolve("(1px)/2px")
|
271
|
+
assert_equal "0.5", resolve("1px/(2px)")
|
272
|
+
end
|
273
|
+
|
274
|
+
def test_slash_divides_with_other_arithmetic
|
275
|
+
assert_equal "0.5px", resolve("1px*1px/2px")
|
276
|
+
assert_equal "0.5px", resolve("1px/2px*1px")
|
277
|
+
assert_equal "0.5", resolve("0+1px/2px")
|
278
|
+
assert_equal "0.5", resolve("1px/2px+0")
|
279
|
+
end
|
280
|
+
|
281
|
+
def test_slash_divides_with_variable
|
282
|
+
assert_equal "0.5", resolve("$var/2px", {}, env("var" => eval("1px")))
|
283
|
+
assert_equal "0.5", resolve("1px/$var", {}, env("var" => eval("2px")))
|
284
|
+
assert_equal "0.5", resolve("$var", {}, env("var" => eval("1px/2px")))
|
285
|
+
end
|
286
|
+
|
298
287
|
# Regression Tests
|
299
288
|
|
300
289
|
def test_funcall_has_higher_precedence_than_color_name
|
@@ -312,7 +301,8 @@ WARN
|
|
312
301
|
|
313
302
|
def resolve(str, opts = {}, environment = env)
|
314
303
|
munge_filename opts
|
315
|
-
eval(str, opts, environment)
|
304
|
+
val = eval(str, opts, environment)
|
305
|
+
val.is_a?(Sass::Script::String) ? val.value : val.to_s
|
316
306
|
end
|
317
307
|
|
318
308
|
def eval(str, opts = {}, environment = env)
|
@@ -0,0 +1,811 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
require File.dirname(__FILE__) + '/test_helper'
|
4
|
+
require 'sass/scss/css_parser'
|
5
|
+
|
6
|
+
# These tests just test the parsing of CSS
|
7
|
+
# (both standard and any hacks we intend to support).
|
8
|
+
# Tests of SCSS-specific behavior go in scss_test.rb.
|
9
|
+
class ScssCssTest < Test::Unit::TestCase
|
10
|
+
include ScssTestHelper
|
11
|
+
|
12
|
+
def test_basic_scss
|
13
|
+
assert_parses <<SCSS
|
14
|
+
selector {
|
15
|
+
property: value;
|
16
|
+
property2: value; }
|
17
|
+
SCSS
|
18
|
+
|
19
|
+
assert_equal <<CSS, render('sel{p:v}')
|
20
|
+
sel {
|
21
|
+
p: v; }
|
22
|
+
CSS
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_empty_rule
|
26
|
+
assert_equal "", render("#foo .bar {}")
|
27
|
+
assert_equal "", render(<<SCSS)
|
28
|
+
#foo .bar {
|
29
|
+
}
|
30
|
+
SCSS
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_cdo_and_cdc_ignored_at_toplevel
|
34
|
+
assert_equal <<CSS, render(<<SCSS)
|
35
|
+
foo {
|
36
|
+
bar: baz; }
|
37
|
+
|
38
|
+
bar {
|
39
|
+
bar: baz; }
|
40
|
+
|
41
|
+
baz {
|
42
|
+
bar: baz; }
|
43
|
+
CSS
|
44
|
+
foo {bar: baz}
|
45
|
+
<!--
|
46
|
+
bar {bar: baz}
|
47
|
+
-->
|
48
|
+
baz {bar: baz}
|
49
|
+
SCSS
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_unicode
|
53
|
+
assert_parses <<SCSS
|
54
|
+
foo {
|
55
|
+
bar: föö bâr; }
|
56
|
+
SCSS
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_invisible_comments
|
60
|
+
assert_equal <<CSS, render(<<SCSS)
|
61
|
+
foo {
|
62
|
+
a: d; }
|
63
|
+
CSS
|
64
|
+
foo {a: /* b; c: */ d}
|
65
|
+
SCSS
|
66
|
+
assert_equal <<CSS, render(<<SCSS)
|
67
|
+
foo {
|
68
|
+
a: d; }
|
69
|
+
CSS
|
70
|
+
foo {a /*: b; c */: d}
|
71
|
+
SCSS
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_crazy_comments
|
75
|
+
# http://www.w3.org/Style/CSS/Test/CSS2.1/current/xhtml1/t040109-c17-comments-00-b.xht
|
76
|
+
assert_equal <<CSS, render(<<SCSS)
|
77
|
+
/* This is a CSS comment. */
|
78
|
+
.one {
|
79
|
+
color: green; }
|
80
|
+
|
81
|
+
/* Another comment */
|
82
|
+
/* The following should not be used:
|
83
|
+
.two {color: red;} */
|
84
|
+
.three {
|
85
|
+
color: green;
|
86
|
+
/* color: red; */ }
|
87
|
+
|
88
|
+
/**
|
89
|
+
.four {color: red;} */
|
90
|
+
.five {
|
91
|
+
color: green; }
|
92
|
+
|
93
|
+
/**/
|
94
|
+
.six {
|
95
|
+
color: green; }
|
96
|
+
|
97
|
+
/*********/
|
98
|
+
.seven {
|
99
|
+
color: green; }
|
100
|
+
|
101
|
+
/* a comment **/
|
102
|
+
.eight {
|
103
|
+
color: green; }
|
104
|
+
CSS
|
105
|
+
/* This is a CSS comment. */
|
106
|
+
.one {color: green;} /* Another comment */
|
107
|
+
/* The following should not be used:
|
108
|
+
.two {color: red;} */
|
109
|
+
.three {color: green; /* color: red; */}
|
110
|
+
/**
|
111
|
+
.four {color: red;} */
|
112
|
+
.five {color: green;}
|
113
|
+
/**/
|
114
|
+
.six {color: green;}
|
115
|
+
/*********/
|
116
|
+
.seven {color: green;}
|
117
|
+
/* a comment **/
|
118
|
+
.eight {color: green;}
|
119
|
+
SCSS
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_rule_comments
|
123
|
+
assert_parses <<SCSS
|
124
|
+
/* Foo */
|
125
|
+
.foo {
|
126
|
+
a: b; }
|
127
|
+
SCSS
|
128
|
+
assert_equal <<CSS, render(<<SCSS)
|
129
|
+
/* Foo
|
130
|
+
* Bar */
|
131
|
+
.foo {
|
132
|
+
a: b; }
|
133
|
+
CSS
|
134
|
+
/* Foo
|
135
|
+
* Bar */.foo {
|
136
|
+
a: b; }
|
137
|
+
SCSS
|
138
|
+
end
|
139
|
+
|
140
|
+
def test_property_comments
|
141
|
+
assert_parses <<SCSS
|
142
|
+
.foo {
|
143
|
+
/* Foo */
|
144
|
+
a: b; }
|
145
|
+
SCSS
|
146
|
+
assert_equal <<CSS, render(<<SCSS)
|
147
|
+
.foo {
|
148
|
+
/* Foo
|
149
|
+
* Bar */
|
150
|
+
a: b; }
|
151
|
+
CSS
|
152
|
+
.foo {
|
153
|
+
/* Foo
|
154
|
+
* Bar */a: b; }
|
155
|
+
SCSS
|
156
|
+
end
|
157
|
+
|
158
|
+
def test_selector_comments
|
159
|
+
assert_equal <<CSS, render(<<SCSS)
|
160
|
+
.foo #bar:baz( bip) {
|
161
|
+
a: b; }
|
162
|
+
CSS
|
163
|
+
.foo /* .a #foo */ #bar:baz(/* bang )*/ bip) {
|
164
|
+
a: b; }
|
165
|
+
SCSS
|
166
|
+
end
|
167
|
+
|
168
|
+
def test_lonely_comments
|
169
|
+
assert_parses <<SCSS
|
170
|
+
/* Foo
|
171
|
+
* Bar */
|
172
|
+
SCSS
|
173
|
+
assert_parses <<SCSS
|
174
|
+
.foo {
|
175
|
+
/* Foo
|
176
|
+
* Bar */ }
|
177
|
+
SCSS
|
178
|
+
end
|
179
|
+
|
180
|
+
def test_multiple_comments
|
181
|
+
assert_parses <<SCSS
|
182
|
+
/* Foo
|
183
|
+
* Bar */
|
184
|
+
/* Baz
|
185
|
+
* Bang */
|
186
|
+
SCSS
|
187
|
+
assert_parses <<SCSS
|
188
|
+
.foo {
|
189
|
+
/* Foo
|
190
|
+
* Bar */
|
191
|
+
/* Baz
|
192
|
+
* Bang */ }
|
193
|
+
SCSS
|
194
|
+
assert_equal <<CSS, render(<<SCSS)
|
195
|
+
.foo {
|
196
|
+
/* Foo Bar */
|
197
|
+
/* Baz Bang */ }
|
198
|
+
CSS
|
199
|
+
.foo {
|
200
|
+
/* Foo Bar *//* Baz Bang */ }
|
201
|
+
SCSS
|
202
|
+
end
|
203
|
+
|
204
|
+
def test_bizarrely_formatted_comments
|
205
|
+
assert_parses <<SCSS
|
206
|
+
.foo {
|
207
|
+
/* Foo
|
208
|
+
Bar
|
209
|
+
Baz */
|
210
|
+
a: b; }
|
211
|
+
SCSS
|
212
|
+
assert_parses <<SCSS
|
213
|
+
.foo {
|
214
|
+
/* Foo
|
215
|
+
Bar
|
216
|
+
Baz */
|
217
|
+
a: b; }
|
218
|
+
SCSS
|
219
|
+
assert_equal <<CSS, render(<<SCSS)
|
220
|
+
.foo {
|
221
|
+
/* Foo
|
222
|
+
Bar */
|
223
|
+
a: b; }
|
224
|
+
CSS
|
225
|
+
.foo {/* Foo
|
226
|
+
Bar */
|
227
|
+
a: b; }
|
228
|
+
SCSS
|
229
|
+
assert_equal <<CSS, render(<<SCSS)
|
230
|
+
.foo {
|
231
|
+
/* Foo
|
232
|
+
Bar
|
233
|
+
Baz */
|
234
|
+
a: b; }
|
235
|
+
CSS
|
236
|
+
.foo {/* Foo
|
237
|
+
Bar
|
238
|
+
Baz */
|
239
|
+
a: b; }
|
240
|
+
SCSS
|
241
|
+
end
|
242
|
+
|
243
|
+
## Declarations
|
244
|
+
|
245
|
+
def test_vendor_properties
|
246
|
+
assert_parses <<SCSS
|
247
|
+
foo {
|
248
|
+
-moz-foo-bar: blat;
|
249
|
+
-o-flat-blang: wibble; }
|
250
|
+
SCSS
|
251
|
+
end
|
252
|
+
|
253
|
+
def test_empty_declarations
|
254
|
+
assert_equal <<CSS, render(<<SCSS)
|
255
|
+
foo {
|
256
|
+
bar: baz; }
|
257
|
+
CSS
|
258
|
+
foo {;;;;
|
259
|
+
bar: baz;;;;
|
260
|
+
;;}
|
261
|
+
SCSS
|
262
|
+
end
|
263
|
+
|
264
|
+
def test_basic_property_types
|
265
|
+
assert_parses <<SCSS
|
266
|
+
foo {
|
267
|
+
a: 2;
|
268
|
+
b: 2.3em;
|
269
|
+
c: 50%;
|
270
|
+
d: "fraz bran";
|
271
|
+
e: flanny-blanny-blan;
|
272
|
+
f: url(http://sass-lang.com);
|
273
|
+
g: U+ffa?;
|
274
|
+
h: #aabbcc; }
|
275
|
+
SCSS
|
276
|
+
end
|
277
|
+
|
278
|
+
def test_functions
|
279
|
+
assert_parses <<SCSS
|
280
|
+
foo {
|
281
|
+
a: foo-bar(12);
|
282
|
+
b: -foo-bar-baz(13, 14 15); }
|
283
|
+
SCSS
|
284
|
+
end
|
285
|
+
|
286
|
+
def test_unary_minus
|
287
|
+
assert_parses <<SCSS
|
288
|
+
foo {
|
289
|
+
a: -2;
|
290
|
+
b: -2.3em;
|
291
|
+
c: -50%;
|
292
|
+
d: -foo(bar baz); }
|
293
|
+
SCSS
|
294
|
+
end
|
295
|
+
|
296
|
+
def test_operators
|
297
|
+
assert_parses <<SCSS
|
298
|
+
foo {
|
299
|
+
a: foo bar baz;
|
300
|
+
b: foo, #aabbcc, -12;
|
301
|
+
c: 1px/2px/-3px;
|
302
|
+
d: foo bar, baz/bang; }
|
303
|
+
SCSS
|
304
|
+
end
|
305
|
+
|
306
|
+
def test_important
|
307
|
+
assert_parses <<SCSS
|
308
|
+
foo {
|
309
|
+
a: foo !important;
|
310
|
+
b: foo bar !important;
|
311
|
+
b: foo, bar !important; }
|
312
|
+
SCSS
|
313
|
+
end
|
314
|
+
|
315
|
+
def test_initial_hyphen
|
316
|
+
assert_parses <<SCSS
|
317
|
+
foo {
|
318
|
+
a: -moz-bar-baz;
|
319
|
+
b: foo -o-bar-baz; }
|
320
|
+
SCSS
|
321
|
+
end
|
322
|
+
|
323
|
+
def test_ms_filter_syntax
|
324
|
+
assert_equal <<CSS, render(<<SCSS)
|
325
|
+
foo {
|
326
|
+
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=1, startColorstr=#c0ff3300, endColorstr=#ff000000);
|
327
|
+
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=1, startColorstr=#c0ff3300, endColorstr=#ff000000); }
|
328
|
+
CSS
|
329
|
+
foo {
|
330
|
+
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=1, startColorstr=#c0ff3300, endColorstr=#ff000000);
|
331
|
+
filter:progid:DXImageTransform.Microsoft.gradient(GradientType=1, startColorstr=#c0ff3300, endColorstr=#ff000000); }
|
332
|
+
SCSS
|
333
|
+
end
|
334
|
+
|
335
|
+
def test_declaration_hacks
|
336
|
+
assert_parses <<SCSS
|
337
|
+
foo {
|
338
|
+
_name: val;
|
339
|
+
*name: val;
|
340
|
+
:name: val;
|
341
|
+
.name: val;
|
342
|
+
name: val; }
|
343
|
+
SCSS
|
344
|
+
end
|
345
|
+
|
346
|
+
def test_zero_arg_functions
|
347
|
+
assert_parses <<SCSS
|
348
|
+
foo {
|
349
|
+
a: foo();
|
350
|
+
b: bar baz-bang() bip; }
|
351
|
+
SCSS
|
352
|
+
end
|
353
|
+
|
354
|
+
def test_expression_function
|
355
|
+
assert_parses <<SCSS
|
356
|
+
foo {
|
357
|
+
a: 12px expression(1 + (3 / Foo.bar("baz" + "bang") + function() {return 12;}) % 12); }
|
358
|
+
SCSS
|
359
|
+
end
|
360
|
+
|
361
|
+
def test_calc_function
|
362
|
+
assert_parses <<SCSS
|
363
|
+
foo {
|
364
|
+
a: 12px calc(100%/3 - 2*1em - 2*1px); }
|
365
|
+
SCSS
|
366
|
+
end
|
367
|
+
|
368
|
+
def test_unary_ops
|
369
|
+
assert_equal <<CSS, render(<<SCSS)
|
370
|
+
foo {
|
371
|
+
a: -0.5em;
|
372
|
+
b: 0.5em;
|
373
|
+
c: -foo(12px);
|
374
|
+
d: +foo(12px); }
|
375
|
+
CSS
|
376
|
+
foo {
|
377
|
+
a: -0.5em;
|
378
|
+
b: +0.5em;
|
379
|
+
c: -foo(12px);
|
380
|
+
d: +foo(12px); }
|
381
|
+
SCSS
|
382
|
+
end
|
383
|
+
|
384
|
+
## Directives
|
385
|
+
|
386
|
+
def test_charset_directive
|
387
|
+
assert_parses '@charset "utf-8";'
|
388
|
+
end
|
389
|
+
|
390
|
+
def test_namespace_directive
|
391
|
+
assert_parses '@namespace "http://www.w3.org/Profiles/xhtml1-strict";'
|
392
|
+
assert_parses '@namespace url(http://www.w3.org/Profiles/xhtml1-strict);'
|
393
|
+
assert_parses '@namespace html url("http://www.w3.org/Profiles/xhtml1-strict");'
|
394
|
+
end
|
395
|
+
|
396
|
+
def test_media_directive
|
397
|
+
assert_parses <<SCSS
|
398
|
+
@media all {
|
399
|
+
rule1 {
|
400
|
+
prop: val; }
|
401
|
+
|
402
|
+
rule2 {
|
403
|
+
prop: val; } }
|
404
|
+
SCSS
|
405
|
+
assert_parses <<SCSS
|
406
|
+
@media screen, print {
|
407
|
+
rule1 {
|
408
|
+
prop: val; }
|
409
|
+
|
410
|
+
rule2 {
|
411
|
+
prop: val; } }
|
412
|
+
SCSS
|
413
|
+
end
|
414
|
+
|
415
|
+
def test_media_directive_with_keywords
|
416
|
+
assert_parses <<SCSS
|
417
|
+
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
418
|
+
a: b; }
|
419
|
+
SCSS
|
420
|
+
assert_parses <<SCSS
|
421
|
+
@media only screen, print and (foo: 0px) and (bar: flam(12px solid)) {
|
422
|
+
a: b; }
|
423
|
+
SCSS
|
424
|
+
end
|
425
|
+
|
426
|
+
def test_import_directive
|
427
|
+
assert_parses '@import "foo.css";'
|
428
|
+
assert_parses "@import 'foo.css';"
|
429
|
+
assert_parses '@import url("foo.css");'
|
430
|
+
assert_parses "@import url('foo.css');"
|
431
|
+
assert_parses '@import url(foo.css);'
|
432
|
+
end
|
433
|
+
|
434
|
+
def test_import_directive_with_media
|
435
|
+
assert_parses '@import "foo.css" screen;'
|
436
|
+
assert_parses '@import "foo.css" screen, print;'
|
437
|
+
assert_parses '@import "foo.css" screen, print and (foo: 0);'
|
438
|
+
assert_parses '@import "foo.css" screen, only print, screen and (foo: 0);'
|
439
|
+
end
|
440
|
+
|
441
|
+
def test_page_directive
|
442
|
+
assert_parses <<SCSS
|
443
|
+
@page {
|
444
|
+
prop1: val;
|
445
|
+
prop2: val; }
|
446
|
+
SCSS
|
447
|
+
assert_parses <<SCSS
|
448
|
+
@page flap {
|
449
|
+
prop1: val;
|
450
|
+
prop2: val; }
|
451
|
+
SCSS
|
452
|
+
assert_parses <<SCSS
|
453
|
+
@page :first {
|
454
|
+
prop1: val;
|
455
|
+
prop2: val; }
|
456
|
+
SCSS
|
457
|
+
assert_parses <<SCSS
|
458
|
+
@page flap:first {
|
459
|
+
prop1: val;
|
460
|
+
prop2: val; }
|
461
|
+
SCSS
|
462
|
+
end
|
463
|
+
|
464
|
+
def test_blockless_directive_without_semicolon
|
465
|
+
assert_equal "@charset \"utf-8\";\n", render('@charset "utf-8"')
|
466
|
+
end
|
467
|
+
|
468
|
+
def test_directive_with_lots_of_whitespace
|
469
|
+
assert_equal "@charset \"utf-16\";\n", render('@charset "utf-16" ;')
|
470
|
+
end
|
471
|
+
|
472
|
+
def test_empty_blockless_directive
|
473
|
+
assert_parses "@foo;"
|
474
|
+
end
|
475
|
+
|
476
|
+
def test_multiple_blockless_directives
|
477
|
+
assert_parses <<SCSS
|
478
|
+
@foo bar;
|
479
|
+
@bar baz;
|
480
|
+
SCSS
|
481
|
+
end
|
482
|
+
|
483
|
+
def test_empty_block_directive
|
484
|
+
assert_parses "@foo {}"
|
485
|
+
assert_equal "@foo {}\n", render(<<SCSS)
|
486
|
+
@foo {
|
487
|
+
}
|
488
|
+
SCSS
|
489
|
+
end
|
490
|
+
|
491
|
+
def test_multiple_block_directives
|
492
|
+
assert_parses <<SCSS
|
493
|
+
@foo bar {
|
494
|
+
a: b; }
|
495
|
+
|
496
|
+
@bar baz {
|
497
|
+
c: d; }
|
498
|
+
SCSS
|
499
|
+
end
|
500
|
+
|
501
|
+
def test_block_directive_with_rule_and_property
|
502
|
+
assert_parses <<SCSS
|
503
|
+
@foo {
|
504
|
+
rule {
|
505
|
+
a: b; }
|
506
|
+
|
507
|
+
a: b; }
|
508
|
+
SCSS
|
509
|
+
end
|
510
|
+
|
511
|
+
def test_block_directive_with_semicolon
|
512
|
+
assert_equal <<CSS, render(<<SCSS)
|
513
|
+
@foo {
|
514
|
+
a: b; }
|
515
|
+
|
516
|
+
@bar {
|
517
|
+
a: b; }
|
518
|
+
CSS
|
519
|
+
@foo {a:b};
|
520
|
+
@bar {a:b};
|
521
|
+
SCSS
|
522
|
+
end
|
523
|
+
|
524
|
+
## Selectors
|
525
|
+
|
526
|
+
# Taken from http://www.w3.org/TR/css3-selectors/#selectors
|
527
|
+
def test_summarized_selectors
|
528
|
+
assert_selector_parses('*')
|
529
|
+
assert_selector_parses('E')
|
530
|
+
assert_selector_parses('E[foo]')
|
531
|
+
assert_selector_parses('E[foo="bar"]')
|
532
|
+
assert_selector_parses('E[foo~="bar"]')
|
533
|
+
assert_selector_parses('E[foo^="bar"]')
|
534
|
+
assert_selector_parses('E[foo$="bar"]')
|
535
|
+
assert_selector_parses('E[foo*="bar"]')
|
536
|
+
assert_selector_parses('E[foo|="en"]')
|
537
|
+
assert_selector_parses('E:root')
|
538
|
+
assert_selector_parses('E:nth-child(n)')
|
539
|
+
assert_selector_parses('E:nth-last-child(n)')
|
540
|
+
assert_selector_parses('E:nth-of-type(n)')
|
541
|
+
assert_selector_parses('E:nth-last-of-type(n)')
|
542
|
+
assert_selector_parses('E:first-child')
|
543
|
+
assert_selector_parses('E:last-child')
|
544
|
+
assert_selector_parses('E:first-of-type')
|
545
|
+
assert_selector_parses('E:last-of-type')
|
546
|
+
assert_selector_parses('E:only-child')
|
547
|
+
assert_selector_parses('E:only-of-type')
|
548
|
+
assert_selector_parses('E:empty')
|
549
|
+
assert_selector_parses('E:link')
|
550
|
+
assert_selector_parses('E:visited')
|
551
|
+
assert_selector_parses('E:active')
|
552
|
+
assert_selector_parses('E:hover')
|
553
|
+
assert_selector_parses('E:focus')
|
554
|
+
assert_selector_parses('E:target')
|
555
|
+
assert_selector_parses('E:lang(fr)')
|
556
|
+
assert_selector_parses('E:enabled')
|
557
|
+
assert_selector_parses('E:disabled')
|
558
|
+
assert_selector_parses('E:checked')
|
559
|
+
assert_selector_parses('E::first-line')
|
560
|
+
assert_selector_parses('E::first-letter')
|
561
|
+
assert_selector_parses('E::before')
|
562
|
+
assert_selector_parses('E::after')
|
563
|
+
assert_selector_parses('E.warning')
|
564
|
+
assert_selector_parses('E#myid')
|
565
|
+
assert_selector_parses('E:not(s)')
|
566
|
+
assert_selector_parses('E F')
|
567
|
+
assert_selector_parses('E > F')
|
568
|
+
assert_selector_parses('E + F')
|
569
|
+
assert_selector_parses('E ~ F')
|
570
|
+
end
|
571
|
+
|
572
|
+
# Taken from http://www.w3.org/TR/css3-selectors/#selectors,
|
573
|
+
# but without the element names
|
574
|
+
def test_lonely_selectors
|
575
|
+
assert_selector_parses('[foo]')
|
576
|
+
assert_selector_parses('[foo="bar"]')
|
577
|
+
assert_selector_parses('[foo~="bar"]')
|
578
|
+
assert_selector_parses('[foo^="bar"]')
|
579
|
+
assert_selector_parses('[foo$="bar"]')
|
580
|
+
assert_selector_parses('[foo*="bar"]')
|
581
|
+
assert_selector_parses('[foo|="en"]')
|
582
|
+
assert_selector_parses(':root')
|
583
|
+
assert_selector_parses(':nth-child(n)')
|
584
|
+
assert_selector_parses(':nth-last-child(n)')
|
585
|
+
assert_selector_parses(':nth-of-type(n)')
|
586
|
+
assert_selector_parses(':nth-last-of-type(n)')
|
587
|
+
assert_selector_parses(':first-child')
|
588
|
+
assert_selector_parses(':last-child')
|
589
|
+
assert_selector_parses(':first-of-type')
|
590
|
+
assert_selector_parses(':last-of-type')
|
591
|
+
assert_selector_parses(':only-child')
|
592
|
+
assert_selector_parses(':only-of-type')
|
593
|
+
assert_selector_parses(':empty')
|
594
|
+
assert_selector_parses(':link')
|
595
|
+
assert_selector_parses(':visited')
|
596
|
+
assert_selector_parses(':active')
|
597
|
+
assert_selector_parses(':hover')
|
598
|
+
assert_selector_parses(':focus')
|
599
|
+
assert_selector_parses(':target')
|
600
|
+
assert_selector_parses(':lang(fr)')
|
601
|
+
assert_selector_parses(':enabled')
|
602
|
+
assert_selector_parses(':disabled')
|
603
|
+
assert_selector_parses(':checked')
|
604
|
+
assert_selector_parses('::first-line')
|
605
|
+
assert_selector_parses('::first-letter')
|
606
|
+
assert_selector_parses('::before')
|
607
|
+
assert_selector_parses('::after')
|
608
|
+
assert_selector_parses('.warning')
|
609
|
+
assert_selector_parses('#myid')
|
610
|
+
assert_selector_parses(':not(s)')
|
611
|
+
end
|
612
|
+
|
613
|
+
def test_attribute_selectors_with_identifiers
|
614
|
+
assert_selector_parses('[foo~=bar]')
|
615
|
+
assert_selector_parses('[foo^=bar]')
|
616
|
+
assert_selector_parses('[foo$=bar]')
|
617
|
+
assert_selector_parses('[foo*=bar]')
|
618
|
+
assert_selector_parses('[foo|=en]')
|
619
|
+
end
|
620
|
+
|
621
|
+
def test_nth_selectors
|
622
|
+
assert_selector_parses(':nth-child(-n)')
|
623
|
+
assert_selector_parses(':nth-child(+n)')
|
624
|
+
|
625
|
+
assert_selector_parses(':nth-child(even)')
|
626
|
+
assert_selector_parses(':nth-child(odd)')
|
627
|
+
|
628
|
+
assert_selector_parses(':nth-child(50)')
|
629
|
+
assert_selector_parses(':nth-child(-50)')
|
630
|
+
assert_selector_parses(':nth-child(+50)')
|
631
|
+
|
632
|
+
assert_selector_parses(':nth-child(2n+3)')
|
633
|
+
assert_selector_parses(':nth-child(2n-3)')
|
634
|
+
assert_selector_parses(':nth-child(+2n-3)')
|
635
|
+
assert_selector_parses(':nth-child(-2n+3)')
|
636
|
+
assert_selector_parses(':nth-child(-2n+ 3)')
|
637
|
+
assert_selector_parses(':nth-child( 2n + 3 )')
|
638
|
+
end
|
639
|
+
|
640
|
+
def test_negation_selectors
|
641
|
+
assert_selector_parses(':not(foo|bar)')
|
642
|
+
assert_selector_parses(':not(*|bar)')
|
643
|
+
|
644
|
+
assert_selector_parses(':not(foo|*)')
|
645
|
+
assert_selector_parses(':not(*|*)')
|
646
|
+
|
647
|
+
assert_selector_parses(':not(#blah)')
|
648
|
+
assert_selector_parses(':not(.blah)')
|
649
|
+
|
650
|
+
assert_selector_parses(':not([foo])')
|
651
|
+
assert_selector_parses(':not([foo^="bar"])')
|
652
|
+
assert_selector_parses(':not([baz|foo~="bar"])')
|
653
|
+
|
654
|
+
assert_selector_parses(':not(:hover)')
|
655
|
+
assert_selector_parses(':not(:nth-child(2n + 3))')
|
656
|
+
end
|
657
|
+
|
658
|
+
def test_namespaced_selectors
|
659
|
+
assert_selector_parses('foo|E')
|
660
|
+
assert_selector_parses('*|E')
|
661
|
+
assert_selector_parses('foo|*')
|
662
|
+
assert_selector_parses('*|*')
|
663
|
+
end
|
664
|
+
|
665
|
+
def test_namespaced_attribute_selectors
|
666
|
+
assert_selector_parses('[foo|bar=baz]')
|
667
|
+
assert_selector_parses('[*|bar=baz]')
|
668
|
+
assert_selector_parses('[foo|bar|=baz]')
|
669
|
+
end
|
670
|
+
|
671
|
+
def test_comma_selectors
|
672
|
+
assert_selector_parses('E, F')
|
673
|
+
assert_selector_parses('E F, G H')
|
674
|
+
assert_selector_parses('E > F, G > H')
|
675
|
+
end
|
676
|
+
|
677
|
+
def test_selectors_with_newlines
|
678
|
+
assert_selector_parses("E,\nF")
|
679
|
+
assert_selector_parses("E\nF")
|
680
|
+
assert_selector_parses("E, F\nG, H")
|
681
|
+
end
|
682
|
+
|
683
|
+
def test_expression_fallback_selectors
|
684
|
+
assert_selector_parses('0%')
|
685
|
+
assert_selector_parses('60%')
|
686
|
+
assert_selector_parses('100%')
|
687
|
+
assert_selector_parses('12px')
|
688
|
+
assert_selector_parses('"foo"')
|
689
|
+
end
|
690
|
+
|
691
|
+
def test_functional_pseudo_selectors
|
692
|
+
assert_selector_parses(':foo("bar")')
|
693
|
+
assert_selector_parses(':foo(bar)')
|
694
|
+
assert_selector_parses(':foo(12px)')
|
695
|
+
assert_selector_parses(':foo(+)')
|
696
|
+
assert_selector_parses(':foo(-)')
|
697
|
+
assert_selector_parses(':foo(+"bar")')
|
698
|
+
assert_selector_parses(':foo(-++--baz-"bar"12px)')
|
699
|
+
end
|
700
|
+
|
701
|
+
def test_selector_hacks
|
702
|
+
assert_selector_parses('> E')
|
703
|
+
assert_selector_parses('+ E')
|
704
|
+
assert_selector_parses('~ E')
|
705
|
+
assert_selector_parses('>> E')
|
706
|
+
|
707
|
+
assert_selector_parses('E*')
|
708
|
+
assert_selector_parses('E*.foo')
|
709
|
+
assert_selector_parses('E*:hover')
|
710
|
+
end
|
711
|
+
|
712
|
+
## Errors
|
713
|
+
|
714
|
+
def test_invalid_directives
|
715
|
+
assert_not_parses("identifier", '@<err> import "foo";')
|
716
|
+
assert_not_parses("identifier", '@<err>12 "foo";')
|
717
|
+
end
|
718
|
+
|
719
|
+
def test_invalid_classes
|
720
|
+
assert_not_parses("identifier", 'p.<err> foo {a: b}')
|
721
|
+
assert_not_parses("identifier", 'p.<err>1foo {a: b}')
|
722
|
+
end
|
723
|
+
|
724
|
+
def test_invalid_ids
|
725
|
+
assert_not_parses('"{"', 'p<err># foo {a: b}')
|
726
|
+
end
|
727
|
+
|
728
|
+
def test_no_properties_at_toplevel
|
729
|
+
assert_not_parses('pseudoclass or pseudoelement', 'a:<err> b;')
|
730
|
+
end
|
731
|
+
|
732
|
+
def test_no_scss_directives
|
733
|
+
assert_parses('@import "foo.sass";')
|
734
|
+
assert_parses <<SCSS
|
735
|
+
@mixin foo {
|
736
|
+
a: b; }
|
737
|
+
SCSS
|
738
|
+
end
|
739
|
+
|
740
|
+
def test_no_variables
|
741
|
+
assert_not_parses("selector or at-rule", "<err>$var = 12;")
|
742
|
+
assert_not_parses('"}"', "foo { <err>!var = 12; }")
|
743
|
+
end
|
744
|
+
|
745
|
+
def test_no_parent_selectors
|
746
|
+
assert_not_parses('"{"', "foo <err>&.bar {a: b}")
|
747
|
+
end
|
748
|
+
|
749
|
+
def test_no_selector_interpolation
|
750
|
+
assert_not_parses('"{"', 'foo <err>#{"bar"}.baz {a: b}')
|
751
|
+
end
|
752
|
+
|
753
|
+
def test_no_prop_name_interpolation
|
754
|
+
assert_not_parses('":"', 'foo {a<err>#{"bar"}baz: b}')
|
755
|
+
end
|
756
|
+
|
757
|
+
def test_no_prop_val_interpolation
|
758
|
+
assert_not_parses('"}"', 'foo {a: b <err>#{"bar"} c}')
|
759
|
+
end
|
760
|
+
|
761
|
+
def test_no_string_interpolation
|
762
|
+
assert_parses <<SCSS
|
763
|
+
foo {
|
764
|
+
a: "bang \#{1 + " bar "} bip"; }
|
765
|
+
SCSS
|
766
|
+
end
|
767
|
+
|
768
|
+
def test_no_sass_script_values
|
769
|
+
assert_not_parses('"}"', 'foo {a: b <err>* c}')
|
770
|
+
end
|
771
|
+
|
772
|
+
def test_no_nested_rules
|
773
|
+
assert_not_parses('":"', 'foo {bar <err>{a: b}}')
|
774
|
+
assert_not_parses('"}"', 'foo {<err>#bar {a: b}}')
|
775
|
+
end
|
776
|
+
|
777
|
+
def test_no_nested_properties
|
778
|
+
assert_not_parses('expression (e.g. 1px, bold)', 'foo {bar: <err>{a: b}}')
|
779
|
+
assert_not_parses('expression (e.g. 1px, bold)', 'foo {bar: bang <err>{a: b}}')
|
780
|
+
end
|
781
|
+
|
782
|
+
def test_no_nested_directives
|
783
|
+
assert_not_parses('"}"', 'foo {<err>@bar {a: b}}')
|
784
|
+
end
|
785
|
+
|
786
|
+
def test_error_with_windows_newlines
|
787
|
+
render <<SCSS
|
788
|
+
foo {bar}\r
|
789
|
+
baz {a: b}
|
790
|
+
SCSS
|
791
|
+
assert(false, "Expected syntax error")
|
792
|
+
rescue Sass::SyntaxError => e
|
793
|
+
assert_equal 'Invalid CSS after "foo {bar": expected ":", was "}"', e.message
|
794
|
+
assert_equal 1, e.sass_line
|
795
|
+
end
|
796
|
+
|
797
|
+
private
|
798
|
+
|
799
|
+
def assert_selector_parses(selector)
|
800
|
+
assert_parses <<SCSS
|
801
|
+
#{selector} {
|
802
|
+
a: b; }
|
803
|
+
SCSS
|
804
|
+
end
|
805
|
+
|
806
|
+
def render(scss, options = {})
|
807
|
+
tree = Sass::SCSS::CssParser.new(scss).parse
|
808
|
+
tree.options = Sass::Engine::DEFAULT_OPTIONS.merge(options)
|
809
|
+
tree.render
|
810
|
+
end
|
811
|
+
end
|