sass 3.6.0 → 3.7.0

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