haml 2.2.24 → 3.0.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of haml might be problematic. Click here for more details.
- data/.yardopts +0 -1
- data/README.md +91 -151
- data/REMEMBER +11 -1
- data/Rakefile +73 -55
- data/VERSION +1 -1
- data/VERSION_NAME +1 -1
- data/bin/css2sass +7 -1
- data/bin/sass-convert +7 -0
- data/extra/haml-mode.el +2 -1
- data/lib/haml/buffer.rb +22 -4
- data/lib/haml/engine.rb +5 -1
- data/lib/haml/exec.rb +231 -46
- data/lib/haml/filters.rb +19 -8
- data/lib/haml/helpers.rb +47 -20
- data/lib/haml/helpers/action_view_extensions.rb +2 -4
- data/lib/haml/helpers/action_view_mods.rb +11 -8
- data/lib/haml/helpers/xss_mods.rb +13 -2
- data/lib/haml/html.rb +179 -48
- data/lib/haml/html/erb.rb +141 -0
- data/lib/haml/precompiler.rb +40 -15
- data/lib/haml/railtie.rb +1 -5
- data/lib/haml/root.rb +3 -0
- data/lib/haml/template.rb +4 -14
- data/lib/haml/util.rb +120 -30
- data/lib/haml/version.rb +25 -2
- data/lib/sass.rb +5 -1
- data/lib/sass/callbacks.rb +50 -0
- data/lib/sass/css.rb +40 -191
- data/lib/sass/engine.rb +170 -74
- data/lib/sass/environment.rb +8 -2
- data/lib/sass/error.rb +163 -25
- data/lib/sass/files.rb +31 -28
- data/lib/sass/plugin.rb +268 -87
- data/lib/sass/plugin/rails.rb +9 -4
- data/lib/sass/repl.rb +1 -1
- data/lib/sass/script.rb +31 -29
- data/lib/sass/script/bool.rb +1 -0
- data/lib/sass/script/color.rb +290 -23
- data/lib/sass/script/css_lexer.rb +22 -0
- data/lib/sass/script/css_parser.rb +28 -0
- data/lib/sass/script/funcall.rb +22 -3
- data/lib/sass/script/functions.rb +523 -33
- data/lib/sass/script/interpolation.rb +42 -0
- data/lib/sass/script/lexer.rb +169 -52
- data/lib/sass/script/literal.rb +58 -9
- data/lib/sass/script/node.rb +79 -1
- data/lib/sass/script/number.rb +20 -5
- data/lib/sass/script/operation.rb +49 -3
- data/lib/sass/script/parser.rb +162 -28
- data/lib/sass/script/string.rb +50 -2
- data/lib/sass/script/unary_operation.rb +25 -2
- data/lib/sass/script/variable.rb +21 -4
- 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 +69 -27
- data/lib/sass/tree/debug_node.rb +7 -2
- data/lib/sass/tree/directive_node.rb +41 -35
- data/lib/sass/tree/for_node.rb +6 -0
- data/lib/sass/tree/if_node.rb +13 -1
- data/lib/sass/tree/import_node.rb +52 -27
- data/lib/sass/tree/mixin_def_node.rb +18 -0
- data/lib/sass/tree/mixin_node.rb +41 -6
- data/lib/sass/tree/node.rb +197 -70
- data/lib/sass/tree/prop_node.rb +152 -57
- data/lib/sass/tree/root_node.rb +118 -0
- data/lib/sass/tree/rule_node.rb +193 -96
- data/lib/sass/tree/variable_node.rb +9 -5
- data/lib/sass/tree/while_node.rb +4 -0
- data/test/benchmark.rb +5 -5
- data/test/haml/engine_test.rb +147 -10
- data/test/haml/{rhtml/_av_partial_1.rhtml → erb/_av_partial_1.erb} +1 -1
- data/test/haml/{rhtml/_av_partial_2.rhtml → erb/_av_partial_2.erb} +1 -1
- data/test/haml/{rhtml/action_view.rhtml → erb/action_view.erb} +1 -1
- data/test/haml/{rhtml/standard.rhtml → erb/standard.erb} +0 -0
- data/test/haml/helper_test.rb +91 -24
- data/test/haml/html2haml/erb_tests.rb +410 -0
- data/test/haml/html2haml_test.rb +210 -66
- data/test/haml/results/filters.xhtml +1 -1
- data/test/haml/results/just_stuff.xhtml +2 -0
- data/test/haml/spec_test.rb +44 -0
- data/test/haml/template_test.rb +22 -2
- data/test/haml/templates/helpers.haml +0 -13
- data/test/haml/templates/just_stuff.haml +2 -0
- data/test/haml/util_test.rb +48 -0
- data/test/sass/callbacks_test.rb +61 -0
- data/test/sass/conversion_test.rb +884 -0
- data/test/sass/css2sass_test.rb +99 -18
- data/test/sass/data/hsl-rgb.txt +319 -0
- data/test/sass/engine_test.rb +1049 -131
- data/test/sass/functions_test.rb +398 -47
- 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 +184 -10
- 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/options.css +1 -0
- 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 +137 -70
- 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 +2 -0
- data/test/sass/templates/bork3.sass +2 -0
- data/test/sass/templates/bork4.sass +2 -0
- 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/mixin_bork.sass +5 -0
- data/test/sass/templates/mixins.sass +2 -2
- 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_mixin_bork.sass +6 -0
- data/test/sass/templates/options.sass +2 -0
- 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 +20 -8
- data/vendor/fssm/LICENSE +20 -0
- data/vendor/fssm/README.markdown +55 -0
- data/vendor/fssm/Rakefile +59 -0
- data/vendor/fssm/VERSION.yml +5 -0
- data/vendor/fssm/example.rb +9 -0
- data/vendor/fssm/fssm.gemspec +77 -0
- data/vendor/fssm/lib/fssm.rb +33 -0
- data/vendor/fssm/lib/fssm/backends/fsevents.rb +36 -0
- data/vendor/fssm/lib/fssm/backends/inotify.rb +26 -0
- data/vendor/fssm/lib/fssm/backends/polling.rb +25 -0
- data/vendor/fssm/lib/fssm/backends/rubycocoa/fsevents.rb +131 -0
- data/vendor/fssm/lib/fssm/monitor.rb +26 -0
- data/vendor/fssm/lib/fssm/path.rb +91 -0
- data/vendor/fssm/lib/fssm/pathname.rb +502 -0
- data/vendor/fssm/lib/fssm/state/directory.rb +57 -0
- data/vendor/fssm/lib/fssm/state/file.rb +24 -0
- data/vendor/fssm/lib/fssm/support.rb +63 -0
- data/vendor/fssm/lib/fssm/tree.rb +176 -0
- data/vendor/fssm/profile/prof-cache.rb +40 -0
- data/vendor/fssm/profile/prof-fssm-pathname.html +1231 -0
- data/vendor/fssm/profile/prof-pathname.rb +68 -0
- data/vendor/fssm/profile/prof-plain-pathname.html +988 -0
- data/vendor/fssm/profile/prof.html +2379 -0
- data/vendor/fssm/spec/path_spec.rb +75 -0
- data/vendor/fssm/spec/root/duck/quack.txt +0 -0
- data/vendor/fssm/spec/root/file.css +0 -0
- data/vendor/fssm/spec/root/file.rb +0 -0
- data/vendor/fssm/spec/root/file.yml +0 -0
- data/vendor/fssm/spec/root/moo/cow.txt +0 -0
- data/vendor/fssm/spec/spec_helper.rb +14 -0
- metadata +94 -14
- data/test/sass/templates/bork.sass +0 -2
@@ -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
|