oreorenasass 3.4.4 → 3.4.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (176) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +50 -70
  4. data/Rakefile +5 -26
  5. data/VERSION +1 -1
  6. data/VERSION_NAME +1 -1
  7. data/bin/sass +1 -1
  8. data/bin/scss +1 -1
  9. data/lib/sass.rb +12 -19
  10. data/lib/sass/cache_stores/base.rb +2 -2
  11. data/lib/sass/cache_stores/chain.rb +1 -2
  12. data/lib/sass/cache_stores/filesystem.rb +5 -1
  13. data/lib/sass/cache_stores/memory.rb +1 -1
  14. data/lib/sass/cache_stores/null.rb +2 -2
  15. data/lib/sass/callbacks.rb +0 -1
  16. data/lib/sass/css.rb +13 -11
  17. data/lib/sass/engine.rb +173 -424
  18. data/lib/sass/environment.rb +58 -148
  19. data/lib/sass/error.rb +14 -11
  20. data/lib/sass/exec.rb +703 -5
  21. data/lib/sass/importers/base.rb +6 -49
  22. data/lib/sass/importers/filesystem.rb +19 -44
  23. data/lib/sass/logger.rb +4 -1
  24. data/lib/sass/logger/base.rb +4 -2
  25. data/lib/sass/logger/log_level.rb +7 -3
  26. data/lib/sass/media.rb +23 -20
  27. data/lib/sass/plugin.rb +7 -7
  28. data/lib/sass/plugin/compiler.rb +145 -304
  29. data/lib/sass/plugin/configuration.rb +23 -18
  30. data/lib/sass/plugin/merb.rb +1 -1
  31. data/lib/sass/plugin/staleness_checker.rb +3 -3
  32. data/lib/sass/repl.rb +3 -3
  33. data/lib/sass/script.rb +8 -35
  34. data/lib/sass/script/{value/arg_list.rb → arg_list.rb} +25 -9
  35. data/lib/sass/script/bool.rb +18 -0
  36. data/lib/sass/script/color.rb +606 -0
  37. data/lib/sass/script/css_lexer.rb +4 -8
  38. data/lib/sass/script/css_parser.rb +2 -5
  39. data/lib/sass/script/funcall.rb +245 -0
  40. data/lib/sass/script/functions.rb +408 -1491
  41. data/lib/sass/script/interpolation.rb +79 -0
  42. data/lib/sass/script/lexer.rb +68 -172
  43. data/lib/sass/script/list.rb +85 -0
  44. data/lib/sass/script/literal.rb +221 -0
  45. data/lib/sass/script/{tree/node.rb → node.rb} +12 -22
  46. data/lib/sass/script/{value/null.rb → null.rb} +7 -14
  47. data/lib/sass/script/{value/number.rb → number.rb} +75 -152
  48. data/lib/sass/script/{tree/operation.rb → operation.rb} +24 -17
  49. data/lib/sass/script/parser.rb +110 -245
  50. data/lib/sass/script/string.rb +51 -0
  51. data/lib/sass/script/{tree/string_interpolation.rb → string_interpolation.rb} +4 -5
  52. data/lib/sass/script/{tree/unary_operation.rb → unary_operation.rb} +6 -6
  53. data/lib/sass/script/variable.rb +58 -0
  54. data/lib/sass/scss/css_parser.rb +3 -9
  55. data/lib/sass/scss/parser.rb +421 -450
  56. data/lib/sass/scss/rx.rb +11 -19
  57. data/lib/sass/scss/static_parser.rb +7 -321
  58. data/lib/sass/selector.rb +194 -68
  59. data/lib/sass/selector/abstract_sequence.rb +14 -29
  60. data/lib/sass/selector/comma_sequence.rb +25 -108
  61. data/lib/sass/selector/sequence.rb +66 -159
  62. data/lib/sass/selector/simple.rb +25 -23
  63. data/lib/sass/selector/simple_sequence.rb +63 -173
  64. data/lib/sass/shared.rb +1 -1
  65. data/lib/sass/supports.rb +15 -13
  66. data/lib/sass/tree/charset_node.rb +1 -1
  67. data/lib/sass/tree/comment_node.rb +3 -3
  68. data/lib/sass/tree/css_import_node.rb +11 -11
  69. data/lib/sass/tree/debug_node.rb +2 -2
  70. data/lib/sass/tree/directive_node.rb +4 -21
  71. data/lib/sass/tree/each_node.rb +8 -8
  72. data/lib/sass/tree/extend_node.rb +7 -14
  73. data/lib/sass/tree/for_node.rb +4 -4
  74. data/lib/sass/tree/function_node.rb +4 -9
  75. data/lib/sass/tree/if_node.rb +1 -1
  76. data/lib/sass/tree/import_node.rb +5 -4
  77. data/lib/sass/tree/media_node.rb +14 -4
  78. data/lib/sass/tree/mixin_def_node.rb +4 -4
  79. data/lib/sass/tree/mixin_node.rb +8 -21
  80. data/lib/sass/tree/node.rb +12 -54
  81. data/lib/sass/tree/prop_node.rb +20 -39
  82. data/lib/sass/tree/return_node.rb +2 -3
  83. data/lib/sass/tree/root_node.rb +3 -19
  84. data/lib/sass/tree/rule_node.rb +22 -35
  85. data/lib/sass/tree/supports_node.rb +13 -0
  86. data/lib/sass/tree/trace_node.rb +1 -2
  87. data/lib/sass/tree/variable_node.rb +3 -9
  88. data/lib/sass/tree/visitors/base.rb +8 -5
  89. data/lib/sass/tree/visitors/check_nesting.rb +19 -49
  90. data/lib/sass/tree/visitors/convert.rb +56 -74
  91. data/lib/sass/tree/visitors/cssize.rb +74 -202
  92. data/lib/sass/tree/visitors/deep_copy.rb +5 -10
  93. data/lib/sass/tree/visitors/extend.rb +7 -7
  94. data/lib/sass/tree/visitors/perform.rb +185 -278
  95. data/lib/sass/tree/visitors/set_options.rb +6 -20
  96. data/lib/sass/tree/visitors/to_css.rb +81 -234
  97. data/lib/sass/tree/warn_node.rb +2 -2
  98. data/lib/sass/tree/while_node.rb +2 -2
  99. data/lib/sass/util.rb +152 -522
  100. data/lib/sass/util/multibyte_string_scanner.rb +0 -2
  101. data/lib/sass/util/subset_map.rb +3 -4
  102. data/lib/sass/util/test.rb +1 -0
  103. data/lib/sass/version.rb +22 -20
  104. data/test/Gemfile +3 -0
  105. data/test/Gemfile.lock +10 -0
  106. data/test/sass/cache_test.rb +20 -62
  107. data/test/sass/callbacks_test.rb +1 -1
  108. data/test/sass/conversion_test.rb +2 -296
  109. data/test/sass/css2sass_test.rb +4 -23
  110. data/test/sass/engine_test.rb +354 -411
  111. data/test/sass/exec_test.rb +2 -2
  112. data/test/sass/extend_test.rb +145 -324
  113. data/test/sass/functions_test.rb +86 -873
  114. data/test/sass/importer_test.rb +21 -241
  115. data/test/sass/logger_test.rb +1 -1
  116. data/test/sass/more_results/more_import.css +1 -1
  117. data/test/sass/plugin_test.rb +26 -16
  118. data/test/sass/results/compact.css +1 -1
  119. data/test/sass/results/complex.css +4 -4
  120. data/test/sass/results/expanded.css +1 -1
  121. data/test/sass/results/import.css +1 -1
  122. data/test/sass/results/import_charset_ibm866.css +2 -2
  123. data/test/sass/results/mixins.css +17 -17
  124. data/test/sass/results/nested.css +1 -1
  125. data/test/sass/results/parent_ref.css +2 -2
  126. data/test/sass/results/script.css +3 -3
  127. data/test/sass/results/scss_import.css +1 -1
  128. data/test/sass/script_conversion_test.rb +7 -36
  129. data/test/sass/script_test.rb +53 -485
  130. data/test/sass/scss/css_test.rb +28 -143
  131. data/test/sass/scss/rx_test.rb +4 -4
  132. data/test/sass/scss/scss_test.rb +325 -2119
  133. data/test/sass/templates/scss_import.scss +1 -2
  134. data/test/sass/test_helper.rb +1 -1
  135. data/test/sass/util/multibyte_string_scanner_test.rb +1 -1
  136. data/test/sass/util/subset_map_test.rb +2 -2
  137. data/test/sass/util_test.rb +1 -86
  138. data/test/test_helper.rb +8 -37
  139. metadata +19 -66
  140. data/lib/sass/exec/base.rb +0 -187
  141. data/lib/sass/exec/sass_convert.rb +0 -264
  142. data/lib/sass/exec/sass_scss.rb +0 -424
  143. data/lib/sass/features.rb +0 -47
  144. data/lib/sass/script/tree.rb +0 -16
  145. data/lib/sass/script/tree/funcall.rb +0 -306
  146. data/lib/sass/script/tree/interpolation.rb +0 -118
  147. data/lib/sass/script/tree/list_literal.rb +0 -77
  148. data/lib/sass/script/tree/literal.rb +0 -45
  149. data/lib/sass/script/tree/map_literal.rb +0 -64
  150. data/lib/sass/script/tree/selector.rb +0 -26
  151. data/lib/sass/script/tree/variable.rb +0 -57
  152. data/lib/sass/script/value.rb +0 -11
  153. data/lib/sass/script/value/base.rb +0 -240
  154. data/lib/sass/script/value/bool.rb +0 -35
  155. data/lib/sass/script/value/color.rb +0 -680
  156. data/lib/sass/script/value/helpers.rb +0 -262
  157. data/lib/sass/script/value/list.rb +0 -113
  158. data/lib/sass/script/value/map.rb +0 -70
  159. data/lib/sass/script/value/string.rb +0 -97
  160. data/lib/sass/selector/pseudo.rb +0 -256
  161. data/lib/sass/source/map.rb +0 -210
  162. data/lib/sass/source/position.rb +0 -39
  163. data/lib/sass/source/range.rb +0 -41
  164. data/lib/sass/stack.rb +0 -120
  165. data/lib/sass/tree/at_root_node.rb +0 -83
  166. data/lib/sass/tree/error_node.rb +0 -18
  167. data/lib/sass/tree/keyframe_rule_node.rb +0 -15
  168. data/lib/sass/util/cross_platform_random.rb +0 -19
  169. data/lib/sass/util/normalized_map.rb +0 -130
  170. data/lib/sass/util/ordered_hash.rb +0 -192
  171. data/test/sass/compiler_test.rb +0 -232
  172. data/test/sass/encoding_test.rb +0 -219
  173. data/test/sass/source_map_test.rb +0 -977
  174. data/test/sass/superselector_test.rb +0 -191
  175. data/test/sass/util/normalized_map_test.rb +0 -51
  176. data/test/sass/value_helpers_test.rb +0 -179
@@ -1,977 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # -*- coding: utf-8 -*-
3
- require File.dirname(__FILE__) + '/../test_helper'
4
- require File.dirname(__FILE__) + '/test_helper'
5
-
6
- class SourcemapTest < MiniTest::Test
7
- def test_to_json_requires_args
8
- _, sourcemap = render_with_sourcemap('')
9
- assert_raises(ArgumentError) {sourcemap.to_json({})}
10
- assert_raises(ArgumentError) {sourcemap.to_json({:css_path => 'foo'})}
11
- assert_raises(ArgumentError) {sourcemap.to_json({:sourcemap_path => 'foo'})}
12
- end
13
-
14
- def test_simple_mapping_scss
15
- assert_parses_with_sourcemap <<SCSS, <<CSS, <<JSON
16
- a {
17
- foo: bar;
18
- /* SOME COMMENT */
19
- font-size: 12px;
20
- }
21
- SCSS
22
- a {
23
- foo: bar;
24
- /* SOME COMMENT */
25
- font-size: 12px; }
26
-
27
- /*# sourceMappingURL=test.css.map */
28
- CSS
29
- {
30
- "version": 3,
31
- "mappings": "AAAA,CAAE;EACA,GAAG,EAAE,GAAG;;EAER,SAAS,EAAE,IAAI",
32
- "sources": ["test_simple_mapping_scss_inline.scss"],
33
- "names": [],
34
- "file": "test.css"
35
- }
36
- JSON
37
- end
38
-
39
- def test_simple_mapping_sass
40
- assert_parses_with_sourcemap <<SASS, <<CSS, <<JSON, :syntax => :sass
41
- a
42
- foo: bar
43
- /* SOME COMMENT */
44
- :font-size 12px
45
- SASS
46
- a {
47
- foo: bar;
48
- /* SOME COMMENT */
49
- font-size: 12px; }
50
-
51
- /*# sourceMappingURL=test.css.map */
52
- CSS
53
- {
54
- "version": 3,
55
- "mappings": "AAAA,CAAC;EACC,GAAG,EAAE,GAAG;;EAEP,SAAS,EAAC,IAAI",
56
- "sources": ["test_simple_mapping_sass_inline.sass"],
57
- "names": [],
58
- "file": "test.css"
59
- }
60
- JSON
61
- end
62
-
63
- def test_simple_mapping_with_file_uris
64
- uri = Sass::Util.file_uri_from_path(Sass::Util.absolute_path(filename_for_test(:scss)))
65
- assert_parses_with_sourcemap <<SCSS, <<CSS, <<JSON, :sourcemap => :file
66
- a {
67
- foo: bar;
68
- /* SOME COMMENT */
69
- font-size: 12px;
70
- }
71
- SCSS
72
- a {
73
- foo: bar;
74
- /* SOME COMMENT */
75
- font-size: 12px; }
76
-
77
- /*# sourceMappingURL=test.css.map */
78
- CSS
79
- {
80
- "version": 3,
81
- "mappings": "AAAA,CAAE;EACA,GAAG,EAAE,GAAG;;EAER,SAAS,EAAE,IAAI",
82
- "sources": ["#{uri}"],
83
- "names": [],
84
- "file": "test.css"
85
- }
86
- JSON
87
- end
88
-
89
- def test_mapping_with_directory_scss
90
- options = {:filename => "scss/style.scss", :output => "css/style.css"}
91
- assert_parses_with_sourcemap <<SCSS, <<CSS, <<JSON, options
92
- a {
93
- foo: bar;
94
- /* SOME COMMENT */
95
- font-size: 12px;
96
- }
97
- SCSS
98
- a {
99
- foo: bar;
100
- /* SOME COMMENT */
101
- font-size: 12px; }
102
-
103
- /*# sourceMappingURL=style.css.map */
104
- CSS
105
- {
106
- "version": 3,
107
- "mappings": "AAAA,CAAE;EACA,GAAG,EAAE,GAAG;;EAER,SAAS,EAAE,IAAI",
108
- "sources": ["../scss/style.scss"],
109
- "names": [],
110
- "file": "style.css"
111
- }
112
- JSON
113
- end
114
-
115
- def test_mapping_with_directory_sass
116
- options = {:filename => "sass/style.sass", :output => "css/style.css", :syntax => :sass}
117
- assert_parses_with_sourcemap <<SASS, <<CSS, <<JSON, options
118
- a
119
- foo: bar
120
- /* SOME COMMENT */
121
- :font-size 12px
122
- SASS
123
- a {
124
- foo: bar;
125
- /* SOME COMMENT */
126
- font-size: 12px; }
127
-
128
- /*# sourceMappingURL=style.css.map */
129
- CSS
130
- {
131
- "version": 3,
132
- "mappings": "AAAA,CAAC;EACC,GAAG,EAAE,GAAG;;EAEP,SAAS,EAAC,IAAI",
133
- "sources": ["../sass/style.sass"],
134
- "names": [],
135
- "file": "style.css"
136
- }
137
- JSON
138
- end
139
-
140
- unless Sass::Util.ruby1_8?
141
- def test_simple_charset_mapping_scss
142
- assert_parses_with_sourcemap <<SCSS, <<CSS, <<JSON
143
- a {
144
- fóó: bár;
145
- }
146
- SCSS
147
- @charset "UTF-8";
148
- a {
149
- fóó: bár; }
150
-
151
- /*# sourceMappingURL=test.css.map */
152
- CSS
153
- {
154
- "version": 3,
155
- "mappings": ";AAAA,CAAE;EACA,GAAG,EAAE,GAAG",
156
- "sources": ["test_simple_charset_mapping_scss_inline.scss"],
157
- "names": [],
158
- "file": "test.css"
159
- }
160
- JSON
161
- end
162
-
163
- def test_simple_charset_mapping_sass
164
- assert_parses_with_sourcemap <<SASS, <<CSS, <<JSON, :syntax => :sass
165
- a
166
- fóó: bár
167
- SASS
168
- @charset "UTF-8";
169
- a {
170
- fóó: bár; }
171
-
172
- /*# sourceMappingURL=test.css.map */
173
- CSS
174
- {
175
- "version": 3,
176
- "mappings": ";AAAA,CAAC;EACC,GAAG,EAAE,GAAG",
177
- "sources": ["test_simple_charset_mapping_sass_inline.sass"],
178
- "names": [],
179
- "file": "test.css"
180
- }
181
- JSON
182
- end
183
-
184
- def test_different_charset_than_encoding_scss
185
- assert_parses_with_sourcemap(<<SCSS.force_encoding("IBM866"), <<CSS, <<JSON)
186
- @charset "IBM866";
187
- f\x86\x86 {
188
- \x86: b;
189
- }
190
- SCSS
191
- @charset "UTF-8";
192
- fЖЖ {
193
- Ж: b; }
194
-
195
- /*# sourceMappingURL=test.css.map */
196
- CSS
197
- {
198
- "version": 3,
199
- "mappings": ";AACA,GAAI;EACF,CAAC,EAAE,CAAC",
200
- "sources": ["test_different_charset_than_encoding_scss_inline.scss"],
201
- "names": [],
202
- "file": "test.css"
203
- }
204
- JSON
205
- end
206
-
207
- def test_different_charset_than_encoding_sass
208
- assert_parses_with_sourcemap(<<SASS.force_encoding("IBM866"), <<CSS, <<JSON, :syntax => :sass)
209
- @charset "IBM866"
210
- f\x86\x86
211
- \x86: b
212
- SASS
213
- @charset "UTF-8";
214
- fЖЖ {
215
- Ж: b; }
216
-
217
- /*# sourceMappingURL=test.css.map */
218
- CSS
219
- {
220
- "version": 3,
221
- "mappings": ";AACA,GAAG;EACD,CAAC,EAAE,CAAC",
222
- "sources": ["test_different_charset_than_encoding_sass_inline.sass"],
223
- "names": [],
224
- "file": "test.css"
225
- }
226
- JSON
227
- end
228
- end
229
-
230
- def test_import_sourcemap_scss
231
- assert_parses_with_mapping <<'SCSS', <<'CSS'
232
- @import {{1}}url(foo){{/1}},{{2}}url(moo) {{/2}}, {{3}}url(bar) {{/3}};
233
- @import {{4}}url(baz) screen print{{/4}};
234
- SCSS
235
- {{1}}@import url(foo){{/1}};
236
- {{2}}@import url(moo){{/2}};
237
- {{3}}@import url(bar){{/3}};
238
- {{4}}@import url(baz) screen print{{/4}};
239
-
240
- /*# sourceMappingURL=test.css.map */
241
- CSS
242
- end
243
-
244
- def test_import_sourcemap_sass
245
- assert_parses_with_mapping <<'SASS', <<'CSS', :syntax => :sass
246
- @import {{1}}foo.css{{/1}},{{2}}moo.css{{/2}}, {{3}}bar.css{{/3}}
247
- @import {{4}}url(baz.css){{/4}}
248
- @import {{5}}url(qux.css) screen print{{/5}}
249
- SASS
250
- {{1}}@import url(foo.css){{/1}};
251
- {{2}}@import url(moo.css){{/2}};
252
- {{3}}@import url(bar.css){{/3}};
253
- {{4}}@import url(baz.css){{/4}};
254
- {{5}}@import url(qux.css) screen print{{/5}};
255
-
256
- /*# sourceMappingURL=test.css.map */
257
- CSS
258
- end
259
-
260
- def test_media_sourcemap_scss
261
- assert_parses_with_mapping <<'SCSS', <<'CSS'
262
- {{1}}@media screen, tv {{/1}}{
263
- {{2}}body {{/2}}{
264
- {{3}}max-width{{/3}}: {{4}}1070px{{/4}};
265
- }
266
- }
267
- SCSS
268
- {{1}}@media screen, tv{{/1}} {
269
- {{2}}body{{/2}} {
270
- {{3}}max-width{{/3}}: {{4}}1070px{{/4}}; } }
271
-
272
- /*# sourceMappingURL=test.css.map */
273
- CSS
274
- end
275
-
276
- def test_media_sourcemap_sass
277
- assert_parses_with_mapping <<'SASS', <<'CSS', :syntax => :sass
278
- {{1}}@media screen, tv{{/1}}
279
- {{2}}body{{/2}}
280
- {{3}}max-width{{/3}}: {{4}}1070px{{/4}}
281
- SASS
282
- {{1}}@media screen, tv{{/1}} {
283
- {{2}}body{{/2}} {
284
- {{3}}max-width{{/3}}: {{4}}1070px{{/4}}; } }
285
-
286
- /*# sourceMappingURL=test.css.map */
287
- CSS
288
- end
289
-
290
- def test_interpolation_and_vars_sourcemap_scss
291
- assert_parses_with_mapping <<'SCSS', <<'CSS'
292
- $te: "te";
293
- $teal: {{5}}teal{{/5}};
294
- {{1}}p {{/1}}{
295
- {{2}}con#{$te}nt{{/2}}: {{3}}"I a#{$te} #{5 + 10} pies!"{{/3}};
296
- {{4}}color{{/4}}: $teal;
297
- }
298
-
299
- $name: foo;
300
- $attr: border;
301
- {{6}}p.#{$name} {{/6}}{
302
- {{7}}#{$attr}-color{{/7}}: {{8}}blue{{/8}};
303
- $font-size: 12px;
304
- $line-height: 30px;
305
- {{9}}font{{/9}}: {{10}}#{$font-size}/#{$line-height}{{/10}};
306
- }
307
- SCSS
308
- {{1}}p{{/1}} {
309
- {{2}}content{{/2}}: {{3}}"I ate 15 pies!"{{/3}};
310
- {{4}}color{{/4}}: {{5}}teal{{/5}}; }
311
-
312
- {{6}}p.foo{{/6}} {
313
- {{7}}border-color{{/7}}: {{8}}blue{{/8}};
314
- {{9}}font{{/9}}: {{10}}12px/30px{{/10}}; }
315
-
316
- /*# sourceMappingURL=test.css.map */
317
- CSS
318
- end
319
-
320
- def test_interpolation_and_vars_sourcemap_sass
321
- assert_parses_with_mapping <<'SASS', <<'CSS', :syntax => :sass
322
- $te: "te"
323
- $teal: {{5}}teal{{/5}}
324
- {{1}}p{{/1}}
325
- {{2}}con#{$te}nt{{/2}}: {{3}}"I a#{$te} #{5 + 10} pies!"{{/3}}
326
- {{4}}color{{/4}}: $teal
327
-
328
- $name: foo
329
- $attr: border
330
- {{6}}p.#{$name}{{/6}}
331
- {{7}}#{$attr}-color{{/7}}: {{8}}blue{{/8}}
332
- $font-size: 12px
333
- $line-height: 30px
334
- {{9}}font{{/9}}: {{10}}#{$font-size}/#{$line-height}{{/10}}
335
- SASS
336
- {{1}}p{{/1}} {
337
- {{2}}content{{/2}}: {{3}}"I ate 15 pies!"{{/3}};
338
- {{4}}color{{/4}}: {{5}}teal{{/5}}; }
339
-
340
- {{6}}p.foo{{/6}} {
341
- {{7}}border-color{{/7}}: {{8}}blue{{/8}};
342
- {{9}}font{{/9}}: {{10}}12px/30px{{/10}}; }
343
-
344
- /*# sourceMappingURL=test.css.map */
345
- CSS
346
- end
347
-
348
- def test_selectors_properties_sourcemap_scss
349
- assert_parses_with_mapping <<'SCSS', <<'CSS'
350
- $width: 2px;
351
- $translucent-red: rgba(255, 0, 0, 0.5);
352
- {{1}}a {{/1}}{
353
- {{8}}.special {{/8}}{
354
- {{9}}color{{/9}}: {{10}}red{{/10}};
355
- {{11}}&:hover {{/11}}{
356
- {{12}}foo{{/12}}: {{13}}bar{{/13}};
357
- {{14}}cursor{{/14}}: {{15}}e + -resize{{/15}};
358
- {{16}}color{{/16}}: {{17}}opacify($translucent-red, 0.3){{/17}};
359
- }
360
- {{18}}&:after {{/18}}{
361
- {{19}}content{{/19}}: {{20}}"I ate #{5 + 10} pies #{$width} thick!"{{/20}};
362
- }
363
- }
364
- {{21}}&:active {{/21}}{
365
- {{22}}color{{/22}}: {{23}}#010203 + #040506{{/23}};
366
- {{24}}border{{/24}}: {{25}}$width solid black{{/25}};
367
- }
368
- /* SOME COMMENT */
369
- {{2}}font{{/2}}: {{3}}2px/3px {{/3}}{
370
- {{4}}family{{/4}}: {{5}}fantasy{{/5}};
371
- {{6}}size{{/6}}: {{7}}1em + (2em * 3){{/7}};
372
- }
373
- }
374
- SCSS
375
- {{1}}a{{/1}} {
376
- /* SOME COMMENT */
377
- {{2}}font{{/2}}: {{3}}2px/3px{{/3}};
378
- {{4}}font-family{{/4}}: {{5}}fantasy{{/5}};
379
- {{6}}font-size{{/6}}: {{7}}7em{{/7}}; }
380
- {{8}}a .special{{/8}} {
381
- {{9}}color{{/9}}: {{10}}red{{/10}}; }
382
- {{11}}a .special:hover{{/11}} {
383
- {{12}}foo{{/12}}: {{13}}bar{{/13}};
384
- {{14}}cursor{{/14}}: {{15}}e-resize{{/15}};
385
- {{16}}color{{/16}}: {{17}}rgba(255, 0, 0, 0.8){{/17}}; }
386
- {{18}}a .special:after{{/18}} {
387
- {{19}}content{{/19}}: {{20}}"I ate 15 pies 2px thick!"{{/20}}; }
388
- {{21}}a:active{{/21}} {
389
- {{22}}color{{/22}}: {{23}}#050709{{/23}};
390
- {{24}}border{{/24}}: {{25}}2px solid black{{/25}}; }
391
-
392
- /*# sourceMappingURL=test.css.map */
393
- CSS
394
- end
395
-
396
- def test_selectors_properties_sourcemap_sass
397
- assert_parses_with_mapping <<'SASS', <<'CSS', :syntax => :sass
398
- $width: 2px
399
- $translucent-red: rgba(255, 0, 0, 0.5)
400
- {{1}}a{{/1}}
401
- {{8}}.special{{/8}}
402
- {{9}}color{{/9}}: {{10}}red{{/10}}
403
- {{11}}&:hover{{/11}}
404
- {{12}}foo{{/12}}: {{13}}bar{{/13}}
405
- {{14}}cursor{{/14}}: {{15}}e + -resize{{/15}}
406
- {{16}}color{{/16}}: {{17}}opacify($translucent-red, 0.3){{/17}}
407
- {{18}}&:after{{/18}}
408
- {{19}}content{{/19}}: {{20}}"I ate #{5 + 10} pies #{$width} thick!"{{/20}}
409
- {{21}}&:active{{/21}}
410
- {{22}}color{{/22}}: {{23}}#010203 + #040506{{/23}}
411
- {{24}}border{{/24}}: {{25}}$width solid black{{/25}}
412
-
413
- /* SOME COMMENT */
414
- {{2}}font{{/2}}: {{3}}2px/3px{{/3}}
415
- {{4}}family{{/4}}: {{5}}fantasy{{/5}}
416
- {{6}}size{{/6}}: {{7}}1em + (2em * 3){{/7}}
417
- SASS
418
- {{1}}a{{/1}} {
419
- /* SOME COMMENT */
420
- {{2}}font{{/2}}: {{3}}2px/3px{{/3}};
421
- {{4}}font-family{{/4}}: {{5}}fantasy{{/5}};
422
- {{6}}font-size{{/6}}: {{7}}7em{{/7}}; }
423
- {{8}}a .special{{/8}} {
424
- {{9}}color{{/9}}: {{10}}red{{/10}}; }
425
- {{11}}a .special:hover{{/11}} {
426
- {{12}}foo{{/12}}: {{13}}bar{{/13}};
427
- {{14}}cursor{{/14}}: {{15}}e-resize{{/15}};
428
- {{16}}color{{/16}}: {{17}}rgba(255, 0, 0, 0.8){{/17}}; }
429
- {{18}}a .special:after{{/18}} {
430
- {{19}}content{{/19}}: {{20}}"I ate 15 pies 2px thick!"{{/20}}; }
431
- {{21}}a:active{{/21}} {
432
- {{22}}color{{/22}}: {{23}}#050709{{/23}};
433
- {{24}}border{{/24}}: {{25}}2px solid black{{/25}}; }
434
-
435
- /*# sourceMappingURL=test.css.map */
436
- CSS
437
- end
438
-
439
- def test_extend_sourcemap_scss
440
- assert_parses_with_mapping <<'SCSS', <<'CSS'
441
- {{1}}.error {{/1}}{
442
- {{2}}border{{/2}}: {{3}}1px #ff00aa{{/3}};
443
- {{4}}background-color{{/4}}: {{5}}#fdd{{/5}};
444
- }
445
- {{6}}.seriousError {{/6}}{
446
- @extend .error;
447
- {{7}}border-width{{/7}}: {{8}}3px{{/8}};
448
- }
449
- SCSS
450
- {{1}}.error, .seriousError{{/1}} {
451
- {{2}}border{{/2}}: {{3}}1px #ff00aa{{/3}};
452
- {{4}}background-color{{/4}}: {{5}}#fdd{{/5}}; }
453
-
454
- {{6}}.seriousError{{/6}} {
455
- {{7}}border-width{{/7}}: {{8}}3px{{/8}}; }
456
-
457
- /*# sourceMappingURL=test.css.map */
458
- CSS
459
- end
460
-
461
- def test_extend_sourcemap_sass
462
- assert_parses_with_mapping <<'SASS', <<'CSS', :syntax => :sass
463
- {{1}}.error{{/1}}
464
- {{2}}border{{/2}}: {{3}}1px #f00{{/3}}
465
- {{4}}background-color{{/4}}: {{5}}#fdd{{/5}}
466
-
467
- {{6}}.seriousError{{/6}}
468
- @extend .error
469
- {{7}}border-width{{/7}}: {{8}}3px{{/8}}
470
- SASS
471
- {{1}}.error, .seriousError{{/1}} {
472
- {{2}}border{{/2}}: {{3}}1px #f00{{/3}};
473
- {{4}}background-color{{/4}}: {{5}}#fdd{{/5}}; }
474
-
475
- {{6}}.seriousError{{/6}} {
476
- {{7}}border-width{{/7}}: {{8}}3px{{/8}}; }
477
-
478
- /*# sourceMappingURL=test.css.map */
479
- CSS
480
- end
481
-
482
- def test_for_sourcemap_scss
483
- assert_parses_with_mapping <<'SCSS', <<'CSS'
484
- @for $i from 1 through 3 {
485
- {{1}}{{4}}{{7}}.item-#{$i} {{/1}}{{/4}}{{/7}}{ {{2}}{{5}}{{8}}width{{/2}}{{/5}}{{/8}}: {{3}}{{6}}{{9}}2em * $i{{/3}}{{/6}}{{/9}}; }
486
- }
487
- SCSS
488
- {{1}}.item-1{{/1}} {
489
- {{2}}width{{/2}}: {{3}}2em{{/3}}; }
490
-
491
- {{4}}.item-2{{/4}} {
492
- {{5}}width{{/5}}: {{6}}4em{{/6}}; }
493
-
494
- {{7}}.item-3{{/7}} {
495
- {{8}}width{{/8}}: {{9}}6em{{/9}}; }
496
-
497
- /*# sourceMappingURL=test.css.map */
498
- CSS
499
- end
500
-
501
- def test_for_sourcemap_sass
502
- assert_parses_with_mapping <<'SASS', <<'CSS', :syntax => :sass
503
- @for $i from 1 through 3
504
- {{1}}{{4}}{{7}}.item-#{$i}{{/1}}{{/4}}{{/7}}
505
- {{2}}{{5}}{{8}}width{{/2}}{{/5}}{{/8}}: {{3}}{{6}}{{9}}2em * $i{{/3}}{{/6}}{{/9}}
506
- SASS
507
- {{1}}.item-1{{/1}} {
508
- {{2}}width{{/2}}: {{3}}2em{{/3}}; }
509
-
510
- {{4}}.item-2{{/4}} {
511
- {{5}}width{{/5}}: {{6}}4em{{/6}}; }
512
-
513
- {{7}}.item-3{{/7}} {
514
- {{8}}width{{/8}}: {{9}}6em{{/9}}; }
515
-
516
- /*# sourceMappingURL=test.css.map */
517
- CSS
518
- end
519
-
520
- def test_while_sourcemap_scss
521
- assert_parses_with_mapping <<'SCSS', <<'CSS'
522
- $i: 6;
523
- @while $i > 0 {
524
- {{1}}{{4}}{{7}}.item-#{$i} {{/1}}{{/4}}{{/7}}{ {{2}}{{5}}{{8}}width{{/2}}{{/5}}{{/8}}: {{3}}{{6}}{{9}}2em * $i{{/3}}{{/6}}{{/9}}; }
525
- $i: $i - 2 !global;
526
- }
527
- SCSS
528
- {{1}}.item-6{{/1}} {
529
- {{2}}width{{/2}}: {{3}}12em{{/3}}; }
530
-
531
- {{4}}.item-4{{/4}} {
532
- {{5}}width{{/5}}: {{6}}8em{{/6}}; }
533
-
534
- {{7}}.item-2{{/7}} {
535
- {{8}}width{{/8}}: {{9}}4em{{/9}}; }
536
-
537
- /*# sourceMappingURL=test.css.map */
538
- CSS
539
- end
540
-
541
- def test_while_sourcemap_sass
542
- assert_parses_with_mapping <<'SASS', <<'CSS', :syntax => :sass
543
- $i: 6
544
- @while $i > 0
545
- {{1}}{{4}}{{7}}.item-#{$i}{{/1}}{{/4}}{{/7}}
546
- {{2}}{{5}}{{8}}width{{/2}}{{/5}}{{/8}}: {{3}}{{6}}{{9}}2em * $i{{/3}}{{/6}}{{/9}}
547
- $i: $i - 2 !global
548
- SASS
549
- {{1}}.item-6{{/1}} {
550
- {{2}}width{{/2}}: {{3}}12em{{/3}}; }
551
-
552
- {{4}}.item-4{{/4}} {
553
- {{5}}width{{/5}}: {{6}}8em{{/6}}; }
554
-
555
- {{7}}.item-2{{/7}} {
556
- {{8}}width{{/8}}: {{9}}4em{{/9}}; }
557
-
558
- /*# sourceMappingURL=test.css.map */
559
- CSS
560
- end
561
-
562
- def test_each_sourcemap_scss
563
- assert_parses_with_mapping <<'SCSS', <<'CSS'
564
- @each $animal in puma, sea-slug, egret, salamander {
565
- {{1}}{{4}}{{7}}{{10}}.#{$animal}-icon {{/1}}{{/4}}{{/7}}{{/10}}{
566
- {{2}}{{5}}{{8}}{{11}}background-image{{/2}}{{/5}}{{/8}}{{/11}}: {{3}}{{6}}{{9}}{{12}}url('/images/#{$animal}.png'){{/3}}{{/6}}{{/9}}{{/12}};
567
- }
568
- }
569
- SCSS
570
- {{1}}.puma-icon{{/1}} {
571
- {{2}}background-image{{/2}}: {{3}}url("/images/puma.png"){{/3}}; }
572
-
573
- {{4}}.sea-slug-icon{{/4}} {
574
- {{5}}background-image{{/5}}: {{6}}url("/images/sea-slug.png"){{/6}}; }
575
-
576
- {{7}}.egret-icon{{/7}} {
577
- {{8}}background-image{{/8}}: {{9}}url("/images/egret.png"){{/9}}; }
578
-
579
- {{10}}.salamander-icon{{/10}} {
580
- {{11}}background-image{{/11}}: {{12}}url("/images/salamander.png"){{/12}}; }
581
-
582
- /*# sourceMappingURL=test.css.map */
583
- CSS
584
- end
585
-
586
- def test_each_sourcemap_sass
587
- assert_parses_with_mapping <<'SASS', <<'CSS', :syntax => :sass
588
- @each $animal in puma, sea-slug, egret, salamander
589
- {{1}}{{4}}{{7}}{{10}}.#{$animal}-icon{{/1}}{{/4}}{{/7}}{{/10}}
590
- {{2}}{{5}}{{8}}{{11}}background-image{{/2}}{{/5}}{{/8}}{{/11}}: {{3}}{{6}}{{9}}{{12}}url('/images/#{$animal}.png'){{/3}}{{/6}}{{/9}}{{/12}}
591
- SASS
592
- {{1}}.puma-icon{{/1}} {
593
- {{2}}background-image{{/2}}: {{3}}url("/images/puma.png"){{/3}}; }
594
-
595
- {{4}}.sea-slug-icon{{/4}} {
596
- {{5}}background-image{{/5}}: {{6}}url("/images/sea-slug.png"){{/6}}; }
597
-
598
- {{7}}.egret-icon{{/7}} {
599
- {{8}}background-image{{/8}}: {{9}}url("/images/egret.png"){{/9}}; }
600
-
601
- {{10}}.salamander-icon{{/10}} {
602
- {{11}}background-image{{/11}}: {{12}}url("/images/salamander.png"){{/12}}; }
603
-
604
- /*# sourceMappingURL=test.css.map */
605
- CSS
606
- end
607
-
608
- def test_mixin_sourcemap_scss
609
- assert_parses_with_mapping <<'SCSS', <<'CSS'
610
- @mixin large-text {
611
- font: {
612
- {{2}}size{{/2}}: {{3}}20px{{/3}};
613
- {{4}}weight{{/4}}: {{5}}bold{{/5}};
614
- }
615
- {{6}}color{{/6}}: {{7}}#ff0000{{/7}};
616
- }
617
-
618
- {{1}}.page-title {{/1}}{
619
- @include large-text;
620
- {{8}}padding{{/8}}: {{9}}4px{{/9}};
621
- }
622
-
623
- @mixin dashed-border($color, $width: {{14}}1in{{/14}}) {
624
- border: {
625
- {{11}}{{18}}color{{/11}}{{/18}}: $color;
626
- {{13}}{{20}}width{{/13}}{{/20}}: $width;
627
- {{15}}{{22}}style{{/15}}{{/22}}: {{16}}{{23}}dashed{{/16}}{{/23}};
628
- }
629
- }
630
-
631
- {{10}}p {{/10}}{ @include dashed-border({{12}}blue{{/12}}); }
632
- {{17}}h1 {{/17}}{ @include dashed-border({{19}}blue{{/19}}, {{21}}2in{{/21}}); }
633
-
634
- @mixin box-shadow($shadows...) {
635
- {{25}}-moz-box-shadow{{/25}}: {{26}}$shadows{{/26}};
636
- {{27}}-webkit-box-shadow{{/27}}: {{28}}$shadows{{/28}};
637
- {{29}}box-shadow{{/29}}: {{30}}$shadows{{/30}};
638
- }
639
-
640
- {{24}}.shadows {{/24}}{
641
- @include box-shadow(0px 4px 5px #666, 2px 6px 10px #999);
642
- }
643
- SCSS
644
- {{1}}.page-title{{/1}} {
645
- {{2}}font-size{{/2}}: {{3}}20px{{/3}};
646
- {{4}}font-weight{{/4}}: {{5}}bold{{/5}};
647
- {{6}}color{{/6}}: {{7}}#ff0000{{/7}};
648
- {{8}}padding{{/8}}: {{9}}4px{{/9}}; }
649
-
650
- {{10}}p{{/10}} {
651
- {{11}}border-color{{/11}}: {{12}}blue{{/12}};
652
- {{13}}border-width{{/13}}: {{14}}1in{{/14}};
653
- {{15}}border-style{{/15}}: {{16}}dashed{{/16}}; }
654
-
655
- {{17}}h1{{/17}} {
656
- {{18}}border-color{{/18}}: {{19}}blue{{/19}};
657
- {{20}}border-width{{/20}}: {{21}}2in{{/21}};
658
- {{22}}border-style{{/22}}: {{23}}dashed{{/23}}; }
659
-
660
- {{24}}.shadows{{/24}} {
661
- {{25}}-moz-box-shadow{{/25}}: {{26}}0px 4px 5px #666, 2px 6px 10px #999{{/26}};
662
- {{27}}-webkit-box-shadow{{/27}}: {{28}}0px 4px 5px #666, 2px 6px 10px #999{{/28}};
663
- {{29}}box-shadow{{/29}}: {{30}}0px 4px 5px #666, 2px 6px 10px #999{{/30}}; }
664
-
665
- /*# sourceMappingURL=test.css.map */
666
- CSS
667
- end
668
-
669
- def test_mixin_sourcemap_sass
670
- assert_parses_with_mapping <<'SASS', <<'CSS', :syntax => :sass
671
- =large-text
672
- :font
673
- {{2}}size{{/2}}: {{3}}20px{{/3}}
674
- {{4}}weight{{/4}}: {{5}}bold{{/5}}
675
- {{6}}color{{/6}}: {{7}}#ff0000{{/7}}
676
-
677
- {{1}}.page-title{{/1}}
678
- +large-text
679
- {{8}}padding{{/8}}: {{9}}4px{{/9}}
680
-
681
- =dashed-border($color, $width: {{14}}1in{{/14}})
682
- border:
683
- {{11}}{{18}}color{{/11}}{{/18}}: $color
684
- {{13}}{{20}}width{{/13}}{{/20}}: $width
685
- {{15}}{{22}}style{{/15}}{{/22}}: {{16}}{{23}}dashed{{/16}}{{/23}}
686
-
687
- {{10}}p{{/10}}
688
- +dashed-border({{12}}blue{{/12}})
689
-
690
- {{17}}h1{{/17}}
691
- +dashed-border({{19}}blue{{/19}}, {{21}}2in{{/21}})
692
-
693
- =box-shadow($shadows...)
694
- {{25}}-moz-box-shadow{{/25}}: {{26}}$shadows{{/26}}
695
- {{27}}-webkit-box-shadow{{/27}}: {{28}}$shadows{{/28}}
696
- {{29}}box-shadow{{/29}}: {{30}}$shadows{{/30}}
697
-
698
- {{24}}.shadows{{/24}}
699
- +box-shadow(0px 4px 5px #666, 2px 6px 10px #999)
700
- SASS
701
- {{1}}.page-title{{/1}} {
702
- {{2}}font-size{{/2}}: {{3}}20px{{/3}};
703
- {{4}}font-weight{{/4}}: {{5}}bold{{/5}};
704
- {{6}}color{{/6}}: {{7}}#ff0000{{/7}};
705
- {{8}}padding{{/8}}: {{9}}4px{{/9}}; }
706
-
707
- {{10}}p{{/10}} {
708
- {{11}}border-color{{/11}}: {{12}}blue{{/12}};
709
- {{13}}border-width{{/13}}: {{14}}1in{{/14}};
710
- {{15}}border-style{{/15}}: {{16}}dashed{{/16}}; }
711
-
712
- {{17}}h1{{/17}} {
713
- {{18}}border-color{{/18}}: {{19}}blue{{/19}};
714
- {{20}}border-width{{/20}}: {{21}}2in{{/21}};
715
- {{22}}border-style{{/22}}: {{23}}dashed{{/23}}; }
716
-
717
- {{24}}.shadows{{/24}} {
718
- {{25}}-moz-box-shadow{{/25}}: {{26}}0px 4px 5px #666, 2px 6px 10px #999{{/26}};
719
- {{27}}-webkit-box-shadow{{/27}}: {{28}}0px 4px 5px #666, 2px 6px 10px #999{{/28}};
720
- {{29}}box-shadow{{/29}}: {{30}}0px 4px 5px #666, 2px 6px 10px #999{{/30}}; }
721
-
722
- /*# sourceMappingURL=test.css.map */
723
- CSS
724
- end
725
-
726
- def test_function_sourcemap_scss
727
- assert_parses_with_mapping <<'SCSS', <<'CSS'
728
- $grid-width: 20px;
729
- $gutter-width: 5px;
730
-
731
- @function grid-width($n) {
732
- @return $n * $grid-width + ($n - 1) * $gutter-width;
733
- }
734
- {{1}}sidebar {{/1}}{ {{2}}width{{/2}}: {{3}}grid-width(5){{/3}}; }
735
- SCSS
736
- {{1}}sidebar{{/1}} {
737
- {{2}}width{{/2}}: {{3}}120px{{/3}}; }
738
-
739
- /*# sourceMappingURL=test.css.map */
740
- CSS
741
- end
742
-
743
- def test_function_sourcemap_sass
744
- assert_parses_with_mapping <<'SASS', <<'CSS', :syntax => :sass
745
- $grid-width: 20px
746
- $gutter-width: 5px
747
-
748
- @function grid-width($n)
749
- @return $n * $grid-width + ($n - 1) * $gutter-width
750
-
751
- {{1}}sidebar{{/1}}
752
- {{2}}width{{/2}}: {{3}}grid-width(5){{/3}}
753
- SASS
754
- {{1}}sidebar{{/1}} {
755
- {{2}}width{{/2}}: {{3}}120px{{/3}}; }
756
-
757
- /*# sourceMappingURL=test.css.map */
758
- CSS
759
- end
760
-
761
- # Regression tests
762
-
763
- def test_properties_sass
764
- assert_parses_with_mapping <<SASS, <<CSS, :syntax => :sass
765
- {{1}}.foo{{/1}}
766
- :{{2}}name{{/2}} {{3}}value{{/3}}
767
- {{4}}name{{/4}}: {{5}}value{{/5}}
768
- :{{6}}name{{/6}} {{7}}value{{/7}}
769
- {{8}}name{{/8}}: {{9}}value{{/9}}
770
- SASS
771
- {{1}}.foo{{/1}} {
772
- {{2}}name{{/2}}: {{3}}value{{/3}};
773
- {{4}}name{{/4}}: {{5}}value{{/5}};
774
- {{6}}name{{/6}}: {{7}}value{{/7}};
775
- {{8}}name{{/8}}: {{9}}value{{/9}}; }
776
-
777
- /*# sourceMappingURL=test.css.map */
778
- CSS
779
- end
780
-
781
- def test_multiline_script_scss
782
- assert_parses_with_mapping <<SCSS, <<CSS, :syntax => :scss
783
- $var: {{3}}foo +
784
- bar{{/3}}; {{1}}x {{/1}}{ {{2}}y{{/2}}: $var }
785
- SCSS
786
- {{1}}x{{/1}} {
787
- {{2}}y{{/2}}: {{3}}foobar{{/3}}; }
788
-
789
- /*# sourceMappingURL=test.css.map */
790
- CSS
791
- end
792
-
793
- def test_multiline_interpolation_source_range
794
- engine = Sass::Engine.new(<<-SCSS, :cache => false, :syntax => :scss)
795
- p {
796
- filter: progid:DXImageTransform(
797
- '\#{123}');
798
- }
799
- SCSS
800
-
801
- interpolated = engine.to_tree.children.
802
- first.children.
803
- first.value.children[1]
804
- assert_equal interpolated.to_sass, "\#{123}"
805
- range = interpolated.source_range
806
- assert_equal 3, range.start_pos.line
807
- assert_equal 12, range.start_pos.offset
808
- assert_equal 3, range.end_pos.line
809
- assert_equal 18, range.end_pos.offset
810
- end
811
-
812
- def test_sources_array_is_uri_escaped
813
- map = Sass::Source::Map.new
814
- importer = Sass::Importers::Filesystem.new('.')
815
- map.add(
816
- Sass::Source::Range.new(
817
- Sass::Source::Position.new(0, 0),
818
- Sass::Source::Position.new(0, 10),
819
- 'source file.scss',
820
- importer),
821
- Sass::Source::Range.new(
822
- Sass::Source::Position.new(0, 0),
823
- Sass::Source::Position.new(0, 10),
824
- nil, nil))
825
-
826
- json = map.to_json(:css_path => 'output file.css', :sourcemap_path => 'output file.css.map')
827
- assert_equal json, <<JSON.rstrip
828
- {
829
- "version": 3,
830
- "mappings": "DADD,UAAU",
831
- "sources": ["source%20file.scss"],
832
- "names": [],
833
- "file": "output%20file.css"
834
- }
835
- JSON
836
- end
837
-
838
- private
839
-
840
- ANNOTATION_REGEX = /\{\{(\/?)([^}]+)\}\}/
841
-
842
- def build_ranges(text, file_name = nil)
843
- ranges = Hash.new {|h, k| h[k] = []}
844
- start_positions = {}
845
- text.split("\n").each_with_index do |line_text, line|
846
- line += 1 # lines shoud be 1-based
847
- while (match = line_text.match(ANNOTATION_REGEX))
848
- closing = !match[1].empty?
849
- name = match[2]
850
- match_offsets = match.offset(0)
851
- offset = match_offsets[0] + 1 # Offsets are 1-based in source maps.
852
- assert(!closing || start_positions[name], "Closing annotation #{name} found before opening one.")
853
- position = Sass::Source::Position.new(line, offset)
854
- if closing
855
- ranges[name] << Sass::Source::Range.new(
856
- start_positions[name], position, file_name,
857
- Sass::Importers::Filesystem.new('.'))
858
- start_positions.delete name
859
- else
860
- assert(!start_positions[name], "Overlapping range annotation #{name} encountered on line #{line}")
861
- start_positions[name] = position
862
- end
863
- line_text.slice!(match_offsets[0], match_offsets[1] - match_offsets[0])
864
- end
865
- end
866
- ranges
867
- end
868
-
869
- def build_mapping_from_annotations(source, css, source_file_name)
870
- source_ranges = build_ranges(source, source_file_name)
871
- target_ranges = build_ranges(css)
872
- map = Sass::Source::Map.new
873
- Sass::Util.flatten(source_ranges.map do |(name, sources)|
874
- assert(sources.length == 1, "#{sources.length} source ranges encountered for annotation #{name}")
875
- assert(target_ranges[name], "No target ranges for annotation #{name}")
876
- target_ranges[name].map {|target_range| [sources.first, target_range]}
877
- end, 1).
878
- sort_by {|(_, target)| [target.start_pos.line, target.start_pos.offset]}.
879
- each {|(s2, target)| map.add(s2, target)}
880
- map
881
- end
882
-
883
- def assert_parses_with_mapping(source, css, options={})
884
- options[:syntax] ||= :scss
885
- input_filename = filename_for_test(options[:syntax])
886
- mapping = build_mapping_from_annotations(source, css, input_filename)
887
- source.gsub!(ANNOTATION_REGEX, "")
888
- css.gsub!(ANNOTATION_REGEX, "")
889
- rendered, sourcemap = render_with_sourcemap(source, options)
890
- assert_equal css.rstrip, rendered.rstrip
891
- assert_sourcemaps_equal source, css, mapping, sourcemap
892
- end
893
-
894
- def assert_positions_equal(expected, actual, lines, message = nil)
895
- prefix = message ? message + ": " : ""
896
- expected_location = lines[expected.line - 1] + "\n" + ("-" * (expected.offset - 1)) + "^"
897
- actual_location = lines[actual.line - 1] + "\n" + ("-" * (actual.offset - 1)) + "^"
898
- assert_equal(expected.line, actual.line, prefix +
899
- "Expected #{expected.inspect}\n" +
900
- expected_location + "\n\n" +
901
- "But was #{actual.inspect}\n" +
902
- actual_location)
903
- assert_equal(expected.offset, actual.offset, prefix +
904
- "Expected #{expected.inspect}\n" +
905
- expected_location + "\n\n" +
906
- "But was #{actual.inspect}\n" +
907
- actual_location)
908
- end
909
-
910
- def assert_ranges_equal(expected, actual, lines, prefix)
911
- assert_positions_equal(expected.start_pos, actual.start_pos, lines, prefix + " start position")
912
- assert_positions_equal(expected.end_pos, actual.end_pos, lines, prefix + " end position")
913
- assert_equal(expected.file, actual.file)
914
- end
915
-
916
- def assert_sourcemaps_equal(source, css, expected, actual)
917
- assert_equal(expected.data.length, actual.data.length, <<MESSAGE)
918
- Wrong number of mappings. Expected:
919
- #{dump_sourcemap_as_expectation(source, css, expected).gsub(/^/, '| ')}
920
-
921
- Actual:
922
- #{dump_sourcemap_as_expectation(source, css, actual).gsub(/^/, '| ')}
923
- MESSAGE
924
- source_lines = source.split("\n")
925
- css_lines = css.split("\n")
926
- expected.data.zip(actual.data) do |expected_mapping, actual_mapping|
927
- assert_ranges_equal(expected_mapping.input, actual_mapping.input, source_lines, "Input")
928
- assert_ranges_equal(expected_mapping.output, actual_mapping.output, css_lines, "Output")
929
- end
930
- end
931
-
932
- def assert_parses_with_sourcemap(source, css, sourcemap_json, options={})
933
- rendered, sourcemap = render_with_sourcemap(source, options)
934
- css_path = options[:output] || "test.css"
935
- sourcemap_path = Sass::Util.sourcemap_name(css_path)
936
- rendered_json = sourcemap.to_json(:css_path => css_path, :sourcemap_path => sourcemap_path, :type => options[:sourcemap])
937
-
938
- assert_equal css.rstrip, rendered.rstrip
939
- assert_equal sourcemap_json.rstrip, rendered_json
940
- end
941
-
942
- def render_with_sourcemap(source, options={})
943
- options[:syntax] ||= :scss
944
- munge_filename options
945
- engine = Sass::Engine.new(source, options)
946
- engine.options[:cache] = false
947
- sourcemap_path = Sass::Util.sourcemap_name(options[:output] || "test.css")
948
- engine.render_with_sourcemap File.basename(sourcemap_path)
949
- end
950
-
951
- def dump_sourcemap_as_expectation(source, css, sourcemap)
952
- mappings_to_annotations(source, sourcemap.data.map {|d| d.input}) + "\n\n" +
953
- "=" * 20 + " maps to:\n\n" +
954
- mappings_to_annotations(css, sourcemap.data.map {|d| d.output})
955
- end
956
-
957
- def mappings_to_annotations(source, ranges)
958
- additional_offsets = Hash.new(0)
959
- lines = source.split("\n")
960
-
961
- add_annotation = lambda do |pos, str|
962
- line_num = pos.line - 1
963
- line = lines[line_num]
964
- offset = pos.offset + additional_offsets[line_num] - 1
965
- line << " " * (offset - line.length) if offset > line.length
966
- line.insert(offset, str)
967
- additional_offsets[line_num] += str.length
968
- end
969
-
970
- ranges.each_with_index do |range, i|
971
- add_annotation[range.start_pos, "{{#{i + 1}}}"]
972
- add_annotation[range.end_pos, "{{/#{i + 1}}}"]
973
- end
974
-
975
- return lines.join("\n")
976
- end
977
- end