haml 3.1.0.alpha.14 → 3.1.0.alpha.17

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.

Files changed (222) hide show
  1. data/EDGE_GEM_VERSION +1 -1
  2. data/VERSION +1 -1
  3. data/lib/haml.rb +3 -2
  4. data/lib/haml/exec.rb +0 -226
  5. data/lib/sass.rb +8 -0
  6. data/lib/sass/plugin.rb +8 -0
  7. data/lib/sass/rails2_shim.rb +9 -0
  8. data/lib/sass/rails3_shim.rb +16 -0
  9. data/vendor/sass/CONTRIBUTING +3 -0
  10. data/vendor/sass/MIT-LICENSE +20 -0
  11. data/vendor/sass/README.md +201 -0
  12. data/vendor/sass/Rakefile +363 -0
  13. data/vendor/sass/TODO +39 -0
  14. data/vendor/sass/VERSION +1 -0
  15. data/vendor/sass/VERSION_NAME +1 -0
  16. data/vendor/sass/bin/css2sass +13 -0
  17. data/vendor/sass/bin/sass +8 -0
  18. data/vendor/sass/bin/sass-convert +7 -0
  19. data/vendor/sass/doc-src/FAQ.md +35 -0
  20. data/vendor/sass/doc-src/INDENTED_SYNTAX.md +210 -0
  21. data/vendor/sass/doc-src/SASS_CHANGELOG.md +1878 -0
  22. data/vendor/sass/doc-src/SASS_REFERENCE.md +1713 -0
  23. data/vendor/sass/doc-src/SCSS_FOR_SASS_USERS.md +155 -0
  24. data/vendor/sass/ext/extconf.rb +10 -0
  25. data/vendor/sass/extra/update_watch.rb +13 -0
  26. data/vendor/sass/init.rb +18 -0
  27. data/vendor/sass/lib/sass.rb +71 -0
  28. data/vendor/sass/lib/sass/cache_store.rb +208 -0
  29. data/vendor/sass/lib/sass/callbacks.rb +66 -0
  30. data/vendor/sass/lib/sass/css.rb +294 -0
  31. data/vendor/sass/lib/sass/engine.rb +792 -0
  32. data/vendor/sass/lib/sass/environment.rb +143 -0
  33. data/vendor/sass/lib/sass/error.rb +201 -0
  34. data/vendor/sass/lib/sass/exec.rb +619 -0
  35. data/vendor/sass/lib/sass/importers.rb +22 -0
  36. data/vendor/sass/lib/sass/importers/base.rb +138 -0
  37. data/vendor/sass/lib/sass/importers/filesystem.rb +121 -0
  38. data/vendor/sass/lib/sass/less.rb +363 -0
  39. data/vendor/sass/lib/sass/plugin.rb +126 -0
  40. data/vendor/sass/lib/sass/plugin/compiler.rb +346 -0
  41. data/vendor/sass/lib/sass/plugin/configuration.rb +123 -0
  42. data/vendor/sass/lib/sass/plugin/generic.rb +15 -0
  43. data/vendor/sass/lib/sass/plugin/merb.rb +48 -0
  44. data/vendor/sass/lib/sass/plugin/rack.rb +47 -0
  45. data/vendor/sass/lib/sass/plugin/rails.rb +41 -0
  46. data/vendor/sass/lib/sass/plugin/staleness_checker.rb +145 -0
  47. data/vendor/sass/lib/sass/railtie.rb +8 -0
  48. data/vendor/sass/lib/sass/repl.rb +58 -0
  49. data/vendor/sass/lib/sass/root.rb +7 -0
  50. data/vendor/sass/lib/sass/script.rb +63 -0
  51. data/vendor/sass/lib/sass/script/bool.rb +18 -0
  52. data/vendor/sass/lib/sass/script/color.rb +491 -0
  53. data/vendor/sass/lib/sass/script/css_lexer.rb +29 -0
  54. data/vendor/sass/lib/sass/script/css_parser.rb +31 -0
  55. data/vendor/sass/lib/sass/script/funcall.rb +76 -0
  56. data/vendor/sass/lib/sass/script/functions.rb +852 -0
  57. data/vendor/sass/lib/sass/script/interpolation.rb +70 -0
  58. data/vendor/sass/lib/sass/script/lexer.rb +337 -0
  59. data/vendor/sass/lib/sass/script/literal.rb +236 -0
  60. data/vendor/sass/lib/sass/script/node.rb +112 -0
  61. data/vendor/sass/lib/sass/script/number.rb +423 -0
  62. data/vendor/sass/lib/sass/script/operation.rb +90 -0
  63. data/vendor/sass/lib/sass/script/parser.rb +392 -0
  64. data/vendor/sass/lib/sass/script/string.rb +67 -0
  65. data/vendor/sass/lib/sass/script/string_interpolation.rb +93 -0
  66. data/vendor/sass/lib/sass/script/unary_operation.rb +57 -0
  67. data/vendor/sass/lib/sass/script/variable.rb +48 -0
  68. data/vendor/sass/lib/sass/scss.rb +17 -0
  69. data/vendor/sass/lib/sass/scss/css_parser.rb +51 -0
  70. data/vendor/sass/lib/sass/scss/parser.rb +838 -0
  71. data/vendor/sass/lib/sass/scss/rx.rb +126 -0
  72. data/vendor/sass/lib/sass/scss/sass_parser.rb +11 -0
  73. data/vendor/sass/lib/sass/scss/script_lexer.rb +15 -0
  74. data/vendor/sass/lib/sass/scss/script_parser.rb +25 -0
  75. data/vendor/sass/lib/sass/scss/static_parser.rb +40 -0
  76. data/vendor/sass/lib/sass/selector.rb +361 -0
  77. data/vendor/sass/lib/sass/selector/abstract_sequence.rb +62 -0
  78. data/vendor/sass/lib/sass/selector/comma_sequence.rb +82 -0
  79. data/vendor/sass/lib/sass/selector/sequence.rb +236 -0
  80. data/vendor/sass/lib/sass/selector/simple.rb +113 -0
  81. data/vendor/sass/lib/sass/selector/simple_sequence.rb +135 -0
  82. data/vendor/sass/lib/sass/shared.rb +78 -0
  83. data/vendor/sass/lib/sass/tree/comment_node.rb +128 -0
  84. data/vendor/sass/lib/sass/tree/debug_node.rb +36 -0
  85. data/vendor/sass/lib/sass/tree/directive_node.rb +75 -0
  86. data/vendor/sass/lib/sass/tree/extend_node.rb +65 -0
  87. data/vendor/sass/lib/sass/tree/for_node.rb +67 -0
  88. data/vendor/sass/lib/sass/tree/if_node.rb +81 -0
  89. data/vendor/sass/lib/sass/tree/import_node.rb +124 -0
  90. data/vendor/sass/lib/sass/tree/mixin_def_node.rb +60 -0
  91. data/vendor/sass/lib/sass/tree/mixin_node.rb +123 -0
  92. data/vendor/sass/lib/sass/tree/node.rb +490 -0
  93. data/vendor/sass/lib/sass/tree/prop_node.rb +220 -0
  94. data/vendor/sass/lib/sass/tree/root_node.rb +125 -0
  95. data/vendor/sass/lib/sass/tree/rule_node.rb +273 -0
  96. data/vendor/sass/lib/sass/tree/variable_node.rb +39 -0
  97. data/vendor/sass/lib/sass/tree/warn_node.rb +42 -0
  98. data/vendor/sass/lib/sass/tree/while_node.rb +48 -0
  99. data/vendor/sass/lib/sass/util.rb +700 -0
  100. data/vendor/sass/lib/sass/util/subset_map.rb +101 -0
  101. data/vendor/sass/lib/sass/version.rb +109 -0
  102. data/vendor/sass/rails/init.rb +1 -0
  103. data/vendor/sass/sass.gemspec +32 -0
  104. data/vendor/sass/test/sass/cache_test.rb +74 -0
  105. data/vendor/sass/test/sass/callbacks_test.rb +61 -0
  106. data/vendor/sass/test/sass/conversion_test.rb +1210 -0
  107. data/vendor/sass/test/sass/css2sass_test.rb +364 -0
  108. data/vendor/sass/test/sass/data/hsl-rgb.txt +319 -0
  109. data/vendor/sass/test/sass/engine_test.rb +2305 -0
  110. data/vendor/sass/test/sass/extend_test.rb +1348 -0
  111. data/vendor/sass/test/sass/functions_test.rb +565 -0
  112. data/vendor/sass/test/sass/importer_test.rb +104 -0
  113. data/vendor/sass/test/sass/less_conversion_test.rb +632 -0
  114. data/vendor/sass/test/sass/mock_importer.rb +49 -0
  115. data/vendor/sass/test/sass/more_results/more1.css +9 -0
  116. data/vendor/sass/test/sass/more_results/more1_with_line_comments.css +26 -0
  117. data/vendor/sass/test/sass/more_results/more_import.css +29 -0
  118. data/vendor/sass/test/sass/more_templates/_more_partial.sass +2 -0
  119. data/vendor/sass/test/sass/more_templates/more1.sass +23 -0
  120. data/vendor/sass/test/sass/more_templates/more_import.sass +11 -0
  121. data/vendor/sass/test/sass/plugin_test.rb +430 -0
  122. data/vendor/sass/test/sass/results/alt.css +4 -0
  123. data/vendor/sass/test/sass/results/basic.css +9 -0
  124. data/vendor/sass/test/sass/results/compact.css +5 -0
  125. data/vendor/sass/test/sass/results/complex.css +86 -0
  126. data/vendor/sass/test/sass/results/compressed.css +1 -0
  127. data/vendor/sass/test/sass/results/expanded.css +19 -0
  128. data/vendor/sass/test/sass/results/import.css +31 -0
  129. data/vendor/sass/test/sass/results/line_numbers.css +49 -0
  130. data/vendor/sass/test/sass/results/mixins.css +95 -0
  131. data/vendor/sass/test/sass/results/multiline.css +24 -0
  132. data/vendor/sass/test/sass/results/nested.css +22 -0
  133. data/vendor/sass/test/sass/results/options.css +1 -0
  134. data/vendor/sass/test/sass/results/parent_ref.css +13 -0
  135. data/vendor/sass/test/sass/results/script.css +16 -0
  136. data/vendor/sass/test/sass/results/scss_import.css +31 -0
  137. data/vendor/sass/test/sass/results/scss_importee.css +2 -0
  138. data/vendor/sass/test/sass/results/subdir/nested_subdir/nested_subdir.css +1 -0
  139. data/vendor/sass/test/sass/results/subdir/subdir.css +3 -0
  140. data/vendor/sass/test/sass/results/units.css +11 -0
  141. data/vendor/sass/test/sass/results/warn.css +0 -0
  142. data/vendor/sass/test/sass/results/warn_imported.css +0 -0
  143. data/vendor/sass/test/sass/script_conversion_test.rb +254 -0
  144. data/vendor/sass/test/sass/script_test.rb +470 -0
  145. data/vendor/sass/test/sass/scss/css_test.rb +897 -0
  146. data/vendor/sass/test/sass/scss/rx_test.rb +156 -0
  147. data/vendor/sass/test/sass/scss/scss_test.rb +1088 -0
  148. data/vendor/sass/test/sass/scss/test_helper.rb +37 -0
  149. data/vendor/sass/test/sass/templates/_partial.sass +2 -0
  150. data/vendor/sass/test/sass/templates/alt.sass +16 -0
  151. data/vendor/sass/test/sass/templates/basic.sass +23 -0
  152. data/vendor/sass/test/sass/templates/bork1.sass +2 -0
  153. data/vendor/sass/test/sass/templates/bork2.sass +2 -0
  154. data/vendor/sass/test/sass/templates/bork3.sass +2 -0
  155. data/vendor/sass/test/sass/templates/bork4.sass +2 -0
  156. data/vendor/sass/test/sass/templates/compact.sass +17 -0
  157. data/vendor/sass/test/sass/templates/complex.sass +305 -0
  158. data/vendor/sass/test/sass/templates/compressed.sass +15 -0
  159. data/vendor/sass/test/sass/templates/expanded.sass +17 -0
  160. data/vendor/sass/test/sass/templates/import.sass +12 -0
  161. data/vendor/sass/test/sass/templates/importee.less +2 -0
  162. data/vendor/sass/test/sass/templates/importee.sass +19 -0
  163. data/vendor/sass/test/sass/templates/line_numbers.sass +13 -0
  164. data/vendor/sass/test/sass/templates/mixin_bork.sass +5 -0
  165. data/vendor/sass/test/sass/templates/mixins.sass +76 -0
  166. data/vendor/sass/test/sass/templates/multiline.sass +20 -0
  167. data/vendor/sass/test/sass/templates/nested.sass +25 -0
  168. data/vendor/sass/test/sass/templates/nested_bork1.sass +2 -0
  169. data/vendor/sass/test/sass/templates/nested_bork2.sass +2 -0
  170. data/vendor/sass/test/sass/templates/nested_bork3.sass +2 -0
  171. data/vendor/sass/test/sass/templates/nested_bork4.sass +2 -0
  172. data/vendor/sass/test/sass/templates/nested_mixin_bork.sass +6 -0
  173. data/vendor/sass/test/sass/templates/options.sass +2 -0
  174. data/vendor/sass/test/sass/templates/parent_ref.sass +25 -0
  175. data/vendor/sass/test/sass/templates/script.sass +101 -0
  176. data/vendor/sass/test/sass/templates/scss_import.scss +11 -0
  177. data/vendor/sass/test/sass/templates/scss_importee.scss +1 -0
  178. data/vendor/sass/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +2 -0
  179. data/vendor/sass/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +3 -0
  180. data/vendor/sass/test/sass/templates/subdir/subdir.sass +6 -0
  181. data/vendor/sass/test/sass/templates/units.sass +11 -0
  182. data/vendor/sass/test/sass/templates/warn.sass +3 -0
  183. data/vendor/sass/test/sass/templates/warn_imported.sass +4 -0
  184. data/vendor/sass/test/sass/test_helper.rb +8 -0
  185. data/vendor/sass/test/sass/util/subset_map_test.rb +91 -0
  186. data/vendor/sass/test/sass/util_test.rb +275 -0
  187. data/vendor/sass/test/test_helper.rb +64 -0
  188. data/vendor/sass/vendor/fssm/LICENSE +20 -0
  189. data/vendor/sass/vendor/fssm/README.markdown +55 -0
  190. data/vendor/sass/vendor/fssm/Rakefile +59 -0
  191. data/vendor/sass/vendor/fssm/VERSION.yml +5 -0
  192. data/vendor/sass/vendor/fssm/example.rb +9 -0
  193. data/vendor/sass/vendor/fssm/fssm.gemspec +77 -0
  194. data/vendor/sass/vendor/fssm/lib/fssm.rb +33 -0
  195. data/vendor/sass/vendor/fssm/lib/fssm/backends/fsevents.rb +36 -0
  196. data/vendor/sass/vendor/fssm/lib/fssm/backends/inotify.rb +26 -0
  197. data/vendor/sass/vendor/fssm/lib/fssm/backends/polling.rb +25 -0
  198. data/vendor/sass/vendor/fssm/lib/fssm/backends/rubycocoa/fsevents.rb +131 -0
  199. data/vendor/sass/vendor/fssm/lib/fssm/monitor.rb +26 -0
  200. data/vendor/sass/vendor/fssm/lib/fssm/path.rb +91 -0
  201. data/vendor/sass/vendor/fssm/lib/fssm/pathname.rb +502 -0
  202. data/vendor/sass/vendor/fssm/lib/fssm/state/directory.rb +57 -0
  203. data/vendor/sass/vendor/fssm/lib/fssm/state/file.rb +24 -0
  204. data/vendor/sass/vendor/fssm/lib/fssm/support.rb +63 -0
  205. data/vendor/sass/vendor/fssm/lib/fssm/tree.rb +176 -0
  206. data/vendor/sass/vendor/fssm/profile/prof-cache.rb +40 -0
  207. data/vendor/sass/vendor/fssm/profile/prof-fssm-pathname.html +1231 -0
  208. data/vendor/sass/vendor/fssm/profile/prof-pathname.rb +68 -0
  209. data/vendor/sass/vendor/fssm/profile/prof-plain-pathname.html +988 -0
  210. data/vendor/sass/vendor/fssm/profile/prof.html +2379 -0
  211. data/vendor/sass/vendor/fssm/spec/path_spec.rb +75 -0
  212. data/vendor/sass/vendor/fssm/spec/root/duck/quack.txt +0 -0
  213. data/vendor/sass/vendor/fssm/spec/root/file.css +0 -0
  214. data/vendor/sass/vendor/fssm/spec/root/file.rb +0 -0
  215. data/vendor/sass/vendor/fssm/spec/root/file.yml +0 -0
  216. data/vendor/sass/vendor/fssm/spec/root/moo/cow.txt +0 -0
  217. data/vendor/sass/vendor/fssm/spec/spec_helper.rb +14 -0
  218. data/vendor/sass/yard/callbacks.rb +29 -0
  219. data/vendor/sass/yard/default/fulldoc/html/css/common.sass +26 -0
  220. data/vendor/sass/yard/default/layout/html/footer.erb +12 -0
  221. data/vendor/sass/yard/inherited_hash.rb +41 -0
  222. metadata +219 -2
@@ -0,0 +1,897 @@
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_long_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_ms_short_filter_syntax
336
+ assert_parses <<SCSS
337
+ foo {
338
+ filter: alpha(opacity=20);
339
+ filter: alpha(opacity=20, enabled=true);
340
+ filter: blaznicate(foo=bar, baz=bang bip, bart=#fa4600); }
341
+ SCSS
342
+ end
343
+
344
+ def test_declaration_hacks
345
+ assert_parses <<SCSS
346
+ foo {
347
+ _name: val;
348
+ *name: val;
349
+ :name: val;
350
+ .name: val;
351
+ #name: val;
352
+ name/**/: val;
353
+ name/*\\**/: val;
354
+ name: val; }
355
+ SCSS
356
+ end
357
+
358
+ def test_trailing_hash_hack
359
+ assert_parses <<SCSS
360
+ foo {
361
+ foo: bar;
362
+ #baz: bang;
363
+ #bip: bop; }
364
+ SCSS
365
+ end
366
+
367
+ def test_zero_arg_functions
368
+ assert_parses <<SCSS
369
+ foo {
370
+ a: foo();
371
+ b: bar baz-bang() bip; }
372
+ SCSS
373
+ end
374
+
375
+ def test_expression_function
376
+ assert_parses <<SCSS
377
+ foo {
378
+ a: 12px expression(1 + (3 / Foo.bar("baz" + "bang") + function() {return 12;}) % 12); }
379
+ SCSS
380
+ end
381
+
382
+ def test_calc_function
383
+ assert_parses <<SCSS
384
+ foo {
385
+ a: 12px calc(100%/3 - 2*1em - 2*1px);
386
+ b: 12px -moz-calc(100%/3 - 2*1em - 2*1px);
387
+ b: 12px -webkit-calc(100%/3 - 2*1em - 2*1px);
388
+ b: 12px -foobar-calc(100%/3 - 2*1em - 2*1px); }
389
+ SCSS
390
+ end
391
+
392
+ def test_unary_ops
393
+ assert_equal <<CSS, render(<<SCSS)
394
+ foo {
395
+ a: -0.5em;
396
+ b: 0.5em;
397
+ c: -foo(12px);
398
+ d: +foo(12px); }
399
+ CSS
400
+ foo {
401
+ a: -0.5em;
402
+ b: +0.5em;
403
+ c: -foo(12px);
404
+ d: +foo(12px); }
405
+ SCSS
406
+ end
407
+
408
+ def test_css_string_escapes
409
+ assert_parses <<SCSS
410
+ foo {
411
+ a: "\\foo bar";
412
+ b: "foo\\ bar";
413
+ c: "\\2022 \\0020";
414
+ d: "foo\\\\bar";
415
+ e: "foo\\"'bar"; }
416
+ SCSS
417
+ end
418
+
419
+ def test_css_ident_escapes
420
+ assert_parses <<SCSS
421
+ foo {
422
+ a: \\foo bar;
423
+ b: foo\\ bar;
424
+ c: \\2022 \\0020;
425
+ d: foo\\\\bar;
426
+ e: foo\\"\\'bar; }
427
+ SCSS
428
+ end
429
+
430
+ ## Directives
431
+
432
+ def test_charset_directive
433
+ assert_parses '@charset "utf-8";'
434
+ end
435
+
436
+ def test_namespace_directive
437
+ assert_parses '@namespace "http://www.w3.org/Profiles/xhtml1-strict";'
438
+ assert_parses '@namespace url(http://www.w3.org/Profiles/xhtml1-strict);'
439
+ assert_parses '@namespace html url("http://www.w3.org/Profiles/xhtml1-strict");'
440
+ end
441
+
442
+ def test_media_directive
443
+ assert_parses <<SCSS
444
+ @media all {
445
+ rule1 {
446
+ prop: val; }
447
+
448
+ rule2 {
449
+ prop: val; } }
450
+ SCSS
451
+ assert_parses <<SCSS
452
+ @media screen, print {
453
+ rule1 {
454
+ prop: val; }
455
+
456
+ rule2 {
457
+ prop: val; } }
458
+ SCSS
459
+ end
460
+
461
+ def test_media_directive_with_keywords
462
+ assert_parses <<SCSS
463
+ @media screen and (-webkit-min-device-pixel-ratio:0) {
464
+ a: b; }
465
+ SCSS
466
+ assert_parses <<SCSS
467
+ @media only screen, print and (foo: 0px) and (bar: flam(12px solid)) {
468
+ a: b; }
469
+ SCSS
470
+ end
471
+
472
+ def test_import_directive
473
+ assert_parses '@import "foo.css";'
474
+ assert_parses "@import 'foo.css';"
475
+ assert_parses '@import url("foo.css");'
476
+ assert_parses "@import url('foo.css');"
477
+ assert_parses '@import url(foo.css);'
478
+ end
479
+
480
+ def test_import_directive_with_media
481
+ assert_parses '@import "foo.css" screen;'
482
+ assert_parses '@import "foo.css" screen, print;'
483
+ assert_parses '@import "foo.css" screen, print and (foo: 0);'
484
+ assert_parses '@import "foo.css" screen, only print, screen and (foo: 0);'
485
+ end
486
+
487
+ def test_page_directive
488
+ assert_parses <<SCSS
489
+ @page {
490
+ prop1: val;
491
+ prop2: val; }
492
+ SCSS
493
+ assert_parses <<SCSS
494
+ @page flap {
495
+ prop1: val;
496
+ prop2: val; }
497
+ SCSS
498
+ assert_parses <<SCSS
499
+ @page :first {
500
+ prop1: val;
501
+ prop2: val; }
502
+ SCSS
503
+ assert_parses <<SCSS
504
+ @page flap:first {
505
+ prop1: val;
506
+ prop2: val; }
507
+ SCSS
508
+ end
509
+
510
+ def test_blockless_directive_without_semicolon
511
+ assert_equal "@charset \"utf-8\";\n", render('@charset "utf-8"')
512
+ end
513
+
514
+ def test_directive_with_lots_of_whitespace
515
+ assert_equal "@charset \"utf-16\";\n", render('@charset "utf-16" ;')
516
+ end
517
+
518
+ def test_empty_blockless_directive
519
+ assert_parses "@foo;"
520
+ end
521
+
522
+ def test_multiple_blockless_directives
523
+ assert_parses <<SCSS
524
+ @foo bar;
525
+ @bar baz;
526
+ SCSS
527
+ end
528
+
529
+ def test_empty_block_directive
530
+ assert_parses "@foo {}"
531
+ assert_equal "@foo {}\n", render(<<SCSS)
532
+ @foo {
533
+ }
534
+ SCSS
535
+ end
536
+
537
+ def test_multiple_block_directives
538
+ assert_parses <<SCSS
539
+ @foo bar {
540
+ a: b; }
541
+
542
+ @bar baz {
543
+ c: d; }
544
+ SCSS
545
+ end
546
+
547
+ def test_block_directive_with_rule_and_property
548
+ assert_parses <<SCSS
549
+ @foo {
550
+ rule {
551
+ a: b; }
552
+
553
+ a: b; }
554
+ SCSS
555
+ end
556
+
557
+ def test_block_directive_with_semicolon
558
+ assert_equal <<CSS, render(<<SCSS)
559
+ @foo {
560
+ a: b; }
561
+
562
+ @bar {
563
+ a: b; }
564
+ CSS
565
+ @foo {a:b};
566
+ @bar {a:b};
567
+ SCSS
568
+ end
569
+
570
+ ## Selectors
571
+
572
+ # Taken from http://www.w3.org/TR/css3-selectors/#selectors
573
+ def test_summarized_selectors
574
+ assert_selector_parses('*')
575
+ assert_selector_parses('E')
576
+ assert_selector_parses('E[foo]')
577
+ assert_selector_parses('E[foo="bar"]')
578
+ assert_selector_parses('E[foo~="bar"]')
579
+ assert_selector_parses('E[foo^="bar"]')
580
+ assert_selector_parses('E[foo$="bar"]')
581
+ assert_selector_parses('E[foo*="bar"]')
582
+ assert_selector_parses('E[foo|="en"]')
583
+ assert_selector_parses('E:root')
584
+ assert_selector_parses('E:nth-child(n)')
585
+ assert_selector_parses('E:nth-last-child(n)')
586
+ assert_selector_parses('E:nth-of-type(n)')
587
+ assert_selector_parses('E:nth-last-of-type(n)')
588
+ assert_selector_parses('E:first-child')
589
+ assert_selector_parses('E:last-child')
590
+ assert_selector_parses('E:first-of-type')
591
+ assert_selector_parses('E:last-of-type')
592
+ assert_selector_parses('E:only-child')
593
+ assert_selector_parses('E:only-of-type')
594
+ assert_selector_parses('E:empty')
595
+ assert_selector_parses('E:link')
596
+ assert_selector_parses('E:visited')
597
+ assert_selector_parses('E:active')
598
+ assert_selector_parses('E:hover')
599
+ assert_selector_parses('E:focus')
600
+ assert_selector_parses('E:target')
601
+ assert_selector_parses('E:lang(fr)')
602
+ assert_selector_parses('E:enabled')
603
+ assert_selector_parses('E:disabled')
604
+ assert_selector_parses('E:checked')
605
+ assert_selector_parses('E::first-line')
606
+ assert_selector_parses('E::first-letter')
607
+ assert_selector_parses('E::before')
608
+ assert_selector_parses('E::after')
609
+ assert_selector_parses('E.warning')
610
+ assert_selector_parses('E#myid')
611
+ assert_selector_parses('E:not(s)')
612
+ assert_selector_parses('E F')
613
+ assert_selector_parses('E > F')
614
+ assert_selector_parses('E + F')
615
+ assert_selector_parses('E ~ F')
616
+ end
617
+
618
+ # Taken from http://www.w3.org/TR/css3-selectors/#selectors,
619
+ # but without the element names
620
+ def test_lonely_selectors
621
+ assert_selector_parses('[foo]')
622
+ assert_selector_parses('[foo="bar"]')
623
+ assert_selector_parses('[foo~="bar"]')
624
+ assert_selector_parses('[foo^="bar"]')
625
+ assert_selector_parses('[foo$="bar"]')
626
+ assert_selector_parses('[foo*="bar"]')
627
+ assert_selector_parses('[foo|="en"]')
628
+ assert_selector_parses(':root')
629
+ assert_selector_parses(':nth-child(n)')
630
+ assert_selector_parses(':nth-last-child(n)')
631
+ assert_selector_parses(':nth-of-type(n)')
632
+ assert_selector_parses(':nth-last-of-type(n)')
633
+ assert_selector_parses(':first-child')
634
+ assert_selector_parses(':last-child')
635
+ assert_selector_parses(':first-of-type')
636
+ assert_selector_parses(':last-of-type')
637
+ assert_selector_parses(':only-child')
638
+ assert_selector_parses(':only-of-type')
639
+ assert_selector_parses(':empty')
640
+ assert_selector_parses(':link')
641
+ assert_selector_parses(':visited')
642
+ assert_selector_parses(':active')
643
+ assert_selector_parses(':hover')
644
+ assert_selector_parses(':focus')
645
+ assert_selector_parses(':target')
646
+ assert_selector_parses(':lang(fr)')
647
+ assert_selector_parses(':enabled')
648
+ assert_selector_parses(':disabled')
649
+ assert_selector_parses(':checked')
650
+ assert_selector_parses('::first-line')
651
+ assert_selector_parses('::first-letter')
652
+ assert_selector_parses('::before')
653
+ assert_selector_parses('::after')
654
+ assert_selector_parses('.warning')
655
+ assert_selector_parses('#myid')
656
+ assert_selector_parses(':not(s)')
657
+ end
658
+
659
+ def test_attribute_selectors_with_identifiers
660
+ assert_selector_parses('[foo~=bar]')
661
+ assert_selector_parses('[foo^=bar]')
662
+ assert_selector_parses('[foo$=bar]')
663
+ assert_selector_parses('[foo*=bar]')
664
+ assert_selector_parses('[foo|=en]')
665
+ end
666
+
667
+ def test_nth_selectors
668
+ assert_selector_parses(':nth-child(-n)')
669
+ assert_selector_parses(':nth-child(+n)')
670
+
671
+ assert_selector_parses(':nth-child(even)')
672
+ assert_selector_parses(':nth-child(odd)')
673
+
674
+ assert_selector_parses(':nth-child(50)')
675
+ assert_selector_parses(':nth-child(-50)')
676
+ assert_selector_parses(':nth-child(+50)')
677
+
678
+ assert_selector_parses(':nth-child(2n+3)')
679
+ assert_selector_parses(':nth-child(2n-3)')
680
+ assert_selector_parses(':nth-child(+2n-3)')
681
+ assert_selector_parses(':nth-child(-2n+3)')
682
+ assert_selector_parses(':nth-child(-2n+ 3)')
683
+
684
+ assert_equal(<<CSS, render(<<SCSS))
685
+ :nth-child(2n + 3) {
686
+ a: b; }
687
+ CSS
688
+ :nth-child( 2n + 3 ) {
689
+ a: b; }
690
+ SCSS
691
+ end
692
+
693
+ def test_negation_selectors
694
+ assert_selector_parses(':not(foo|bar)')
695
+ assert_selector_parses(':not(*|bar)')
696
+
697
+ assert_selector_parses(':not(foo|*)')
698
+ assert_selector_parses(':not(*|*)')
699
+
700
+ assert_selector_parses(':not(#blah)')
701
+ assert_selector_parses(':not(.blah)')
702
+
703
+ assert_selector_parses(':not([foo])')
704
+ assert_selector_parses(':not([foo^="bar"])')
705
+ assert_selector_parses(':not([baz|foo~="bar"])')
706
+
707
+ assert_selector_parses(':not(:hover)')
708
+ assert_selector_parses(':not(:nth-child(2n + 3))')
709
+
710
+ # Not technically allowed, but what the heck
711
+ assert_selector_parses(':not(:not(#foo))')
712
+ assert_selector_parses(':not(a#foo.bar)')
713
+ assert_selector_parses(':not(#foo .bar > baz)')
714
+ assert_selector_parses(':not(h1, h2, h3)')
715
+ end
716
+
717
+ def test_moz_any_selector
718
+ assert_selector_parses(':-moz-any(h1, h2, h3)')
719
+ assert_selector_parses(':-moz-any(.foo)')
720
+ assert_selector_parses(':-moz-any(foo bar, .baz > .bang)')
721
+ end
722
+
723
+ def test_namespaced_selectors
724
+ assert_selector_parses('foo|E')
725
+ assert_selector_parses('*|E')
726
+ assert_selector_parses('foo|*')
727
+ assert_selector_parses('*|*')
728
+ end
729
+
730
+ def test_namespaced_attribute_selectors
731
+ assert_selector_parses('[foo|bar=baz]')
732
+ assert_selector_parses('[*|bar=baz]')
733
+ assert_selector_parses('[foo|bar|=baz]')
734
+ end
735
+
736
+ def test_comma_selectors
737
+ assert_selector_parses('E, F')
738
+ assert_selector_parses('E F, G H')
739
+ assert_selector_parses('E > F, G > H')
740
+ end
741
+
742
+ def test_selectors_with_newlines
743
+ assert_selector_parses("E,\nF")
744
+ assert_selector_parses("E\nF")
745
+ assert_selector_parses("E, F\nG, H")
746
+ end
747
+
748
+ def test_expression_fallback_selectors
749
+ assert_selector_parses('0%')
750
+ assert_selector_parses('60%')
751
+ assert_selector_parses('100%')
752
+ assert_selector_parses('12px')
753
+ assert_selector_parses('"foo"')
754
+ end
755
+
756
+ def test_functional_pseudo_selectors
757
+ assert_selector_parses(':foo("bar")')
758
+ assert_selector_parses(':foo(bar)')
759
+ assert_selector_parses(':foo(12px)')
760
+ assert_selector_parses(':foo(+)')
761
+ assert_selector_parses(':foo(-)')
762
+ assert_selector_parses(':foo(+"bar")')
763
+ assert_selector_parses(':foo(-++--baz-"bar"12px)')
764
+ end
765
+
766
+ def test_selector_hacks
767
+ assert_selector_parses('> E')
768
+ assert_selector_parses('+ E')
769
+ assert_selector_parses('~ E')
770
+ assert_selector_parses('> > E')
771
+ assert_equal <<CSS, render(<<SCSS)
772
+ > > E {
773
+ a: b; }
774
+ CSS
775
+ >> E {
776
+ a: b; }
777
+ SCSS
778
+
779
+ assert_selector_parses('E*')
780
+ assert_selector_parses('E*.foo')
781
+ assert_selector_parses('E*:hover')
782
+ end
783
+
784
+ ## Errors
785
+
786
+ def test_invalid_directives
787
+ assert_not_parses("identifier", '@<err> import "foo";')
788
+ assert_not_parses("identifier", '@<err>12 "foo";')
789
+ end
790
+
791
+ def test_invalid_classes
792
+ assert_not_parses("class name", 'p.<err> foo {a: b}')
793
+ assert_not_parses("class name", 'p.<err>1foo {a: b}')
794
+ end
795
+
796
+ def test_invalid_ids
797
+ assert_not_parses("id name", 'p#<err> foo {a: b}')
798
+ end
799
+
800
+ def test_no_properties_at_toplevel
801
+ assert_not_parses('pseudoclass or pseudoelement', 'a:<err> b;')
802
+ end
803
+
804
+ def test_no_scss_directives
805
+ assert_parses('@import "foo.sass";')
806
+ assert_parses <<SCSS
807
+ @mixin foo {
808
+ a: b; }
809
+ SCSS
810
+ end
811
+
812
+ def test_no_variables
813
+ assert_not_parses("selector or at-rule", "<err>$var = 12;")
814
+ assert_not_parses('"}"', "foo { <err>!var = 12; }")
815
+ end
816
+
817
+ def test_no_parent_selectors
818
+ assert_not_parses('"{"', "foo <err>&.bar {a: b}")
819
+ end
820
+
821
+ def test_no_selector_interpolation
822
+ assert_not_parses('"{"', 'foo <err>#{"bar"}.baz {a: b}')
823
+ end
824
+
825
+ def test_no_prop_name_interpolation
826
+ assert_not_parses('":"', 'foo {a<err>#{"bar"}baz: b}')
827
+ end
828
+
829
+ def test_no_prop_val_interpolation
830
+ assert_not_parses('"}"', 'foo {a: b <err>#{"bar"} c}')
831
+ end
832
+
833
+ def test_no_string_interpolation
834
+ assert_parses <<SCSS
835
+ foo {
836
+ a: "bang \#{1 + " bar "} bip"; }
837
+ SCSS
838
+ end
839
+
840
+ def test_no_sass_script_values
841
+ assert_not_parses('"}"', 'foo {a: b <err>* c}')
842
+ end
843
+
844
+ def test_no_nested_rules
845
+ assert_not_parses('":"', 'foo {bar <err>{a: b}}')
846
+ assert_not_parses('"}"', 'foo {<err>[bar=baz] {a: b}}')
847
+ end
848
+
849
+ def test_no_nested_properties
850
+ assert_not_parses('expression (e.g. 1px, bold)', 'foo {bar: <err>{a: b}}')
851
+ assert_not_parses('expression (e.g. 1px, bold)', 'foo {bar: bang <err>{a: b}}')
852
+ end
853
+
854
+ def test_no_nested_directives
855
+ assert_not_parses('"}"', 'foo {<err>@bar {a: b}}')
856
+ end
857
+
858
+ def test_error_with_windows_newlines
859
+ render <<SCSS
860
+ foo {bar}\r
861
+ baz {a: b}
862
+ SCSS
863
+ assert(false, "Expected syntax error")
864
+ rescue Sass::SyntaxError => e
865
+ assert_equal 'Invalid CSS after "foo {bar": expected ":", was "}"', e.message
866
+ assert_equal 1, e.sass_line
867
+ end
868
+
869
+ ## Regressions
870
+
871
+ def test_closing_line_comment_end_with_compact_output
872
+ assert_equal(<<CSS, render(<<SCSS, :style => :compact))
873
+ /* foo */
874
+ bar { baz: bang; }
875
+ CSS
876
+ /*
877
+ * foo
878
+ */
879
+ bar {baz: bang}
880
+ SCSS
881
+ end
882
+
883
+ private
884
+
885
+ def assert_selector_parses(selector)
886
+ assert_parses <<SCSS
887
+ #{selector} {
888
+ a: b; }
889
+ SCSS
890
+ end
891
+
892
+ def render(scss, options = {})
893
+ tree = Sass::SCSS::CssParser.new(scss).parse
894
+ tree.options = Sass::Engine::DEFAULT_OPTIONS.merge(options)
895
+ tree.render
896
+ end
897
+ end