sass 3.6.0 → 3.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. checksums.yaml +5 -5
  2. data/CONTRIBUTING.md +1 -1
  3. data/README.md +10 -0
  4. data/VERSION +1 -1
  5. data/VERSION_DATE +1 -1
  6. data/lib/sass/script/css_parser.rb +4 -1
  7. data/lib/sass/script/functions.rb +15 -25
  8. data/lib/sass/script/lexer.rb +45 -7
  9. data/lib/sass/script/parser.rb +259 -93
  10. data/lib/sass/scss/parser.rb +43 -16
  11. data/lib/sass/scss/static_parser.rb +15 -15
  12. data/lib/sass/util.rb +31 -0
  13. metadata +8 -156
  14. data/Rakefile +0 -364
  15. data/test/sass-spec.yml +0 -3
  16. data/test/sass/cache_test.rb +0 -130
  17. data/test/sass/callbacks_test.rb +0 -60
  18. data/test/sass/compiler_test.rb +0 -225
  19. data/test/sass/conversion_test.rb +0 -2138
  20. data/test/sass/css2sass_test.rb +0 -523
  21. data/test/sass/css_variable_test.rb +0 -237
  22. data/test/sass/data/hsl-rgb.txt +0 -319
  23. data/test/sass/encoding_test.rb +0 -188
  24. data/test/sass/engine_test.rb +0 -3499
  25. data/test/sass/exec_test.rb +0 -95
  26. data/test/sass/extend_test.rb +0 -1679
  27. data/test/sass/fixtures/test_staleness_check_across_importers.css +0 -1
  28. data/test/sass/fixtures/test_staleness_check_across_importers.scss +0 -1
  29. data/test/sass/functions_test.rb +0 -2021
  30. data/test/sass/importer_test.rb +0 -420
  31. data/test/sass/logger_test.rb +0 -57
  32. data/test/sass/mock_importer.rb +0 -49
  33. data/test/sass/more_results/more1.css +0 -9
  34. data/test/sass/more_results/more1_with_line_comments.css +0 -26
  35. data/test/sass/more_results/more_import.css +0 -29
  36. data/test/sass/more_templates/_more_partial.sass +0 -2
  37. data/test/sass/more_templates/more1.sass +0 -23
  38. data/test/sass/more_templates/more_import.sass +0 -11
  39. data/test/sass/plugin_test.rb +0 -552
  40. data/test/sass/results/alt.css +0 -4
  41. data/test/sass/results/basic.css +0 -9
  42. data/test/sass/results/cached_import_option.css +0 -3
  43. data/test/sass/results/compact.css +0 -5
  44. data/test/sass/results/complex.css +0 -86
  45. data/test/sass/results/compressed.css +0 -1
  46. data/test/sass/results/expanded.css +0 -19
  47. data/test/sass/results/filename_fn.css +0 -3
  48. data/test/sass/results/if.css +0 -3
  49. data/test/sass/results/import.css +0 -31
  50. data/test/sass/results/import_charset.css +0 -5
  51. data/test/sass/results/import_charset_ibm866.css +0 -5
  52. data/test/sass/results/import_content.css +0 -1
  53. data/test/sass/results/line_numbers.css +0 -49
  54. data/test/sass/results/mixins.css +0 -95
  55. data/test/sass/results/multiline.css +0 -24
  56. data/test/sass/results/nested.css +0 -22
  57. data/test/sass/results/options.css +0 -1
  58. data/test/sass/results/parent_ref.css +0 -13
  59. data/test/sass/results/script.css +0 -16
  60. data/test/sass/results/scss_import.css +0 -31
  61. data/test/sass/results/scss_importee.css +0 -2
  62. data/test/sass/results/subdir/nested_subdir/nested_subdir.css +0 -1
  63. data/test/sass/results/subdir/subdir.css +0 -3
  64. data/test/sass/results/units.css +0 -11
  65. data/test/sass/results/warn.css +0 -0
  66. data/test/sass/results/warn_imported.css +0 -0
  67. data/test/sass/script_conversion_test.rb +0 -365
  68. data/test/sass/script_test.rb +0 -1427
  69. data/test/sass/scss/css_test.rb +0 -1266
  70. data/test/sass/scss/rx_test.rb +0 -159
  71. data/test/sass/scss/scss_test.rb +0 -4238
  72. data/test/sass/scss/test_helper.rb +0 -37
  73. data/test/sass/source_map_test.rb +0 -1063
  74. data/test/sass/superselector_test.rb +0 -209
  75. data/test/sass/templates/_cached_import_option_partial.scss +0 -1
  76. data/test/sass/templates/_double_import_loop2.sass +0 -1
  77. data/test/sass/templates/_filename_fn_import.scss +0 -11
  78. data/test/sass/templates/_imported_charset_ibm866.sass +0 -4
  79. data/test/sass/templates/_imported_charset_utf8.sass +0 -4
  80. data/test/sass/templates/_imported_content.sass +0 -3
  81. data/test/sass/templates/_partial.sass +0 -2
  82. data/test/sass/templates/_same_name_different_partiality.scss +0 -1
  83. data/test/sass/templates/alt.sass +0 -16
  84. data/test/sass/templates/basic.sass +0 -23
  85. data/test/sass/templates/bork1.sass +0 -2
  86. data/test/sass/templates/bork2.sass +0 -2
  87. data/test/sass/templates/bork3.sass +0 -2
  88. data/test/sass/templates/bork4.sass +0 -2
  89. data/test/sass/templates/bork5.sass +0 -3
  90. data/test/sass/templates/cached_import_option.scss +0 -3
  91. data/test/sass/templates/compact.sass +0 -17
  92. data/test/sass/templates/complex.sass +0 -305
  93. data/test/sass/templates/compressed.sass +0 -15
  94. data/test/sass/templates/double_import_loop1.sass +0 -1
  95. data/test/sass/templates/expanded.sass +0 -17
  96. data/test/sass/templates/filename_fn.scss +0 -18
  97. data/test/sass/templates/if.sass +0 -11
  98. data/test/sass/templates/import.sass +0 -12
  99. data/test/sass/templates/import_charset.sass +0 -9
  100. data/test/sass/templates/import_charset_ibm866.sass +0 -11
  101. data/test/sass/templates/import_content.sass +0 -4
  102. data/test/sass/templates/importee.less +0 -2
  103. data/test/sass/templates/importee.sass +0 -19
  104. data/test/sass/templates/line_numbers.sass +0 -13
  105. data/test/sass/templates/mixin_bork.sass +0 -5
  106. data/test/sass/templates/mixins.sass +0 -76
  107. data/test/sass/templates/multiline.sass +0 -20
  108. data/test/sass/templates/nested.sass +0 -25
  109. data/test/sass/templates/nested_bork1.sass +0 -2
  110. data/test/sass/templates/nested_bork2.sass +0 -2
  111. data/test/sass/templates/nested_bork3.sass +0 -2
  112. data/test/sass/templates/nested_bork4.sass +0 -2
  113. data/test/sass/templates/nested_import.sass +0 -2
  114. data/test/sass/templates/nested_mixin_bork.sass +0 -6
  115. data/test/sass/templates/options.sass +0 -2
  116. data/test/sass/templates/parent_ref.sass +0 -25
  117. data/test/sass/templates/same_name_different_ext.sass +0 -2
  118. data/test/sass/templates/same_name_different_ext.scss +0 -1
  119. data/test/sass/templates/same_name_different_partiality.scss +0 -1
  120. data/test/sass/templates/script.sass +0 -101
  121. data/test/sass/templates/scss_import.scss +0 -12
  122. data/test/sass/templates/scss_importee.scss +0 -1
  123. data/test/sass/templates/single_import_loop.sass +0 -1
  124. data/test/sass/templates/subdir/import_up1.scss +0 -1
  125. data/test/sass/templates/subdir/import_up2.scss +0 -1
  126. data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +0 -2
  127. data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +0 -3
  128. data/test/sass/templates/subdir/subdir.sass +0 -6
  129. data/test/sass/templates/units.sass +0 -11
  130. data/test/sass/templates/warn.sass +0 -3
  131. data/test/sass/templates/warn_imported.sass +0 -4
  132. data/test/sass/test_helper.rb +0 -8
  133. data/test/sass/util/multibyte_string_scanner_test.rb +0 -152
  134. data/test/sass/util/normalized_map_test.rb +0 -50
  135. data/test/sass/util/subset_map_test.rb +0 -90
  136. data/test/sass/util_test.rb +0 -393
  137. data/test/sass/value_helpers_test.rb +0 -178
  138. data/test/test_helper.rb +0 -149
@@ -1,2 +0,0 @@
1
- scss {
2
- imported: yes; }
@@ -1 +0,0 @@
1
- #pi { width: 314px; }
@@ -1,3 +0,0 @@
1
- #nested { relative: true; }
2
-
3
- #subdir { font-size: 20px; font-weight: bold; }
@@ -1,11 +0,0 @@
1
- b {
2
- foo: 5px;
3
- bar: 24px;
4
- baz: 66.6666666667%;
5
- many-units: 32em;
6
- mm: 15mm;
7
- pc: 2pc;
8
- pt: -72pt;
9
- inches: 2in;
10
- more-inches: 3.5in;
11
- mixed: 2.0416666667in; }
File without changes
File without changes
@@ -1,365 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- require File.dirname(__FILE__) + '/../test_helper'
3
- require 'sass/engine'
4
-
5
- class SassScriptConversionTest < MiniTest::Test
6
- def test_bool
7
- assert_renders "true"
8
- assert_renders "false"
9
- end
10
-
11
- def test_color
12
- assert_renders "#abcdef"
13
- assert_renders "blue"
14
- assert_renders "rgba(0, 1, 2, 0.2)"
15
- assert_renders "#abc"
16
- assert_renders "#0000ff"
17
- end
18
-
19
- def test_number
20
- assert_renders "10"
21
- assert_renders "10.35"
22
- assert_renders "12px"
23
- assert_renders "12.45px"
24
-
25
- assert_equal "12.3456789013", render("12.34567890129")
26
- end
27
-
28
- def test_string
29
- assert_renders '"foo"'
30
- assert_renders '"bar baz"'
31
- assert_equal '"baz bang"', render("'baz bang'")
32
- end
33
-
34
- def test_string_quotes
35
- assert_equal "'quote\"quote'", render('"quote\\"quote"')
36
- assert_equal '"quote\'quote"', render("'quote\\'quote'")
37
- assert_renders '"quote\'quote\\"quote"'
38
- assert_equal '"quote\'quote\\"quote"', render("'quote\\'quote\"quote'")
39
- end
40
-
41
- def test_string_escapes
42
- assert_renders '"foo\\\\bar"'
43
- end
44
-
45
- def test_funcall
46
- assert_renders "foo(true, blue)"
47
- assert_renders "hsla(20deg, 30%, 50%, 0.3)"
48
- assert_renders "blam()"
49
-
50
- assert_renders "-\xC3\xBFoo(12px)"
51
- assert_renders "-foo(12px)"
52
- end
53
-
54
- def test_funcall_with_keyword_args
55
- assert_renders "foo(arg1, arg2, $karg1: val, $karg2: val2)"
56
- assert_renders "foo($karg1: val, $karg2: val2)"
57
- end
58
-
59
- def test_funcall_with_hyphen_conversion_keyword_arg
60
- assert_renders "foo($a-b_c: val)"
61
- end
62
-
63
- def test_url
64
- assert_renders "url(foo.gif)"
65
- assert_renders "url($var)"
66
- assert_renders "url(\#{$var}/flip.gif)"
67
- end
68
-
69
- def test_variable
70
- assert_renders "$foo-bar"
71
- assert_renders "$flaznicate"
72
- end
73
-
74
- def test_null
75
- assert_renders "null"
76
- end
77
-
78
- def test_space_list
79
- assert_renders "foo bar baz"
80
- assert_renders "foo (bar baz) bip"
81
- assert_renders "foo (bar, baz) bip"
82
- end
83
-
84
- def test_comma_list
85
- assert_renders "foo, bar, baz"
86
- assert_renders "foo, (bar, baz), bip"
87
- assert_renders "foo, bar baz, bip"
88
- end
89
-
90
- def test_space_list_adds_parens_for_clarity
91
- assert_renders "(1 + 1) (2 / 4) (3 * 5)"
92
- end
93
-
94
- def test_comma_list_doesnt_add_parens
95
- assert_renders "1 + 1, 2 / 4, 3 * 5"
96
- end
97
-
98
- def test_empty_list
99
- assert_renders "()"
100
- end
101
-
102
- def test_list_in_args
103
- assert_renders "foo((a, b, c))"
104
- assert_renders "foo($arg: (a, b, c))"
105
- assert_renders "foo(a, b, (a, b, c)...)"
106
- end
107
-
108
- def test_singleton_list
109
- assert_renders "(1,)"
110
- assert_renders "(1 2 3,)"
111
- assert_renders "((1, 2, 3),)"
112
- end
113
-
114
- def test_map
115
- assert_renders "(foo: bar)"
116
- assert_renders "(foo: bar, baz: bip)"
117
- assert_renders "(foo: bar, baz: (bip: bap))"
118
- end
119
-
120
- def test_map_in_list
121
- assert_renders "(foo: bar) baz"
122
- assert_renders "(foo: bar), (baz: bip)"
123
- end
124
-
125
- def test_list_in_map
126
- assert_renders "(foo: bar baz)"
127
- assert_renders "(foo: (bar, baz), bip: bop)"
128
- end
129
-
130
- def test_selector
131
- assert_renders "&"
132
- end
133
-
134
- def self.test_precedence(outer, inner)
135
- op_outer = Sass::Script::Lexer::OPERATORS_REVERSE[outer]
136
- op_inner = Sass::Script::Lexer::OPERATORS_REVERSE[inner]
137
- class_eval <<RUBY
138
- def test_precedence_#{outer}_#{inner}
139
- assert_renders "$foo #{op_outer} $bar #{op_inner} $baz"
140
- assert_renders "$foo #{op_inner} $bar #{op_outer} $baz"
141
-
142
- assert_renders "($foo #{op_outer} $bar) #{op_inner} $baz"
143
- assert_renders "$foo #{op_inner} ($bar #{op_outer} $baz)"
144
-
145
- assert_equal "$foo #{op_outer} $bar #{op_inner} $baz",
146
- render("$foo #{op_outer} ($bar #{op_inner} $baz)")
147
- assert_equal "$foo #{op_inner} $bar #{op_outer} $baz",
148
- render("($foo #{op_inner} $bar) #{op_outer} $baz")
149
- end
150
- RUBY
151
- end
152
-
153
- def self.assert_associative(op_name, sibling_name)
154
- op = separator_for(op_name)
155
- sibling = separator_for(sibling_name)
156
- class_eval <<RUBY
157
- def test_associative_#{op_name}_#{sibling_name}
158
- assert_renders "$foo#{op}$bar#{op}$baz"
159
-
160
- assert_equal "$foo#{op}$bar#{op}$baz",
161
- render("$foo#{op}($bar#{op}$baz)")
162
- assert_equal "$foo#{op}$bar#{op}$baz",
163
- render("($foo#{op}$bar)#{op}$baz")
164
-
165
- assert_equal "$foo#{op}$bar#{sibling}$baz",
166
- render("$foo#{op}($bar#{sibling}$baz)")
167
- assert_equal "$foo#{sibling}$bar#{op}$baz",
168
- render("($foo#{sibling}$bar)#{op}$baz")
169
- end
170
- RUBY
171
- end
172
-
173
- def self.separator_for(op_name)
174
- case op_name
175
- when :comma; ", "
176
- when :space; " "
177
- else; " #{Sass::Script::Lexer::OPERATORS_REVERSE[op_name]} "
178
- end
179
- end
180
-
181
- def self.assert_non_associative(op_name, sibling_name)
182
- op = Sass::Script::Lexer::OPERATORS_REVERSE[op_name]
183
- sibling = Sass::Script::Lexer::OPERATORS_REVERSE[sibling_name]
184
- class_eval <<RUBY
185
- def test_non_associative_#{op_name}_#{sibling_name}
186
- assert_renders "$foo #{op} $bar #{op} $baz"
187
-
188
- assert_renders "$foo #{op} ($bar #{op} $baz)"
189
- assert_equal "$foo #{op} $bar #{op} $baz",
190
- render("($foo #{op} $bar) #{op} $baz")
191
-
192
- assert_renders "$foo #{op} ($bar #{sibling} $baz)"
193
- assert_equal "$foo #{sibling} $bar #{op} $baz",
194
- render("($foo #{sibling} $bar) #{op} $baz")
195
- end
196
- RUBY
197
- end
198
-
199
- test_precedence :or, :and
200
- test_precedence :and, :eq
201
- test_precedence :and, :neq
202
- test_precedence :eq, :gt
203
- test_precedence :eq, :gte
204
- test_precedence :eq, :lt
205
- test_precedence :eq, :lte
206
- test_precedence :gt, :plus
207
- test_precedence :gt, :minus
208
- test_precedence :plus, :times
209
- test_precedence :plus, :div
210
- test_precedence :plus, :mod
211
-
212
- assert_associative :plus, :minus
213
- assert_associative :times, :div
214
- assert_associative :times, :mod
215
-
216
- assert_non_associative :minus, :plus
217
- assert_non_associative :div, :times
218
- assert_non_associative :mod, :times
219
- assert_non_associative :gt, :gte
220
- assert_non_associative :gte, :lt
221
- assert_non_associative :lt, :lte
222
- assert_non_associative :lte, :gt
223
-
224
- def test_comma_precedence
225
- assert_renders "$foo, $bar, $baz"
226
-
227
- assert_renders "$foo ($bar, $baz)"
228
- assert_renders "($foo, $bar) $baz"
229
-
230
- assert_equal "$foo, $bar $baz", render("$foo, ($bar $baz)")
231
- assert_equal "$foo $bar, $baz", render("($foo $bar), $baz")
232
-
233
- assert_equal "$foo, ($bar, $baz)", render("$foo, ($bar, $baz)")
234
- assert_equal "($foo, $bar), $baz", render("($foo, $bar), $baz")
235
- end
236
-
237
- def test_space_precedence
238
- assert_renders "$foo $bar $baz"
239
-
240
- assert_renders "$foo or ($bar $baz)"
241
- assert_renders "($foo $bar) or $baz"
242
-
243
- assert_renders "$foo ($bar or $baz)"
244
- assert_renders "($foo or $bar) $baz"
245
-
246
- assert_equal "$foo ($bar $baz)", render("$foo ($bar $baz)")
247
- assert_equal "($foo $bar) $baz", render("($foo $bar) $baz")
248
- end
249
-
250
- def test_unary_op
251
- assert_renders "-12px"
252
- assert_renders '/"foo"'
253
- assert_renders 'not true'
254
-
255
- assert_renders "-(foo(12px))"
256
- assert_renders "-(-foo(12px))"
257
- assert_renders "-(_foo(12px))"
258
- assert_renders "-(\xC3\xBFoo(12px))"
259
- assert_renders "-(blue)"
260
-
261
- assert_equal 'not true or false', render('(not true) or false')
262
- assert_equal 'not (true or false)', render('not (true or false)')
263
- end
264
-
265
- def test_interpolation
266
- assert_equal 'unquote("#{$foo}#{$bar}#{$baz}")', render("$foo\#{$bar}$baz")
267
- assert_equal 'unquote("#{$foo}#{$bar} #{$baz}")', render("$foo\#{$bar} $baz")
268
- assert_equal 'unquote("#{$foo} #{$bar}#{$baz}")', render("$foo \#{$bar}$baz")
269
- assert_renders "$foo \#{$bar} $baz"
270
- assert_renders "$foo \#{$bar}\#{$bang} $baz"
271
- assert_renders "$foo \#{$bar} \#{$bang} $baz"
272
- assert_equal 'unquote("#{$bar}#{$baz}")', render("\#{$bar}$baz")
273
- assert_equal 'unquote("#{$foo}#{$bar}")', render("$foo\#{$bar}")
274
- assert_renders "\#{$bar}"
275
- end
276
-
277
- def test_interpolation_in_function
278
- assert_renders 'flabnabbit(#{1 + "foo"})'
279
- assert_equal 'flabnabbit(unquote("#{$foo} #{1 + "foo"}#{$baz}"))',
280
- render('flabnabbit($foo #{1 + "foo"}$baz)')
281
- assert_renders 'flabnabbit($foo #{1 + "foo"}#{2 + "bar"} $baz)'
282
- end
283
-
284
- def test_interpolation_in_string_function
285
- assert_renders 'calc(#{1 + "foo"})'
286
- assert_renders 'calc(foo#{1 + "foo"}baz)'
287
- end
288
-
289
- def test_interpolation_near_operators
290
- assert_renders '#{1 + 2} , #{3 + 4}'
291
- assert_renders '#{1 + 2}, #{3 + 4}'
292
- assert_renders '#{1 + 2} ,#{3 + 4}'
293
- assert_renders '#{1 + 2},#{3 + 4}'
294
- assert_renders '#{1 + 2}, #{3 + 4}, #{5 + 6}'
295
- assert_renders '3, #{3 + 4}, 11'
296
-
297
- assert_renders '3 / #{3 + 4}'
298
- assert_renders '3 /#{3 + 4}'
299
- assert_renders '3/ #{3 + 4}'
300
- assert_renders '3/#{3 + 4}'
301
-
302
- assert_equal 'unquote("#{1 + 2} * 7")', render('#{1 + 2} * 7')
303
- assert_equal 'unquote("#{1 + 2}* 7")', render('#{1 + 2}* 7')
304
- assert_equal 'unquote("#{1 + 2} *7")', render('#{1 + 2} *7')
305
- assert_equal 'unquote("#{1 + 2}*7")', render('#{1 + 2}*7')
306
-
307
- assert_renders '-#{1 + 2}'
308
- assert_equal 'unquote("- #{1 + 2}")', render('- #{1 + 2}')
309
-
310
- assert_equal 'unquote("5 + #{1 + 2} * #{3 + 4}")', render('5 + #{1 + 2} * #{3 + 4}')
311
- assert_equal 'unquote("5 +#{1 + 2} * #{3 + 4}")', render('5 +#{1 + 2} * #{3 + 4}')
312
- assert_equal 'unquote("5+#{1 + 2} * #{3 + 4}")', render('5+#{1 + 2} * #{3 + 4}')
313
- assert_equal 'unquote("#{1 + 2} * #{3 + 4} + 5")', render('#{1 + 2} * #{3 + 4} + 5')
314
- assert_equal 'unquote("#{1 + 2} * #{3 + 4}+ 5")', render('#{1 + 2} * #{3 + 4}+ 5')
315
- assert_equal 'unquote("#{1 + 2} * #{3 + 4}+5")', render('#{1 + 2} * #{3 + 4}+5')
316
-
317
- assert_equal '5 / unquote("#{1 + 2} + #{3 + 4}")', render('5 / (#{1 + 2} + #{3 + 4})')
318
- assert_equal '5 / unquote("#{1 + 2} + #{3 + 4}")', render('5 /(#{1 + 2} + #{3 + 4})')
319
- assert_equal '5 / unquote("#{1 + 2} + #{3 + 4}")', render('5 /( #{1 + 2} + #{3 + 4} )')
320
- assert_equal 'unquote("#{1 + 2} + #{3 + 4}") / 5', render('(#{1 + 2} + #{3 + 4}) / 5')
321
- assert_equal 'unquote("#{1 + 2} + #{3 + 4}") / 5', render('(#{1 + 2} + #{3 + 4})/ 5')
322
- assert_equal 'unquote("#{1 + 2} + #{3 + 4}") / 5', render('( #{1 + 2} + #{3 + 4} )/ 5')
323
-
324
- assert_equal 'unquote("#{1 + 2} + #{2 + 3}")', render('#{1 + 2} + 2 + 3')
325
- assert_equal 'unquote("#{1 + 2} +#{2 + 3}")', render('#{1 + 2} +2 + 3')
326
- end
327
-
328
- def test_string_interpolation
329
- assert_renders '"foo#{$bar}baz"'
330
- assert_renders '"foo #{$bar}baz"'
331
- assert_renders '"foo#{$bar} baz"'
332
- assert_renders '"foo #{$bar} baz"'
333
- assert_renders '"foo #{$bar}#{$bang} baz"'
334
- assert_renders '"foo #{$bar} #{$bang} baz"'
335
- assert_renders '"#{$bar}baz"'
336
- assert_renders '"foo#{$bar}"'
337
- assert_renders '"#{$bar}"'
338
-
339
- assert_renders "'\"\#{\"bar\"}\"'"
340
- assert_renders '"\#{bar}"'
341
-
342
- assert_equal '"foo#{$bar}baz"', render("'foo\#{$bar}baz'")
343
- end
344
-
345
- def test_bracketed_lists
346
- assert_renders("[]")
347
- assert_renders("[foo, bar]")
348
- assert_renders("[[foo]]")
349
- assert_renders("[(foo bar)]")
350
- assert_renders("[foo bar,]")
351
- assert_renders("[(foo,)]")
352
- end
353
-
354
- private
355
-
356
- def assert_renders(script, options = {})
357
- assert_equal(script, render(script, options))
358
- end
359
-
360
- def render(script, options = {})
361
- munge_filename(options)
362
- node = Sass::Script.parse(script, 1, 0, options.merge(:_convert => true))
363
- node.to_sass
364
- end
365
- end
@@ -1,1427 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- require File.dirname(__FILE__) + '/../test_helper'
3
- require 'sass/engine'
4
-
5
- module Sass::Script::Functions::UserFunctions
6
- def assert_options(val)
7
- val.options[:foo]
8
- Sass::Script::Value::String.new("Options defined!")
9
- end
10
-
11
- def arg_error
12
- assert_options
13
- end
14
- end
15
-
16
- module Sass::Script::Functions
17
- include Sass::Script::Functions::UserFunctions
18
- end
19
-
20
- class SassScriptTest < MiniTest::Test
21
- include Sass::Script
22
-
23
- def test_color_clamps_input
24
- assert_equal 0, Sass::Script::Value::Color.new([1, 2, -1]).blue
25
- assert_equal 255, Sass::Script::Value::Color.new([256, 2, 3]).red
26
- end
27
-
28
- def test_color_clamps_rgba_input
29
- assert_equal 1, Sass::Script::Value::Color.new([1, 2, 3, 1.1]).alpha
30
- assert_equal 0, Sass::Script::Value::Color.new([1, 2, 3, -0.1]).alpha
31
- end
32
-
33
- def test_color_from_hex
34
- assert_equal Sass::Script::Value::Color.new([0,0,0]), Sass::Script::Value::Color.from_hex('000000')
35
- assert_equal Sass::Script::Value::Color.new([0,0,0]), Sass::Script::Value::Color.from_hex('#000000')
36
- end
37
-
38
- def test_string_escapes
39
- assert_equal "'", resolve("\"'\"")
40
- assert_equal '"', resolve("\"\\\"\"")
41
- assert_equal "\\", resolve("\"\\\\\"")
42
- assert_equal "☃", resolve("\"\\2603\"")
43
- assert_equal "☃f", resolve("\"\\2603 f\"")
44
- assert_equal "☃x", resolve("\"\\2603x\"")
45
- assert_equal "\\2603", resolve("\"\\\\2603\"")
46
- assert_equal "\#{foo}", resolve("\"\\\#{foo}\"")
47
-
48
- # U+FFFD is the replacement character, "�".
49
- assert_equal [0xFFFD].pack("U"), resolve("\"\\0\"")
50
- assert_equal [0xFFFD].pack("U"), resolve("\"\\FFFFFF\"")
51
- assert_equal [0xFFFD].pack("U"), resolve("\"\\D800\"")
52
- assert_equal [0xD7FF].pack("U"), resolve("\"\\D7FF\"")
53
- assert_equal [0xFFFD].pack("U"), resolve("\"\\DFFF\"")
54
- assert_equal [0xE000].pack("U"), resolve("\"\\E000\"")
55
- end
56
-
57
- def test_string_escapes_are_resolved_before_operators
58
- assert_equal "true", resolve('"abc" == "\61\62\63"')
59
- end
60
-
61
- def test_string_quote
62
- assert_equal '"foo"', resolve_quoted('"foo"')
63
- assert_equal "'f\"oo'", resolve_quoted('"f\"oo"')
64
- assert_equal "\"f'oo\"", resolve_quoted("'f\\'oo'")
65
- assert_equal "\"f'o\\\"o\"", resolve_quoted("'f\\'o\"o'")
66
- assert_equal '"foo bar"', resolve_quoted('"foo\20 bar"')
67
- assert_equal '"foo\a bar"', resolve_quoted('"foo\a bar"')
68
- assert_equal '"x\ay"', resolve_quoted('"x\a y"')
69
- assert_equal '"\a "', resolve_quoted('"\a\20"')
70
- assert_equal '"\a abcdef"', resolve_quoted('"\a abcdef"')
71
- assert_equal '"☃abcdef"', resolve_quoted('"\2603 abcdef"')
72
- assert_equal '"\\\\"', resolve_quoted('"\\\\"')
73
- assert_equal '"foobar"', resolve_quoted("\"foo\\\nbar\"")
74
- assert_equal '"#{foo}"', resolve_quoted("\"\\\#{foo}\"")
75
- end
76
-
77
- def test_color_names
78
- assert_equal "white", resolve("white")
79
- assert_equal "#ffffff", resolve("#ffffff")
80
- silence_warnings {assert_equal "#fffffe", resolve("white - #000001")}
81
- assert_equal "transparent", resolve("transparent")
82
- assert_equal "rgba(0, 0, 0, 0)", resolve("rgba(0, 0, 0, 0)")
83
- end
84
-
85
- def test_rgba_color_literals
86
- assert_equal Sass::Script::Value::Color.new([1, 2, 3, 0.75]), eval("rgba(1, 2, 3, 0.75)")
87
- assert_equal "rgba(1, 2, 3, 0.75)", resolve("rgba(1, 2, 3, 0.75)")
88
-
89
- assert_equal Sass::Script::Value::Color.new([1, 2, 3, 0]), eval("rgba(1, 2, 3, 0)")
90
- assert_equal "rgba(1, 2, 3, 0)", resolve("rgba(1, 2, 3, 0)")
91
-
92
- assert_equal Sass::Script::Value::Color.new([1, 2, 3]), eval("rgba(1, 2, 3, 1)")
93
- assert_equal Sass::Script::Value::Color.new([1, 2, 3, 1]), eval("rgba(1, 2, 3, 1)")
94
- assert_equal "#010203", resolve("rgba(1, 2, 3, 1)")
95
- assert_equal "white", resolve("rgba(255, 255, 255, 1)")
96
- end
97
-
98
- def test_rgba_color_math
99
- silence_warnings {assert_equal "rgba(50, 50, 100, 0.35)", resolve("rgba(1, 1, 2, 0.35) * rgba(50, 50, 50, 0.35)")}
100
- silence_warnings {assert_equal "rgba(52, 52, 52, 0.25)", resolve("rgba(2, 2, 2, 0.25) + rgba(50, 50, 50, 0.25)")}
101
-
102
- assert_raise_message(Sass::SyntaxError, "Alpha channels must be equal: rgba(1, 2, 3, 0.15) + rgba(50, 50, 50, 0.75)") do
103
- silence_warnings {resolve("rgba(1, 2, 3, 0.15) + rgba(50, 50, 50, 0.75)")}
104
- end
105
- assert_raise_message(Sass::SyntaxError, "Alpha channels must be equal: #123456 * rgba(50, 50, 50, 0.75)") do
106
- silence_warnings {resolve("#123456 * rgba(50, 50, 50, 0.75)")}
107
- end
108
- assert_raise_message(Sass::SyntaxError, "Alpha channels must be equal: rgba(50, 50, 50, 0.75) / #123456") do
109
- silence_warnings {resolve("rgba(50, 50, 50, 0.75) / #123456")}
110
- end
111
- end
112
-
113
- def test_rgba_number_math
114
- silence_warnings {assert_equal "rgba(49, 49, 49, 0.75)", resolve("rgba(50, 50, 50, 0.75) - 1")}
115
- silence_warnings {assert_equal "rgba(100, 100, 100, 0.75)", resolve("rgba(50, 50, 50, 0.75) * 2")}
116
- end
117
-
118
- def test_rgba_rounding
119
- assert_equal "rgba(10, 1, 0, 0.1234567892)", resolve("rgba(10.0, 1.23456789, 0.0, 0.12345678919)")
120
- end
121
-
122
- def test_rgb_calc
123
- assert_equal "rgb(calc(255 - 5), 0, 0)", resolve("rgb(calc(255 - 5), 0, 0)")
124
- end
125
-
126
- def test_rgba_calc
127
- assert_equal "rgba(calc(255 - 5), 0, 0, 0.1)",
128
- resolve("rgba(calc(255 - 5), 0, 0, 0.1)")
129
- assert_equal "rgba(127, 0, 0, calc(0.1 + 0.5))",
130
- resolve("rgba(127, 0, 0, calc(0.1 + 0.5))")
131
- end
132
-
133
- def test_rgba_shorthand_calc
134
- assert_equal "rgba(255, 0, 0, calc(0.1 + 0.5))",
135
- resolve("rgba(red, calc(0.1 + 0.5))")
136
- end
137
-
138
- def test_hsl_calc
139
- assert_equal "hsl(calc(360 * 5 / 6), 50%, 50%)", resolve("hsl(calc(360 * 5 / 6), 50%, 50%)")
140
- end
141
-
142
- def test_hsla_calc
143
- assert_equal "hsla(calc(360 * 5 / 6), 50%, 50%, 0.1)",
144
- resolve("hsla(calc(360 * 5 / 6), 50%, 50%, 0.1)")
145
- assert_equal "hsla(270, 50%, 50%, calc(0.1 + 0.1))",
146
- resolve("hsla(270, 50%, 50%, calc(0.1 + 0.1))")
147
- end
148
-
149
- def test_compressed_colors
150
- assert_equal "#123456", resolve("#123456", :style => :compressed)
151
- assert_equal "rgba(1,2,3,0.5)", resolve("rgba(1, 2, 3, 0.5)", :style => :compressed)
152
- assert_equal "#123", resolve("#112233", :style => :compressed)
153
- assert_equal "#000", resolve("black", :style => :compressed)
154
- assert_equal "red", resolve("#f00", :style => :compressed)
155
- assert_equal "blue", resolve("blue", :style => :compressed)
156
- assert_equal "navy", resolve("#000080", :style => :compressed)
157
- assert_equal "navy #fff", resolve("#000080 white", :style => :compressed)
158
- assert_equal "This color is #fff", resolve('"This color is #{ white }"', :style => :compressed)
159
- assert_equal "transparent", resolve("rgba(0, 0, 0, 0)", :style => :compressed)
160
- end
161
-
162
- def test_compressed_comma
163
- # assert_equal "foo,bar,baz", resolve("foo, bar, baz", :style => :compressed)
164
- # assert_equal "foo,#baf,baz", resolve("foo, #baf, baz", :style => :compressed)
165
- assert_equal "foo,#baf,red", resolve("foo, #baf, #f00", :style => :compressed)
166
- end
167
-
168
- def test_implicit_strings
169
- assert_equal Sass::Script::Value::String.new("foo"), eval("foo")
170
- assert_equal Sass::Script::Value::String.new("foo/bar"), eval("foo/bar")
171
- end
172
-
173
- def test_basic_interpolation
174
- assert_equal "foo3bar", resolve("foo\#{1 + 2}bar")
175
- assert_equal "foo3 bar", resolve("foo\#{1 + 2} bar")
176
- assert_equal "foo 3bar", resolve("foo \#{1 + 2}bar")
177
- assert_equal "foo 3 bar", resolve("foo \#{1 + 2} bar")
178
- assert_equal "foo 35 bar", resolve("foo \#{1 + 2}\#{2 + 3} bar")
179
- assert_equal "foo 3 5 bar", resolve("foo \#{1 + 2} \#{2 + 3} bar")
180
- assert_equal "3bar", resolve("\#{1 + 2}bar")
181
- assert_equal "foo3", resolve("foo\#{1 + 2}")
182
- assert_equal "3", resolve("\#{1 + 2}")
183
- end
184
-
185
- def test_interpolation_in_function
186
- assert_equal 'flabnabbit(1foo)', resolve('flabnabbit(#{1 + "foo"})')
187
- assert_equal 'flabnabbit(foo 1foobaz)', resolve('flabnabbit(foo #{1 + "foo"}baz)')
188
- assert_equal('flabnabbit(foo 1foo2bar baz)',
189
- resolve('flabnabbit(foo #{1 + "foo"}#{2 + "bar"} baz)'))
190
- end
191
-
192
- def test_interpolation_near_operators
193
- silence_warnings do
194
- assert_equal '3 , 7', resolve('#{1 + 2} , #{3 + 4}')
195
- assert_equal '3, 7', resolve('#{1 + 2}, #{3 + 4}')
196
- assert_equal '3 ,7', resolve('#{1 + 2} ,#{3 + 4}')
197
- assert_equal '3,7', resolve('#{1 + 2},#{3 + 4}')
198
- assert_equal '3, 7, 11', resolve('#{1 + 2}, #{3 + 4}, #{5 + 6}')
199
- assert_equal '3, 7, 11', resolve('3, #{3 + 4}, 11')
200
- assert_equal '3, 7, 11', resolve('3, 7, #{5 + 6}')
201
-
202
- assert_equal '3 / 7', resolve('3 / #{3 + 4}')
203
- assert_equal '3 /7', resolve('3 /#{3 + 4}')
204
- assert_equal '3/ 7', resolve('3/ #{3 + 4}')
205
- assert_equal '3/7', resolve('3/#{3 + 4}')
206
-
207
- assert_equal '3 * 7', resolve('#{1 + 2} * 7')
208
- assert_equal '3* 7', resolve('#{1 + 2}* 7')
209
- assert_equal '3 *7', resolve('#{1 + 2} *7')
210
- assert_equal '3*7', resolve('#{1 + 2}*7')
211
-
212
- assert_equal '-3', resolve('-#{1 + 2}')
213
- assert_equal '- 3', resolve('- #{1 + 2}')
214
-
215
- assert_equal '5 + 3 * 7', resolve('5 + #{1 + 2} * #{3 + 4}')
216
- assert_equal '5 +3 * 7', resolve('5 +#{1 + 2} * #{3 + 4}')
217
- assert_equal '5+3 * 7', resolve('5+#{1 + 2} * #{3 + 4}')
218
- assert_equal '3 * 7 + 5', resolve('#{1 + 2} * #{3 + 4} + 5')
219
- assert_equal '3 * 7+ 5', resolve('#{1 + 2} * #{3 + 4}+ 5')
220
- assert_equal '3 * 7+5', resolve('#{1 + 2} * #{3 + 4}+5')
221
-
222
- assert_equal '5/3 + 7', resolve('5 / (#{1 + 2} + #{3 + 4})')
223
- assert_equal '5/3 + 7', resolve('5 /(#{1 + 2} + #{3 + 4})')
224
- assert_equal '5/3 + 7', resolve('5 /( #{1 + 2} + #{3 + 4} )')
225
- assert_equal '3 + 7/5', resolve('(#{1 + 2} + #{3 + 4}) / 5')
226
- assert_equal '3 + 7/5', resolve('(#{1 + 2} + #{3 + 4})/ 5')
227
- assert_equal '3 + 7/5', resolve('( #{1 + 2} + #{3 + 4} )/ 5')
228
-
229
- assert_equal '3 + 5', resolve('#{1 + 2} + 2 + 3')
230
- assert_equal '3 +5', resolve('#{1 + 2} +2 + 3')
231
- end
232
- end
233
-
234
- def test_string_interpolation
235
- assert_equal "foo bar, baz bang", resolve('"foo #{"bar"}, #{"baz"} bang"')
236
- assert_equal "foo bar baz bang", resolve('"foo #{"#{"ba" + "r"} baz"} bang"')
237
- assert_equal 'foo #{bar baz} bang', resolve('"foo \#{#{"ba" + "r"} baz} bang"')
238
- assert_equal 'foo #{baz bang', resolve('"foo #{"\#{" + "baz"} bang"')
239
- assert_equal "foo2bar", resolve('\'foo#{1 + 1}bar\'')
240
- assert_equal "foo2bar", resolve('"foo#{1 + 1}bar"')
241
- assert_equal "foo1bar5baz4bang", resolve('\'foo#{1 + "bar#{2 + 3}baz" + 4}bang\'')
242
- end
243
-
244
- def test_interpolation_in_interpolation
245
- assert_equal 'foo', resolve('#{#{foo}}')
246
- assert_equal 'foo', resolve('"#{#{foo}}"')
247
- assert_equal 'foo', resolve('#{"#{foo}"}')
248
- assert_equal 'foo', resolve('"#{"#{foo}"}"')
249
- end
250
-
251
- def test_interpolation_with_newline
252
- assert_equal "\nbang", resolve('"#{"\a "}bang"')
253
- assert_equal "\n\nbang", resolve('"#{"\a "}\a bang"')
254
- end
255
-
256
- def test_rule_interpolation
257
- assert_equal(<<CSS, render(<<SASS))
258
- foo bar baz bang {
259
- a: b; }
260
- CSS
261
- foo \#{"\#{"ba" + "r"} baz"} bang
262
- a: b
263
- SASS
264
- assert_equal(<<CSS, render(<<SASS))
265
- foo [bar="\#{bar baz}"] bang {
266
- a: b; }
267
- CSS
268
- foo [bar="\\\#{\#{"ba" + "r"} baz}"] bang
269
- a: b
270
- SASS
271
- assert_equal(<<CSS, render(<<SASS))
272
- foo [bar="\#{baz"] bang {
273
- a: b; }
274
- CSS
275
- foo [bar="\#{"\\\#{" + "baz"}"] bang
276
- a: b
277
- SASS
278
- end
279
-
280
- def test_inaccessible_functions
281
- assert_equal "send(to_s)", resolve("send(to_s)", :line => 2)
282
- assert_equal "public_instance_methods()", resolve("public_instance_methods()")
283
- end
284
-
285
- def test_adding_functions_directly_to_functions_module
286
- assert !Functions.callable?('nonexistent')
287
- Functions.class_eval { def nonexistent; end }
288
- assert Functions.callable?('nonexistent')
289
- Functions.send :remove_method, :nonexistent
290
- end
291
-
292
- def test_default_functions
293
- assert_equal "url(12)", resolve("url(12)")
294
- assert_equal 'blam("foo")', resolve('blam("foo")')
295
- end
296
-
297
- def test_function_results_have_options
298
- assert_equal "Options defined!", resolve("assert_options(abs(1))")
299
- assert_equal "Options defined!", resolve("assert_options(round(1.2))")
300
- end
301
-
302
- def test_funcall_requires_no_whitespace_before_lparen
303
- assert_equal "no-repeat 15px", resolve("no-repeat (7px + 8px)")
304
- assert_equal "no-repeat(15px)", resolve("no-repeat(7px + 8px)")
305
- end
306
-
307
- def test_dynamic_url
308
- assert_equal "url(foo-bar)", resolve("url($foo)", {}, env('foo' => Sass::Script::Value::String.new("foo-bar")))
309
- assert_equal "url(foo-bar baz)", resolve("url($foo $bar)", {}, env('foo' => Sass::Script::Value::String.new("foo-bar"), 'bar' => Sass::Script::Value::String.new("baz")))
310
- assert_equal "url(foo baz)", resolve("url(foo $bar)", {}, env('bar' => Sass::Script::Value::String.new("baz")))
311
- assert_equal "url(foo bar)", resolve("url(foo bar)")
312
- end
313
-
314
- def test_url_with_interpolation
315
- assert_equal "url(http://sass-lang.com/images/foo-bar)", resolve("url(http://sass-lang.com/images/\#{foo-bar})")
316
- assert_equal 'url("http://sass-lang.com/images/foo-bar")', resolve("url('http://sass-lang.com/images/\#{foo-bar}')")
317
- assert_equal 'url("http://sass-lang.com/images/foo-bar")', resolve('url("http://sass-lang.com/images/#{foo-bar}")')
318
- assert_unquoted "url(http://sass-lang.com/images/\#{foo-bar})"
319
- end
320
-
321
- def test_hyphenated_variables
322
- assert_equal("a-b", resolve("$a-b", {}, env("a-b" => Sass::Script::Value::String.new("a-b"))))
323
- end
324
-
325
- def test_ruby_equality
326
- assert_equal eval('"foo"'), eval('"foo"')
327
- assert_equal eval('1'), eval('1.0')
328
- assert_equal eval('1 2 3.0'), eval('1 2 3')
329
- assert_equal eval('1, 2, 3.0'), eval('1, 2, 3')
330
- assert_equal eval('(1 2), (3, 4), (5 6)'), eval('(1 2), (3, 4), (5 6)')
331
- refute_equal eval('1, 2, 3'), eval('1 2 3')
332
- refute_equal eval('1'), eval('"1"')
333
- end
334
-
335
- def test_booleans
336
- assert_equal "true", resolve("true")
337
- assert_equal "false", resolve("false")
338
- end
339
-
340
- def test_null
341
- assert_equal "", resolve("null")
342
- end
343
-
344
- def test_boolean_ops
345
- assert_equal "true", resolve("true and true")
346
- assert_equal "true", resolve("false or true")
347
- assert_equal "true", resolve("true or false")
348
- assert_equal "true", resolve("true or true")
349
- assert_equal "false", resolve("false or false")
350
- assert_equal "false", resolve("false and true")
351
- assert_equal "false", resolve("true and false")
352
- assert_equal "false", resolve("false and false")
353
-
354
- assert_equal "true", resolve("not false")
355
- assert_equal "false", resolve("not true")
356
- assert_equal "true", resolve("not not true")
357
-
358
- assert_equal "1", resolve("false or 1")
359
- assert_equal "false", resolve("false and 1")
360
- assert_equal "2", resolve("2 or 3")
361
- assert_equal "3", resolve("2 and 3")
362
-
363
- assert_equal "true", resolve("null or true")
364
- assert_equal "true", resolve("true or null")
365
- assert_equal "", resolve("null or null")
366
- assert_equal "", resolve("null and true")
367
- assert_equal "", resolve("true and null")
368
- assert_equal "", resolve("null and null")
369
-
370
- assert_equal "true", resolve("not null")
371
-
372
- assert_equal "1", resolve("null or 1")
373
- assert_equal "", resolve("null and 1")
374
- end
375
-
376
- def test_arithmetic_ops
377
- assert_equal "2", resolve("1 + 1")
378
- assert_equal "0", resolve("1 - 1")
379
- assert_equal "8", resolve("2 * 4")
380
- assert_equal "0.5", resolve("(2 / 4)")
381
- assert_equal "2", resolve("(4 / 2)")
382
-
383
- assert_equal "-1", resolve("-1")
384
- end
385
-
386
- def test_subtraction_vs_minus_vs_identifier
387
- assert_equal "0.25em", resolve("1em-.75")
388
- assert_equal "0.25em", resolve("1em-0.75")
389
- assert_equal "1em -0.75", resolve("1em -.75")
390
- assert_equal "1em -0.75", resolve("1em -0.75")
391
- assert_equal "1em- 0.75", resolve("1em- .75")
392
- assert_equal "1em- 0.75", resolve("1em- 0.75")
393
- assert_equal "0.25em", resolve("1em - .75")
394
- assert_equal "0.25em", resolve("1em - 0.75")
395
- end
396
-
397
- def test_string_ops
398
- assert_equal '"foo" "bar"', resolve('"foo" "bar"')
399
- assert_equal "true 1", resolve('true 1')
400
- assert_equal '"foo", "bar"', resolve("'foo' , 'bar'")
401
- assert_equal "true, 1", resolve('true , 1')
402
- assert_equal "foobar", resolve('"foo" + "bar"')
403
- assert_equal "\nfoo\nxyz", resolve('"\a foo" + "\axyz"')
404
- assert_equal "true1", resolve('true + 1')
405
- assert_equal '"foo"-"bar"', resolve("'foo' - 'bar'")
406
- assert_equal "true-1", resolve('true - 1')
407
- assert_equal '"foo"/"bar"', resolve('"foo" / "bar"')
408
- assert_equal "true/1", resolve('true / 1')
409
-
410
- assert_equal '-"bar"', resolve("- 'bar'")
411
- assert_equal "-true", resolve('- true')
412
- assert_equal '/"bar"', resolve('/ "bar"')
413
- assert_equal "/true", resolve('/ true')
414
- end
415
-
416
- def test_relational_ops
417
- assert_equal "false", resolve("1 > 2")
418
- assert_equal "false", resolve("2 > 2")
419
- assert_equal "true", resolve("3 > 2")
420
- assert_equal "false", resolve("1 >= 2")
421
- assert_equal "true", resolve("2 >= 2")
422
- assert_equal "true", resolve("3 >= 2")
423
- assert_equal "true", resolve("1 < 2")
424
- assert_equal "false", resolve("2 < 2")
425
- assert_equal "false", resolve("3 < 2")
426
- assert_equal "true", resolve("1 <= 2")
427
- assert_equal "true", resolve("2 <= 2")
428
- assert_equal "false", resolve("3 <= 2")
429
- end
430
-
431
- def test_null_ops
432
- assert_raise_message(Sass::SyntaxError,
433
- 'Invalid null operation: "null plus 1".') {eval("null + 1")}
434
- assert_raise_message(Sass::SyntaxError,
435
- 'Invalid null operation: "null minus 1".') {eval("null - 1")}
436
- assert_raise_message(Sass::SyntaxError,
437
- 'Invalid null operation: "null times 1".') {eval("null * 1")}
438
- assert_raise_message(Sass::SyntaxError,
439
- 'Invalid null operation: "null div 1".') {eval("null / 1")}
440
- assert_raise_message(Sass::SyntaxError,
441
- 'Invalid null operation: "null mod 1".') {eval("null % 1")}
442
- assert_raise_message(Sass::SyntaxError,
443
- 'Invalid null operation: "1 plus null".') {eval("1 + null")}
444
- assert_raise_message(Sass::SyntaxError,
445
- 'Invalid null operation: "1 minus null".') {eval("1 - null")}
446
- assert_raise_message(Sass::SyntaxError,
447
- 'Invalid null operation: "1 times null".') {eval("1 * null")}
448
- assert_raise_message(Sass::SyntaxError,
449
- 'Invalid null operation: "1 div null".') {eval("1 / null")}
450
- assert_raise_message(Sass::SyntaxError,
451
- 'Invalid null operation: "1 mod null".') {eval("1 % null")}
452
- assert_raise_message(Sass::SyntaxError,
453
- 'Invalid null operation: "1 gt null".') {eval("1 > null")}
454
- assert_raise_message(Sass::SyntaxError,
455
- 'Invalid null operation: "null lt 1".') {eval("null < 1")}
456
- assert_raise_message(Sass::SyntaxError,
457
- 'Invalid null operation: "null plus null".') {eval("null + null")}
458
- assert_raise_message(Sass::SyntaxError,
459
- 'Invalid null operation: ""foo" plus null".') {eval("foo + null")}
460
- end
461
-
462
- def test_equals
463
- assert_equal("true", resolve('"foo" == $foo', {},
464
- env("foo" => Sass::Script::Value::String.new("foo"))))
465
- assert_equal "true", resolve("1 == 1.0")
466
- assert_equal "true", resolve("false != true")
467
- assert_equal "false", resolve("1em == 1px")
468
- assert_equal "false", resolve("12 != 12")
469
- assert_equal "true", resolve("(foo bar baz) == (foo bar baz)")
470
- assert_equal "true", resolve("(foo, bar, baz) == (foo, bar, baz)")
471
- assert_equal "true", resolve('((1 2), (3, 4), (5 6)) == ((1 2), (3, 4), (5 6))')
472
- assert_equal "true", resolve('((1 2), (3 4)) == (1 2, 3 4)')
473
- assert_equal "false", resolve('((1 2) 3) == (1 2 3)')
474
- assert_equal "false", resolve('(1 (2 3)) == (1 2 3)')
475
- assert_equal "false", resolve('((1, 2) (3, 4)) == (1, 2 3, 4)')
476
- assert_equal "false", resolve('(1 2 3) == (1, 2, 3)')
477
-
478
- assert_equal "true", resolve('null == null')
479
- assert_equal "false", resolve('"null" == null')
480
- assert_equal "false", resolve('0 == null')
481
- assert_equal "false", resolve('() == null')
482
-
483
- assert_equal "false", resolve('null != null')
484
- assert_equal "true", resolve('"null" != null')
485
- assert_equal "true", resolve('0 != null')
486
- assert_equal "true", resolve('() != null')
487
- end
488
-
489
- def test_mod
490
- assert_equal "5", resolve("29 % 12")
491
- assert_equal "5px", resolve("29px % 12")
492
- assert_equal "5px", resolve("29px % 12px")
493
- end
494
-
495
- def test_operation_precedence
496
- assert_equal "false true", resolve("true and false false or true")
497
- assert_equal "true", resolve("false and true or true and true")
498
- assert_equal "true", resolve("1 == 2 or 3 == 3")
499
- assert_equal "true", resolve("1 < 2 == 3 >= 3")
500
- assert_equal "true", resolve("1 + 3 > 4 - 2")
501
- assert_equal "11", resolve("1 + 2 * 3 + 4")
502
- end
503
-
504
- def test_functions
505
- assert_equal "#80ff80", resolve("hsl(120, 100%, 75%)")
506
- silence_warnings {assert_equal "#81ff81", resolve("hsl(120, 100%, 75%) + #010001")}
507
- end
508
-
509
- def test_operator_unit_conversion
510
- assert_equal "1.1cm", resolve("1cm + 1mm")
511
- assert_equal "8q", resolve("4q + 1mm")
512
- assert_equal "40.025cm", resolve("40cm + 1q")
513
- assert_equal "2in", resolve("1in + 96px")
514
- assert_equal "true", resolve("2mm < 1cm")
515
- assert_equal "true", resolve("10mm == 1cm")
516
- assert_equal "true", resolve("1.1cm == 11mm")
517
- assert_equal "true", resolve("2mm == 8q")
518
- assert_equal "false", resolve("2px > 3q")
519
-
520
- Sass::Deprecation.allow_double_warnings do
521
- assert_warning(<<WARNING) {assert_equal "true", resolve("1 == 1cm")}
522
- DEPRECATION WARNING on line 1 of test_operator_unit_conversion_inline.sass:
523
- The result of `1 == 1cm` will be `false` in future releases of Sass.
524
- Unitless numbers will no longer be equal to the same numbers with units.
525
- WARNING
526
-
527
- assert_warning(<<WARNING) {assert_equal "false", resolve("1 != 1cm")}
528
- DEPRECATION WARNING on line 1 of test_operator_unit_conversion_inline.sass:
529
- The result of `1 != 1cm` will be `true` in future releases of Sass.
530
- Unitless numbers will no longer be equal to the same numbers with units.
531
- WARNING
532
- end
533
- end
534
-
535
- def test_length_units
536
- assert_equal "2.54", resolve("(1in/1cm)")
537
- assert_equal "2.3622047244", resolve("(1cm/1pc)")
538
- assert_equal "4.2333333333", resolve("(1pc/1mm)")
539
- assert_equal "2.8346456693", resolve("(1mm/1pt)")
540
- assert_equal "1.3333333333", resolve("(1pt/1px)")
541
- assert_equal "0.0104166667", resolve("(1px/1in)")
542
- assert_equal "1.0583333333", resolve("(1px/1q)")
543
- assert_equal "0.0590551181", resolve("(1q/1pc)")
544
- end
545
-
546
- def test_angle_units
547
- assert_equal "1.1111111111", resolve("(1deg/1grad)")
548
- assert_equal "0.0157079633", resolve("(1grad/1rad)")
549
- assert_equal "0.1591549431", resolve("(1rad/1turn)")
550
- assert_equal "360", resolve("(1turn/1deg)")
551
- end
552
-
553
- def test_time_units
554
- assert_equal "1000", resolve("(1s/1ms)")
555
- end
556
-
557
- def test_frequency_units
558
- assert_equal "0.001", resolve("(1Hz/1kHz)")
559
- end
560
-
561
- def test_resolution_units
562
- assert_equal "0.3937007874", resolve("(1dpi/1dpcm)")
563
- assert_equal "0.0264583333", resolve("(1dpcm/1dppx)")
564
- assert_equal "96", resolve("(1dppx/1dpi)")
565
- end
566
-
567
- def test_operations_have_options
568
- assert_equal "Options defined!", resolve("assert_options(1 + 1)")
569
- assert_equal "Options defined!", resolve("assert_options('bar' + 'baz')")
570
- end
571
-
572
- def test_slash_compiles_literally_when_left_alone
573
- assert_equal "1px/2px", resolve("1px/2px")
574
- assert_equal "1px/2px/3px/4px", resolve("1px/2px/3px/4px")
575
-
576
- assert_equal "1px/2px redpx bluepx", resolve("1px/2px redpx bluepx")
577
- assert_equal "foo 1px/2px/3px bar", resolve("foo 1px/2px/3px bar")
578
- end
579
-
580
- def test_slash_divides_with_parens
581
- assert_equal "0.5", resolve("(1px/2px)")
582
- assert_equal "0.5", resolve("(1px)/2px")
583
- assert_equal "0.5", resolve("1px/(2px)")
584
- end
585
-
586
- def test_slash_divides_with_other_arithmetic
587
- assert_equal "0.5px", resolve("1px*1px/2px")
588
- assert_equal "0.5px", resolve("1px/2px*1px")
589
- assert_equal "0.5", resolve("0+1px/2px")
590
- assert_equal "0.5", resolve("1px/2px+0")
591
- end
592
-
593
- def test_slash_divides_with_variable
594
- assert_equal "0.5", resolve("$var/2px", {}, env("var" => eval("1px")))
595
- assert_equal "0.5", resolve("1px/$var", {}, env("var" => eval("2px")))
596
- assert_equal "0.5", resolve("$var", {}, env("var" => eval("1px/2px")))
597
- end
598
-
599
- # Regression test for issue 1786.
600
- def test_slash_division_within_list
601
- assert_equal "1 1/2 1/2", resolve("(1 1/2 1/2)")
602
- assert_equal "1/2 1/2", resolve("(1/2 1/2)")
603
- assert_equal "1/2", resolve("(1/2,)")
604
- end
605
-
606
- def test_non_ident_colors_with_wrong_number_of_digits
607
- assert_raise_message(Sass::SyntaxError,
608
- 'Invalid CSS after "": expected expression (e.g. 1px, bold), was "#1"') {eval("#1")}
609
- assert_raise_message(Sass::SyntaxError,
610
- 'Invalid CSS after "": expected expression (e.g. 1px, bold), was "#12"') {eval("#12")}
611
- assert_raise_message(Sass::SyntaxError,
612
- 'Invalid CSS after "": expected expression (e.g. 1px, bold), was "#12345"') {eval("#12345")}
613
- assert_raise_message(Sass::SyntaxError, 'Invalid CSS after "": expected expression (e.g. ' \
614
- '1px, bold), was "#1234567"') {eval("#1234567")}
615
- end
616
-
617
- def test_case_insensitive_color_names
618
- assert_equal "BLUE", resolve("BLUE")
619
- assert_equal "rEd", resolve("rEd")
620
- assert_equal "#804000", resolve("mix(GrEeN, ReD)")
621
- end
622
-
623
- def test_empty_list
624
- assert_equal "1 2 3", resolve("1 2 () 3")
625
- assert_equal "1 2 3", resolve("1 2 3 ()")
626
- assert_equal "1 2 3", resolve("() 1 2 3")
627
- assert_raise_message(Sass::SyntaxError, "() isn't a valid CSS value.") {resolve("()")}
628
- assert_raise_message(Sass::SyntaxError, "() isn't a valid CSS value.") {resolve("nth(append((), ()), 1)")}
629
- end
630
-
631
- def test_list_with_nulls
632
- assert_equal "1, 2, 3", resolve("1, 2, null, 3")
633
- assert_equal "1 2 3", resolve("1 2 null 3")
634
- assert_equal "1, 2, 3", resolve("1, 2, 3, null")
635
- assert_equal "1 2 3", resolve("1 2 3 null")
636
- assert_equal "1, 2, 3", resolve("null, 1, 2, 3")
637
- assert_equal "1 2 3", resolve("null 1 2 3")
638
- end
639
-
640
- def test_map_can_have_trailing_comma
641
- assert_equal("(foo: 1, bar: 2)", eval("(foo: 1, bar: 2,)").to_sass)
642
- end
643
-
644
- def test_list_can_have_trailing_comma
645
- assert_equal("1, 2, 3", resolve("1, 2, 3,"))
646
- end
647
-
648
- def test_trailing_comma_defines_singleton_list
649
- assert_equal("1 2 3", resolve("nth((1 2 3,), 1)"))
650
- end
651
-
652
- def test_map_cannot_have_duplicate_keys
653
- assert_raise_message(Sass::SyntaxError, 'Duplicate key "foo" in map (foo: bar, foo: baz).') do
654
- eval("(foo: bar, foo: baz)")
655
- end
656
- assert_raise_message(Sass::SyntaxError, 'Duplicate key "foo" in map (foo: bar, fo + o: baz).') do
657
- eval("(foo: bar, fo + o: baz)")
658
- end
659
- assert_raise_message(Sass::SyntaxError, 'Duplicate key "foo" in map (foo: bar, "foo": baz).') do
660
- eval("(foo: bar, 'foo': baz)")
661
- end
662
- assert_raise_message(Sass::SyntaxError, 'Duplicate key 2px in map (2px: bar, 1px + 1px: baz).') do
663
- eval("(2px: bar, 1px + 1px: baz)")
664
- end
665
- assert_raise_message(Sass::SyntaxError, 'Duplicate key #0000ff in map (blue: bar, #00f: baz).') do
666
- eval("(blue: bar, #00f: baz)")
667
- end
668
- end
669
-
670
- def test_non_duplicate_map_keys
671
- # These shouldn't throw errors
672
- eval("(foo: foo, bar: bar)")
673
- eval("(2px: foo, 2: bar)")
674
- eval("(2px: foo, 2em: bar)")
675
- eval("('2px': foo, 2px: bar)")
676
- end
677
-
678
- def test_map_syntax_errors
679
- assert_raise_message(Sass::SyntaxError, 'Invalid CSS after "(foo:": expected expression (e.g. 1px, bold), was ")"') do
680
- eval("(foo:)")
681
- end
682
- assert_raise_message(Sass::SyntaxError, 'Invalid CSS after "(": expected ")", was ":bar)"') do
683
- eval("(:bar)")
684
- end
685
- assert_raise_message(Sass::SyntaxError, 'Invalid CSS after "(foo, bar": expected ")", was ": baz)"') do
686
- eval("(foo, bar: baz)")
687
- end
688
- assert_raise_message(Sass::SyntaxError, 'Invalid CSS after "(foo: bar, baz": expected ":", was ")"') do
689
- eval("(foo: bar, baz)")
690
- end
691
- end
692
-
693
- def test_deep_argument_error_not_unwrapped
694
- # JRuby (as of 1.6.7.2) offers no way of distinguishing between
695
- # argument errors caused by programming errors in a function and
696
- # argument errors explicitly thrown within that function.
697
- return if RUBY_PLATFORM =~ /java/
698
-
699
- # Don't validate the message; it's different on Rubinius.
700
- assert_raises(ArgumentError) {resolve("arg-error()")}
701
- end
702
-
703
- def test_shallow_argument_error_unwrapped
704
- assert_raise_message(Sass::SyntaxError, "wrong number of arguments (1 for 0) for `arg-error'") {resolve("arg-error(1)")}
705
- end
706
-
707
- def test_boolean_ops_short_circuit
708
- assert_equal "false", resolve("$ie and $ie <= 7", {}, env('ie' => Sass::Script::Value::Bool.new(false)))
709
- assert_equal "true", resolve("$ie or $undef", {}, env('ie' => Sass::Script::Value::Bool.new(true)))
710
- end
711
-
712
- def test_selector
713
- env = Sass::Environment.new
714
- assert_equal "true", resolve("& == null", {}, env)
715
-
716
- env.selector = selector('.foo.bar .baz.bang, .bip.bop')
717
- assert_equal ".foo.bar .baz.bang, .bip.bop", resolve("&", {}, env)
718
- assert_equal ".foo.bar .baz.bang", resolve("nth(&, 1)", {}, env)
719
- assert_equal ".bip.bop", resolve("nth(&, 2)", {}, env)
720
- assert_equal ".foo.bar", resolve("nth(nth(&, 1), 1)", {}, env)
721
- assert_equal ".baz.bang", resolve("nth(nth(&, 1), 2)", {}, env)
722
- assert_equal ".bip.bop", resolve("nth(nth(&, 2), 1)", {}, env)
723
- assert_equal "string", resolve("type-of(nth(nth(&, 1), 1))", {}, env)
724
-
725
- env.selector = selector('.foo > .bar')
726
- assert_equal ".foo > .bar", resolve("&", {}, env)
727
- assert_equal ".foo > .bar", resolve("nth(&, 1)", {}, env)
728
- assert_equal ".foo", resolve("nth(nth(&, 1), 1)", {}, env)
729
- assert_equal ">", resolve("nth(nth(&, 1), 2)", {}, env)
730
- assert_equal ".bar", resolve("nth(nth(&, 1), 3)", {}, env)
731
- end
732
-
733
- def test_selector_with_newlines
734
- env = Sass::Environment.new
735
- env.selector = selector(".foo.bar\n.baz.bang,\n\n.bip.bop")
736
- assert_equal ".foo.bar .baz.bang, .bip.bop", resolve("&", {}, env)
737
- assert_equal ".foo.bar .baz.bang", resolve("nth(&, 1)", {}, env)
738
- assert_equal ".bip.bop", resolve("nth(&, 2)", {}, env)
739
- assert_equal ".foo.bar", resolve("nth(nth(&, 1), 1)", {}, env)
740
- assert_equal ".baz.bang", resolve("nth(nth(&, 1), 2)", {}, env)
741
- assert_equal ".bip.bop", resolve("nth(nth(&, 2), 1)", {}, env)
742
- assert_equal "string", resolve("type-of(nth(nth(&, 1), 1))", {}, env)
743
- end
744
-
745
- def test_setting_global_variable_globally
746
- assert_no_warning {assert_equal(<<CSS, render(<<SCSS, :syntax => :scss))}
747
- .foo {
748
- a: 1; }
749
-
750
- .bar {
751
- b: 2; }
752
- CSS
753
- $var: 1;
754
-
755
- .foo {
756
- a: $var;
757
- }
758
-
759
- $var: 2;
760
-
761
- .bar {
762
- b: $var;
763
- }
764
- SCSS
765
- end
766
-
767
- def test_setting_global_variable_locally
768
- assert_no_warning {assert_equal(<<CSS, render(<<SCSS, :syntax => :scss))}
769
- .bar {
770
- a: x;
771
- b: y;
772
- c: z; }
773
- CSS
774
- $var1: 1;
775
- $var3: 3;
776
-
777
- .foo {
778
- $var1: x !global;
779
- $var2: y !global;
780
- @each $var3 in _ {
781
- $var3: z !global;
782
- }
783
- }
784
-
785
- .bar {
786
- a: $var1;
787
- b: $var2;
788
- c: $var3;
789
- }
790
- SCSS
791
- end
792
-
793
- def test_setting_global_variable_locally_with_default
794
- assert_equal(<<CSS, render(<<SCSS, :syntax => :scss))
795
- .bar {
796
- a: 1;
797
- b: y;
798
- c: z; }
799
- CSS
800
- $var1: 1;
801
-
802
- .foo {
803
- $var1: x !global !default;
804
- $var2: y !global !default;
805
- @each $var3 in _ {
806
- $var3: z !global !default;
807
- }
808
- }
809
-
810
- .bar {
811
- a: $var1;
812
- b: $var2;
813
- c: $var3;
814
- }
815
- SCSS
816
- end
817
-
818
- def test_setting_local_variable
819
- assert_equal(<<CSS, render(<<SCSS, :syntax => :scss))
820
- .a {
821
- value: inside; }
822
-
823
- .b {
824
- value: outside; }
825
- CSS
826
- $var: outside;
827
-
828
- .a {
829
- $var: inside;
830
- value: $var;
831
- }
832
-
833
- .b {
834
- value: $var;
835
- }
836
- SCSS
837
- end
838
-
839
- def test_setting_local_variable_from_inner_scope
840
- assert_equal(<<CSS, render(<<SCSS, :syntax => :scss))
841
- .a .b {
842
- value: inside; }
843
- .a .c {
844
- value: inside; }
845
- CSS
846
- .a {
847
- $var: outside;
848
-
849
- .b {
850
- $var: inside;
851
- value: $var;
852
- }
853
-
854
- .c {
855
- value: $var;
856
- }
857
- }
858
- SCSS
859
- end
860
-
861
- def test_if_can_assign_to_global_variables
862
- assert_equal <<CSS, render(<<SCSS, :syntax => :scss)
863
- .a {
864
- b: 2; }
865
- CSS
866
- $var: 1;
867
- @if true {$var: 2}
868
- .a {b: $var}
869
- SCSS
870
- end
871
-
872
- def test_else_can_assign_to_global_variables
873
- assert_equal <<CSS, render(<<SCSS, :syntax => :scss)
874
- .a {
875
- b: 2; }
876
- CSS
877
- $var: 1;
878
- @if false {}
879
- @else {$var: 2}
880
- .a {b: $var}
881
- SCSS
882
- end
883
-
884
- def test_for_can_assign_to_global_variables
885
- assert_equal <<CSS, render(<<SCSS, :syntax => :scss)
886
- .a {
887
- b: 2; }
888
- CSS
889
- $var: 1;
890
- @for $i from 1 to 2 {$var: 2}
891
- .a {b: $var}
892
- SCSS
893
- end
894
-
895
- def test_each_can_assign_to_global_variables
896
- assert_equal <<CSS, render(<<SCSS, :syntax => :scss)
897
- .a {
898
- b: 2; }
899
- CSS
900
- $var: 1;
901
- @each $a in 1 {$var: 2}
902
- .a {b: $var}
903
- SCSS
904
- end
905
-
906
- def test_while_can_assign_to_global_variables
907
- assert_equal <<CSS, render(<<SCSS, :syntax => :scss)
908
- .a {
909
- b: 2; }
910
- CSS
911
- $var: 1;
912
- @while $var != 2 {$var: 2}
913
- .a {b: $var}
914
- SCSS
915
- end
916
-
917
- def test_if_doesnt_leak_local_variables
918
- assert_raise_message(Sass::SyntaxError, 'Undefined variable: "$var".') do
919
- render(<<SCSS, :syntax => :scss)
920
- @if true {$var: 1}
921
- .a {b: $var}
922
- SCSS
923
- end
924
- end
925
-
926
- def test_else_doesnt_leak_local_variables
927
- assert_raise_message(Sass::SyntaxError, 'Undefined variable: "$var".') do
928
- render(<<SCSS, :syntax => :scss)
929
- @if false {}
930
- @else {$var: 1}
931
- .a {b: $var}
932
- SCSS
933
- end
934
- end
935
-
936
- def test_for_doesnt_leak_local_variables
937
- assert_raise_message(Sass::SyntaxError, 'Undefined variable: "$var".') do
938
- render(<<SCSS, :syntax => :scss)
939
- @for $i from 1 to 2 {$var: 1}
940
- .a {b: $var}
941
- SCSS
942
- end
943
- end
944
-
945
- def test_each_doesnt_leak_local_variables
946
- assert_raise_message(Sass::SyntaxError, 'Undefined variable: "$var".') do
947
- render(<<SCSS, :syntax => :scss)
948
- @each $a in 1 {$var: 1}
949
- .a {b: $var}
950
- SCSS
951
- end
952
- end
953
-
954
- def test_while_doesnt_leak_local_variables
955
- assert_raise_message(Sass::SyntaxError, 'Undefined variable: "$var".') do
956
- render(<<SCSS, :syntax => :scss)
957
- $iter: true;
958
- @while $iter {
959
- $var: 1;
960
- $iter: false;
961
- }
962
- .a {b: $var}
963
- SCSS
964
- end
965
- end
966
-
967
- def test_color_format_is_preserved_by_default
968
- assert_equal "blue", resolve("blue")
969
- assert_equal "bLuE", resolve("bLuE")
970
- assert_equal "#00f", resolve("#00f")
971
- assert_equal "blue #00F", resolve("blue #00F")
972
- assert_equal "blue", resolve("nth(blue #00F, 1)")
973
- assert_equal "#00F", resolve("nth(blue #00F, 2)")
974
- end
975
-
976
- def test_color_format_isnt_always_preserved_in_compressed_style
977
- assert_equal "red", resolve("red", :style => :compressed)
978
- assert_equal "red", resolve("#f00", :style => :compressed)
979
- assert_equal "red red", resolve("red #f00", :style => :compressed)
980
- assert_equal "red", resolve("nth(red #f00, 2)", :style => :compressed)
981
- end
982
-
983
- def test_color_format_is_sometimes_preserved_in_compressed_style
984
- assert_equal "ReD", resolve("ReD", :style => :compressed)
985
- assert_equal "blue", resolve("blue", :style => :compressed)
986
- assert_equal "#00f", resolve("#00f", :style => :compressed)
987
- end
988
-
989
- def test_color_format_isnt_preserved_when_modified
990
- assert_equal "magenta", resolve("change-color(#f00, $blue: 255)")
991
- end
992
-
993
- def test_ids
994
- assert_equal "#foo", resolve("#foo")
995
- silence_warnings {assert_equal "#abcd", resolve("#abcd")}
996
- assert_equal "#abc-def", resolve("#abc-def")
997
- assert_equal "#abc_def", resolve("#abc_def")
998
- assert_equal "#uvw-xyz", resolve("#uvw-xyz")
999
- assert_equal "#uvw_xyz", resolve("#uvw_xyz")
1000
- assert_equal "#uvwxyz", resolve("#uvw + xyz")
1001
- end
1002
-
1003
- def test_scientific_notation
1004
- assert_equal "2000", resolve("2e3")
1005
- assert_equal "2000", resolve("2E3")
1006
- assert_equal "2000", resolve("2e+3")
1007
- assert_equal "2000em", resolve("2e3em")
1008
- assert_equal "25000000000", resolve("2.5e10")
1009
- assert_equal "0.1234", resolve("1234e-4")
1010
- assert_equal "12.34", resolve("1.234e1")
1011
- end
1012
-
1013
- def test_identifier_units
1014
- assert_equal "5-foo", resolve("2-foo + 3-foo")
1015
- assert_equal "5-foo-", resolve("2-foo- + 3-foo-")
1016
- assert_equal "5-\\u2603", resolve("2-\\u2603 + 3-\\u2603")
1017
- end
1018
-
1019
- def test_backslash_newline_in_string
1020
- assert_equal 'foobar', resolve("\"foo\\\nbar\"")
1021
- assert_equal 'foobar', resolve("'foo\\\nbar'")
1022
- end
1023
-
1024
- def test_unclosed_special_fun
1025
- assert_raise_message(Sass::SyntaxError, 'Invalid CSS after "calc(foo()": expected ")", was ""') do
1026
- resolve("calc(foo()")
1027
- end
1028
- assert_raise_message(Sass::SyntaxError, 'Invalid CSS after "calc(#{\')\'}": expected ")", was ""') do
1029
- resolve("calc(\#{')'}")
1030
- end
1031
- assert_raise_message(Sass::SyntaxError, 'Invalid CSS after "calc(#{foo": expected "}", was ""') do
1032
- resolve("calc(\#{foo")
1033
- end
1034
- end
1035
-
1036
- def test_special_fun_with_interpolation
1037
- assert_equal "calc())", resolve("calc(\#{')'})")
1038
- assert_equal "calc(# {foo})", resolve("calc(# {foo})")
1039
- end
1040
-
1041
- # Regression Tests
1042
-
1043
- def test_interpolation_after_string
1044
- assert_equal '"foobar" 2', resolve('"foobar" #{2}')
1045
- assert_equal "calc(1 + 2) 3", resolve('calc(1 + 2) #{3}')
1046
- end
1047
-
1048
- def test_repeatedly_modified_color
1049
- assert_equal(<<CSS, render(<<SASS))
1050
- a {
1051
- link-color: #161C14;
1052
- link-color-hover: black;
1053
- link-color-tap: rgba(22, 28, 20, 0.3); }
1054
- CSS
1055
- $green: #161C14
1056
- $link-color: $green
1057
- $link-color-hover: darken($link-color, 10%)
1058
- $link-color-tap: rgba($green, 0.3)
1059
-
1060
- a
1061
- link-color: $link-color
1062
- link-color-hover: $link-color-hover
1063
- link-color-tap: $link-color-tap
1064
- SASS
1065
- end
1066
-
1067
- def test_inspect_divided_numbers
1068
- assert_equal "1px/2px", resolve("inspect(1px/2px)")
1069
- assert_equal "0.5", resolve("inspect((1px/2px))")
1070
- end
1071
-
1072
- def test_minus_without_whitespace
1073
- assert_equal "5px", resolve("15px-10px")
1074
- assert_equal "5px-", resolve("15px--10px-")
1075
- end
1076
-
1077
- def test_minus_preceded_by_comment
1078
- assert_equal "15px -10px", resolve("15px/**/-10px")
1079
- end
1080
-
1081
- def test_user_defined_function_forces_division
1082
- assert_equal(<<CSS, render(<<SASS))
1083
- a {
1084
- b: 10px; }
1085
- CSS
1086
- @function foo()
1087
- @return 20px
1088
-
1089
- a
1090
- b: (foo() / 2)
1091
- SASS
1092
-
1093
- assert_equal(<<CSS, render(<<SASS))
1094
- a {
1095
- b: 10px; }
1096
- CSS
1097
- @function foo()
1098
- @return 20px
1099
-
1100
- a
1101
- b: foo() / 2
1102
- SASS
1103
- end
1104
-
1105
- def test_funcall_has_higher_precedence_than_color_name
1106
- assert_equal "teal(12)", resolve("teal(12)")
1107
- assert_equal "tealbang(12)", resolve("tealbang(12)")
1108
- assert_equal "teal-bang(12)", resolve("teal-bang(12)")
1109
- assert_equal "teal\\+bang(12)", resolve("teal\\+bang(12)")
1110
- end
1111
-
1112
- def test_funcall_has_higher_precedence_than_true_false_null
1113
- assert_equal "teal(12)", resolve("teal(12)")
1114
- assert_equal "tealbang(12)", resolve("tealbang(12)")
1115
- assert_equal "teal-bang(12)", resolve("teal-bang(12)")
1116
- assert_equal "teal\\+bang(12)", resolve("teal\\+bang(12)")
1117
- end
1118
-
1119
- def test_and_or_not_disallowed_as_function_names
1120
- %w[and or not].each do |name|
1121
- assert_raise_message(Sass::SyntaxError, "Invalid function name \"#{name}\".") do
1122
- render(<<SASS)
1123
- @function #{name}()
1124
- @return null
1125
- SASS
1126
- end
1127
- end
1128
- end
1129
-
1130
- def test_interpolation_after_hash
1131
- assert_equal "#2", resolve('"##{1 + 1}"')
1132
- end
1133
-
1134
- def test_func_call_arglist_trailing_comma
1135
- assert_equal eval('foo(bar)'), eval('foo(bar, )')
1136
- end
1137
-
1138
- def test_color_prefixed_identifier
1139
- assert_equal "tealbang", resolve("tealbang")
1140
- assert_equal "teal-bang", resolve("teal-bang")
1141
- end
1142
-
1143
- def test_op_prefixed_identifier
1144
- assert_equal "notbang", resolve("notbang")
1145
- assert_equal "not-bang", resolve("not-bang")
1146
- assert_equal "or-bang", resolve("or-bang")
1147
- assert_equal "and-bang", resolve("and-bang")
1148
- end
1149
-
1150
- def test_number_initialization
1151
- assert_equal Sass::Script::Value::Number.new(10, ["px"]), Sass::Script::Value::Number.new(10, "px")
1152
- assert_equal Sass::Script::Value::Number.new(10, ["px"], ["em"]), Sass::Script::Value::Number.new(10, "px", "em")
1153
- end
1154
-
1155
- def test_is_unit
1156
- assert Sass::Script::Value::Number.new(10, "px").is_unit?("px")
1157
- assert Sass::Script::Value::Number.new(10).is_unit?(nil)
1158
- assert !Sass::Script::Value::Number.new(10, "px", "em").is_unit?("px")
1159
- assert !Sass::Script::Value::Number.new(10, [], "em").is_unit?("em")
1160
- assert !Sass::Script::Value::Number.new(10, ["px", "em"]).is_unit?("px")
1161
- end
1162
-
1163
- def test_rename_redirect
1164
- assert_no_warning do
1165
- assert_equal Sass::Script::Value::Base, Sass::Script::Literal
1166
- assert_equal Sass::Script::Tree::Node, Sass::Script::Node
1167
- assert_equal Sass::Script::Tree::Operation, Sass::Script::Operation
1168
- assert_equal Sass::Script::Value::String, Sass::Script::String
1169
- end
1170
- end
1171
-
1172
- def test_number_printing
1173
- assert_equal "1", resolve("1")
1174
- assert_equal "1", resolve("1.0")
1175
- assert_equal "1000000000", resolve("1000000000")
1176
- assert_equal "0.00001", resolve("0.00001")
1177
- assert_equal "1.1212121212", resolve("1.12121212124")
1178
- assert_equal "1.1212121213", resolve("1.12121212125")
1179
- assert_equal "Infinity", resolve("(1.0/0.0)")
1180
- assert_equal "-Infinity", resolve("(-1.0/0.0)")
1181
- assert_equal "NaN", resolve("(0.0/0.0)")
1182
- end
1183
-
1184
- def test_equality_uses_an_epsilon
1185
- # At least on my machine, this calculation introduces a floating point error:
1186
- # 29.0 / 7 * 7
1187
- # => 29.000000000000004
1188
- assert_equal "true", resolve("29 == (29 / 7 * 7)")
1189
- end
1190
-
1191
- def test_compressed_output_of_numbers_with_leading_zeros
1192
- assert_equal "1.5", resolve("1.5", :style => :compressed)
1193
- assert_equal ".5", resolve("0.5", :style => :compressed)
1194
- assert_equal "-.5", resolve("-0.5", :style => :compressed)
1195
- assert_equal "0.5", resolve("0.5", :style => :compact)
1196
- end
1197
-
1198
- def test_interpolation_without_deprecation_warning
1199
- assert_no_warning {assert_equal "a", resolve('#{a}')}
1200
- assert_no_warning {assert_equal "abc", resolve('a#{b}c')}
1201
- assert_no_warning {assert_equal "+ a", resolve('+ #{a}')}
1202
- assert_no_warning {assert_equal "/ a", resolve('/ #{a}')}
1203
- assert_no_warning {assert_equal "1 / a", resolve('1 / #{a}')}
1204
- assert_no_warning {assert_equal "a / b", resolve('#{a} / #{b}')}
1205
- assert_no_warning {assert_equal "foo(1 = a)", resolve('foo(1 = #{a})')}
1206
- assert_no_warning {assert_equal "foo(a = b)", resolve('foo(#{a} = #{b})')}
1207
- assert_no_warning {assert_equal "-a", resolve('-#{a}')}
1208
- assert_no_warning {assert_equal "1-a", resolve('1-#{a}')}
1209
- assert_no_warning {assert_equal "a- 1", resolve('#{a}- 1')}
1210
- assert_no_warning {assert_equal "a-1", resolve('#{a}-1')}
1211
- assert_no_warning {assert_equal "a-b", resolve('#{a}-#{b}')}
1212
- assert_no_warning {assert_equal "a1", resolve('#{a}1')}
1213
- assert_no_warning {assert_equal "ab", resolve('#{a}b')}
1214
- assert_no_warning {assert_equal "1a", resolve('1#{a}')}
1215
- assert_no_warning {assert_equal "ba", resolve('b#{a}')}
1216
- end
1217
-
1218
- def test_leading_interpolation_with_deprecation_warning
1219
- assert_equal "ab == 1", resolve_with_interp_warning('#{a + b} == 1')
1220
- assert_equal "ab != 1", resolve_with_interp_warning('#{a + b} != 1')
1221
- assert_equal "ab > 1", resolve_with_interp_warning('#{a + b} > 1')
1222
- assert_equal "ab >= 1", resolve_with_interp_warning('#{a + b} >= 1')
1223
- assert_equal "ab < 1", resolve_with_interp_warning('#{a + b} < 1')
1224
- assert_equal "ab <= 1", resolve_with_interp_warning('#{a + b} <= 1')
1225
- assert_equal "ab + 1", resolve_with_interp_warning('#{a + b} + 1')
1226
- assert_equal "ab * 1", resolve_with_interp_warning('#{a + b} * 1')
1227
- assert_equal "ab - 1", resolve_with_interp_warning('#{a + b} - 1')
1228
- assert_equal "ab % 1", resolve_with_interp_warning('#{a + b} % 1')
1229
- assert_equal(
1230
- "abvar",
1231
- resolve_with_interp_warning(
1232
- '#{a + b}$var', '"#{a + b}#{$var}"',
1233
- env('var' => Sass::Script::Value::String.new("var"))))
1234
- assert_equal(
1235
- "varab",
1236
- resolve_with_interp_warning(
1237
- '$var#{a + b}', '"#{$var}#{a + b}"',
1238
- env('var' => Sass::Script::Value::String.new("var"))))
1239
- assert_equal "ab1", resolve_with_interp_warning('#{a + b}(1)', '"#{a + b}1"')
1240
- assert_equal "1ab", resolve_with_interp_warning('(1)#{a + b}', '"1#{a + b}"')
1241
- end
1242
-
1243
- def test_trailing_interpolation_with_deprecation_warning
1244
- assert_equal "not ab", resolve_with_interp_warning('not #{a + b}')
1245
- assert_equal "1 and ab", resolve_with_interp_warning('1 and #{a + b}')
1246
- assert_equal "1 or ab", resolve_with_interp_warning('1 or #{a + b}')
1247
- assert_equal "1 == ab", resolve_with_interp_warning('1 == #{a + b}')
1248
- assert_equal "1 != ab", resolve_with_interp_warning('1 != #{a + b}')
1249
- assert_equal "1 > ab", resolve_with_interp_warning('1 > #{a + b}')
1250
- assert_equal "1 >= ab", resolve_with_interp_warning('1 >= #{a + b}')
1251
- assert_equal "1 < ab", resolve_with_interp_warning('1 < #{a + b}')
1252
- assert_equal "1 <= ab", resolve_with_interp_warning('1 <= #{a + b}')
1253
- assert_equal "1 + ab", resolve_with_interp_warning('1 + #{a + b}')
1254
- assert_equal "1 * ab", resolve_with_interp_warning('1 * #{a + b}')
1255
- assert_equal "1 - ab", resolve_with_interp_warning('1 - #{a + b}')
1256
- assert_equal "1 % ab", resolve_with_interp_warning('1 % #{a + b}')
1257
- assert_equal "- ab", resolve_with_interp_warning('- #{a + b}')
1258
- assert_equal "1- ab", resolve_with_interp_warning('1- #{a + b}')
1259
- assert_equal "- ab 2 3", resolve_with_interp_warning('- #{a + b} 2 3', '"- #{a + b} #{2 3}"')
1260
- end
1261
-
1262
- def test_brackteing_interpolation_with_deprecation_warning
1263
- assert_equal "ab == cd", resolve_with_interp_warning('#{a + b} == #{c + d}')
1264
- assert_equal "ab != cd", resolve_with_interp_warning('#{a + b} != #{c + d}')
1265
- assert_equal "ab > cd", resolve_with_interp_warning('#{a + b} > #{c + d}')
1266
- assert_equal "ab >= cd", resolve_with_interp_warning('#{a + b} >= #{c + d}')
1267
- assert_equal "ab < cd", resolve_with_interp_warning('#{a + b} < #{c + d}')
1268
- assert_equal "ab <= cd", resolve_with_interp_warning('#{a + b} <= #{c + d}')
1269
- assert_equal "ab + cd", resolve_with_interp_warning('#{a + b} + #{c + d}')
1270
- assert_equal "ab * cd", resolve_with_interp_warning('#{a + b} * #{c + d}')
1271
- assert_equal "ab - cd", resolve_with_interp_warning('#{a + b} - #{c + d}')
1272
- assert_equal "ab % cd", resolve_with_interp_warning('#{a + b} % #{c + d}')
1273
- end
1274
-
1275
- def test_interp_warning_formatting
1276
- resolve_with_interp_warning('#{1} + 1', '"1 + 1"')
1277
- resolve_with_interp_warning('#{1} + "foo"', '\'1 + "foo"\'')
1278
- resolve_with_interp_warning('#{1} + \'foo\'', '\'1 + "foo"\'')
1279
-
1280
- resolve_with_interp_warning('#{1} + "#{a + b}"', '\'1 + "#{a + b}"\'')
1281
- resolve_with_interp_warning('"#{a + b}" + #{1}', '\'"#{a + b}" + 1\'')
1282
- resolve_with_interp_warning('"#{a + b}" + #{1} + "#{c + d}"', '\'"#{a + b}" + 1 + "#{c + d}"\'')
1283
-
1284
- resolve_with_interp_warning('#{1} + "\'"', '"1 + \\"\'\\""')
1285
- resolve_with_interp_warning('#{1} + \'"\'', '"1 + \'\\"\'"')
1286
- resolve_with_interp_warning('#{1} + "\'\\""', '"1 + \\"\'\\\\\\"\\""')
1287
- end
1288
-
1289
- def test_inactive_lazy_interpolation_deprecation_warning
1290
- assert_equal '1, 2, 3', assert_no_warning {resolve('1, #{2}, 3')}
1291
- assert_equal '1, 2, 3', assert_no_warning {resolve('1, 2, #{3}')}
1292
- assert_equal '1,2,3', assert_no_warning {resolve('1,#{2},3')}
1293
- assert_equal '1 2 3', assert_no_warning {resolve('#{1} 2 3')}
1294
- assert_equal '1 2 3', assert_no_warning {resolve('1 #{2} 3')}
1295
- assert_equal '1 2 3', assert_no_warning {resolve('1 2 #{3}')}
1296
-
1297
- assert_equal '+1 2 3', assert_no_warning {resolve('+#{1} 2 3')}
1298
- assert_equal '-1 2 3', assert_no_warning {resolve('-#{1} 2 3')}
1299
- assert_equal '/1 2 3', assert_no_warning {resolve('/#{1} 2 3')}
1300
-
1301
- assert_equal '1, 2, 31', assert_no_warning {resolve('(1, #{2}, 3) + 1')}
1302
- assert_equal '11, 2, 3', assert_no_warning {resolve('1 + (1, #{2}, 3)')}
1303
-
1304
- assert_equal 'a, b, c', assert_no_warning {resolve('selector-parse((a, #{b}, c))')}
1305
- end
1306
-
1307
- def test_active_lazy_interpolation_deprecation_warning
1308
- Sass::Deprecation.allow_double_warnings do
1309
- assert_equal "1, 2, 3", resolve_with_lazy_interp_warning('quote((1, #{2}, 3))', '"1, 2, 3"')
1310
- assert_equal "1", resolve_with_lazy_interp_warning('length((1, #{2}, 3))', '"1, 2, 3"')
1311
- assert_equal "1, 2, 3", resolve_with_lazy_interp_warning('inspect((1, #{2}, 3))', '"1, 2, 3"')
1312
- assert_equal "string", resolve_with_lazy_interp_warning('type-of((1, #{2}, 3))', '"1, 2, 3"')
1313
-
1314
- assert_equal "+1 2 3", resolve_with_lazy_interp_warning('quote((+#{1} 2 3))', '"+1 #{2 3}"')
1315
- assert_equal "/1 2 3", resolve_with_lazy_interp_warning('quote((/#{1} 2 3))', '"/1 #{2 3}"')
1316
- assert_equal "-1 2 3", resolve_with_lazy_interp_warning('quote((-#{1} 2 3))', '"-1 #{2 3}"')
1317
- end
1318
- end
1319
-
1320
- def test_comparison_of_complex_units
1321
- # Tests for issue #1960
1322
- Sass::Deprecation.allow_double_warnings do
1323
- assert_warning(<<WARNING) do
1324
- DEPRECATION WARNING on line 1 of test_comparison_of_complex_units_inline.sass:
1325
- The result of `10 == 10px` will be `false` in future releases of Sass.
1326
- Unitless numbers will no longer be equal to the same numbers with units.
1327
- WARNING
1328
- assert_equal "true", resolve("10 == 2 * 5px")
1329
- end
1330
- assert_warning(<<WARNING) do
1331
- DEPRECATION WARNING on line 1 of test_comparison_of_complex_units_inline.sass:
1332
- The result of `10 == 10px*px` will be `false` in future releases of Sass.
1333
- Unitless numbers will no longer be equal to the same numbers with units.
1334
- WARNING
1335
- assert_equal "true", resolve("10 == 2px * 5px")
1336
- end
1337
- end
1338
-
1339
- assert_equal "true", resolve("10px * 1px == 2px * 5px")
1340
- assert_equal "true", resolve("5px * 1px < 2px * 5px")
1341
- end
1342
-
1343
- private
1344
-
1345
- def resolve_with_lazy_interp_warning(str, contents = nil, environment = env)
1346
- contents ||= "\"#{str}\""
1347
- result = assert_warning(<<WARNING) {resolve(str, {}, environment)}
1348
- DEPRECATION WARNING on line 1 of #{filename_for_test}:
1349
- \#{} interpolation near operators will be simplified in a future version of Sass.
1350
- To preserve the current behavior, use quotes:
1351
-
1352
- unquote(#{contents})
1353
- WARNING
1354
- $_sass_deprecated_interp_warnings = nil
1355
- result
1356
- end
1357
-
1358
- def resolve_with_interp_warning(str, contents = nil, environment = env)
1359
- contents ||= "\"#{str}\""
1360
- assert_warning(<<WARNING) {resolve(str, {}, environment)}
1361
- DEPRECATION WARNING on line 1 of #{filename_for_test}:
1362
- \#{} interpolation near operators will be simplified in a future version of Sass.
1363
- To preserve the current behavior, use quotes:
1364
-
1365
- unquote(#{contents})
1366
-
1367
- You can use the sass-convert command to automatically fix most cases.
1368
- WARNING
1369
- end
1370
-
1371
- def resolve(str, opts = {}, environment = env)
1372
- munge_filename opts
1373
- val = eval(str, opts, environment)
1374
- assert_kind_of Sass::Script::Value::Base, val
1375
- val.options = opts
1376
- val.is_a?(Sass::Script::Value::String) ? val.value : val.to_s
1377
- end
1378
-
1379
- def resolve_quoted(str, opts = {}, environment = env)
1380
- munge_filename opts
1381
- val = eval(str, opts, environment)
1382
- assert_kind_of Sass::Script::Value::Base, val
1383
- val.to_s
1384
- end
1385
-
1386
- def assert_unquoted(str, opts = {}, environment = env)
1387
- munge_filename opts
1388
- val = eval(str, opts, environment)
1389
- assert_kind_of Sass::Script::Value::String, val
1390
- assert_equal :identifier, val.type
1391
- end
1392
-
1393
- def assert_quoted(str, opts = {}, environment = env)
1394
- munge_filename opts
1395
- val = eval(str, opts, environment)
1396
- assert_kind_of Sass::Script::Value::String, val
1397
- assert_equal :string, val.type
1398
- end
1399
-
1400
- def eval(str, opts = {}, environment = env)
1401
- munge_filename opts
1402
- Sass::Script.parse(str, opts.delete(:line) || 1,
1403
- opts.delete(:offset) || 0, opts).
1404
- perform(Sass::Environment.new(environment, opts))
1405
- end
1406
-
1407
- def render(sass, options = {})
1408
- munge_filename options
1409
- Sass::Engine.new(sass, options).render
1410
- end
1411
-
1412
- def env(hash = {})
1413
- env = Sass::Environment.new
1414
- hash.each {|k, v| env.set_var(k, v)}
1415
- env
1416
- end
1417
-
1418
- def selector(str)
1419
- parser = Sass::SCSS::StaticParser.new(
1420
- str, filename_for_test, Sass::Importers::Filesystem.new('.'))
1421
- parser.parse_selector
1422
- end
1423
-
1424
- def test_null_is_a_singleton
1425
- assert_same Sass::Script::Value::Null.new, Sass::Script::Value::Null.new
1426
- end
1427
- end