sass 3.5.2 → 3.7.4

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 (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