sass 3.5.2 → 3.7.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (163) hide show
  1. checksums.yaml +4 -4
  2. data/CODE_OF_CONDUCT.md +1 -1
  3. data/CONTRIBUTING.md +3 -3
  4. data/README.md +17 -9
  5. data/VERSION +1 -1
  6. data/VERSION_DATE +1 -1
  7. data/extra/sass-spec-ref.sh +9 -1
  8. data/lib/sass/engine.rb +1 -9
  9. data/lib/sass/exec/base.rb +0 -2
  10. data/lib/sass/exec/sass_scss.rb +1 -5
  11. data/lib/sass/importers/filesystem.rb +4 -2
  12. data/lib/sass/logger/base.rb +11 -0
  13. data/lib/sass/script/css_parser.rb +4 -1
  14. data/lib/sass/script/functions.rb +76 -41
  15. data/lib/sass/script/lexer.rb +62 -19
  16. data/lib/sass/script/parser.rb +260 -93
  17. data/lib/sass/script/tree/funcall.rb +0 -4
  18. data/lib/sass/script/tree/interpolation.rb +0 -3
  19. data/lib/sass/script/tree/operation.rb +1 -1
  20. data/lib/sass/script/value/color.rb +3 -2
  21. data/lib/sass/script/value/helpers.rb +8 -2
  22. data/lib/sass/script/value/number.rb +2 -1
  23. data/lib/sass/scss/css_parser.rb +6 -1
  24. data/lib/sass/scss/parser.rb +48 -18
  25. data/lib/sass/scss/rx.rb +1 -1
  26. data/lib/sass/scss/static_parser.rb +15 -18
  27. data/lib/sass/selector/comma_sequence.rb +2 -1
  28. data/lib/sass/selector/pseudo.rb +1 -1
  29. data/lib/sass/selector/sequence.rb +0 -4
  30. data/lib/sass/source/map.rb +0 -4
  31. data/lib/sass/tree/rule_node.rb +3 -6
  32. data/lib/sass/tree/visitors/perform.rb +2 -6
  33. data/lib/sass/tree/visitors/to_css.rb +4 -11
  34. data/lib/sass/util.rb +60 -20
  35. data/lib/sass/version.rb +0 -2
  36. metadata +38 -162
  37. data/Rakefile +0 -338
  38. data/lib/test.css +0 -4
  39. data/lib/test.css.map +0 -7
  40. data/test/sass-spec.yml +0 -3
  41. data/test/sass/cache_test.rb +0 -130
  42. data/test/sass/callbacks_test.rb +0 -60
  43. data/test/sass/compiler_test.rb +0 -225
  44. data/test/sass/conversion_test.rb +0 -2138
  45. data/test/sass/css2sass_test.rb +0 -523
  46. data/test/sass/css_variable_test.rb +0 -237
  47. data/test/sass/data/hsl-rgb.txt +0 -319
  48. data/test/sass/encoding_test.rb +0 -188
  49. data/test/sass/engine_test.rb +0 -3499
  50. data/test/sass/exec_test.rb +0 -95
  51. data/test/sass/extend_test.rb +0 -1678
  52. data/test/sass/fixtures/test_staleness_check_across_importers.css +0 -1
  53. data/test/sass/fixtures/test_staleness_check_across_importers.scss +0 -1
  54. data/test/sass/functions_test.rb +0 -2021
  55. data/test/sass/importer_test.rb +0 -420
  56. data/test/sass/logger_test.rb +0 -57
  57. data/test/sass/mock_importer.rb +0 -49
  58. data/test/sass/more_results/more1.css +0 -9
  59. data/test/sass/more_results/more1_with_line_comments.css +0 -26
  60. data/test/sass/more_results/more_import.css +0 -29
  61. data/test/sass/more_templates/_more_partial.sass +0 -2
  62. data/test/sass/more_templates/more1.sass +0 -23
  63. data/test/sass/more_templates/more_import.sass +0 -11
  64. data/test/sass/plugin_test.rb +0 -552
  65. data/test/sass/results/alt.css +0 -4
  66. data/test/sass/results/basic.css +0 -9
  67. data/test/sass/results/cached_import_option.css +0 -3
  68. data/test/sass/results/compact.css +0 -5
  69. data/test/sass/results/complex.css +0 -86
  70. data/test/sass/results/compressed.css +0 -1
  71. data/test/sass/results/expanded.css +0 -19
  72. data/test/sass/results/filename_fn.css +0 -3
  73. data/test/sass/results/if.css +0 -3
  74. data/test/sass/results/import.css +0 -31
  75. data/test/sass/results/import_charset.css +0 -5
  76. data/test/sass/results/import_charset_ibm866.css +0 -5
  77. data/test/sass/results/import_content.css +0 -1
  78. data/test/sass/results/line_numbers.css +0 -49
  79. data/test/sass/results/mixins.css +0 -95
  80. data/test/sass/results/multiline.css +0 -24
  81. data/test/sass/results/nested.css +0 -22
  82. data/test/sass/results/options.css +0 -1
  83. data/test/sass/results/parent_ref.css +0 -13
  84. data/test/sass/results/script.css +0 -16
  85. data/test/sass/results/scss_import.css +0 -31
  86. data/test/sass/results/scss_importee.css +0 -2
  87. data/test/sass/results/subdir/nested_subdir/nested_subdir.css +0 -1
  88. data/test/sass/results/subdir/subdir.css +0 -3
  89. data/test/sass/results/units.css +0 -11
  90. data/test/sass/results/warn.css +0 -0
  91. data/test/sass/results/warn_imported.css +0 -0
  92. data/test/sass/script_conversion_test.rb +0 -365
  93. data/test/sass/script_test.rb +0 -1429
  94. data/test/sass/scss/css_test.rb +0 -1266
  95. data/test/sass/scss/rx_test.rb +0 -159
  96. data/test/sass/scss/scss_test.rb +0 -4238
  97. data/test/sass/scss/test_helper.rb +0 -37
  98. data/test/sass/source_map_test.rb +0 -1052
  99. data/test/sass/superselector_test.rb +0 -209
  100. data/test/sass/templates/_cached_import_option_partial.scss +0 -1
  101. data/test/sass/templates/_double_import_loop2.sass +0 -1
  102. data/test/sass/templates/_filename_fn_import.scss +0 -11
  103. data/test/sass/templates/_imported_charset_ibm866.sass +0 -4
  104. data/test/sass/templates/_imported_charset_utf8.sass +0 -4
  105. data/test/sass/templates/_imported_content.sass +0 -3
  106. data/test/sass/templates/_partial.sass +0 -2
  107. data/test/sass/templates/_same_name_different_partiality.scss +0 -1
  108. data/test/sass/templates/alt.sass +0 -16
  109. data/test/sass/templates/basic.sass +0 -23
  110. data/test/sass/templates/bork1.sass +0 -2
  111. data/test/sass/templates/bork2.sass +0 -2
  112. data/test/sass/templates/bork3.sass +0 -2
  113. data/test/sass/templates/bork4.sass +0 -2
  114. data/test/sass/templates/bork5.sass +0 -3
  115. data/test/sass/templates/cached_import_option.scss +0 -3
  116. data/test/sass/templates/compact.sass +0 -17
  117. data/test/sass/templates/complex.sass +0 -305
  118. data/test/sass/templates/compressed.sass +0 -15
  119. data/test/sass/templates/double_import_loop1.sass +0 -1
  120. data/test/sass/templates/expanded.sass +0 -17
  121. data/test/sass/templates/filename_fn.scss +0 -18
  122. data/test/sass/templates/if.sass +0 -11
  123. data/test/sass/templates/import.sass +0 -12
  124. data/test/sass/templates/import_charset.sass +0 -9
  125. data/test/sass/templates/import_charset_ibm866.sass +0 -11
  126. data/test/sass/templates/import_content.sass +0 -4
  127. data/test/sass/templates/importee.less +0 -2
  128. data/test/sass/templates/importee.sass +0 -19
  129. data/test/sass/templates/line_numbers.sass +0 -13
  130. data/test/sass/templates/mixin_bork.sass +0 -5
  131. data/test/sass/templates/mixins.sass +0 -76
  132. data/test/sass/templates/multiline.sass +0 -20
  133. data/test/sass/templates/nested.sass +0 -25
  134. data/test/sass/templates/nested_bork1.sass +0 -2
  135. data/test/sass/templates/nested_bork2.sass +0 -2
  136. data/test/sass/templates/nested_bork3.sass +0 -2
  137. data/test/sass/templates/nested_bork4.sass +0 -2
  138. data/test/sass/templates/nested_import.sass +0 -2
  139. data/test/sass/templates/nested_mixin_bork.sass +0 -6
  140. data/test/sass/templates/options.sass +0 -2
  141. data/test/sass/templates/parent_ref.sass +0 -25
  142. data/test/sass/templates/same_name_different_ext.sass +0 -2
  143. data/test/sass/templates/same_name_different_ext.scss +0 -1
  144. data/test/sass/templates/same_name_different_partiality.scss +0 -1
  145. data/test/sass/templates/script.sass +0 -101
  146. data/test/sass/templates/scss_import.scss +0 -12
  147. data/test/sass/templates/scss_importee.scss +0 -1
  148. data/test/sass/templates/single_import_loop.sass +0 -1
  149. data/test/sass/templates/subdir/import_up1.scss +0 -1
  150. data/test/sass/templates/subdir/import_up2.scss +0 -1
  151. data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +0 -2
  152. data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +0 -3
  153. data/test/sass/templates/subdir/subdir.sass +0 -6
  154. data/test/sass/templates/units.sass +0 -11
  155. data/test/sass/templates/warn.sass +0 -3
  156. data/test/sass/templates/warn_imported.sass +0 -4
  157. data/test/sass/test_helper.rb +0 -8
  158. data/test/sass/util/multibyte_string_scanner_test.rb +0 -152
  159. data/test/sass/util/normalized_map_test.rb +0 -50
  160. data/test/sass/util/subset_map_test.rb +0 -90
  161. data/test/sass/util_test.rb +0 -403
  162. data/test/sass/value_helpers_test.rb +0 -178
  163. data/test/test_helper.rb +0 -149
@@ -1,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,1429 +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 "#1234"') {eval("#1234")}
613
- assert_raise_message(Sass::SyntaxError,
614
- 'Invalid CSS after "": expected expression (e.g. 1px, bold), was "#12345"') {eval("#12345")}
615
- assert_raise_message(Sass::SyntaxError, 'Invalid CSS after "": expected expression (e.g. ' \
616
- '1px, bold), was "#1234567"') {eval("#1234567")}
617
- end
618
-
619
- def test_case_insensitive_color_names
620
- assert_equal "BLUE", resolve("BLUE")
621
- assert_equal "rEd", resolve("rEd")
622
- assert_equal "#804000", resolve("mix(GrEeN, ReD)")
623
- end
624
-
625
- def test_empty_list
626
- assert_equal "1 2 3", resolve("1 2 () 3")
627
- assert_equal "1 2 3", resolve("1 2 3 ()")
628
- assert_equal "1 2 3", resolve("() 1 2 3")
629
- assert_raise_message(Sass::SyntaxError, "() isn't a valid CSS value.") {resolve("()")}
630
- assert_raise_message(Sass::SyntaxError, "() isn't a valid CSS value.") {resolve("nth(append((), ()), 1)")}
631
- end
632
-
633
- def test_list_with_nulls
634
- assert_equal "1, 2, 3", resolve("1, 2, null, 3")
635
- assert_equal "1 2 3", resolve("1 2 null 3")
636
- assert_equal "1, 2, 3", resolve("1, 2, 3, null")
637
- assert_equal "1 2 3", resolve("1 2 3 null")
638
- assert_equal "1, 2, 3", resolve("null, 1, 2, 3")
639
- assert_equal "1 2 3", resolve("null 1 2 3")
640
- end
641
-
642
- def test_map_can_have_trailing_comma
643
- assert_equal("(foo: 1, bar: 2)", eval("(foo: 1, bar: 2,)").to_sass)
644
- end
645
-
646
- def test_list_can_have_trailing_comma
647
- assert_equal("1, 2, 3", resolve("1, 2, 3,"))
648
- end
649
-
650
- def test_trailing_comma_defines_singleton_list
651
- assert_equal("1 2 3", resolve("nth((1 2 3,), 1)"))
652
- end
653
-
654
- def test_map_cannot_have_duplicate_keys
655
- assert_raise_message(Sass::SyntaxError, 'Duplicate key "foo" in map (foo: bar, foo: baz).') do
656
- eval("(foo: bar, foo: baz)")
657
- end
658
- assert_raise_message(Sass::SyntaxError, 'Duplicate key "foo" in map (foo: bar, fo + o: baz).') do
659
- eval("(foo: bar, fo + o: baz)")
660
- end
661
- assert_raise_message(Sass::SyntaxError, 'Duplicate key "foo" in map (foo: bar, "foo": baz).') do
662
- eval("(foo: bar, 'foo': baz)")
663
- end
664
- assert_raise_message(Sass::SyntaxError, 'Duplicate key 2px in map (2px: bar, 1px + 1px: baz).') do
665
- eval("(2px: bar, 1px + 1px: baz)")
666
- end
667
- assert_raise_message(Sass::SyntaxError, 'Duplicate key #0000ff in map (blue: bar, #00f: baz).') do
668
- eval("(blue: bar, #00f: baz)")
669
- end
670
- end
671
-
672
- def test_non_duplicate_map_keys
673
- # These shouldn't throw errors
674
- eval("(foo: foo, bar: bar)")
675
- eval("(2px: foo, 2: bar)")
676
- eval("(2px: foo, 2em: bar)")
677
- eval("('2px': foo, 2px: bar)")
678
- end
679
-
680
- def test_map_syntax_errors
681
- assert_raise_message(Sass::SyntaxError, 'Invalid CSS after "(foo:": expected expression (e.g. 1px, bold), was ")"') do
682
- eval("(foo:)")
683
- end
684
- assert_raise_message(Sass::SyntaxError, 'Invalid CSS after "(": expected ")", was ":bar)"') do
685
- eval("(:bar)")
686
- end
687
- assert_raise_message(Sass::SyntaxError, 'Invalid CSS after "(foo, bar": expected ")", was ": baz)"') do
688
- eval("(foo, bar: baz)")
689
- end
690
- assert_raise_message(Sass::SyntaxError, 'Invalid CSS after "(foo: bar, baz": expected ":", was ")"') do
691
- eval("(foo: bar, baz)")
692
- end
693
- end
694
-
695
- def test_deep_argument_error_not_unwrapped
696
- # JRuby (as of 1.6.7.2) offers no way of distinguishing between
697
- # argument errors caused by programming errors in a function and
698
- # argument errors explicitly thrown within that function.
699
- return if RUBY_PLATFORM =~ /java/
700
-
701
- # Don't validate the message; it's different on Rubinius.
702
- assert_raises(ArgumentError) {resolve("arg-error()")}
703
- end
704
-
705
- def test_shallow_argument_error_unwrapped
706
- assert_raise_message(Sass::SyntaxError, "wrong number of arguments (1 for 0) for `arg-error'") {resolve("arg-error(1)")}
707
- end
708
-
709
- def test_boolean_ops_short_circuit
710
- assert_equal "false", resolve("$ie and $ie <= 7", {}, env('ie' => Sass::Script::Value::Bool.new(false)))
711
- assert_equal "true", resolve("$ie or $undef", {}, env('ie' => Sass::Script::Value::Bool.new(true)))
712
- end
713
-
714
- def test_selector
715
- env = Sass::Environment.new
716
- assert_equal "true", resolve("& == null", {}, env)
717
-
718
- env.selector = selector('.foo.bar .baz.bang, .bip.bop')
719
- assert_equal ".foo.bar .baz.bang, .bip.bop", resolve("&", {}, env)
720
- assert_equal ".foo.bar .baz.bang", resolve("nth(&, 1)", {}, env)
721
- assert_equal ".bip.bop", resolve("nth(&, 2)", {}, env)
722
- assert_equal ".foo.bar", resolve("nth(nth(&, 1), 1)", {}, env)
723
- assert_equal ".baz.bang", resolve("nth(nth(&, 1), 2)", {}, env)
724
- assert_equal ".bip.bop", resolve("nth(nth(&, 2), 1)", {}, env)
725
- assert_equal "string", resolve("type-of(nth(nth(&, 1), 1))", {}, env)
726
-
727
- env.selector = selector('.foo > .bar')
728
- assert_equal ".foo > .bar", resolve("&", {}, env)
729
- assert_equal ".foo > .bar", resolve("nth(&, 1)", {}, env)
730
- assert_equal ".foo", resolve("nth(nth(&, 1), 1)", {}, env)
731
- assert_equal ">", resolve("nth(nth(&, 1), 2)", {}, env)
732
- assert_equal ".bar", resolve("nth(nth(&, 1), 3)", {}, env)
733
- end
734
-
735
- def test_selector_with_newlines
736
- env = Sass::Environment.new
737
- env.selector = selector(".foo.bar\n.baz.bang,\n\n.bip.bop")
738
- assert_equal ".foo.bar .baz.bang, .bip.bop", resolve("&", {}, env)
739
- assert_equal ".foo.bar .baz.bang", resolve("nth(&, 1)", {}, env)
740
- assert_equal ".bip.bop", resolve("nth(&, 2)", {}, env)
741
- assert_equal ".foo.bar", resolve("nth(nth(&, 1), 1)", {}, env)
742
- assert_equal ".baz.bang", resolve("nth(nth(&, 1), 2)", {}, env)
743
- assert_equal ".bip.bop", resolve("nth(nth(&, 2), 1)", {}, env)
744
- assert_equal "string", resolve("type-of(nth(nth(&, 1), 1))", {}, env)
745
- end
746
-
747
- def test_setting_global_variable_globally
748
- assert_no_warning {assert_equal(<<CSS, render(<<SCSS, :syntax => :scss))}
749
- .foo {
750
- a: 1; }
751
-
752
- .bar {
753
- b: 2; }
754
- CSS
755
- $var: 1;
756
-
757
- .foo {
758
- a: $var;
759
- }
760
-
761
- $var: 2;
762
-
763
- .bar {
764
- b: $var;
765
- }
766
- SCSS
767
- end
768
-
769
- def test_setting_global_variable_locally
770
- assert_no_warning {assert_equal(<<CSS, render(<<SCSS, :syntax => :scss))}
771
- .bar {
772
- a: x;
773
- b: y;
774
- c: z; }
775
- CSS
776
- $var1: 1;
777
- $var3: 3;
778
-
779
- .foo {
780
- $var1: x !global;
781
- $var2: y !global;
782
- @each $var3 in _ {
783
- $var3: z !global;
784
- }
785
- }
786
-
787
- .bar {
788
- a: $var1;
789
- b: $var2;
790
- c: $var3;
791
- }
792
- SCSS
793
- end
794
-
795
- def test_setting_global_variable_locally_with_default
796
- assert_equal(<<CSS, render(<<SCSS, :syntax => :scss))
797
- .bar {
798
- a: 1;
799
- b: y;
800
- c: z; }
801
- CSS
802
- $var1: 1;
803
-
804
- .foo {
805
- $var1: x !global !default;
806
- $var2: y !global !default;
807
- @each $var3 in _ {
808
- $var3: z !global !default;
809
- }
810
- }
811
-
812
- .bar {
813
- a: $var1;
814
- b: $var2;
815
- c: $var3;
816
- }
817
- SCSS
818
- end
819
-
820
- def test_setting_local_variable
821
- assert_equal(<<CSS, render(<<SCSS, :syntax => :scss))
822
- .a {
823
- value: inside; }
824
-
825
- .b {
826
- value: outside; }
827
- CSS
828
- $var: outside;
829
-
830
- .a {
831
- $var: inside;
832
- value: $var;
833
- }
834
-
835
- .b {
836
- value: $var;
837
- }
838
- SCSS
839
- end
840
-
841
- def test_setting_local_variable_from_inner_scope
842
- assert_equal(<<CSS, render(<<SCSS, :syntax => :scss))
843
- .a .b {
844
- value: inside; }
845
- .a .c {
846
- value: inside; }
847
- CSS
848
- .a {
849
- $var: outside;
850
-
851
- .b {
852
- $var: inside;
853
- value: $var;
854
- }
855
-
856
- .c {
857
- value: $var;
858
- }
859
- }
860
- SCSS
861
- end
862
-
863
- def test_if_can_assign_to_global_variables
864
- assert_equal <<CSS, render(<<SCSS, :syntax => :scss)
865
- .a {
866
- b: 2; }
867
- CSS
868
- $var: 1;
869
- @if true {$var: 2}
870
- .a {b: $var}
871
- SCSS
872
- end
873
-
874
- def test_else_can_assign_to_global_variables
875
- assert_equal <<CSS, render(<<SCSS, :syntax => :scss)
876
- .a {
877
- b: 2; }
878
- CSS
879
- $var: 1;
880
- @if false {}
881
- @else {$var: 2}
882
- .a {b: $var}
883
- SCSS
884
- end
885
-
886
- def test_for_can_assign_to_global_variables
887
- assert_equal <<CSS, render(<<SCSS, :syntax => :scss)
888
- .a {
889
- b: 2; }
890
- CSS
891
- $var: 1;
892
- @for $i from 1 to 2 {$var: 2}
893
- .a {b: $var}
894
- SCSS
895
- end
896
-
897
- def test_each_can_assign_to_global_variables
898
- assert_equal <<CSS, render(<<SCSS, :syntax => :scss)
899
- .a {
900
- b: 2; }
901
- CSS
902
- $var: 1;
903
- @each $a in 1 {$var: 2}
904
- .a {b: $var}
905
- SCSS
906
- end
907
-
908
- def test_while_can_assign_to_global_variables
909
- assert_equal <<CSS, render(<<SCSS, :syntax => :scss)
910
- .a {
911
- b: 2; }
912
- CSS
913
- $var: 1;
914
- @while $var != 2 {$var: 2}
915
- .a {b: $var}
916
- SCSS
917
- end
918
-
919
- def test_if_doesnt_leak_local_variables
920
- assert_raise_message(Sass::SyntaxError, 'Undefined variable: "$var".') do
921
- render(<<SCSS, :syntax => :scss)
922
- @if true {$var: 1}
923
- .a {b: $var}
924
- SCSS
925
- end
926
- end
927
-
928
- def test_else_doesnt_leak_local_variables
929
- assert_raise_message(Sass::SyntaxError, 'Undefined variable: "$var".') do
930
- render(<<SCSS, :syntax => :scss)
931
- @if false {}
932
- @else {$var: 1}
933
- .a {b: $var}
934
- SCSS
935
- end
936
- end
937
-
938
- def test_for_doesnt_leak_local_variables
939
- assert_raise_message(Sass::SyntaxError, 'Undefined variable: "$var".') do
940
- render(<<SCSS, :syntax => :scss)
941
- @for $i from 1 to 2 {$var: 1}
942
- .a {b: $var}
943
- SCSS
944
- end
945
- end
946
-
947
- def test_each_doesnt_leak_local_variables
948
- assert_raise_message(Sass::SyntaxError, 'Undefined variable: "$var".') do
949
- render(<<SCSS, :syntax => :scss)
950
- @each $a in 1 {$var: 1}
951
- .a {b: $var}
952
- SCSS
953
- end
954
- end
955
-
956
- def test_while_doesnt_leak_local_variables
957
- assert_raise_message(Sass::SyntaxError, 'Undefined variable: "$var".') do
958
- render(<<SCSS, :syntax => :scss)
959
- $iter: true;
960
- @while $iter {
961
- $var: 1;
962
- $iter: false;
963
- }
964
- .a {b: $var}
965
- SCSS
966
- end
967
- end
968
-
969
- def test_color_format_is_preserved_by_default
970
- assert_equal "blue", resolve("blue")
971
- assert_equal "bLuE", resolve("bLuE")
972
- assert_equal "#00f", resolve("#00f")
973
- assert_equal "blue #00F", resolve("blue #00F")
974
- assert_equal "blue", resolve("nth(blue #00F, 1)")
975
- assert_equal "#00F", resolve("nth(blue #00F, 2)")
976
- end
977
-
978
- def test_color_format_isnt_always_preserved_in_compressed_style
979
- assert_equal "red", resolve("red", :style => :compressed)
980
- assert_equal "red", resolve("#f00", :style => :compressed)
981
- assert_equal "red red", resolve("red #f00", :style => :compressed)
982
- assert_equal "red", resolve("nth(red #f00, 2)", :style => :compressed)
983
- end
984
-
985
- def test_color_format_is_sometimes_preserved_in_compressed_style
986
- assert_equal "ReD", resolve("ReD", :style => :compressed)
987
- assert_equal "blue", resolve("blue", :style => :compressed)
988
- assert_equal "#00f", resolve("#00f", :style => :compressed)
989
- end
990
-
991
- def test_color_format_isnt_preserved_when_modified
992
- assert_equal "magenta", resolve("change-color(#f00, $blue: 255)")
993
- end
994
-
995
- def test_ids
996
- assert_equal "#foo", resolve("#foo")
997
- assert_equal "#abcd", resolve("#abcd")
998
- assert_equal "#abc-def", resolve("#abc-def")
999
- assert_equal "#abc_def", resolve("#abc_def")
1000
- assert_equal "#uvw-xyz", resolve("#uvw-xyz")
1001
- assert_equal "#uvw_xyz", resolve("#uvw_xyz")
1002
- assert_equal "#uvwxyz", resolve("#uvw + xyz")
1003
- end
1004
-
1005
- def test_scientific_notation
1006
- assert_equal "2000", resolve("2e3")
1007
- assert_equal "2000", resolve("2E3")
1008
- assert_equal "2000", resolve("2e+3")
1009
- assert_equal "2000em", resolve("2e3em")
1010
- assert_equal "25000000000", resolve("2.5e10")
1011
- assert_equal "0.1234", resolve("1234e-4")
1012
- assert_equal "12.34", resolve("1.234e1")
1013
- end
1014
-
1015
- def test_identifier_units
1016
- assert_equal "5-foo", resolve("2-foo + 3-foo")
1017
- assert_equal "5-foo-", resolve("2-foo- + 3-foo-")
1018
- assert_equal "5-\\u2603", resolve("2-\\u2603 + 3-\\u2603")
1019
- end
1020
-
1021
- def test_backslash_newline_in_string
1022
- assert_equal 'foobar', resolve("\"foo\\\nbar\"")
1023
- assert_equal 'foobar', resolve("'foo\\\nbar'")
1024
- end
1025
-
1026
- def test_unclosed_special_fun
1027
- assert_raise_message(Sass::SyntaxError, 'Invalid CSS after "calc(foo()": expected ")", was ""') do
1028
- resolve("calc(foo()")
1029
- end
1030
- assert_raise_message(Sass::SyntaxError, 'Invalid CSS after "calc(#{\')\'}": expected ")", was ""') do
1031
- resolve("calc(\#{')'}")
1032
- end
1033
- assert_raise_message(Sass::SyntaxError, 'Invalid CSS after "calc(#{foo": expected "}", was ""') do
1034
- resolve("calc(\#{foo")
1035
- end
1036
- end
1037
-
1038
- def test_special_fun_with_interpolation
1039
- assert_equal "calc())", resolve("calc(\#{')'})")
1040
- assert_equal "calc(# {foo})", resolve("calc(# {foo})")
1041
- end
1042
-
1043
- # Regression Tests
1044
-
1045
- def test_interpolation_after_string
1046
- assert_equal '"foobar" 2', resolve('"foobar" #{2}')
1047
- assert_equal "calc(1 + 2) 3", resolve('calc(1 + 2) #{3}')
1048
- end
1049
-
1050
- def test_repeatedly_modified_color
1051
- assert_equal(<<CSS, render(<<SASS))
1052
- a {
1053
- link-color: #161C14;
1054
- link-color-hover: black;
1055
- link-color-tap: rgba(22, 28, 20, 0.3); }
1056
- CSS
1057
- $green: #161C14
1058
- $link-color: $green
1059
- $link-color-hover: darken($link-color, 10%)
1060
- $link-color-tap: rgba($green, 0.3)
1061
-
1062
- a
1063
- link-color: $link-color
1064
- link-color-hover: $link-color-hover
1065
- link-color-tap: $link-color-tap
1066
- SASS
1067
- end
1068
-
1069
- def test_inspect_divided_numbers
1070
- assert_equal "1px/2px", resolve("inspect(1px/2px)")
1071
- assert_equal "0.5", resolve("inspect((1px/2px))")
1072
- end
1073
-
1074
- def test_minus_without_whitespace
1075
- assert_equal "5px", resolve("15px-10px")
1076
- assert_equal "5px-", resolve("15px--10px-")
1077
- end
1078
-
1079
- def test_minus_preceded_by_comment
1080
- assert_equal "15px -10px", resolve("15px/**/-10px")
1081
- end
1082
-
1083
- def test_user_defined_function_forces_division
1084
- assert_equal(<<CSS, render(<<SASS))
1085
- a {
1086
- b: 10px; }
1087
- CSS
1088
- @function foo()
1089
- @return 20px
1090
-
1091
- a
1092
- b: (foo() / 2)
1093
- SASS
1094
-
1095
- assert_equal(<<CSS, render(<<SASS))
1096
- a {
1097
- b: 10px; }
1098
- CSS
1099
- @function foo()
1100
- @return 20px
1101
-
1102
- a
1103
- b: foo() / 2
1104
- SASS
1105
- end
1106
-
1107
- def test_funcall_has_higher_precedence_than_color_name
1108
- assert_equal "teal(12)", resolve("teal(12)")
1109
- assert_equal "tealbang(12)", resolve("tealbang(12)")
1110
- assert_equal "teal-bang(12)", resolve("teal-bang(12)")
1111
- assert_equal "teal\\+bang(12)", resolve("teal\\+bang(12)")
1112
- end
1113
-
1114
- def test_funcall_has_higher_precedence_than_true_false_null
1115
- assert_equal "teal(12)", resolve("teal(12)")
1116
- assert_equal "tealbang(12)", resolve("tealbang(12)")
1117
- assert_equal "teal-bang(12)", resolve("teal-bang(12)")
1118
- assert_equal "teal\\+bang(12)", resolve("teal\\+bang(12)")
1119
- end
1120
-
1121
- def test_and_or_not_disallowed_as_function_names
1122
- %w[and or not].each do |name|
1123
- assert_raise_message(Sass::SyntaxError, "Invalid function name \"#{name}\".") do
1124
- render(<<SASS)
1125
- @function #{name}()
1126
- @return null
1127
- SASS
1128
- end
1129
- end
1130
- end
1131
-
1132
- def test_interpolation_after_hash
1133
- assert_equal "#2", resolve('"##{1 + 1}"')
1134
- end
1135
-
1136
- def test_func_call_arglist_trailing_comma
1137
- assert_equal eval('foo(bar)'), eval('foo(bar, )')
1138
- end
1139
-
1140
- def test_color_prefixed_identifier
1141
- assert_equal "tealbang", resolve("tealbang")
1142
- assert_equal "teal-bang", resolve("teal-bang")
1143
- end
1144
-
1145
- def test_op_prefixed_identifier
1146
- assert_equal "notbang", resolve("notbang")
1147
- assert_equal "not-bang", resolve("not-bang")
1148
- assert_equal "or-bang", resolve("or-bang")
1149
- assert_equal "and-bang", resolve("and-bang")
1150
- end
1151
-
1152
- def test_number_initialization
1153
- assert_equal Sass::Script::Value::Number.new(10, ["px"]), Sass::Script::Value::Number.new(10, "px")
1154
- assert_equal Sass::Script::Value::Number.new(10, ["px"], ["em"]), Sass::Script::Value::Number.new(10, "px", "em")
1155
- end
1156
-
1157
- def test_is_unit
1158
- assert Sass::Script::Value::Number.new(10, "px").is_unit?("px")
1159
- assert Sass::Script::Value::Number.new(10).is_unit?(nil)
1160
- assert !Sass::Script::Value::Number.new(10, "px", "em").is_unit?("px")
1161
- assert !Sass::Script::Value::Number.new(10, [], "em").is_unit?("em")
1162
- assert !Sass::Script::Value::Number.new(10, ["px", "em"]).is_unit?("px")
1163
- end
1164
-
1165
- def test_rename_redirect
1166
- assert_no_warning do
1167
- assert_equal Sass::Script::Value::Base, Sass::Script::Literal
1168
- assert_equal Sass::Script::Tree::Node, Sass::Script::Node
1169
- assert_equal Sass::Script::Tree::Operation, Sass::Script::Operation
1170
- assert_equal Sass::Script::Value::String, Sass::Script::String
1171
- end
1172
- end
1173
-
1174
- def test_number_printing
1175
- assert_equal "1", resolve("1")
1176
- assert_equal "1", resolve("1.0")
1177
- assert_equal "1000000000", resolve("1000000000")
1178
- assert_equal "0.00001", resolve("0.00001")
1179
- assert_equal "1.1212121212", resolve("1.12121212124")
1180
- assert_equal "1.1212121213", resolve("1.12121212125")
1181
- assert_equal "Infinity", resolve("(1.0/0.0)")
1182
- assert_equal "-Infinity", resolve("(-1.0/0.0)")
1183
- assert_equal "NaN", resolve("(0.0/0.0)")
1184
- end
1185
-
1186
- def test_equality_uses_an_epsilon
1187
- # At least on my machine, this calculation introduces a floating point error:
1188
- # 29.0 / 7 * 7
1189
- # => 29.000000000000004
1190
- assert_equal "true", resolve("29 == (29 / 7 * 7)")
1191
- end
1192
-
1193
- def test_compressed_output_of_numbers_with_leading_zeros
1194
- assert_equal "1.5", resolve("1.5", :style => :compressed)
1195
- assert_equal ".5", resolve("0.5", :style => :compressed)
1196
- assert_equal "-.5", resolve("-0.5", :style => :compressed)
1197
- assert_equal "0.5", resolve("0.5", :style => :compact)
1198
- end
1199
-
1200
- def test_interpolation_without_deprecation_warning
1201
- assert_no_warning {assert_equal "a", resolve('#{a}')}
1202
- assert_no_warning {assert_equal "abc", resolve('a#{b}c')}
1203
- assert_no_warning {assert_equal "+ a", resolve('+ #{a}')}
1204
- assert_no_warning {assert_equal "/ a", resolve('/ #{a}')}
1205
- assert_no_warning {assert_equal "1 / a", resolve('1 / #{a}')}
1206
- assert_no_warning {assert_equal "a / b", resolve('#{a} / #{b}')}
1207
- assert_no_warning {assert_equal "foo(1 = a)", resolve('foo(1 = #{a})')}
1208
- assert_no_warning {assert_equal "foo(a = b)", resolve('foo(#{a} = #{b})')}
1209
- assert_no_warning {assert_equal "-a", resolve('-#{a}')}
1210
- assert_no_warning {assert_equal "1-a", resolve('1-#{a}')}
1211
- assert_no_warning {assert_equal "a- 1", resolve('#{a}- 1')}
1212
- assert_no_warning {assert_equal "a-1", resolve('#{a}-1')}
1213
- assert_no_warning {assert_equal "a-b", resolve('#{a}-#{b}')}
1214
- assert_no_warning {assert_equal "a1", resolve('#{a}1')}
1215
- assert_no_warning {assert_equal "ab", resolve('#{a}b')}
1216
- assert_no_warning {assert_equal "1a", resolve('1#{a}')}
1217
- assert_no_warning {assert_equal "ba", resolve('b#{a}')}
1218
- end
1219
-
1220
- def test_leading_interpolation_with_deprecation_warning
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 "ab - 1", resolve_with_interp_warning('#{a + b} - 1')
1230
- assert_equal "ab % 1", resolve_with_interp_warning('#{a + b} % 1')
1231
- assert_equal(
1232
- "abvar",
1233
- resolve_with_interp_warning(
1234
- '#{a + b}$var', '"#{a + b}#{$var}"',
1235
- env('var' => Sass::Script::Value::String.new("var"))))
1236
- assert_equal(
1237
- "varab",
1238
- resolve_with_interp_warning(
1239
- '$var#{a + b}', '"#{$var}#{a + b}"',
1240
- env('var' => Sass::Script::Value::String.new("var"))))
1241
- assert_equal "ab1", resolve_with_interp_warning('#{a + b}(1)', '"#{a + b}1"')
1242
- assert_equal "1ab", resolve_with_interp_warning('(1)#{a + b}', '"1#{a + b}"')
1243
- end
1244
-
1245
- def test_trailing_interpolation_with_deprecation_warning
1246
- assert_equal "not ab", resolve_with_interp_warning('not #{a + b}')
1247
- assert_equal "1 and ab", resolve_with_interp_warning('1 and #{a + b}')
1248
- assert_equal "1 or ab", resolve_with_interp_warning('1 or #{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 "1 - ab", resolve_with_interp_warning('1 - #{a + b}')
1258
- assert_equal "1 % ab", resolve_with_interp_warning('1 % #{a + b}')
1259
- assert_equal "- ab", resolve_with_interp_warning('- #{a + b}')
1260
- assert_equal "1- ab", resolve_with_interp_warning('1- #{a + b}')
1261
- assert_equal "- ab 2 3", resolve_with_interp_warning('- #{a + b} 2 3', '"- #{a + b} #{2 3}"')
1262
- end
1263
-
1264
- def test_brackteing_interpolation_with_deprecation_warning
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
- assert_equal "ab - cd", resolve_with_interp_warning('#{a + b} - #{c + d}')
1274
- assert_equal "ab % cd", resolve_with_interp_warning('#{a + b} % #{c + d}')
1275
- end
1276
-
1277
- def test_interp_warning_formatting
1278
- resolve_with_interp_warning('#{1} + 1', '"1 + 1"')
1279
- resolve_with_interp_warning('#{1} + "foo"', '\'1 + "foo"\'')
1280
- resolve_with_interp_warning('#{1} + \'foo\'', '\'1 + "foo"\'')
1281
-
1282
- resolve_with_interp_warning('#{1} + "#{a + b}"', '\'1 + "#{a + b}"\'')
1283
- resolve_with_interp_warning('"#{a + b}" + #{1}', '\'"#{a + b}" + 1\'')
1284
- resolve_with_interp_warning('"#{a + b}" + #{1} + "#{c + d}"', '\'"#{a + b}" + 1 + "#{c + d}"\'')
1285
-
1286
- resolve_with_interp_warning('#{1} + "\'"', '"1 + \\"\'\\""')
1287
- resolve_with_interp_warning('#{1} + \'"\'', '"1 + \'\\"\'"')
1288
- resolve_with_interp_warning('#{1} + "\'\\""', '"1 + \\"\'\\\\\\"\\""')
1289
- end
1290
-
1291
- def test_inactive_lazy_interpolation_deprecation_warning
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
- assert_equal '1 2 3', assert_no_warning {resolve('1 #{2} 3')}
1297
- assert_equal '1 2 3', assert_no_warning {resolve('1 2 #{3}')}
1298
-
1299
- assert_equal '+1 2 3', assert_no_warning {resolve('+#{1} 2 3')}
1300
- assert_equal '-1 2 3', assert_no_warning {resolve('-#{1} 2 3')}
1301
- assert_equal '/1 2 3', assert_no_warning {resolve('/#{1} 2 3')}
1302
-
1303
- assert_equal '1, 2, 31', assert_no_warning {resolve('(1, #{2}, 3) + 1')}
1304
- assert_equal '11, 2, 3', assert_no_warning {resolve('1 + (1, #{2}, 3)')}
1305
-
1306
- assert_equal 'a, b, c', assert_no_warning {resolve('selector-parse((a, #{b}, c))')}
1307
- end
1308
-
1309
- def test_active_lazy_interpolation_deprecation_warning
1310
- Sass::Deprecation.allow_double_warnings do
1311
- assert_equal "1, 2, 3", resolve_with_lazy_interp_warning('quote((1, #{2}, 3))', '"1, 2, 3"')
1312
- assert_equal "1", resolve_with_lazy_interp_warning('length((1, #{2}, 3))', '"1, 2, 3"')
1313
- assert_equal "1, 2, 3", resolve_with_lazy_interp_warning('inspect((1, #{2}, 3))', '"1, 2, 3"')
1314
- assert_equal "string", resolve_with_lazy_interp_warning('type-of((1, #{2}, 3))', '"1, 2, 3"')
1315
-
1316
- assert_equal "+1 2 3", resolve_with_lazy_interp_warning('quote((+#{1} 2 3))', '"+1 #{2 3}"')
1317
- assert_equal "/1 2 3", resolve_with_lazy_interp_warning('quote((/#{1} 2 3))', '"/1 #{2 3}"')
1318
- assert_equal "-1 2 3", resolve_with_lazy_interp_warning('quote((-#{1} 2 3))', '"-1 #{2 3}"')
1319
- end
1320
- end
1321
-
1322
- def test_comparison_of_complex_units
1323
- # Tests for issue #1960
1324
- Sass::Deprecation.allow_double_warnings do
1325
- assert_warning(<<WARNING) do
1326
- DEPRECATION WARNING on line 1 of test_comparison_of_complex_units_inline.sass:
1327
- The result of `10 == 10px` will be `false` in future releases of Sass.
1328
- Unitless numbers will no longer be equal to the same numbers with units.
1329
- WARNING
1330
- assert_equal "true", resolve("10 == 2 * 5px")
1331
- end
1332
- assert_warning(<<WARNING) do
1333
- DEPRECATION WARNING on line 1 of test_comparison_of_complex_units_inline.sass:
1334
- The result of `10 == 10px*px` will be `false` in future releases of Sass.
1335
- Unitless numbers will no longer be equal to the same numbers with units.
1336
- WARNING
1337
- assert_equal "true", resolve("10 == 2px * 5px")
1338
- end
1339
- end
1340
-
1341
- assert_equal "true", resolve("10px * 1px == 2px * 5px")
1342
- assert_equal "true", resolve("5px * 1px < 2px * 5px")
1343
- end
1344
-
1345
- private
1346
-
1347
- def resolve_with_lazy_interp_warning(str, contents = nil, environment = env)
1348
- contents ||= "\"#{str}\""
1349
- result = assert_warning(<<WARNING) {resolve(str, {}, environment)}
1350
- DEPRECATION WARNING on line 1 of #{filename_for_test}:
1351
- \#{} interpolation near operators will be simplified in a future version of Sass.
1352
- To preserve the current behavior, use quotes:
1353
-
1354
- unquote(#{contents})
1355
- WARNING
1356
- $_sass_deprecated_interp_warnings = nil
1357
- result
1358
- end
1359
-
1360
- def resolve_with_interp_warning(str, contents = nil, environment = env)
1361
- contents ||= "\"#{str}\""
1362
- assert_warning(<<WARNING) {resolve(str, {}, environment)}
1363
- DEPRECATION WARNING on line 1 of #{filename_for_test}:
1364
- \#{} interpolation near operators will be simplified in a future version of Sass.
1365
- To preserve the current behavior, use quotes:
1366
-
1367
- unquote(#{contents})
1368
-
1369
- You can use the sass-convert command to automatically fix most cases.
1370
- WARNING
1371
- end
1372
-
1373
- def resolve(str, opts = {}, environment = env)
1374
- munge_filename opts
1375
- val = eval(str, opts, environment)
1376
- assert_kind_of Sass::Script::Value::Base, val
1377
- val.options = opts
1378
- val.is_a?(Sass::Script::Value::String) ? val.value : val.to_s
1379
- end
1380
-
1381
- def resolve_quoted(str, opts = {}, environment = env)
1382
- munge_filename opts
1383
- val = eval(str, opts, environment)
1384
- assert_kind_of Sass::Script::Value::Base, val
1385
- val.to_s
1386
- end
1387
-
1388
- def assert_unquoted(str, opts = {}, environment = env)
1389
- munge_filename opts
1390
- val = eval(str, opts, environment)
1391
- assert_kind_of Sass::Script::Value::String, val
1392
- assert_equal :identifier, val.type
1393
- end
1394
-
1395
- def assert_quoted(str, opts = {}, environment = env)
1396
- munge_filename opts
1397
- val = eval(str, opts, environment)
1398
- assert_kind_of Sass::Script::Value::String, val
1399
- assert_equal :string, val.type
1400
- end
1401
-
1402
- def eval(str, opts = {}, environment = env)
1403
- munge_filename opts
1404
- Sass::Script.parse(str, opts.delete(:line) || 1,
1405
- opts.delete(:offset) || 0, opts).
1406
- perform(Sass::Environment.new(environment, opts))
1407
- end
1408
-
1409
- def render(sass, options = {})
1410
- munge_filename options
1411
- Sass::Engine.new(sass, options).render
1412
- end
1413
-
1414
- def env(hash = {})
1415
- env = Sass::Environment.new
1416
- hash.each {|k, v| env.set_var(k, v)}
1417
- env
1418
- end
1419
-
1420
- def selector(str)
1421
- parser = Sass::SCSS::StaticParser.new(
1422
- str, filename_for_test, Sass::Importers::Filesystem.new('.'))
1423
- parser.parse_selector
1424
- end
1425
-
1426
- def test_null_is_a_singleton
1427
- assert_same Sass::Script::Value::Null.new, Sass::Script::Value::Null.new
1428
- end
1429
- end