sass 3.5.2 → 3.7.4

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