oreorenasass 3.4.4 → 3.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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