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