sass 3.6.0 → 3.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. checksums.yaml +5 -5
  2. data/CONTRIBUTING.md +1 -1
  3. data/README.md +10 -0
  4. data/VERSION +1 -1
  5. data/VERSION_DATE +1 -1
  6. data/lib/sass/script/css_parser.rb +4 -1
  7. data/lib/sass/script/functions.rb +15 -25
  8. data/lib/sass/script/lexer.rb +45 -7
  9. data/lib/sass/script/parser.rb +259 -93
  10. data/lib/sass/scss/parser.rb +43 -16
  11. data/lib/sass/scss/static_parser.rb +15 -15
  12. data/lib/sass/util.rb +31 -0
  13. metadata +8 -156
  14. data/Rakefile +0 -364
  15. data/test/sass-spec.yml +0 -3
  16. data/test/sass/cache_test.rb +0 -130
  17. data/test/sass/callbacks_test.rb +0 -60
  18. data/test/sass/compiler_test.rb +0 -225
  19. data/test/sass/conversion_test.rb +0 -2138
  20. data/test/sass/css2sass_test.rb +0 -523
  21. data/test/sass/css_variable_test.rb +0 -237
  22. data/test/sass/data/hsl-rgb.txt +0 -319
  23. data/test/sass/encoding_test.rb +0 -188
  24. data/test/sass/engine_test.rb +0 -3499
  25. data/test/sass/exec_test.rb +0 -95
  26. data/test/sass/extend_test.rb +0 -1679
  27. data/test/sass/fixtures/test_staleness_check_across_importers.css +0 -1
  28. data/test/sass/fixtures/test_staleness_check_across_importers.scss +0 -1
  29. data/test/sass/functions_test.rb +0 -2021
  30. data/test/sass/importer_test.rb +0 -420
  31. data/test/sass/logger_test.rb +0 -57
  32. data/test/sass/mock_importer.rb +0 -49
  33. data/test/sass/more_results/more1.css +0 -9
  34. data/test/sass/more_results/more1_with_line_comments.css +0 -26
  35. data/test/sass/more_results/more_import.css +0 -29
  36. data/test/sass/more_templates/_more_partial.sass +0 -2
  37. data/test/sass/more_templates/more1.sass +0 -23
  38. data/test/sass/more_templates/more_import.sass +0 -11
  39. data/test/sass/plugin_test.rb +0 -552
  40. data/test/sass/results/alt.css +0 -4
  41. data/test/sass/results/basic.css +0 -9
  42. data/test/sass/results/cached_import_option.css +0 -3
  43. data/test/sass/results/compact.css +0 -5
  44. data/test/sass/results/complex.css +0 -86
  45. data/test/sass/results/compressed.css +0 -1
  46. data/test/sass/results/expanded.css +0 -19
  47. data/test/sass/results/filename_fn.css +0 -3
  48. data/test/sass/results/if.css +0 -3
  49. data/test/sass/results/import.css +0 -31
  50. data/test/sass/results/import_charset.css +0 -5
  51. data/test/sass/results/import_charset_ibm866.css +0 -5
  52. data/test/sass/results/import_content.css +0 -1
  53. data/test/sass/results/line_numbers.css +0 -49
  54. data/test/sass/results/mixins.css +0 -95
  55. data/test/sass/results/multiline.css +0 -24
  56. data/test/sass/results/nested.css +0 -22
  57. data/test/sass/results/options.css +0 -1
  58. data/test/sass/results/parent_ref.css +0 -13
  59. data/test/sass/results/script.css +0 -16
  60. data/test/sass/results/scss_import.css +0 -31
  61. data/test/sass/results/scss_importee.css +0 -2
  62. data/test/sass/results/subdir/nested_subdir/nested_subdir.css +0 -1
  63. data/test/sass/results/subdir/subdir.css +0 -3
  64. data/test/sass/results/units.css +0 -11
  65. data/test/sass/results/warn.css +0 -0
  66. data/test/sass/results/warn_imported.css +0 -0
  67. data/test/sass/script_conversion_test.rb +0 -365
  68. data/test/sass/script_test.rb +0 -1427
  69. data/test/sass/scss/css_test.rb +0 -1266
  70. data/test/sass/scss/rx_test.rb +0 -159
  71. data/test/sass/scss/scss_test.rb +0 -4238
  72. data/test/sass/scss/test_helper.rb +0 -37
  73. data/test/sass/source_map_test.rb +0 -1063
  74. data/test/sass/superselector_test.rb +0 -209
  75. data/test/sass/templates/_cached_import_option_partial.scss +0 -1
  76. data/test/sass/templates/_double_import_loop2.sass +0 -1
  77. data/test/sass/templates/_filename_fn_import.scss +0 -11
  78. data/test/sass/templates/_imported_charset_ibm866.sass +0 -4
  79. data/test/sass/templates/_imported_charset_utf8.sass +0 -4
  80. data/test/sass/templates/_imported_content.sass +0 -3
  81. data/test/sass/templates/_partial.sass +0 -2
  82. data/test/sass/templates/_same_name_different_partiality.scss +0 -1
  83. data/test/sass/templates/alt.sass +0 -16
  84. data/test/sass/templates/basic.sass +0 -23
  85. data/test/sass/templates/bork1.sass +0 -2
  86. data/test/sass/templates/bork2.sass +0 -2
  87. data/test/sass/templates/bork3.sass +0 -2
  88. data/test/sass/templates/bork4.sass +0 -2
  89. data/test/sass/templates/bork5.sass +0 -3
  90. data/test/sass/templates/cached_import_option.scss +0 -3
  91. data/test/sass/templates/compact.sass +0 -17
  92. data/test/sass/templates/complex.sass +0 -305
  93. data/test/sass/templates/compressed.sass +0 -15
  94. data/test/sass/templates/double_import_loop1.sass +0 -1
  95. data/test/sass/templates/expanded.sass +0 -17
  96. data/test/sass/templates/filename_fn.scss +0 -18
  97. data/test/sass/templates/if.sass +0 -11
  98. data/test/sass/templates/import.sass +0 -12
  99. data/test/sass/templates/import_charset.sass +0 -9
  100. data/test/sass/templates/import_charset_ibm866.sass +0 -11
  101. data/test/sass/templates/import_content.sass +0 -4
  102. data/test/sass/templates/importee.less +0 -2
  103. data/test/sass/templates/importee.sass +0 -19
  104. data/test/sass/templates/line_numbers.sass +0 -13
  105. data/test/sass/templates/mixin_bork.sass +0 -5
  106. data/test/sass/templates/mixins.sass +0 -76
  107. data/test/sass/templates/multiline.sass +0 -20
  108. data/test/sass/templates/nested.sass +0 -25
  109. data/test/sass/templates/nested_bork1.sass +0 -2
  110. data/test/sass/templates/nested_bork2.sass +0 -2
  111. data/test/sass/templates/nested_bork3.sass +0 -2
  112. data/test/sass/templates/nested_bork4.sass +0 -2
  113. data/test/sass/templates/nested_import.sass +0 -2
  114. data/test/sass/templates/nested_mixin_bork.sass +0 -6
  115. data/test/sass/templates/options.sass +0 -2
  116. data/test/sass/templates/parent_ref.sass +0 -25
  117. data/test/sass/templates/same_name_different_ext.sass +0 -2
  118. data/test/sass/templates/same_name_different_ext.scss +0 -1
  119. data/test/sass/templates/same_name_different_partiality.scss +0 -1
  120. data/test/sass/templates/script.sass +0 -101
  121. data/test/sass/templates/scss_import.scss +0 -12
  122. data/test/sass/templates/scss_importee.scss +0 -1
  123. data/test/sass/templates/single_import_loop.sass +0 -1
  124. data/test/sass/templates/subdir/import_up1.scss +0 -1
  125. data/test/sass/templates/subdir/import_up2.scss +0 -1
  126. data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +0 -2
  127. data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +0 -3
  128. data/test/sass/templates/subdir/subdir.sass +0 -6
  129. data/test/sass/templates/units.sass +0 -11
  130. data/test/sass/templates/warn.sass +0 -3
  131. data/test/sass/templates/warn_imported.sass +0 -4
  132. data/test/sass/test_helper.rb +0 -8
  133. data/test/sass/util/multibyte_string_scanner_test.rb +0 -152
  134. data/test/sass/util/normalized_map_test.rb +0 -50
  135. data/test/sass/util/subset_map_test.rb +0 -90
  136. data/test/sass/util_test.rb +0 -393
  137. data/test/sass/value_helpers_test.rb +0 -178
  138. data/test/test_helper.rb +0 -149
@@ -1 +0,0 @@
1
- .pear { color: green; }
@@ -1,2021 +0,0 @@
1
- require 'minitest/autorun'
2
- require File.dirname(__FILE__) + '/../test_helper'
3
- require File.dirname(__FILE__) + '/test_helper'
4
- require 'sass/script'
5
- require 'mock_importer'
6
-
7
- module Sass::Script::Functions
8
- def no_kw_args
9
- Sass::Script::Value::String.new("no-kw-args")
10
- end
11
-
12
- def only_var_args(*args)
13
- Sass::Script::Value::String.new("only-var-args("+args.map{|a| a.plus(Sass::Script::Value::Number.new(1)).to_s }.join(", ")+")")
14
- end
15
- declare :only_var_args, [], :var_args => true
16
-
17
- def only_kw_args(kwargs)
18
- Sass::Script::Value::String.new("only-kw-args(" + kwargs.keys.map {|a| a.to_s}.sort.join(", ") + ")")
19
- end
20
- declare :only_kw_args, [], :var_kwargs => true
21
-
22
- def deprecated_arg_fn(arg1, arg2, arg3 = nil)
23
- Sass::Script::Value::List.new(
24
- [arg1, arg2, arg3 || Sass::Script::Value::Null.new],
25
- separator: :space)
26
- end
27
- declare :deprecated_arg_fn, [:arg1, :arg2, :arg3], :deprecated => [:arg_1, :arg_2, :arg3]
28
- declare :deprecated_arg_fn, [:arg1, :arg2], :deprecated => [:arg_1, :arg_2]
29
- end
30
-
31
- module Sass::Script::Functions::UserFunctions
32
- def call_options_on_new_value
33
- str = Sass::Script::Value::String.new("foo")
34
- str.options[:foo]
35
- str
36
- end
37
-
38
- def user_defined
39
- Sass::Script::Value::String.new("I'm a user-defined string!")
40
- end
41
-
42
- def _preceding_underscore
43
- Sass::Script::Value::String.new("I'm another user-defined string!")
44
- end
45
-
46
- def fetch_the_variable
47
- environment.var('variable')
48
- end
49
- end
50
-
51
- module Sass::Script::Functions
52
- include Sass::Script::Functions::UserFunctions
53
- end
54
-
55
- class SassFunctionTest < MiniTest::Test
56
- # Tests taken from:
57
- # http://www.w3.org/Style/CSS/Test/CSS3/Color/20070927/html4/t040204-hsl-h-rotating-b.htm
58
- # http://www.w3.org/Style/CSS/Test/CSS3/Color/20070927/html4/t040204-hsl-values-b.htm
59
- File.read(File.dirname(__FILE__) + "/data/hsl-rgb.txt").split("\n\n").each do |chunk|
60
- hsls, rgbs = chunk.strip.split("====")
61
- hsls.strip.split("\n").zip(rgbs.strip.split("\n")) do |hsl, rgb|
62
- hsl_method = "test_hsl: #{hsl} = #{rgb}"
63
- unless method_defined?(hsl_method)
64
- define_method(hsl_method) do
65
- assert_equal(evaluate(rgb), evaluate(hsl))
66
- end
67
- end
68
-
69
- rgb_to_hsl_method = "test_rgb_to_hsl: #{rgb} = #{hsl}"
70
- unless method_defined?(rgb_to_hsl_method)
71
- define_method(rgb_to_hsl_method) do
72
- rgb_color = perform(rgb)
73
- hsl_color = perform(hsl)
74
-
75
- white = hsl_color.lightness == 100
76
- black = hsl_color.lightness == 0
77
- grayscale = white || black || hsl_color.saturation == 0
78
-
79
- assert_in_delta(hsl_color.hue, rgb_color.hue, 0.0001,
80
- "Hues should be equal") unless grayscale
81
- assert_in_delta(hsl_color.saturation, rgb_color.saturation, 0.0001,
82
- "Saturations should be equal") unless white || black
83
- assert_in_delta(hsl_color.lightness, rgb_color.lightness, 0.0001,
84
- "Lightnesses should be equal")
85
- end
86
- end
87
- end
88
- end
89
-
90
- def test_hsl_kwargs
91
- assert_equal "#33cccc", evaluate("hsl($hue: 180, $saturation: 60%, $lightness: 50%)")
92
- end
93
-
94
- def test_hsl_clamps_bounds
95
- assert_equal("#1f1f1f", evaluate("hsl(10, -114, 12)"))
96
- assert_equal("white", evaluate("hsl(10, 10, 256%)"))
97
- end
98
-
99
- def test_hsl_checks_types
100
- assert_error_message("$hue: \"foo\" is not a number for `hsl'", "hsl(\"foo\", 10, 12)");
101
- assert_error_message("$saturation: \"foo\" is not a number for `hsl'", "hsl(10, \"foo\", 12)");
102
- assert_error_message("$lightness: \"foo\" is not a number for `hsl'", "hsl(10, 10, \"foo\")");
103
- end
104
-
105
- def test_hsla
106
- assert_equal "rgba(51, 204, 204, 0.4)", evaluate("hsla(180, 60%, 50%, 0.4)")
107
- assert_equal "#33cccc", evaluate("hsla(180, 60%, 50%, 1)")
108
- assert_equal "rgba(51, 204, 204, 0)", evaluate("hsla(180, 60%, 50%, 0)")
109
- assert_equal "rgba(51, 204, 204, 0.4)", evaluate("hsla($hue: 180, $saturation: 60%, $lightness: 50%, $alpha: 0.4)")
110
- end
111
-
112
- def test_hsla_clamps_bounds
113
- assert_equal("#1f1f1f", evaluate("hsla(10, -114, 12, 1)"))
114
- assert_equal("rgba(255, 255, 255, 0)", evaluate("hsla(10, 10, 256%, 0)"))
115
- assert_equal("rgba(28, 24, 23, 0)", evaluate("hsla(10, 10, 10, -0.1)"))
116
- assert_equal("#1c1817", evaluate("hsla(10, 10, 10, 1.1)"))
117
- end
118
-
119
- def test_hsla_checks_types
120
- assert_error_message("$hue: \"foo\" is not a number for `hsla'", "hsla(\"foo\", 10, 12, 0.3)");
121
- assert_error_message("$saturation: \"foo\" is not a number for `hsla'", "hsla(10, \"foo\", 12, 0)");
122
- assert_error_message("$lightness: \"foo\" is not a number for `hsla'", "hsla(10, 10, \"foo\", 1)");
123
- assert_error_message("$alpha: \"foo\" is not a number for `hsla'", "hsla(10, 10, 10, \"foo\")");
124
- end
125
-
126
- def test_hsla_percent_warning
127
- assert_warning(<<WARNING) {evaluate("hsla(180, 60%, 50%, 40%)")}
128
- DEPRECATION WARNING: Passing a percentage as the alpha value to hsla() will be
129
- interpreted differently in future versions of Sass. For now, use 40 instead.
130
- WARNING
131
- end
132
-
133
- def test_hsla_unit_warning
134
- assert_warning(<<WARNING) {evaluate("hsla(180, 60%, 50%, 40em)")}
135
- DEPRECATION WARNING: Passing a number with units as the alpha value to hsla() is
136
- deprecated and will be an error in future versions of Sass. Use 40 instead.
137
- WARNING
138
- end
139
-
140
- def test_percentage
141
- assert_equal("50%", evaluate("percentage(.5)"))
142
- assert_equal("100%", evaluate("percentage(1)"))
143
- assert_equal("25%", evaluate("percentage(25px / 100px)"))
144
- assert_equal("50%", evaluate("percentage($number: 0.5)"))
145
- end
146
-
147
- def test_percentage_checks_types
148
- assert_error_message("$number: 25px is not a unitless number for `percentage'", "percentage(25px)")
149
- assert_error_message("$number: #cccccc is not a unitless number for `percentage'", "percentage(#ccc)")
150
- assert_error_message("$number: \"string\" is not a unitless number for `percentage'", %Q{percentage("string")})
151
- end
152
-
153
- def test_round
154
- assert_equal("5", evaluate("round(4.8)"))
155
- assert_equal("5px", evaluate("round(4.8px)"))
156
- assert_equal("5px", evaluate("round(5.49px)"))
157
- assert_equal("5px", evaluate("round($number: 5.49px)"))
158
- assert_equal("-6", evaluate("round(-5.5)"))
159
- end
160
-
161
- def test_round_checks_types
162
- assert_error_message("$value: #cccccc is not a number for `round'", "round(#ccc)")
163
- end
164
-
165
- def test_floor
166
- assert_equal("4", evaluate("floor(4.8)"))
167
- assert_equal("4px", evaluate("floor(4.8px)"))
168
- assert_equal("4px", evaluate("floor($number: 4.8px)"))
169
- end
170
-
171
- def test_floor_checks_types
172
- assert_error_message("$value: \"foo\" is not a number for `floor'", "floor(\"foo\")")
173
- end
174
-
175
- def test_ceil
176
- assert_equal("5", evaluate("ceil(4.1)"))
177
- assert_equal("5px", evaluate("ceil(4.8px)"))
178
- assert_equal("5px", evaluate("ceil($number: 4.8px)"))
179
- end
180
-
181
- def test_ceil_checks_types
182
- assert_error_message("$value: \"a\" is not a number for `ceil'", "ceil(\"a\")")
183
- end
184
-
185
- def test_abs
186
- assert_equal("5", evaluate("abs(-5)"))
187
- assert_equal("5px", evaluate("abs(-5px)"))
188
- assert_equal("5", evaluate("abs(5)"))
189
- assert_equal("5px", evaluate("abs(5px)"))
190
- assert_equal("5px", evaluate("abs($number: 5px)"))
191
- end
192
-
193
- def test_abs_checks_types
194
- assert_error_message("$value: #aaaaaa is not a number for `abs'", "abs(#aaa)")
195
- end
196
-
197
- def test_min
198
- assert_equal("1", evaluate("min(1, 2, 3)"))
199
- assert_equal("1", evaluate("min(3px, 2px, 1)"))
200
- assert_equal("4em", evaluate("min(4em)"))
201
- assert_equal("10cm", evaluate("min(10cm, 6in)"))
202
- assert_equal("1q", evaluate("min(1cm, 1q)"))
203
-
204
- assert_error_message("#aaaaaa is not a number for `min'", "min(#aaa)")
205
- assert_error_message("Incompatible units: 'px' and 'em'.", "min(3em, 4em, 1px)")
206
- end
207
-
208
- def test_max
209
- assert_equal("3", evaluate("max(1, 2, 3)"))
210
- assert_equal("3", evaluate("max(3, 2px, 1px)"))
211
- assert_equal("4em", evaluate("max(4em)"))
212
- assert_equal("6in", evaluate("max(10cm, 6in)"))
213
- assert_equal("11mm", evaluate("max(11mm, 10q)"))
214
-
215
- assert_error_message("#aaaaaa is not a number for `max'", "max(#aaa)")
216
- assert_error_message("Incompatible units: 'px' and 'em'.", "max(3em, 4em, 1px)")
217
- end
218
-
219
- def test_rgb
220
- assert_equal("#123456", evaluate("rgb(18, 52, 86)"))
221
- assert_equal("#beaded", evaluate("rgb(190, 173, 237)"))
222
- assert_equal("springgreen", evaluate("rgb(0, 255, 127)"))
223
- assert_equal("springgreen", evaluate("rgb($red: 0, $green: 255, $blue: 127)"))
224
- end
225
-
226
- def test_rgb_percent
227
- assert_equal("#123457", evaluate("rgb(7.1%, 20.4%, 34%)"))
228
- assert_equal("#beaded", evaluate("rgb(74.7%, 173, 93%)"))
229
- assert_equal("#beaded", evaluate("rgb(190, 68%, 237)"))
230
- assert_equal("#00ff80", evaluate("rgb(0%, 100%, 50%)"))
231
- end
232
-
233
- def test_rgb_clamps_bounds
234
- assert_equal("#ff0101", evaluate("rgb(256, 1, 1)"))
235
- assert_equal("#01ff01", evaluate("rgb(1, 256, 1)"))
236
- assert_equal("#0101ff", evaluate("rgb(1, 1, 256)"))
237
- assert_equal("#01ffff", evaluate("rgb(1, 256, 257)"))
238
- assert_equal("#000101", evaluate("rgb(-1, 1, 1)"))
239
- end
240
-
241
- def test_rgb_clamps_percent_bounds
242
- assert_equal("red", evaluate("rgb(100.1%, 0, 0)"))
243
- assert_equal("black", evaluate("rgb(0, -0.1%, 0)"))
244
- assert_equal("blue", evaluate("rgb(0, 0, 101%)"))
245
- end
246
-
247
- def test_rgb_tests_types
248
- assert_error_message("$red: \"foo\" is not a number for `rgb'", "rgb(\"foo\", 10, 12)");
249
- assert_error_message("$green: \"foo\" is not a number for `rgb'", "rgb(10, \"foo\", 12)");
250
- assert_error_message("$blue: \"foo\" is not a number for `rgb'", "rgb(10, 10, \"foo\")");
251
- end
252
-
253
- def test_rgba
254
- assert_equal("rgba(18, 52, 86, 0.5)", evaluate("rgba(18, 52, 86, 0.5)"))
255
- assert_equal("#beaded", evaluate("rgba(190, 173, 237, 1)"))
256
- assert_equal("rgba(0, 255, 127, 0)", evaluate("rgba(0, 255, 127, 0)"))
257
- assert_equal("rgba(0, 255, 127, 0)", evaluate("rgba($red: 0, $green: 255, $blue: 127, $alpha: 0)"))
258
- end
259
-
260
- def test_rgba_clamps_bounds
261
- assert_equal("rgba(255, 1, 1, 0.3)", evaluate("rgba(256, 1, 1, 0.3)"))
262
- assert_equal("rgba(1, 255, 1, 0.3)", evaluate("rgba(1, 256, 1, 0.3)"))
263
- assert_equal("rgba(1, 1, 255, 0.3)", evaluate("rgba(1, 1, 256, 0.3)"))
264
- assert_equal("rgba(1, 255, 255, 0.3)", evaluate("rgba(1, 256, 257, 0.3)"))
265
- assert_equal("rgba(0, 1, 1, 0.3)", evaluate("rgba(-1, 1, 1, 0.3)"))
266
- assert_equal("rgba(1, 1, 1, 0)", evaluate("rgba(1, 1, 1, -0.2)"))
267
- assert_equal("#010101", evaluate("rgba(1, 1, 1, 1.2)"))
268
- end
269
-
270
- def test_rgba_tests_types
271
- assert_error_message("$red: \"foo\" is not a number for `rgba'", "rgba(\"foo\", 10, 12, 0.2)");
272
- assert_error_message("$green: \"foo\" is not a number for `rgba'", "rgba(10, \"foo\", 12, 0.1)");
273
- assert_error_message("$blue: \"foo\" is not a number for `rgba'", "rgba(10, 10, \"foo\", 0)");
274
- assert_error_message("$alpha: \"foo\" is not a number for `rgba'", "rgba(10, 10, 10, \"foo\")");
275
- end
276
-
277
- def test_rgba_with_color
278
- assert_equal "rgba(16, 32, 48, 0.5)", evaluate("rgba(#102030, 0.5)")
279
- assert_equal "rgba(0, 0, 255, 0.5)", evaluate("rgba(blue, 0.5)")
280
- assert_equal "rgba(0, 0, 255, 0.5)", evaluate("rgba($color: blue, $alpha: 0.5)")
281
- end
282
-
283
- def test_rgba_with_color_tests_types
284
- assert_error_message("$color: \"foo\" is not a color for `rgba'", "rgba(\"foo\", 0.2)");
285
- assert_error_message("$alpha: \"foo\" is not a number for `rgba'", "rgba(blue, \"foo\")");
286
- end
287
-
288
- def test_rgba_tests_num_args
289
- assert_error_message("wrong number of arguments (0 for 4) for `rgba'", "rgba()");
290
- assert_error_message("wrong number of arguments (1 for 4) for `rgba'", "rgba(blue)");
291
- assert_error_message("wrong number of arguments (3 for 4) for `rgba'", "rgba(1, 2, 3)");
292
- assert_error_message("wrong number of arguments (5 for 4) for `rgba'", "rgba(1, 2, 3, 0.4, 5)");
293
- end
294
-
295
- def test_rgba_percent_warning
296
- assert_warning(<<WARNING) {evaluate("rgba(1, 2, 3, 40%)")}
297
- DEPRECATION WARNING: Passing a percentage as the alpha value to rgba() will be
298
- interpreted differently in future versions of Sass. For now, use 40 instead.
299
- WARNING
300
- end
301
-
302
- def test_rgba_unit_warning
303
- assert_warning(<<WARNING) {evaluate("rgba(1, 2, 3, 40em)")}
304
- DEPRECATION WARNING: Passing a number with units as the alpha value to rgba() is
305
- deprecated and will be an error in future versions of Sass. Use 40 instead.
306
- WARNING
307
- end
308
-
309
- def test_red
310
- assert_equal("18", evaluate("red(#123456)"))
311
- assert_equal("18", evaluate("red($color: #123456)"))
312
- end
313
-
314
- def test_red_exception
315
- assert_error_message("$color: 12 is not a color for `red'", "red(12)")
316
- end
317
-
318
- def test_green
319
- assert_equal("52", evaluate("green(#123456)"))
320
- assert_equal("52", evaluate("green($color: #123456)"))
321
- end
322
-
323
- def test_green_exception
324
- assert_error_message("$color: 12 is not a color for `green'", "green(12)")
325
- end
326
-
327
- def test_blue
328
- assert_equal("86", evaluate("blue(#123456)"))
329
- assert_equal("86", evaluate("blue($color: #123456)"))
330
- end
331
-
332
- def test_blue_exception
333
- assert_error_message("$color: 12 is not a color for `blue'", "blue(12)")
334
- end
335
-
336
- def test_hue
337
- assert_equal("18deg", evaluate("hue(hsl(18, 50%, 20%))"))
338
- assert_equal("18deg", evaluate("hue($color: hsl(18, 50%, 20%))"))
339
- end
340
-
341
- def test_hue_exception
342
- assert_error_message("$color: 12 is not a color for `hue'", "hue(12)")
343
- end
344
-
345
- def test_saturation
346
- assert_equal("52%", evaluate("saturation(hsl(20, 52%, 20%))"))
347
- assert_equal("52%", evaluate("saturation(hsl(20, 52, 20%))"))
348
- assert_equal("52%", evaluate("saturation($color: hsl(20, 52, 20%))"))
349
- end
350
-
351
- def test_saturation_exception
352
- assert_error_message("$color: 12 is not a color for `saturation'", "saturation(12)")
353
- end
354
-
355
- def test_lightness
356
- assert_equal("86%", evaluate("lightness(hsl(120, 50%, 86%))"))
357
- assert_equal("86%", evaluate("lightness(hsl(120, 50%, 86))"))
358
- assert_equal("86%", evaluate("lightness($color: hsl(120, 50%, 86))"))
359
- end
360
-
361
- def test_lightness_exception
362
- assert_error_message("$color: 12 is not a color for `lightness'", "lightness(12)")
363
- end
364
-
365
- def test_alpha
366
- assert_equal("1", evaluate("alpha(#123456)"))
367
- assert_equal("0.34", evaluate("alpha(rgba(0, 1, 2, 0.34))"))
368
- assert_equal("0", evaluate("alpha(hsla(0, 1, 2, 0))"))
369
- assert_equal("0", evaluate("alpha($color: hsla(0, 1, 2, 0))"))
370
- end
371
-
372
- def test_alpha_exception
373
- assert_error_message("$color: 12 is not a color for `alpha'", "alpha(12)")
374
- end
375
-
376
- def test_opacity
377
- assert_equal("1", evaluate("opacity(#123456)"))
378
- assert_equal("0.34", evaluate("opacity(rgba(0, 1, 2, 0.34))"))
379
- assert_equal("0", evaluate("opacity(hsla(0, 1, 2, 0))"))
380
- assert_equal("0", evaluate("opacity($color: hsla(0, 1, 2, 0))"))
381
- assert_equal("opacity(20%)", evaluate("opacity(20%)"))
382
- end
383
-
384
- def test_opacity_exception
385
- assert_error_message("$color: \"foo\" is not a color for `opacity'", "opacity(foo)")
386
- end
387
-
388
- def test_opacify
389
- assert_equal("rgba(0, 0, 0, 0.75)", evaluate("opacify(rgba(0, 0, 0, 0.5), 0.25)"))
390
- assert_equal("rgba(0, 0, 0, 0.3)", evaluate("opacify(rgba(0, 0, 0, 0.2), 0.1)"))
391
- assert_equal("rgba(0, 0, 0, 0.7)", evaluate("fade-in(rgba(0, 0, 0, 0.2), 0.5px)"))
392
- assert_equal("black", evaluate("fade_in(rgba(0, 0, 0, 0.2), 0.8)"))
393
- assert_equal("black", evaluate("opacify(rgba(0, 0, 0, 0.2), 1)"))
394
- assert_equal("rgba(0, 0, 0, 0.2)", evaluate("opacify(rgba(0, 0, 0, 0.2), 0%)"))
395
- assert_equal("rgba(0, 0, 0, 0.2)", evaluate("opacify($color: rgba(0, 0, 0, 0.2), $amount: 0%)"))
396
- assert_equal("rgba(0, 0, 0, 0.2)", evaluate("fade-in($color: rgba(0, 0, 0, 0.2), $amount: 0%)"))
397
- end
398
-
399
- def test_opacify_tests_bounds
400
- assert_error_message("Amount -0.001 must be between 0 and 1 for `opacify'",
401
- "opacify(rgba(0, 0, 0, 0.2), -0.001)")
402
- assert_error_message("Amount 1.001 must be between 0 and 1 for `opacify'",
403
- "opacify(rgba(0, 0, 0, 0.2), 1.001)")
404
- end
405
-
406
- def test_opacify_tests_types
407
- assert_error_message("$color: \"foo\" is not a color for `opacify'", "opacify(\"foo\", 10%)")
408
- assert_error_message("$amount: \"foo\" is not a number for `opacify'", "opacify(#fff, \"foo\")")
409
- end
410
-
411
- def test_transparentize
412
- assert_equal("rgba(0, 0, 0, 0.3)", evaluate("transparentize(rgba(0, 0, 0, 0.5), 0.2)"))
413
- assert_equal("rgba(0, 0, 0, 0.1)", evaluate("transparentize(rgba(0, 0, 0, 0.2), 0.1)"))
414
- assert_equal("rgba(0, 0, 0, 0.2)", evaluate("fade-out(rgba(0, 0, 0, 0.5), 0.3px)"))
415
- assert_equal("rgba(0, 0, 0, 0)", evaluate("fade_out(rgba(0, 0, 0, 0.2), 0.2)"))
416
- assert_equal("rgba(0, 0, 0, 0)", evaluate("transparentize(rgba(0, 0, 0, 0.2), 1)"))
417
- assert_equal("rgba(0, 0, 0, 0.2)", evaluate("transparentize(rgba(0, 0, 0, 0.2), 0)"))
418
- assert_equal("rgba(0, 0, 0, 0.2)", evaluate("transparentize($color: rgba(0, 0, 0, 0.2), $amount: 0)"))
419
- assert_equal("rgba(0, 0, 0, 0.2)", evaluate("fade-out($color: rgba(0, 0, 0, 0.2), $amount: 0)"))
420
- end
421
-
422
- def test_transparentize_tests_bounds
423
- assert_error_message("Amount -0.001 must be between 0 and 1 for `transparentize'",
424
- "transparentize(rgba(0, 0, 0, 0.2), -0.001)")
425
- assert_error_message("Amount 1.001 must be between 0 and 1 for `transparentize'",
426
- "transparentize(rgba(0, 0, 0, 0.2), 1.001)")
427
- end
428
-
429
- def test_transparentize_tests_types
430
- assert_error_message("$color: \"foo\" is not a color for `transparentize'", "transparentize(\"foo\", 10%)")
431
- assert_error_message("$amount: \"foo\" is not a number for `transparentize'", "transparentize(#fff, \"foo\")")
432
- end
433
-
434
- def test_lighten
435
- assert_equal("#4d4d4d", evaluate("lighten(hsl(0, 0, 0), 30%)"))
436
- assert_equal("#ee0000", evaluate("lighten(#800, 20%)"))
437
- assert_equal("white", evaluate("lighten(#fff, 20%)"))
438
- assert_equal("white", evaluate("lighten(#800, 100%)"))
439
- assert_equal("#880000", evaluate("lighten(#800, 0%)"))
440
- assert_equal("rgba(238, 0, 0, 0.5)", evaluate("lighten(rgba(136, 0, 0, 0.5), 20%)"))
441
- assert_equal("rgba(238, 0, 0, 0.5)", evaluate("lighten($color: rgba(136, 0, 0, 0.5), $amount: 20%)"))
442
- end
443
-
444
- def test_lighten_tests_bounds
445
- assert_error_message("Amount -0.001 must be between 0% and 100% for `lighten'",
446
- "lighten(#123, -0.001)")
447
- assert_error_message("Amount 100.001 must be between 0% and 100% for `lighten'",
448
- "lighten(#123, 100.001)")
449
- end
450
-
451
- def test_lighten_tests_types
452
- assert_error_message("$color: \"foo\" is not a color for `lighten'", "lighten(\"foo\", 10%)")
453
- assert_error_message("$amount: \"foo\" is not a number for `lighten'", "lighten(#fff, \"foo\")")
454
- end
455
-
456
- def test_darken
457
- assert_equal("#ff6a00", evaluate("darken(hsl(25, 100, 80), 30%)"))
458
- assert_equal("#220000", evaluate("darken(#800, 20%)"))
459
- assert_equal("black", evaluate("darken(#000, 20%)"))
460
- assert_equal("black", evaluate("darken(#800, 100%)"))
461
- assert_equal("#880000", evaluate("darken(#800, 0%)"))
462
- assert_equal("rgba(34, 0, 0, 0.5)", evaluate("darken(rgba(136, 0, 0, 0.5), 20%)"))
463
- assert_equal("rgba(34, 0, 0, 0.5)", evaluate("darken($color: rgba(136, 0, 0, 0.5), $amount: 20%)"))
464
- end
465
-
466
- def test_darken_tests_bounds
467
- assert_error_message("Amount -0.001 must be between 0% and 100% for `darken'",
468
- "darken(#123, -0.001)")
469
- assert_error_message("Amount 100.001 must be between 0% and 100% for `darken'",
470
- "darken(#123, 100.001)")
471
- end
472
-
473
- def test_darken_tests_types
474
- assert_error_message("$color: \"foo\" is not a color for `darken'", "darken(\"foo\", 10%)")
475
- assert_error_message("$amount: \"foo\" is not a number for `darken'", "darken(#fff, \"foo\")")
476
- end
477
-
478
- def test_saturate
479
- assert_equal("#d9f2d9", evaluate("saturate(hsl(120, 30, 90), 20%)"))
480
- assert_equal("#9e3f3f", evaluate("saturate(#855, 20%)"))
481
- assert_equal("black", evaluate("saturate(#000, 20%)"))
482
- assert_equal("white", evaluate("saturate(#fff, 20%)"))
483
- assert_equal("#33ff33", evaluate("saturate(#8a8, 100%)"))
484
- assert_equal("#88aa88", evaluate("saturate(#8a8, 0%)"))
485
- assert_equal("rgba(158, 63, 63, 0.5)", evaluate("saturate(rgba(136, 85, 85, 0.5), 20%)"))
486
- assert_equal("rgba(158, 63, 63, 0.5)", evaluate("saturate($color: rgba(136, 85, 85, 0.5), $amount: 20%)"))
487
- assert_equal("saturate(50%)", evaluate("saturate(50%)"))
488
- end
489
-
490
- def test_saturate_tests_bounds
491
- assert_error_message("Amount -0.001 must be between 0% and 100% for `saturate'",
492
- "saturate(#123, -0.001)")
493
- assert_error_message("Amount 100.001 must be between 0% and 100% for `saturate'",
494
- "saturate(#123, 100.001)")
495
- end
496
-
497
- def test_saturate_tests_types
498
- assert_error_message("$color: \"foo\" is not a color for `saturate'", "saturate(\"foo\", 10%)")
499
- assert_error_message("$amount: \"foo\" is not a number for `saturate'", "saturate(#fff, \"foo\")")
500
- end
501
-
502
- def test_desaturate
503
- assert_equal("#e3e8e3", evaluate("desaturate(hsl(120, 30, 90), 20%)"))
504
- assert_equal("#726b6b", evaluate("desaturate(#855, 20%)"))
505
- assert_equal("black", evaluate("desaturate(#000, 20%)"))
506
- assert_equal("white", evaluate("desaturate(#fff, 20%)"))
507
- assert_equal("#999999", evaluate("desaturate(#8a8, 100%)"))
508
- assert_equal("#88aa88", evaluate("desaturate(#8a8, 0%)"))
509
- assert_equal("rgba(114, 107, 107, 0.5)", evaluate("desaturate(rgba(136, 85, 85, 0.5), 20%)"))
510
- assert_equal("rgba(114, 107, 107, 0.5)", evaluate("desaturate($color: rgba(136, 85, 85, 0.5), $amount: 20%)"))
511
- end
512
-
513
- def test_desaturate_tests_bounds
514
- assert_error_message("Amount -0.001 must be between 0% and 100% for `desaturate'",
515
- "desaturate(#123, -0.001)")
516
- assert_error_message("Amount 100.001 must be between 0% and 100% for `desaturate'",
517
- "desaturate(#123, 100.001)")
518
- end
519
-
520
- def test_desaturate_tests_types
521
- assert_error_message("$color: \"foo\" is not a color for `desaturate'", "desaturate(\"foo\", 10%)")
522
- assert_error_message("$amount: \"foo\" is not a number for `desaturate'", "desaturate(#fff, \"foo\")")
523
- end
524
-
525
- def test_adjust_hue
526
- assert_equal("#deeded", evaluate("adjust-hue(hsl(120, 30, 90), 60deg)"))
527
- assert_equal("#ededde", evaluate("adjust-hue(hsl(120, 30, 90), -60deg)"))
528
- assert_equal("#886a11", evaluate("adjust-hue(#811, 45deg)"))
529
- assert_equal("black", evaluate("adjust-hue(#000, 45deg)"))
530
- assert_equal("white", evaluate("adjust-hue(#fff, 45deg)"))
531
- assert_equal("#88aa88", evaluate("adjust-hue(#8a8, 360deg)"))
532
- assert_equal("#88aa88", evaluate("adjust-hue(#8a8, 0deg)"))
533
- assert_equal("rgba(136, 106, 17, 0.5)", evaluate("adjust-hue(rgba(136, 17, 17, 0.5), 45deg)"))
534
- assert_equal("rgba(136, 106, 17, 0.5)", evaluate("adjust-hue($color: rgba(136, 17, 17, 0.5), $degrees: 45deg)"))
535
- end
536
-
537
- def test_adjust_hue_tests_types
538
- assert_error_message("$color: \"foo\" is not a color for `adjust-hue'", "adjust-hue(\"foo\", 10%)")
539
- assert_error_message("$degrees: \"foo\" is not a number for `adjust-hue'", "adjust-hue(#fff, \"foo\")")
540
- end
541
-
542
- def test_adjust_color
543
- # HSL
544
- assert_equal(evaluate("hsl(180, 30, 90)"),
545
- evaluate("adjust-color(hsl(120, 30, 90), $hue: 60deg)"))
546
- assert_equal(evaluate("hsl(120, 50, 90)"),
547
- evaluate("adjust-color(hsl(120, 30, 90), $saturation: 20%)"))
548
- assert_equal(evaluate("hsl(120, 30, 60)"),
549
- evaluate("adjust-color(hsl(120, 30, 90), $lightness: -30%)"))
550
- # RGB
551
- assert_equal(evaluate("rgb(15, 20, 30)"),
552
- evaluate("adjust-color(rgb(10, 20, 30), $red: 5)"))
553
- assert_equal(evaluate("rgb(10, 15, 30)"),
554
- evaluate("adjust-color(rgb(10, 20, 30), $green: -5)"))
555
- assert_equal(evaluate("rgb(10, 20, 40)"),
556
- evaluate("adjust-color(rgb(10, 20, 30), $blue: 10)"))
557
- # Alpha
558
- assert_equal(evaluate("hsla(120, 30, 90, 0.65)"),
559
- evaluate("adjust-color(hsl(120, 30, 90), $alpha: -0.35)"))
560
- assert_equal(evaluate("rgba(10, 20, 30, 0.9)"),
561
- evaluate("adjust-color(rgba(10, 20, 30, 0.4), $alpha: 0.5)"))
562
-
563
- # HSL composability
564
- assert_equal(evaluate("hsl(180, 20, 90)"),
565
- evaluate("adjust-color(hsl(120, 30, 90), $hue: 60deg, $saturation: -10%)"))
566
- assert_equal(evaluate("hsl(180, 20, 95)"),
567
- evaluate("adjust-color(hsl(120, 30, 90), $hue: 60deg, $saturation: -10%, $lightness: 5%)"))
568
- assert_equal(evaluate("hsla(120, 20, 95, 0.3)"),
569
- evaluate("adjust-color(hsl(120, 30, 90), $saturation: -10%, $lightness: 5%, $alpha: -0.7)"))
570
-
571
- # RGB composability
572
- assert_equal(evaluate("rgb(15, 20, 29)"),
573
- evaluate("adjust-color(rgb(10, 20, 30), $red: 5, $blue: -1)"))
574
- assert_equal(evaluate("rgb(15, 45, 29)"),
575
- evaluate("adjust-color(rgb(10, 20, 30), $red: 5, $green: 25, $blue: -1)"))
576
- assert_equal(evaluate("rgba(10, 25, 29, 0.7)"),
577
- evaluate("adjust-color(rgb(10, 20, 30), $green: 5, $blue: -1, $alpha: -0.3)"))
578
-
579
- # HSL range restriction
580
- assert_equal(evaluate("hsl(120, 30, 90)"),
581
- evaluate("adjust-color(hsl(120, 30, 90), $hue: 720deg)"))
582
- assert_equal(evaluate("hsl(120, 0, 90)"),
583
- evaluate("adjust-color(hsl(120, 30, 90), $saturation: -90%)"))
584
- assert_equal(evaluate("hsl(120, 30, 100)"),
585
- evaluate("adjust-color(hsl(120, 30, 90), $lightness: 30%)"))
586
-
587
- # RGB range restriction
588
- assert_equal(evaluate("rgb(255, 20, 30)"),
589
- evaluate("adjust-color(rgb(10, 20, 30), $red: 250)"))
590
- assert_equal(evaluate("rgb(10, 0, 30)"),
591
- evaluate("adjust-color(rgb(10, 20, 30), $green: -30)"))
592
- assert_equal(evaluate("rgb(10, 20, 0)"),
593
- evaluate("adjust-color(rgb(10, 20, 30), $blue: -40)"))
594
- end
595
-
596
- def test_adjust_color_tests_types
597
- assert_error_message("$color: \"foo\" is not a color for `adjust-color'", "adjust-color(foo, $hue: 10)")
598
- # HSL
599
- assert_error_message("$hue: \"foo\" is not a number for `adjust-color'",
600
- "adjust-color(blue, $hue: foo)")
601
- assert_error_message("$saturation: \"foo\" is not a number for `adjust-color'",
602
- "adjust-color(blue, $saturation: foo)")
603
- assert_error_message("$lightness: \"foo\" is not a number for `adjust-color'",
604
- "adjust-color(blue, $lightness: foo)")
605
- # RGB
606
- assert_error_message("$red: \"foo\" is not a number for `adjust-color'",
607
- "adjust-color(blue, $red: foo)")
608
- assert_error_message("$green: \"foo\" is not a number for `adjust-color'",
609
- "adjust-color(blue, $green: foo)")
610
- assert_error_message("$blue: \"foo\" is not a number for `adjust-color'",
611
- "adjust-color(blue, $blue: foo)")
612
- # Alpha
613
- assert_error_message("$alpha: \"foo\" is not a number for `adjust-color'",
614
- "adjust-color(blue, $alpha: foo)")
615
- end
616
-
617
- def test_adjust_color_tests_arg_range
618
- # HSL
619
- assert_error_message("$saturation: Amount 101% must be between -100% and 100% for `adjust-color'",
620
- "adjust-color(blue, $saturation: 101%)")
621
- assert_error_message("$saturation: Amount -101% must be between -100% and 100% for `adjust-color'",
622
- "adjust-color(blue, $saturation: -101%)")
623
- assert_error_message("$lightness: Amount 101% must be between -100% and 100% for `adjust-color'",
624
- "adjust-color(blue, $lightness: 101%)")
625
- assert_error_message("$lightness: Amount -101% must be between -100% and 100% for `adjust-color'",
626
- "adjust-color(blue, $lightness: -101%)")
627
- # RGB
628
- assert_error_message("$red: Amount 256 must be between -255 and 255 for `adjust-color'",
629
- "adjust-color(blue, $red: 256)")
630
- assert_error_message("$red: Amount -256 must be between -255 and 255 for `adjust-color'",
631
- "adjust-color(blue, $red: -256)")
632
- assert_error_message("$green: Amount 256 must be between -255 and 255 for `adjust-color'",
633
- "adjust-color(blue, $green: 256)")
634
- assert_error_message("$green: Amount -256 must be between -255 and 255 for `adjust-color'",
635
- "adjust-color(blue, $green: -256)")
636
- assert_error_message("$blue: Amount 256 must be between -255 and 255 for `adjust-color'",
637
- "adjust-color(blue, $blue: 256)")
638
- assert_error_message("$blue: Amount -256 must be between -255 and 255 for `adjust-color'",
639
- "adjust-color(blue, $blue: -256)")
640
- # Alpha
641
- assert_error_message("$alpha: Amount 1.1 must be between -1 and 1 for `adjust-color'",
642
- "adjust-color(blue, $alpha: 1.1)")
643
- assert_error_message("$alpha: Amount -1.1 must be between -1 and 1 for `adjust-color'",
644
- "adjust-color(blue, $alpha: -1.1)")
645
- end
646
-
647
- def test_adjust_color_argument_errors
648
- assert_error_message("Unknown argument $hoo (260deg) for `adjust-color'",
649
- "adjust-color(blue, $hoo: 260deg)")
650
- assert_error_message("Cannot specify HSL and RGB values for a color at the same time for `adjust-color'",
651
- "adjust-color(blue, $hue: 120deg, $red: 10)");
652
- assert_error_message("10px is not a keyword argument for `adjust_color'",
653
- "adjust-color(blue, 10px)")
654
- assert_error_message("10px is not a keyword argument for `adjust_color'",
655
- "adjust-color(blue, 10px, 20px)")
656
- assert_error_message("10px is not a keyword argument for `adjust_color'",
657
- "adjust-color(blue, 10px, $hue: 180deg)")
658
- end
659
-
660
- def test_scale_color
661
- # HSL
662
- assert_equal(evaluate("hsl(120, 51, 90)"),
663
- evaluate("scale-color(hsl(120, 30, 90), $saturation: 30%)"))
664
- assert_equal(evaluate("hsl(120, 30, 76.5)"),
665
- evaluate("scale-color(hsl(120, 30, 90), $lightness: -15%)"))
666
- # RGB
667
- assert_equal(evaluate("rgb(157, 20, 30)"),
668
- evaluate("scale-color(rgb(10, 20, 30), $red: 60%)"))
669
- assert_equal(evaluate("rgb(10, 38.8, 30)"),
670
- evaluate("scale-color(rgb(10, 20, 30), $green: 8%)"))
671
- assert_equal(evaluate("rgb(10, 20, 20)"),
672
- evaluate("scale-color(rgb(10, 20, 30), $blue: -(1/3)*100%)"))
673
- # Alpha
674
- assert_equal(evaluate("hsla(120, 30, 90, 0.86)"),
675
- evaluate("scale-color(hsl(120, 30, 90), $alpha: -14%)"))
676
- assert_equal(evaluate("rgba(10, 20, 30, 0.82)"),
677
- evaluate("scale-color(rgba(10, 20, 30, 0.8), $alpha: 10%)"))
678
-
679
- # HSL composability
680
- assert_equal(evaluate("hsl(120, 51, 76.5)"),
681
- evaluate("scale-color(hsl(120, 30, 90), $saturation: 30%, $lightness: -15%)"))
682
- assert_equal(evaluate("hsla(120, 51, 90, 0.2)"),
683
- evaluate("scale-color(hsl(120, 30, 90), $saturation: 30%, $alpha: -80%)"))
684
-
685
- # RGB composability
686
- assert_equal(evaluate("rgb(157, 38.8, 30)"),
687
- evaluate("scale-color(rgb(10, 20, 30), $red: 60%, $green: 8%)"))
688
- assert_equal(evaluate("rgb(157, 38.8, 20)"),
689
- evaluate("scale-color(rgb(10, 20, 30), $red: 60%, $green: 8%, $blue: -(1/3)*100%)"))
690
- assert_equal(evaluate("rgba(10, 38.8, 20, 0.55)"),
691
- evaluate("scale-color(rgba(10, 20, 30, 0.5), $green: 8%, $blue: -(1/3)*100%, $alpha: 10%)"))
692
-
693
- # Extremes
694
- assert_equal(evaluate("hsl(120, 100, 90)"),
695
- evaluate("scale-color(hsl(120, 30, 90), $saturation: 100%)"))
696
- assert_equal(evaluate("hsl(120, 30, 90)"),
697
- evaluate("scale-color(hsl(120, 30, 90), $saturation: 0%)"))
698
- assert_equal(evaluate("hsl(120, 0, 90)"),
699
- evaluate("scale-color(hsl(120, 30, 90), $saturation: -100%)"))
700
- end
701
-
702
- def test_scale_color_tests_types
703
- assert_error_message("$color: \"foo\" is not a color for `scale-color'", "scale-color(foo, $red: 10%)")
704
- # HSL
705
- assert_error_message("$saturation: \"foo\" is not a number for `scale-color'",
706
- "scale-color(blue, $saturation: foo)")
707
- assert_error_message("$lightness: \"foo\" is not a number for `scale-color'",
708
- "scale-color(blue, $lightness: foo)")
709
- # RGB
710
- assert_error_message("$red: \"foo\" is not a number for `scale-color'",
711
- "scale-color(blue, $red: foo)")
712
- assert_error_message("$green: \"foo\" is not a number for `scale-color'",
713
- "scale-color(blue, $green: foo)")
714
- assert_error_message("$blue: \"foo\" is not a number for `scale-color'",
715
- "scale-color(blue, $blue: foo)")
716
- # Alpha
717
- assert_error_message("$alpha: \"foo\" is not a number for `scale-color'",
718
- "scale-color(blue, $alpha: foo)")
719
- end
720
-
721
- def test_scale_color_argument_errors
722
- # Range
723
- assert_error_message("$saturation: Amount 101% must be between -100% and 100% for `scale-color'",
724
- "scale-color(blue, $saturation: 101%)")
725
- assert_error_message("$red: Amount -101% must be between -100% and 100% for `scale-color'",
726
- "scale-color(blue, $red: -101%)")
727
- assert_error_message("$alpha: Amount -101% must be between -100% and 100% for `scale-color'",
728
- "scale-color(blue, $alpha: -101%)")
729
-
730
- # Unit
731
- assert_error_message("Expected $saturation to have a unit of % but got 80 for `scale-color'",
732
- "scale-color(blue, $saturation: 80)")
733
- assert_error_message("Expected $alpha to have a unit of % but got 0.5 for `scale-color'",
734
- "scale-color(blue, $alpha: 0.5)")
735
-
736
- # Unknown argument
737
- assert_error_message("Unknown argument $hue (80%) for `scale-color'", "scale-color(blue, $hue: 80%)")
738
-
739
- # Non-keyword arg
740
- assert_error_message("10px is not a keyword argument for `scale_color'", "scale-color(blue, 10px)")
741
-
742
- # HSL/RGB
743
- assert_error_message("Cannot specify HSL and RGB values for a color at the same time for `scale-color'",
744
- "scale-color(blue, $lightness: 10%, $red: 20%)");
745
- end
746
-
747
- def test_change_color
748
- # HSL
749
- assert_equal(evaluate("hsl(195, 30, 90)"),
750
- evaluate("change-color(hsl(120, 30, 90), $hue: 195deg)"))
751
- assert_equal(evaluate("hsl(120, 50, 90)"),
752
- evaluate("change-color(hsl(120, 30, 90), $saturation: 50%)"))
753
- assert_equal(evaluate("hsl(120, 30, 40)"),
754
- evaluate("change-color(hsl(120, 30, 90), $lightness: 40%)"))
755
- # RGB
756
- assert_equal(evaluate("rgb(123, 20, 30)"),
757
- evaluate("change-color(rgb(10, 20, 30), $red: 123)"))
758
- assert_equal(evaluate("rgb(10, 234, 30)"),
759
- evaluate("change-color(rgb(10, 20, 30), $green: 234)"))
760
- assert_equal(evaluate("rgb(10, 20, 198)"),
761
- evaluate("change-color(rgb(10, 20, 30), $blue: 198)"))
762
- # Alpha
763
- assert_equal(evaluate("rgba(10, 20, 30, 0.76)"),
764
- evaluate("change-color(rgb(10, 20, 30), $alpha: 0.76)"))
765
-
766
- # HSL composability
767
- assert_equal(evaluate("hsl(56, 30, 47)"),
768
- evaluate("change-color(hsl(120, 30, 90), $hue: 56deg, $lightness: 47%)"))
769
- assert_equal(evaluate("hsla(56, 30, 47, 0.9)"),
770
- evaluate("change-color(hsl(120, 30, 90), $hue: 56deg, $lightness: 47%, $alpha: 0.9)"))
771
- end
772
-
773
- def test_change_color_tests_types
774
- assert_error_message("$color: \"foo\" is not a color for `change-color'", "change-color(foo, $red: 10%)")
775
- # HSL
776
- assert_error_message("$saturation: \"foo\" is not a number for `change-color'",
777
- "change-color(blue, $saturation: foo)")
778
- assert_error_message("$lightness: \"foo\" is not a number for `change-color'",
779
- "change-color(blue, $lightness: foo)")
780
- # RGB
781
- assert_error_message("$red: \"foo\" is not a number for `change-color'", "change-color(blue, $red: foo)")
782
- assert_error_message("$green: \"foo\" is not a number for `change-color'", "change-color(blue, $green: foo)")
783
- assert_error_message("$blue: \"foo\" is not a number for `change-color'", "change-color(blue, $blue: foo)")
784
- # Alpha
785
- assert_error_message("$alpha: \"foo\" is not a number for `change-color'", "change-color(blue, $alpha: foo)")
786
- end
787
-
788
- def test_change_color_argument_errors
789
- # Range
790
- assert_error_message("Saturation 101% must be between 0% and 100% for `change-color'",
791
- "change-color(blue, $saturation: 101%)")
792
- assert_error_message("Lightness 101% must be between 0% and 100% for `change-color'",
793
- "change-color(blue, $lightness: 101%)")
794
- assert_error_message("Red value -1 must be between 0 and 255 for `change-color'",
795
- "change-color(blue, $red: -1)")
796
- assert_error_message("Green value 256 must be between 0 and 255 for `change-color'",
797
- "change-color(blue, $green: 256)")
798
- assert_error_message("Blue value 500 must be between 0 and 255 for `change-color'",
799
- "change-color(blue, $blue: 500)")
800
-
801
- # Unknown argument
802
- assert_error_message("Unknown argument $hoo (80%) for `change-color'", "change-color(blue, $hoo: 80%)")
803
-
804
- # Non-keyword arg
805
- assert_error_message("10px is not a keyword argument for `change_color'", "change-color(blue, 10px)")
806
-
807
- # HSL/RGB
808
- assert_error_message("Cannot specify HSL and RGB values for a color at the same time for `change-color'",
809
- "change-color(blue, $lightness: 10%, $red: 120)");
810
- end
811
-
812
- def test_ie_hex_str
813
- assert_equal("#FFAA11CC", evaluate('ie-hex-str(#aa11cc)'))
814
- assert_equal("#FFAA11CC", evaluate('ie-hex-str(#a1c)'))
815
- assert_equal("#FFAA11CC", evaluate('ie-hex-str(#A1c)'))
816
- assert_equal("#80FF0000", evaluate('ie-hex-str(rgba(255, 0, 0, 0.5))'))
817
- end
818
-
819
- def test_mix
820
- assert_equal("purple", evaluate("mix(#f00, #00f)"))
821
- assert_equal("gray", evaluate("mix(#f00, #0ff)"))
822
- assert_equal("#809155", evaluate("mix(#f70, #0aa)"))
823
- assert_equal("#4000bf", evaluate("mix(#f00, #00f, 25%)"))
824
- assert_equal("rgba(64, 0, 191, 0.75)", evaluate("mix(rgba(255, 0, 0, 0.5), #00f)"))
825
- assert_equal("red", evaluate("mix(#f00, #00f, 100%)"))
826
- assert_equal("blue", evaluate("mix(#f00, #00f, 0%)"))
827
- assert_equal("rgba(255, 0, 0, 0.5)", evaluate("mix(#f00, transparentize(#00f, 1))"))
828
- assert_equal("rgba(0, 0, 255, 0.5)", evaluate("mix(transparentize(#f00, 1), #00f)"))
829
- assert_equal("red", evaluate("mix(#f00, transparentize(#00f, 1), 100%)"))
830
- assert_equal("blue", evaluate("mix(transparentize(#f00, 1), #00f, 0%)"))
831
- assert_equal("rgba(0, 0, 255, 0)", evaluate("mix(#f00, transparentize(#00f, 1), 0%)"))
832
- assert_equal("rgba(255, 0, 0, 0)", evaluate("mix(transparentize(#f00, 1), #00f, 100%)"))
833
- assert_equal("rgba(255, 0, 0, 0)", evaluate("mix($color1: transparentize(#f00, 1), $color2: #00f, $weight: 100%)"))
834
- end
835
-
836
- def test_mix_tests_types
837
- assert_error_message("$color1: \"foo\" is not a color for `mix'", "mix(\"foo\", #f00, 10%)")
838
- assert_error_message("$color2: \"foo\" is not a color for `mix'", "mix(#f00, \"foo\", 10%)")
839
- assert_error_message("$weight: \"foo\" is not a number for `mix'", "mix(#f00, #baf, \"foo\")")
840
- end
841
-
842
- def test_mix_tests_bounds
843
- assert_error_message("Weight -0.001 must be between 0% and 100% for `mix'",
844
- "mix(#123, #456, -0.001)")
845
- assert_error_message("Weight 100.001 must be between 0% and 100% for `mix'",
846
- "mix(#123, #456, 100.001)")
847
- end
848
-
849
- def test_grayscale
850
- assert_equal("#bbbbbb", evaluate("grayscale(#abc)"))
851
- assert_equal("gray", evaluate("grayscale(#f00)"))
852
- assert_equal("gray", evaluate("grayscale(#00f)"))
853
- assert_equal("white", evaluate("grayscale(white)"))
854
- assert_equal("black", evaluate("grayscale(black)"))
855
- assert_equal("black", evaluate("grayscale($color: black)"))
856
-
857
- assert_equal("grayscale(2)", evaluate("grayscale(2)"))
858
- assert_equal("grayscale(-5px)", evaluate("grayscale(-5px)"))
859
- end
860
-
861
- def tets_grayscale_tests_types
862
- assert_error_message("$color: \"foo\" is not a color for `grayscale'", "grayscale(\"foo\")")
863
- end
864
-
865
- def test_complement
866
- assert_equal("#ccbbaa", evaluate("complement(#abc)"))
867
- assert_equal("cyan", evaluate("complement(red)"))
868
- assert_equal("red", evaluate("complement(cyan)"))
869
- assert_equal("white", evaluate("complement(white)"))
870
- assert_equal("black", evaluate("complement(black)"))
871
- assert_equal("black", evaluate("complement($color: black)"))
872
- end
873
-
874
- def tets_complement_tests_types
875
- assert_error_message("$color: \"foo\" is not a color for `complement'", "complement(\"foo\")")
876
- end
877
-
878
- def test_invert
879
- assert_equal("#112233", evaluate("invert(#edc)"))
880
- assert_equal("#d8cabd", evaluate("invert(#edc, 10%)"))
881
- assert_equal("rgba(245, 235, 225, 0.5)", evaluate("invert(rgba(10, 20, 30, 0.5))"))
882
- assert_equal("rgba(34, 42, 50, 0.5)", evaluate("invert(rgba(10, 20, 30, 0.5), 10%)"))
883
- assert_equal("invert(20%)", evaluate("invert(20%)"))
884
- end
885
-
886
- def test_invert_tests_types
887
- assert_error_message("$color: \"foo\" is not a color for `invert'", "invert(\"foo\")")
888
- assert_error_message("$weight: \"foo\" is not a number for `invert'", "invert(#edc, \"foo\")")
889
- end
890
-
891
- def test_invert_tests_bounds
892
- assert_error_message("Weight -0.001 must be between 0% and 100% for `invert'",
893
- "invert(#edc, -0.001)")
894
- assert_error_message("Weight 100.001 must be between 0% and 100% for `invert'",
895
- "invert(#edc, 100.001)")
896
- end
897
-
898
- def test_unquote
899
- assert_equal('foo', evaluate('unquote("foo")'))
900
- assert_equal('foo', evaluate('unquote(foo)'))
901
- assert_equal('foo', evaluate('unquote($string: foo)'))
902
- assert_warning <<MESSAGE do
903
- DEPRECATION WARNING: Passing blue, a non-string value, to unquote()
904
- will be an error in future versions of Sass.
905
- on line 1 of test_unquote_inline.scss
906
- MESSAGE
907
- assert_equal('blue', evaluate('unquote(blue)'))
908
- end
909
- end
910
-
911
- def test_quote
912
- assert_equal('"foo"', evaluate('quote(foo)'))
913
- assert_equal('"foo"', evaluate('quote("foo")'))
914
- assert_equal('"foo"', evaluate('quote($string: "foo")'))
915
- end
916
-
917
- def test_quote_tests_type
918
- assert_error_message("$string: #ff0000 is not a string for `quote'", "quote(#f00)")
919
- end
920
-
921
- def test_str_length
922
- assert_equal('3', evaluate('str-length(foo)'))
923
- end
924
-
925
- def test_str_length_requires_a_string
926
- assert_error_message("$string: #ff0000 is not a string for `str-length'", "str-length(#f00)")
927
- end
928
-
929
- def test_str_insert
930
- assert_equal('Xabcd', evaluate('str-insert(abcd, X, 0)'))
931
- assert_equal('Xabcd', evaluate('str-insert(abcd, X, 1)'))
932
- assert_equal('abcXd', evaluate('str-insert(abcd, X, 4)'))
933
- assert_equal('abcdX', evaluate('str-insert(abcd, X, 100)'))
934
- assert_equal('Xabcd', evaluate('str-insert(abcd, X, -100)'))
935
- assert_equal('aXbcd', evaluate('str-insert(abcd, X, -4)'))
936
- assert_equal('abcdX', evaluate('str-insert(abcd, X, -1)'))
937
- end
938
-
939
- def test_str_insert_maintains_quote_of_primary_string
940
- assert_equal('"Xfoo"', evaluate('str-insert("foo", X, 1)'))
941
- assert_equal('"Xfoo"', evaluate('str-insert("foo", "X", 1)'))
942
- assert_equal('Xfoo', evaluate('str-insert(foo, "X", 1)'))
943
- end
944
-
945
- def test_str_insert_asserts_types
946
- assert_error_message("$string: #ff0000 is not a string for `str-insert'", "str-insert(#f00, X, 1)")
947
- assert_error_message("$insert: #ff0000 is not a string for `str-insert'", "str-insert(foo, #f00, 1)")
948
- assert_error_message("$index: #ff0000 is not a number for `str-insert'", "str-insert(foo, X, #f00)")
949
- assert_error_message("Expected $index to be unitless but got 10px for `str-insert'", "str-insert(foo, X, 10px)")
950
- end
951
-
952
- def test_str_index
953
- assert_equal('1', evaluate('str-index(abcd, a)'))
954
- assert_equal('1', evaluate('str-index(abcd, ab)'))
955
- assert_equal(Sass::Script::Value::Null.new, perform('str-index(abcd, X)'))
956
- assert_equal('3', evaluate('str-index(abcd, c)'))
957
- end
958
-
959
- def test_str_index_asserts_types
960
- assert_error_message("$string: #ff0000 is not a string for `str-index'", "str-index(#f00, X)")
961
- assert_error_message("$substring: #ff0000 is not a string for `str-index'", "str-index(asdf, #f00)")
962
- end
963
-
964
- def test_to_lower_case
965
- assert_equal('abcd', evaluate('to-lower-case(ABCD)'))
966
- assert_equal('"abcd"', evaluate('to-lower-case("ABCD")'))
967
- assert_error_message("$string: #ff0000 is not a string for `to-lower-case'", "to-lower-case(#f00)")
968
- end
969
-
970
- def test_to_upper_case
971
- assert_equal('ABCD', evaluate('to-upper-case(abcd)'))
972
- assert_equal('"ABCD"', evaluate('to-upper-case("abcd")'))
973
- assert_error_message("$string: #ff0000 is not a string for `to-upper-case'", "to-upper-case(#f00)")
974
- end
975
-
976
- def test_str_slice
977
- assert_equal('bc', evaluate('str-slice(abcd,2,3)')) # in the middle of the string
978
- assert_equal('a', evaluate('str-slice(abcd,1,1)')) # when start = end
979
- assert_equal('ab', evaluate('str-slice(abcd,1,2)')) # for completeness
980
- assert_equal('abcd', evaluate('str-slice(abcd,1,4)')) # at the end points
981
- assert_equal('abcd', evaluate('str-slice(abcd,0,4)')) # when start is before the start of the string
982
- assert_equal('', evaluate('str-slice(abcd,1,0)')) # when end is before the start of the string
983
- assert_equal('abcd', evaluate('str-slice(abcd,1,100)')) # when end is past the end of the string
984
- assert_equal('', evaluate('str-slice(abcd,2,1)')) # when end is before start
985
- assert_equal('"bc"', evaluate('str-slice("abcd",2,3)')) # when used with a quoted string
986
- assert_equal('bcd', evaluate('str-slice(abcd,2)')) # when end is omitted, you get the remainder of the string
987
- assert_equal('cd', evaluate('str-slice(abcd,-2)')) # when start is negative, it counts from the beginning
988
- assert_equal('bc', evaluate('str-slice(abcd,2,-2)')) # when end is negative it counts in from the end
989
- assert_equal('', evaluate('str-slice(abcd,3,-3)')) # when end is negative and comes before the start
990
- assert_equal('bc', evaluate('str-slice(abcd,-3,-2)')) # when both are negative
991
- assert_error_message("$string: #ff0000 is not a string for `str-slice'", "str-slice(#f00,2,3)")
992
- assert_error_message("$start-at: #ff0000 is not a number for `str-slice'", "str-slice(abcd,#f00,3)")
993
- assert_error_message("$end-at: #ff0000 is not a number for `str-slice'", "str-slice(abcd,2,#f00)")
994
- assert_error_message("Expected $end-at to be unitless but got 3px for `str-slice'", "str-slice(abcd,2,3px)")
995
- assert_error_message("Expected $start-at to be unitless but got 2px for `str-slice'", "str-slice(abcd,2px,3)")
996
- end
997
-
998
- def test_user_defined_function
999
- assert_equal("I'm a user-defined string!", evaluate("user_defined()"))
1000
- end
1001
-
1002
- def test_user_defined_function_with_preceding_underscore
1003
- assert_equal("I'm another user-defined string!", evaluate("_preceding_underscore()"))
1004
- assert_equal("I'm another user-defined string!", evaluate("-preceding-underscore()"))
1005
- end
1006
-
1007
- def test_user_defined_function_using_environment
1008
- environment = env('variable' => Sass::Script::Value::String.new('The variable'))
1009
- assert_equal("The variable", evaluate("fetch_the_variable()", environment))
1010
- end
1011
-
1012
- def test_options_on_new_values_fails
1013
- assert_error_message(<<MSG, "call-options-on-new-value()")
1014
- The #options attribute is not set on this Sass::Script::Value::String.
1015
- This error is probably occurring because #to_s was called
1016
- on this value within a custom Sass function without first
1017
- setting the #options attribute.
1018
- MSG
1019
- end
1020
-
1021
- def test_type_of
1022
- assert_equal("string", evaluate("type-of(\"asdf\")"))
1023
- assert_equal("string", evaluate("type-of(asdf)"))
1024
- assert_equal("number", evaluate("type-of(1px)"))
1025
- assert_equal("bool", evaluate("type-of(true)"))
1026
- assert_equal("color", evaluate("type-of(#fff)"))
1027
- assert_equal("color", evaluate("type-of($value: #fff)"))
1028
- assert_equal("null", evaluate("type-of(null)"))
1029
- assert_equal("list", evaluate("type-of(1 2 3)"))
1030
- assert_equal("list", evaluate("type-of((1, 2, 3))"))
1031
- assert_equal("list", evaluate("type-of(())"))
1032
- assert_equal("map", evaluate("type-of((foo: bar))"))
1033
- end
1034
-
1035
- def test_feature_exists
1036
- assert_raises ArgumentError do
1037
- Sass.add_feature("my-test-feature")
1038
- end
1039
- Sass.add_feature("-my-test-feature")
1040
- assert_equal("true", evaluate("feature-exists(-my-test-feature)"))
1041
- assert_equal("false", evaluate("feature-exists(whatisthisidontevenknow)"))
1042
- assert_equal("true", evaluate("feature-exists($feature: -my-test-feature)"))
1043
- ensure
1044
- Sass::Features::KNOWN_FEATURES.delete("-my-test-feature")
1045
- end
1046
-
1047
- def test_unit
1048
- assert_equal(%Q{""}, evaluate("unit(100)"))
1049
- assert_equal(%Q{"px"}, evaluate("unit(100px)"))
1050
- assert_equal(%Q{"em*px"}, evaluate("unit(10px * 5em)"))
1051
- assert_equal(%Q{"em*px"}, evaluate("unit(5em * 10px)"))
1052
- assert_equal(%Q{"em/rem"}, evaluate("unit(10px * 5em / 30cm / 1rem)"))
1053
- assert_equal(%Q{"em*vh/cm*rem"}, evaluate("unit(10vh * 5em / 30cm / 1rem)"))
1054
- assert_equal(%Q{"px"}, evaluate("unit($number: 100px)"))
1055
- assert_error_message("$number: #ff0000 is not a number for `unit'", "unit(#f00)")
1056
- end
1057
-
1058
- def test_unitless
1059
- assert_equal(%Q{true}, evaluate("unitless(100)"))
1060
- assert_equal(%Q{false}, evaluate("unitless(100px)"))
1061
- assert_equal(%Q{false}, evaluate("unitless($number: 100px)"))
1062
- assert_error_message("$number: #ff0000 is not a number for `unitless'", "unitless(#f00)")
1063
- end
1064
-
1065
- def test_comparable
1066
- assert_equal(%Q{true}, evaluate("comparable(2px, 1px)"))
1067
- assert_equal(%Q{true}, evaluate("comparable(10cm, 3mm)"))
1068
- assert_equal(%Q{false}, evaluate("comparable(100px, 3em)"))
1069
- assert_equal(%Q{false}, evaluate("comparable($number1: 100px, $number2: 3em)"))
1070
- end
1071
-
1072
- def test_comparable_checks_types
1073
- assert_error_message("$number1: #ff0000 is not a number for `comparable'", "comparable(#f00, 1px)")
1074
- assert_error_message("$number2: #ff0000 is not a number for `comparable'", "comparable(1px, #f00)")
1075
- end
1076
-
1077
- def test_length
1078
- assert_equal("5", evaluate("length(1 2 3 4 5)"))
1079
- assert_equal("4", evaluate("length((foo, bar, baz, bip))"))
1080
- assert_equal("3", evaluate("length((foo, bar, baz bip))"))
1081
- assert_equal("3", evaluate("length((foo, bar, (baz, bip)))"))
1082
- assert_equal("1", evaluate("length(#f00)"))
1083
- assert_equal("0", evaluate("length(())"))
1084
- assert_equal("4", evaluate("length(1 2 () 3)"))
1085
-
1086
- assert_equal("2", evaluate("length((foo: bar, bar: baz))"))
1087
- end
1088
-
1089
- def test_nth
1090
- assert_equal("1", evaluate("nth(1 2 3, 1)"))
1091
- assert_equal("2", evaluate("nth(1 2 3, 2)"))
1092
- assert_equal("3", evaluate("nth(1 2 3, -1)"))
1093
- assert_equal("1", evaluate("nth(1 2 3, -3)"))
1094
- assert_equal("3", evaluate("nth((1, 2, 3), 3)"))
1095
- assert_equal("3", evaluate("nth($list: (1, 2, 3), $n: 3)"))
1096
- assert_equal("foo", evaluate("nth(foo, 1)"))
1097
- assert_equal("bar baz", evaluate("nth(foo (bar baz) bang, 2)"))
1098
- assert_error_message("List index 0 must be a non-zero integer for `nth'", "nth(foo, 0)")
1099
- assert_error_message("List index is -10 but list is only 1 item long for `nth'", "nth(foo, -10)")
1100
- assert_error_message("List index 1.5 must be a non-zero integer for `nth'", "nth(foo, 1.5)")
1101
- assert_error_message("List index is 5 but list is only 4 items long for `nth'", "nth(1 2 3 4, 5)")
1102
- assert_error_message("List index is 2 but list is only 1 item long for `nth'", "nth(foo, 2)")
1103
- assert_error_message("List index is 1 but list has no items for `nth'", "nth((), 1)")
1104
- assert_error_message("$n: \"foo\" is not a number for `nth'", "nth(1 2 3, foo)")
1105
-
1106
- assert_equal("foo bar", evaluate("nth((foo: bar, bar: baz), 1)"))
1107
- assert_equal("bar baz", evaluate("nth((foo: bar, bar: baz), 2)"))
1108
- end
1109
-
1110
- def test_set_nth
1111
- assert_equal("a 2 3", evaluate("set-nth(1 2 3, 1, a)"))
1112
- assert_equal("1 a 3", evaluate("set-nth(1 2 3, 2, a)"))
1113
- assert_equal("1 2 a", evaluate("set-nth(1 2 3, -1, a)"))
1114
- assert_equal("a 2 3", evaluate("set-nth(1 2 3, -3, a)"))
1115
- assert_equal("a 2 3", evaluate("set-nth($list: 1 2 3, $n: -3, $value: a)"))
1116
- assert_equal("1, 2, a", evaluate("set-nth((1, 2, 3), 3, a)"))
1117
- assert_equal("a", evaluate("set-nth(foo, 1, a)"))
1118
- assert_equal("foo, a b, baz", evaluate("set-nth((foo, bar, baz), 2, (a b))"))
1119
- assert_error_message("List index 0 must be a non-zero integer for `set-nth'", "set-nth(foo, 0, a)")
1120
- assert_error_message("List index is -10 but list is only 1 item long for `set-nth'", "set-nth(foo, -10, a)")
1121
- assert_error_message("List index 1.5 must be a non-zero integer for `set-nth'", "set-nth(foo, 1.5, a)")
1122
- assert_error_message("List index is 5 but list is only 4 items long for `set-nth'", "set-nth(1 2 3 4, 5, a)")
1123
- assert_error_message("List index is 2 but list is only 1 item long for `set-nth'", "set-nth(foo, 2, a)")
1124
- assert_error_message("List index is 1 but list has no items for `set-nth'", "set-nth((), 1, a)")
1125
- assert_error_message("$n: \"foo\" is not a number for `set-nth'", "set-nth(1 2 3, foo, a)")
1126
- end
1127
-
1128
- def test_join
1129
- assert_equal("1 2 3", evaluate("join(1 2, 3)"))
1130
- assert_equal("1 2 3", evaluate("join(1, 2 3)"))
1131
- assert_equal("1 2 3 4", evaluate("join(1 2, 3 4)"))
1132
- assert_equal("true", evaluate("(1 2 3 4) == join(1 2, 3 4)"))
1133
- assert_equal("false", evaluate("(1 2 (3 4)) == join(1 2, 3 4)"))
1134
- assert_equal("1, 2, 3", evaluate("join((1, 2), 3)"))
1135
- assert_equal("1, 2, 3", evaluate("join(1, (2, 3))"))
1136
- assert_equal("1, 2, 3, 4", evaluate("join((1, 2), (3, 4))"))
1137
- assert_equal("true", evaluate("(1, 2, 3, 4) == join((1, 2), (3, 4))"))
1138
- assert_equal("false", evaluate("(1, 2, (3, 4)) == join((1, 2), (3, 4))"))
1139
-
1140
- assert_equal("1 2", evaluate("join(1, 2)"))
1141
- assert_equal("1 2 3 4", evaluate("join(1 2, (3, 4))"))
1142
- assert_equal("1, 2, 3, 4", evaluate("join((1, 2), 3 4)"))
1143
-
1144
- assert_equal("1 2", evaluate("join(1, 2, auto)"))
1145
- assert_equal("1, 2, 3, 4", evaluate("join(1 2, 3 4, comma)"))
1146
- assert_equal("1 2 3 4", evaluate("join((1, 2), (3, 4), space)"))
1147
- assert_equal("1, 2", evaluate("join(1, 2, comma)"))
1148
-
1149
- assert_equal("1 2", evaluate("join(1 2, ())"))
1150
- assert_equal("1, 2", evaluate("join((1, 2), ())"))
1151
- assert_equal("true", evaluate("(1 2) == join(1 2, ())"))
1152
- assert_equal("true", evaluate("(1, 2) == join((1, 2), ())"))
1153
- assert_equal("false", evaluate("(1 2 ()) == join(1 2, ())"))
1154
- assert_equal("false", evaluate("(1, 2, ()) == join((1, 2), ())"))
1155
-
1156
- assert_equal("1 2", evaluate("join((), 1 2)"))
1157
- assert_equal("1, 2", evaluate("join((), (1, 2))"))
1158
- assert_equal("true", evaluate("(1 2) == join((), 1 2)"))
1159
- assert_equal("true", evaluate("(1, 2) == join((), (1, 2))"))
1160
- assert_equal("false", evaluate("(1 2 ()) == join((), 1 2)"))
1161
- assert_equal("false", evaluate("(1, 2, ()) == join((), (1, 2))"))
1162
-
1163
- assert_error_message("Separator name must be space, comma, or auto for `join'", "join(1, 2, baboon)")
1164
- assert_error_message("$separator: 12 is not a string for `join'", "join(1, 2, 12)")
1165
-
1166
- assert_equal("foo bar, bar baz, baz bip, bip bop",
1167
- perform("join((foo: bar, bar: baz), (baz: bip, bip: bop))").to_sass)
1168
- assert_equal("(foo bar) (bar baz) (baz bip) (bip bop)",
1169
- perform("join((foo: bar, bar: baz), (baz: bip, bip: bop), space)").to_sass)
1170
- assert_equal("foo bar (baz bip) (bip bop)",
1171
- perform("join(foo bar, (baz: bip, bip: bop))").to_sass)
1172
- assert_equal("foo bar, bar baz, bip, bop",
1173
- perform("join((foo: bar, bar: baz), bip bop)").to_sass)
1174
- assert_equal("baz bip, bip bop",
1175
- perform("join((), (baz: bip, bip: bop))").to_sass)
1176
- assert_equal("foo bar, bar baz",
1177
- perform("join((foo: bar, bar: baz), ())").to_sass)
1178
- end
1179
-
1180
- def test_append
1181
- assert_equal("1 2 3", evaluate("append(1 2, 3)"))
1182
- assert_equal("1 2 3 4", evaluate("append(1 2, 3 4)"))
1183
- assert_equal("false", evaluate("(1 2 3 4) == append(1 2, 3 4)"))
1184
- assert_equal("true", evaluate("(1 2 (3 4)) == append(1 2, 3 4)"))
1185
- assert_equal("1, 2, 3", evaluate("append((1, 2), 3)"))
1186
- assert_equal("1, 2, 3, 4", evaluate("append((1, 2), (3, 4))"))
1187
- assert_equal("false", evaluate("(1, 2, 3, 4) == append((1, 2), (3, 4))"))
1188
- assert_equal("true", evaluate("(1, 2, (3, 4)) == append((1, 2), (3, 4))"))
1189
-
1190
- assert_equal("1 2", evaluate("append(1, 2)"))
1191
- assert_equal("1 2 3, 4", evaluate("append(1 2, (3, 4))"))
1192
- assert_equal("true", evaluate("(1 2 (3, 4)) == append(1 2, (3, 4))"))
1193
- assert_equal("1, 2, 3 4", evaluate("append((1, 2), 3 4)"))
1194
- assert_equal("true", evaluate("(1, 2, 3 4) == append((1, 2), 3 4)"))
1195
-
1196
- assert_equal("1 2", evaluate("append(1, 2, auto)"))
1197
- assert_equal("1, 2, 3 4", evaluate("append(1 2, 3 4, comma)"))
1198
- assert_equal("1 2 3, 4", evaluate("append((1, 2), (3, 4), space)"))
1199
- assert_equal("1, 2", evaluate("append(1, 2, comma)"))
1200
-
1201
- assert_equal("1 2", evaluate("append(1 2, ())"))
1202
- assert_equal("1, 2", evaluate("append((1, 2), ())"))
1203
- assert_equal("true", evaluate("(1 2 ()) == append(1 2, ())"))
1204
- assert_equal("true", evaluate("(1, 2, ()) == append((1, 2), ())"))
1205
-
1206
- assert_equal("1 2", evaluate("append((), 1 2)"))
1207
- assert_equal("1, 2", evaluate("append((), (1, 2))"))
1208
- assert_equal("false", evaluate("(1 2) == append((), 1 2)"))
1209
- assert_equal("true", evaluate("(1 2) == nth(append((), 1 2), 1)"))
1210
-
1211
- assert_error_message("Separator name must be space, comma, or auto for `append'", "append(1, 2, baboon)")
1212
- assert_error_message("$separator: 12 is not a string for `append'", "append(1, 2, 12)")
1213
-
1214
- assert_equal("1 2 (foo: bar)", perform("append(1 2, (foo: bar))").to_sass)
1215
- assert_equal("foo bar, bar baz, 1", perform("append((foo: bar, bar: baz), 1)").to_sass)
1216
- assert_equal("foo bar, bar baz, (baz: bip)",
1217
- perform("append((foo: bar, bar: baz), (baz: bip))").to_sass)
1218
- end
1219
-
1220
- def test_zip
1221
- assert_equal("1 3 5, 2 4 6", evaluate("zip(1 2, 3 4, 5 6)"))
1222
- assert_equal("1 4 7, 2 5 8", evaluate("zip(1 2 3, 4 5 6, 7 8)"))
1223
- assert_equal("1 2 3", evaluate("zip(1, 2, 3)"))
1224
- assert_equal("(foo bar) 1 3, (bar baz) 2 4",
1225
- perform("zip((foo: bar, bar: baz), 1 2, 3 4)").to_sass)
1226
- end
1227
-
1228
- def test_index
1229
- null = Sass::Script::Value::Null.new
1230
- assert_equal("1", evaluate("index(1px solid blue, 1px)"))
1231
- assert_equal("2", evaluate("index(1px solid blue, solid)"))
1232
- assert_equal("3", evaluate("index(1px solid blue, #00f)"))
1233
- assert_equal("1", evaluate("index(1px, 1px)"))
1234
- assert_equal(null, perform("index(1px solid blue, 1em)"))
1235
- assert_equal(null, perform("index(1px solid blue, notfound)"))
1236
- assert_equal(null, perform("index(1px, #00f)"))
1237
-
1238
- assert_equal("1", evaluate("index((foo: bar, bar: baz), (foo bar))"))
1239
- assert_equal(null, perform("index((foo: bar, bar: baz), (foo: bar))"))
1240
- end
1241
-
1242
- def test_list_separator
1243
- assert_equal("space", evaluate("list-separator(1 2 3 4 5)"))
1244
- assert_equal("comma", evaluate("list-separator((foo, bar, baz, bip))"))
1245
- assert_equal("comma", evaluate("list-separator((foo, bar, baz bip))"))
1246
- assert_equal("comma", evaluate("list-separator((foo, bar, (baz, bip)))"))
1247
- assert_equal("space", evaluate("list-separator(#f00)"))
1248
- assert_equal("space", evaluate("list-separator(())"))
1249
- assert_equal("space", evaluate("list-separator(1 2 () 3)"))
1250
-
1251
- assert_equal("comma", evaluate("list-separator((foo: bar, bar: baz))"))
1252
- end
1253
-
1254
- def test_if
1255
- assert_equal("1px", evaluate("if(true, 1px, 2px)"))
1256
- assert_equal("2px", evaluate("if(false, 1px, 2px)"))
1257
- assert_equal("2px", evaluate("if(null, 1px, 2px)"))
1258
- assert_equal("1px", evaluate("if(true, 1px, $broken)"))
1259
- assert_equal("1px", evaluate("if(false, $broken, 1px)"))
1260
- assert_equal("1px", evaluate("if(false, $if-true: $broken, $if-false: 1px)"))
1261
- assert_equal("1px", evaluate("if(true, $if-true: 1px, $if-false: $broken)"))
1262
- assert_equal(<<CSS, render(<<SCSS))
1263
- .if {
1264
- result: yay; }
1265
- CSS
1266
- .if {
1267
- $something: yay;
1268
- result: if(true, $if-true: $something, $if-false: $broken);
1269
- }
1270
- SCSS
1271
- assert_equal(<<CSS, render(<<SCSS))
1272
- .if {
1273
- result: 1px; }
1274
- CSS
1275
- .if {
1276
- $splat: 1px, 2px;
1277
- result: if(true, $splat...);
1278
- }
1279
- SCSS
1280
- end
1281
-
1282
- def test_counter
1283
- assert_equal("counter(foo)", evaluate("counter(foo)"))
1284
- assert_equal('counter(item,".")', evaluate('counter(item, ".")'))
1285
- assert_equal('counter(item,".")', evaluate('counter(item,".")'))
1286
- end
1287
-
1288
- def test_counters
1289
- assert_equal("counters(foo)", evaluate("counters(foo)"))
1290
- assert_equal('counters(item,".")', evaluate('counters(item, ".")'))
1291
- assert_equal('counters(item,".")', evaluate('counters(item,".")'))
1292
- end
1293
-
1294
- def test_keyword_args_rgb
1295
- assert_equal(%Q{white}, evaluate("rgb($red: 255, $green: 255, $blue: 255)"))
1296
- end
1297
-
1298
- def test_keyword_args_rgba
1299
- assert_equal(%Q{rgba(255, 255, 255, 0.5)}, evaluate("rgba($red: 255, $green: 255, $blue: 255, $alpha: 0.5)"))
1300
- assert_equal(%Q{rgba(255, 255, 255, 0.5)}, evaluate("rgba($color: #fff, $alpha: 0.5)"))
1301
- end
1302
-
1303
- def test_keyword_args_rgba_with_extra_args
1304
- evaluate("rgba($red: 255, $green: 255, $blue: 255, $alpha: 0.5, $extra: error)")
1305
- flunk("Expected exception")
1306
- rescue Sass::SyntaxError => e
1307
- assert_equal("Function rgba doesn't have an argument named $extra", e.message)
1308
- end
1309
-
1310
- def test_keyword_args_must_have_signature
1311
- evaluate("no-kw-args($fake: value)")
1312
- flunk("Expected exception")
1313
- rescue Sass::SyntaxError => e
1314
- assert_equal("Function no_kw_args doesn't support keyword arguments", e.message)
1315
- end
1316
-
1317
- def test_keyword_args_with_missing_argument
1318
- evaluate("rgb($red: 255, $green: 255)")
1319
- flunk("Expected exception")
1320
- rescue Sass::SyntaxError => e
1321
- assert_equal("wrong number of arguments (2 for 3) for `rgb'", e.message)
1322
- end
1323
-
1324
- def test_keyword_args_with_extra_argument
1325
- evaluate("rgb($red: 255, $green: 255, $blue: 255, $purple: 255)")
1326
- flunk("Expected exception")
1327
- rescue Sass::SyntaxError => e
1328
- assert_equal("Function rgb doesn't have an argument named $purple", e.message)
1329
- end
1330
-
1331
- def test_keyword_args_with_positional_and_keyword_argument
1332
- evaluate("rgb(255, 255, 255, $red: 255)")
1333
- flunk("Expected exception")
1334
- rescue Sass::SyntaxError => e
1335
- assert_equal("Function rgb was passed argument $red both by position and by name", e.message)
1336
- end
1337
-
1338
- def test_keyword_args_with_keyword_before_positional_argument
1339
- evaluate("rgb($red: 255, 255, 255)")
1340
- flunk("Expected exception")
1341
- rescue Sass::SyntaxError => e
1342
- assert_equal("Positional arguments must come before keyword arguments.", e.message)
1343
- end
1344
-
1345
- def test_only_var_args
1346
- assert_equal "only-var-args(2px, 3px, 4px)", evaluate("only-var-args(1px, 2px, 3px)")
1347
- end
1348
-
1349
- def test_only_kw_args
1350
- assert_equal "only-kw-args(a, b, c)", evaluate("only-kw-args($a: 1, $b: 2, $c: 3)")
1351
- end
1352
-
1353
- def test_unique_id
1354
- last_id, current_id = nil, evaluate("unique-id()")
1355
-
1356
- 50.times do
1357
- last_id, current_id = current_id, evaluate("unique-id()")
1358
- assert_match(/u[a-z0-9]{8}/, current_id)
1359
- refute_equal last_id, current_id
1360
- end
1361
- end
1362
-
1363
- def test_map_get
1364
- assert_equal "1", evaluate("map-get((foo: 1, bar: 2), foo)")
1365
- assert_equal "2", evaluate("map-get((foo: 1, bar: 2), bar)")
1366
- assert_equal "null", perform("map-get((foo: 1, bar: 2), baz)").to_sass
1367
- assert_equal "null", perform("map-get((), foo)").to_sass
1368
- end
1369
-
1370
- def test_map_get_checks_type
1371
- assert_error_message("$map: 12 is not a map for `map-get'", "map-get(12, bar)")
1372
- end
1373
-
1374
- def test_map_merge
1375
- assert_equal("(foo: 1, bar: 2, baz: 3)",
1376
- perform("map-merge((foo: 1, bar: 2), (baz: 3))").to_sass)
1377
- assert_equal("(foo: 1, bar: 2)",
1378
- perform("map-merge((), (foo: 1, bar: 2))").to_sass)
1379
- assert_equal("(foo: 1, bar: 2)",
1380
- perform("map-merge((foo: 1, bar: 2), ())").to_sass)
1381
- end
1382
-
1383
- def test_map_merge_checks_type
1384
- assert_error_message("$map1: 12 is not a map for `map-merge'", "map-merge(12, (foo: 1))")
1385
- assert_error_message("$map2: 12 is not a map for `map-merge'", "map-merge((foo: 1), 12)")
1386
- end
1387
-
1388
- def test_map_remove
1389
- assert_equal("(foo: 1, baz: 3)",
1390
- perform("map-remove((foo: 1, bar: 2, baz: 3), bar)").to_sass)
1391
- assert_equal("(foo: 1, baz: 3)",
1392
- perform("map-remove($map: (foo: 1, bar: 2, baz: 3), $key: bar)").to_sass)
1393
- assert_equal("()",
1394
- perform("map-remove((foo: 1, bar: 2, baz: 3), foo, bar, baz)").to_sass)
1395
- assert_equal("()", perform("map-remove((), foo)").to_sass)
1396
- assert_equal("()", perform("map-remove((), foo, bar)").to_sass)
1397
- end
1398
-
1399
- def test_map_remove_checks_type
1400
- assert_error_message("$map: 12 is not a map for `map-remove'", "map-remove(12, foo)")
1401
- end
1402
-
1403
- def test_map_keys
1404
- assert_equal("foo, bar",
1405
- perform("map-keys((foo: 1, bar: 2))").to_sass)
1406
- assert_equal("()", perform("map-keys(())").to_sass)
1407
- end
1408
-
1409
- def test_map_keys_checks_type
1410
- assert_error_message("$map: 12 is not a map for `map-keys'", "map-keys(12)")
1411
- end
1412
-
1413
- def test_map_values
1414
- assert_equal("1, 2", perform("map-values((foo: 1, bar: 2))").to_sass)
1415
- assert_equal("1, 2, 2",
1416
- perform("map-values((foo: 1, bar: 2, baz: 2))").to_sass)
1417
- assert_equal("()", perform("map-values(())").to_sass)
1418
- end
1419
-
1420
- def test_map_values_checks_type
1421
- assert_error_message("$map: 12 is not a map for `map-values'", "map-values(12)")
1422
- end
1423
-
1424
- def test_map_has_key
1425
- assert_equal "true", evaluate("map-has-key((foo: 1, bar: 1), foo)")
1426
- assert_equal "false", evaluate("map-has-key((foo: 1, bar: 1), baz)")
1427
- assert_equal "false", evaluate("map-has-key((), foo)")
1428
- end
1429
-
1430
- def test_map_has_key_checks_type
1431
- assert_error_message("$map: 12 is not a map for `map-has-key'", "map-has-key(12, foo)")
1432
- end
1433
-
1434
- def test_keywords
1435
- # The actual functionality is tested in tests where real arglists are passed.
1436
- assert_error_message("$args: 12 is not a variable argument list for `keywords'", "keywords(12)")
1437
- assert_error_message(
1438
- "$args: (1 2 3) is not a variable argument list for `keywords'", "keywords(1 2 3)")
1439
- end
1440
-
1441
- def test_partial_list_of_pairs_doesnt_work_as_a_map
1442
- assert_raises(Sass::SyntaxError) {evaluate("map-get((foo bar, baz bang, bip), 1)")}
1443
- assert_raises(Sass::SyntaxError) {evaluate("map-get((foo bar, baz bang, bip bap bop), 1)")}
1444
- assert_raises(Sass::SyntaxError) {evaluate("map-get((foo bar), 1)")}
1445
- end
1446
-
1447
- def test_assert_unit
1448
- ctx = Sass::Script::Functions::EvaluationContext.new(Sass::Environment.new(nil, {}))
1449
- ctx.assert_unit Sass::Script::Value::Number.new(10, ["px"], []), "px"
1450
- ctx.assert_unit Sass::Script::Value::Number.new(10, [], []), nil
1451
-
1452
- begin
1453
- ctx.assert_unit Sass::Script::Value::Number.new(10, [], []), "px"
1454
- fail
1455
- rescue ArgumentError => e
1456
- assert_equal "Expected 10 to have a unit of px", e.message
1457
- end
1458
-
1459
- begin
1460
- ctx.assert_unit Sass::Script::Value::Number.new(10, ["px"], []), nil
1461
- fail
1462
- rescue ArgumentError => e
1463
- assert_equal "Expected 10px to be unitless", e.message
1464
- end
1465
-
1466
- begin
1467
- ctx.assert_unit Sass::Script::Value::Number.new(10, [], []), "px", "arg"
1468
- fail
1469
- rescue ArgumentError => e
1470
- assert_equal "Expected $arg to have a unit of px but got 10", e.message
1471
- end
1472
-
1473
- begin
1474
- ctx.assert_unit Sass::Script::Value::Number.new(10, ["px"], []), nil, "arg"
1475
- fail
1476
- rescue ArgumentError => e
1477
- assert_equal "Expected $arg to be unitless but got 10px", e.message
1478
- end
1479
- end
1480
-
1481
- def test_call_with_positional_arguments
1482
- # TODO: Remove this block in 4.0
1483
- Sass::Util.silence_sass_warnings do
1484
- assert_equal evaluate("lighten(blue, 5%)"), evaluate("call(lighten, blue, 5%)")
1485
- end
1486
- assert_equal evaluate("lighten(blue, 5%)"), evaluate("call(get-function(lighten), blue, 5%)")
1487
- end
1488
-
1489
- def test_call_with_keyword_arguments
1490
- # TODO: Remove this block in 4.0
1491
- Sass::Util.silence_sass_warnings do
1492
- assert_equal(
1493
- evaluate("lighten($color: blue, $amount: 5%)"),
1494
- evaluate("call(lighten, $color: blue, $amount: 5%)"))
1495
- end
1496
- assert_equal(
1497
- evaluate("lighten($color: blue, $amount: 5%)"),
1498
- evaluate("call(get-function(lighten), $color: blue, $amount: 5%)"))
1499
- end
1500
-
1501
- def test_call_with_keyword_and_positional_arguments
1502
- # TODO: Remove this block in 4.0
1503
- Sass::Util.silence_sass_warnings do
1504
- assert_equal(
1505
- evaluate("lighten(blue, $amount: 5%)"),
1506
- evaluate("call(lighten, blue, $amount: 5%)"))
1507
- end
1508
- assert_equal(
1509
- evaluate("lighten(blue, $amount: 5%)"),
1510
- evaluate("call(get-function(lighten), blue, $amount: 5%)"))
1511
- end
1512
-
1513
- def test_call_with_dynamic_name
1514
- # TODO: Remove this block in 4.0
1515
- Sass::Util.silence_sass_warnings do
1516
- assert_equal(
1517
- evaluate("lighten($color: blue, $amount: 5%)"),
1518
- evaluate("call($fn, $color: blue, $amount: 5%)",
1519
- env("fn" => Sass::Script::Value::String.new("lighten"))))
1520
- end
1521
- assert_equal(
1522
- evaluate("lighten($color: blue, $amount: 5%)"),
1523
- evaluate("call($fn, $color: blue, $amount: 5%)",
1524
- env("fn" => Sass::Script::Value::Function.new(
1525
- Sass::Callable.new("lighten", nil, nil, nil, nil, nil, "function", :builtin)))))
1526
- end
1527
-
1528
- # TODO: Remove this test in 4.0
1529
- def test_call_uses_local_scope
1530
- Sass::Util.silence_sass_warnings do
1531
- assert_equal <<CSS, render(<<SCSS)
1532
- .first-scope {
1533
- a: local; }
1534
-
1535
- .second-scope {
1536
- a: global; }
1537
- CSS
1538
- @function foo() {@return global}
1539
-
1540
- .first-scope {
1541
- @function foo() {@return local}
1542
- a: call(foo);
1543
- }
1544
-
1545
- .second-scope {
1546
- a: call(foo);
1547
- }
1548
- SCSS
1549
- end
1550
- end
1551
-
1552
- def test_call_unknown_function
1553
- # TODO: Remove this block in 4.0
1554
- Sass::Util.silence_sass_warnings do
1555
- assert_equal evaluate("unknown(red, blue)"), evaluate("call(unknown, red, blue)")
1556
- end
1557
- assert_equal evaluate("unknown(red, blue)"), evaluate("call(get-function(unknown, $css: true), red, blue)")
1558
- end
1559
-
1560
- def test_call_with_non_string_argument
1561
- assert_error_message "$function: 3px is not a function for `call'", "call(3px)"
1562
- end
1563
-
1564
- def test_errors_in_called_function
1565
- assert_error_message "$color: 3px is not a color for `lighten'",
1566
- "call(get-function(lighten), 3px, 5%)"
1567
- end
1568
-
1569
- def test_variable_exists
1570
- assert_equal <<CSS, render(<<SCSS)
1571
- .test {
1572
- false: false;
1573
- true: true;
1574
- true: true;
1575
- true: true;
1576
- true: true; }
1577
- CSS
1578
- $global-var: has-value;
1579
- .test {
1580
- false: variable-exists(foo);
1581
- $foo: has-value;
1582
- true: variable-exists(foo);
1583
- true: variable-exists($name: foo);
1584
- true: variable-exists(global-var);
1585
- true: variable-exists($name: global-var);
1586
- }
1587
- SCSS
1588
- end
1589
-
1590
- def test_variable_exists_checks_type
1591
- assert_error_message("$name: 1 is not a string for `variable-exists'", "variable-exists(1)")
1592
- end
1593
-
1594
- def test_global_variable_exists
1595
- assert_equal <<CSS, render(<<SCSS)
1596
- .test {
1597
- false: false;
1598
- false: false;
1599
- true: true;
1600
- true: true;
1601
- false: false;
1602
- true: true;
1603
- true: true; }
1604
- CSS
1605
- $g: something;
1606
- $h: null;
1607
- $false: global-variable-exists(foo);
1608
- $true: global-variable-exists(g);
1609
- $named: global-variable-exists($name: g);
1610
- .test {
1611
- $foo: locally-defined;
1612
- false: global-variable-exists(foo);
1613
- false: global-variable-exists(foo2);
1614
- true: global-variable-exists(g);
1615
- true: global-variable-exists(h);
1616
- false: $false;
1617
- true: $true;
1618
- true: $named;
1619
- }
1620
- SCSS
1621
- end
1622
-
1623
- def test_global_variable_exists_checks_type
1624
- assert_error_message("$name: 1 is not a string for `global-variable-exists'",
1625
- "global-variable-exists(1)")
1626
- end
1627
-
1628
- def test_function_exists
1629
- # built-ins
1630
- assert_equal "true", evaluate("function-exists(lighten)")
1631
- # with named argument
1632
- assert_equal "true", evaluate("function-exists($name: lighten)")
1633
- # user-defined
1634
- assert_equal <<CSS, render(<<SCSS)
1635
- .test {
1636
- foo-exists: true;
1637
- bar-exists: false; }
1638
- CSS
1639
- @function foo() { @return "foo" }
1640
- .test {
1641
- foo-exists: function-exists(foo);
1642
- bar-exists: function-exists(bar);
1643
- }
1644
- SCSS
1645
- end
1646
-
1647
- def test_function_exists_checks_type
1648
- assert_error_message("$name: 1 is not a string for `function-exists'", "function-exists(1)")
1649
- end
1650
-
1651
- def test_mixin_exists
1652
- assert_equal "false", evaluate("mixin-exists(foo)")
1653
- # with named argument
1654
- assert_equal "false", evaluate("mixin-exists($name: foo)")
1655
- assert_equal <<CSS, render(<<SCSS)
1656
- .test {
1657
- foo-exists: true;
1658
- bar-exists: false; }
1659
- CSS
1660
- @mixin foo() { foo: exists }
1661
- .test {
1662
- foo-exists: mixin-exists(foo);
1663
- bar-exists: mixin-exists(bar);
1664
- }
1665
- SCSS
1666
- end
1667
-
1668
- def test_mixin_exists_checks_type
1669
- assert_error_message("$name: 1 is not a string for `mixin-exists'", "mixin-exists(1)")
1670
- end
1671
-
1672
- def test_inspect
1673
- assert_equal "()", evaluate("inspect(())")
1674
- assert_equal "null", evaluate("inspect(null)")
1675
- assert_equal "1px null 3px", evaluate("inspect(1px null 3px)")
1676
- assert_equal "(a: 1, b: 2)", evaluate("inspect((a: 1, b: 2))")
1677
- assert_equal "(a: 1, b: (c: 2))", evaluate("inspect((a: 1, b: (c: 2)))")
1678
- assert_equal "(a: 1, b: (2, 3))", evaluate("inspect((a: 1, b: (2, 3)))")
1679
- assert_equal "(a: 1, b: 2 3)", evaluate("inspect((a: 1, b: 2 3))")
1680
- end
1681
-
1682
- def test_random
1683
- Sass::Script::Functions.random_seed = 1
1684
- assert_equal "0.4170220047", evaluate("random()")
1685
- assert_equal "13", evaluate("random(100)")
1686
- end
1687
-
1688
- def test_random_works_without_a_seed
1689
- if Sass::Script::Functions.instance_variable_defined?("@random_number_generator")
1690
- Sass::Script::Functions.send(:remove_instance_variable, "@random_number_generator")
1691
- end
1692
-
1693
- result = perform("random()")
1694
- assert_kind_of Sass::Script::Number, result
1695
- assert result.value >= 0, "Random number was below 0"
1696
- assert result.value <= 1, "Random number was above 1"
1697
- end
1698
-
1699
- def test_random_with_limit_one
1700
- # Passing 1 as the limit should always return 1, since limit calls return
1701
- # integers from 1 to the argument, so when the argument is 1, its a predicatble
1702
- # outcome
1703
- assert "1", evaluate("random(1)")
1704
- end
1705
-
1706
- def test_random_with_limit_too_low
1707
- assert_error_message("$limit 0 must be greater than or equal to 1 for `random'", "random(0)")
1708
- end
1709
-
1710
- def test_random_with_non_integer_limit
1711
- assert_error_message("Expected $limit to be an integer but got 1.5 for `random'", "random(1.5)")
1712
- end
1713
-
1714
- # Regression test for #1638.
1715
- def test_random_with_float_integer_limit
1716
- result = perform("random(1.0)")
1717
- assert_kind_of Sass::Script::Number, result
1718
- assert result.value >= 0, "Random number was below 0"
1719
- assert result.value <= 1, "Random number was above 1"
1720
- end
1721
-
1722
- # This could *possibly* fail, but exceedingly unlikely
1723
- def test_random_is_semi_unique
1724
- if Sass::Script::Functions.instance_variable_defined?("@random_number_generator")
1725
- Sass::Script::Functions.send(:remove_instance_variable, "@random_number_generator")
1726
- end
1727
- refute_equal evaluate("random()"), evaluate("random()")
1728
- end
1729
-
1730
- def test_deprecated_arg_names
1731
- assert_warning <<WARNING do
1732
- DEPRECATION WARNING: The `$arg-1' argument for `deprecated-arg-fn()' has been renamed to `$arg1'.
1733
- DEPRECATION WARNING: The `$arg-2' argument for `deprecated-arg-fn()' has been renamed to `$arg2'.
1734
- WARNING
1735
- assert_equal("1 2 3",
1736
- evaluate("deprecated-arg-fn($arg-1: 1, $arg-2: 2, $arg3: 3)"))
1737
- end
1738
-
1739
- assert_warning <<WARNING do
1740
- DEPRECATION WARNING: The `$arg-1' argument for `deprecated-arg-fn()' has been renamed to `$arg1'.
1741
- DEPRECATION WARNING: The `$arg-2' argument for `deprecated-arg-fn()' has been renamed to `$arg2'.
1742
- WARNING
1743
- assert_equal("1 2",
1744
- evaluate("deprecated-arg-fn($arg-1: 1, $arg-2: 2)"))
1745
- end
1746
-
1747
- assert_warning <<WARNING do
1748
- DEPRECATION WARNING: The `$arg_1' argument for `deprecated-arg-fn()' has been renamed to `$arg1'.
1749
- DEPRECATION WARNING: The `$arg_2' argument for `deprecated-arg-fn()' has been renamed to `$arg2'.
1750
- WARNING
1751
- assert_equal("1 2",
1752
- evaluate("deprecated-arg-fn($arg_1: 1, $arg_2: 2)"))
1753
- end
1754
- end
1755
-
1756
- def test_non_deprecated_arg_names
1757
- assert_equal("1 2 3", evaluate("deprecated-arg-fn($arg1: 1, $arg2: 2, $arg3: 3)"))
1758
- assert_equal("1 2", evaluate("deprecated-arg-fn($arg1: 1, $arg2: 2)"))
1759
- end
1760
-
1761
- ## Selector Functions
1762
-
1763
- def test_selector_argument_parsing
1764
- assert_equal("true", evaluate("selector-parse('.foo') == (join(('.foo',), (), space),)"))
1765
- assert_equal("true", evaluate("selector-parse('.foo .bar') == ('.foo' '.bar',)"))
1766
- assert_equal("true",
1767
- evaluate("selector-parse('.foo .bar, .baz .bang') == ('.foo' '.bar', '.baz' '.bang')"))
1768
-
1769
- assert_equal(".foo %bar", evaluate("selector-parse('.foo %bar')"))
1770
-
1771
- assert_equal("true",
1772
- evaluate("selector-parse(('.foo', '.bar')) == selector-parse('.foo, .bar')"))
1773
- assert_equal("true",
1774
- evaluate("selector-parse('.foo' '.bar') == selector-parse('.foo .bar')"))
1775
-
1776
- assert_equal("true", evaluate("selector-parse(('.foo' '.bar', '.baz' '.bang')) == " +
1777
- "selector-parse('.foo .bar, .baz .bang')"))
1778
- assert_equal("true", evaluate("selector-parse(('.foo .bar', '.baz .bang')) == " +
1779
- "selector-parse('.foo .bar, .baz .bang')"))
1780
-
1781
- # This may throw an error in the future.
1782
- assert_equal("true", evaluate("selector-parse(('.foo, .bar' '.baz, .bang')) == " +
1783
- "selector-parse('.foo, .bar .baz, .bang')"))
1784
- end
1785
-
1786
- def test_selector_argument_validation
1787
- assert_error_message("$selector: 12 is not a valid selector: it must be a string,\n" +
1788
- "a list of strings, or a list of lists of strings for `selector-parse'", "selector-parse(12)")
1789
- assert_error_message("$selector: (((\".foo\" \".bar\"), \".baz\") (\".bang\", \".qux\")) is not a valid selector: it must be a string,\n" +
1790
- "a list of strings, or a list of lists of strings for `selector-parse'",
1791
- "selector-parse(('.foo' '.bar', '.baz') ('.bang', '.qux'))")
1792
- assert_error_message("$selector: \".#\" is not a valid selector: Invalid CSS after \".\": " +
1793
- "expected class name, was \"#\" for `selector-parse'", "selector-parse('.#')")
1794
- assert_error_message("$selector: \"&.foo\" is not a valid selector: Invalid CSS after \"\": " +
1795
- "expected selector, was \"&.foo\" for `selector-parse'", "selector-parse('&.foo')")
1796
- end
1797
-
1798
- def test_selector_nest
1799
- assert_equal(".foo", evaluate("selector-nest('.foo')"))
1800
- assert_equal(".foo .bar", evaluate("selector-nest('.foo', '.bar')"))
1801
- assert_equal(".foo .bar .baz", evaluate("selector-nest('.foo', '.bar', '.baz')"))
1802
- assert_equal(".a .foo .b .bar", evaluate("selector-nest('.a .foo', '.b .bar')"))
1803
- assert_equal(".foo.bar", evaluate("selector-nest('.foo', '&.bar')"))
1804
- assert_equal(".baz .foo.bar", evaluate("selector-nest('.foo', '&.bar', '.baz &')"))
1805
- end
1806
-
1807
- def test_selector_nest_checks_types
1808
- assert_error_message("$selectors: 12 is not a valid selector: it must be a string,\n" +
1809
- "a list of strings, or a list of lists of strings for `selector-nest'",
1810
- "selector-nest(12)")
1811
- assert_error_message("$selectors: 12 is not a valid selector: it must be a string,\n" +
1812
- "a list of strings, or a list of lists of strings for `selector-nest'",
1813
- "selector-nest('.foo', 12)")
1814
- end
1815
-
1816
- def test_selector_nest_argument_validation
1817
- assert_error_message("$selectors: At least one selector must be passed for `selector-nest'",
1818
- "selector-nest()")
1819
- end
1820
-
1821
- def test_selector_append
1822
- assert_equal(".foo.bar", evaluate("selector-append('.foo', '.bar')"))
1823
- assert_equal(".a .foo.b .bar", evaluate("selector-append('.a .foo', '.b .bar')"))
1824
- assert_equal(".foo-suffix", evaluate("selector-append('.foo', '-suffix')"))
1825
- assert_equal(".foo.bar, .foo-suffix", evaluate("selector-append('.foo', '.bar, -suffix')"))
1826
- assert_equal(".foo--suffix", evaluate("selector-append('.foo', '--suffix')"))
1827
- assert_equal(".foo.bar, .foo--suffix", evaluate("selector-append('.foo', '.bar, --suffix')"))
1828
- end
1829
-
1830
- def test_selector_append_checks_types
1831
- assert_error_message("$selectors: 12 is not a valid selector: it must be a string,\n" +
1832
- "a list of strings, or a list of lists of strings for `selector-append'",
1833
- "selector-append(12)")
1834
- assert_error_message("$selectors: 12 is not a valid selector: it must be a string,\n" +
1835
- "a list of strings, or a list of lists of strings for `selector-append'",
1836
- "selector-append('.foo', 12)")
1837
- end
1838
-
1839
- def test_selector_append_errors
1840
- assert_error_message("$selectors: At least one selector must be passed for `selector-append'",
1841
- "selector-append()")
1842
- assert_error_message("Can't append \"> .bar\" to \".foo\" for `selector-append'",
1843
- "selector-append('.foo', '> .bar')")
1844
- assert_error_message("Can't append \"*.bar\" to \".foo\" for `selector-append'",
1845
- "selector-append('.foo', '*.bar')")
1846
- assert_error_message("Can't append \"ns|suffix\" to \".foo\" for `selector-append'",
1847
- "selector-append('.foo', 'ns|suffix')")
1848
- end
1849
-
1850
- def test_selector_extend
1851
- assert_equal(".foo .x, .foo .a .bar, .a .foo .bar",
1852
- evaluate("selector-extend('.foo .x', '.x', '.a .bar')"))
1853
- assert_equal(".foo .x, .foo .bang, .x.bar, .bar.bang",
1854
- evaluate("selector-extend('.foo .x, .x.bar', '.x', '.bang')"))
1855
- assert_equal(".y .x, .foo .x, .y .foo, .foo .foo",
1856
- evaluate("selector-extend('.y .x', '.x, .y', '.foo')"))
1857
- assert_equal(".foo .x, .foo .bar, .foo .bang",
1858
- evaluate("selector-extend('.foo .x', '.x', '.bar, .bang')"))
1859
- assert_equal(".foo.x, .foo",
1860
- evaluate("selector-extend('.foo.x', '.x', '.foo')"))
1861
- end
1862
-
1863
- def test_selector_extend_checks_types
1864
- assert_error_message("$selector: 12 is not a valid selector: it must be a string,\n" +
1865
- "a list of strings, or a list of lists of strings for `selector-extend'",
1866
- "selector-extend(12, '.foo', '.bar')")
1867
- assert_error_message("$extendee: 12 is not a valid selector: it must be a string,\n" +
1868
- "a list of strings, or a list of lists of strings for `selector-extend'",
1869
- "selector-extend('.foo', 12, '.bar')")
1870
- assert_error_message("$extender: 12 is not a valid selector: it must be a string,\n" +
1871
- "a list of strings, or a list of lists of strings for `selector-extend'",
1872
- "selector-extend('.foo', '.bar', 12)")
1873
- end
1874
-
1875
- def test_selector_extend_errors
1876
- assert_error_message("Can't extend .bar .baz: can't extend nested selectors for " +
1877
- "`selector-extend'", "selector-extend('.foo', '.bar .baz', '.bang')")
1878
- assert_error_message("Can't extend >: invalid selector for `selector-extend'",
1879
- "selector-extend('.foo', '>', '.bang')")
1880
- assert_error_message(".bang > can't extend: invalid selector for `selector-extend'",
1881
- "selector-extend('.foo', '.bar', '.bang >')")
1882
- end
1883
-
1884
- def test_selector_replace
1885
- assert_equal(".bar", evaluate("selector-replace('.foo', '.foo', '.bar')"))
1886
- assert_equal(".foo.baz", evaluate("selector-replace('.foo.bar', '.bar', '.baz')"))
1887
- assert_equal(".a .foo.baz", evaluate("selector-replace('.foo.bar', '.bar', '.a .baz')"))
1888
-
1889
- # These shouldn't warn since we still support componud targets for selector
1890
- # functions.
1891
- assert_no_warning {assert_equal(".foo.bar", evaluate("selector-replace('.foo.bar', '.baz.bar', '.qux')"))}
1892
- assert_no_warning {assert_equal(".bar.qux", evaluate("selector-replace('.foo.bar.baz', '.foo.baz', '.qux')"))}
1893
-
1894
- assert_equal(":not(.bar)", evaluate("selector-replace(':not(.foo)', '.foo', '.bar')"))
1895
- assert_equal(".bar", evaluate("selector-replace(':not(.foo)', ':not(.foo)', '.bar')"))
1896
- end
1897
-
1898
- def test_selector_replace_checks_types
1899
- assert_error_message("$selector: 12 is not a valid selector: it must be a string,\n" +
1900
- "a list of strings, or a list of lists of strings for `selector-replace'",
1901
- "selector-replace(12, '.foo', '.bar')")
1902
- assert_error_message("$original: 12 is not a valid selector: it must be a string,\n" +
1903
- "a list of strings, or a list of lists of strings for `selector-replace'",
1904
- "selector-replace('.foo', 12, '.bar')")
1905
- assert_error_message("$replacement: 12 is not a valid selector: it must be a string,\n" +
1906
- "a list of strings, or a list of lists of strings for `selector-replace'",
1907
- "selector-replace('.foo', '.bar', 12)")
1908
- end
1909
-
1910
- def test_selector_replace_errors
1911
- assert_error_message("Can't extend .bar .baz: can't extend nested selectors for " +
1912
- "`selector-replace'", "selector-replace('.foo', '.bar .baz', '.bang')")
1913
- assert_error_message("Can't extend >: invalid selector for `selector-replace'",
1914
- "selector-replace('.foo', '>', '.bang')")
1915
- assert_error_message(".bang > can't extend: invalid selector for `selector-replace'",
1916
- "selector-replace('.foo', '.bar', '.bang >')")
1917
- end
1918
-
1919
- def test_selector_unify
1920
- assert_equal(".foo", evaluate("selector-unify('.foo', '.foo')"))
1921
- assert_equal(".foo.bar", evaluate("selector-unify('.foo', '.bar')"))
1922
- assert_equal(".foo.bar.baz", evaluate("selector-unify('.foo.bar', '.bar.baz')"))
1923
- assert_equal(".a .b .foo.bar, .b .a .foo.bar", evaluate("selector-unify('.a .foo', '.b .bar')"))
1924
- assert_equal(".a .foo.bar", evaluate("selector-unify('.a .foo', '.a .bar')"))
1925
- assert_equal("", evaluate("selector-unify('p', 'a')"))
1926
- assert_equal("", evaluate("selector-unify('.foo >', '.bar')"))
1927
- assert_equal("", evaluate("selector-unify('.foo', '.bar >')"))
1928
- assert_equal(".foo.baz, .foo.bang, .bar.baz, .bar.bang",
1929
- evaluate("selector-unify('.foo, .bar', '.baz, .bang')"))
1930
- end
1931
-
1932
- def test_selector_unify_checks_types
1933
- assert_error_message("$selector1: 12 is not a valid selector: it must be a string,\n" +
1934
- "a list of strings, or a list of lists of strings for `selector-unify'",
1935
- "selector-unify(12, '.foo')")
1936
- assert_error_message("$selector2: 12 is not a valid selector: it must be a string,\n" +
1937
- "a list of strings, or a list of lists of strings for `selector-unify'",
1938
- "selector-unify('.foo', 12)")
1939
- end
1940
-
1941
- def test_simple_selectors
1942
- assert_equal('(.foo,)', evaluate("inspect(simple-selectors('.foo'))"))
1943
- assert_equal('.foo, .bar', evaluate("inspect(simple-selectors('.foo.bar'))"))
1944
- assert_equal('.foo, .bar, :pseudo("flip, flap")',
1945
- evaluate("inspect(simple-selectors('.foo.bar:pseudo(\"flip, flap\")'))"))
1946
- end
1947
-
1948
- def test_simple_selectors_checks_types
1949
- assert_error_message("$selector: 12 is not a string for `simple-selectors'",
1950
- "simple-selectors(12)")
1951
- end
1952
-
1953
- def test_simple_selectors_errors
1954
- assert_error_message("$selector: \".foo .bar\" is not a compound selector for `simple-selectors'",
1955
- "simple-selectors('.foo .bar')")
1956
- assert_error_message("$selector: \".foo,.bar\" is not a compound selector for `simple-selectors'",
1957
- "simple-selectors('.foo,.bar')")
1958
- assert_error_message("$selector: \".#\" is not a valid selector: Invalid CSS after \".\": " +
1959
- "expected class name, was \"#\" for `simple-selectors'", "simple-selectors('.#')")
1960
- end
1961
-
1962
- def test_is_superselector
1963
- assert_equal("true", evaluate("is-superselector('.foo', '.foo.bar')"))
1964
- assert_equal("false", evaluate("is-superselector('.foo.bar', '.foo')"))
1965
- assert_equal("true", evaluate("is-superselector('.foo', '.foo')"))
1966
- assert_equal("true", evaluate("is-superselector('.bar', '.foo .bar')"))
1967
- assert_equal("false", evaluate("is-superselector('.foo .bar', '.bar')"))
1968
- assert_equal("true", evaluate("is-superselector('.foo .bar', '.foo > .bar')"))
1969
- assert_equal("false", evaluate("is-superselector('.foo > .bar', '.foo .bar')"))
1970
- end
1971
-
1972
- def test_is_superselector_checks_types
1973
- assert_error_message("$super: 12 is not a valid selector: it must be a string,\n" +
1974
- "a list of strings, or a list of lists of strings for `is-superselector'",
1975
- "is-superselector(12, '.foo')")
1976
- assert_error_message("$sub: 12 is not a valid selector: it must be a string,\n" +
1977
- "a list of strings, or a list of lists of strings for `is-superselector'",
1978
- "is-superselector('.foo', 12)")
1979
- end
1980
-
1981
- ## Regression Tests
1982
-
1983
- def test_inspect_nested_empty_lists
1984
- assert_equal "() ()", evaluate("inspect(() ())")
1985
- end
1986
-
1987
- def test_saturation_bounds
1988
- assert_equal "#fbfdff", evaluate("hsl(hue(#fbfdff), saturation(#fbfdff), lightness(#fbfdff))")
1989
- end
1990
-
1991
- private
1992
- def env(hash = {}, parent = nil)
1993
- env = Sass::Environment.new(parent)
1994
- hash.each {|k, v| env.set_var(k, v)}
1995
- env
1996
- end
1997
-
1998
- def evaluate(value, environment = env)
1999
- result = perform(value, environment)
2000
- assert_kind_of Sass::Script::Value::Base, result
2001
- return result.to_s
2002
- end
2003
-
2004
- def perform(value, environment = env)
2005
- Sass::Script::Parser.parse(value, 1, 0, {:filename => "#{test_name}_inline.scss"}).perform(environment)
2006
- end
2007
-
2008
- def render(sass, options = {})
2009
- options[:syntax] ||= :scss
2010
- munge_filename options
2011
- options[:importer] ||= MockImporter.new
2012
- Sass::Engine.new(sass, options).render
2013
- end
2014
-
2015
- def assert_error_message(message, value)
2016
- evaluate(value)
2017
- flunk("Error message expected but not raised: #{message}")
2018
- rescue Sass::SyntaxError => e
2019
- assert_equal(message, e.message)
2020
- end
2021
- end