sass 3.1.0.alpha.15 → 3.1.0.alpha.16
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.
- data/EDGE_GEM_VERSION +1 -1
- data/VERSION +1 -1
- data/lib/sass/engine.rb +2 -2
- data/lib/sass/script/funcall.rb +49 -8
- data/lib/sass/script/functions.rb +189 -57
- data/lib/sass/script/node.rb +7 -1
- data/lib/sass/script/parser.rb +52 -17
- data/lib/sass/script/variable.rb +6 -0
- data/lib/sass/scss/parser.rb +2 -2
- data/lib/sass/tree/mixin_node.rb +25 -5
- data/test/sass/conversion_test.rb +14 -0
- data/test/sass/engine_test.rb +75 -0
- data/test/sass/functions_test.rb +87 -0
- data/test/sass/script_conversion_test.rb +5 -0
- data/test/sass/scss/scss_test.rb +63 -0
- metadata +2 -2
data/lib/sass/script/node.rb
CHANGED
@@ -32,7 +32,13 @@ module Sass::Script
|
|
32
32
|
# @param options [{Symbol => Object}] The options
|
33
33
|
def options=(options)
|
34
34
|
@options = options
|
35
|
-
children.each
|
35
|
+
children.each do |c|
|
36
|
+
if c.is_a? Hash
|
37
|
+
c.values.each {|v| v.options = options }
|
38
|
+
else
|
39
|
+
c.options = options
|
40
|
+
end
|
41
|
+
end
|
36
42
|
end
|
37
43
|
|
38
44
|
# Sets the context for this node,
|
data/lib/sass/script/parser.rb
CHANGED
@@ -74,19 +74,21 @@ module Sass
|
|
74
74
|
|
75
75
|
# Parses the argument list for a mixin include.
|
76
76
|
#
|
77
|
-
# @return [Array<Script::Node
|
77
|
+
# @return [(Array<Script::Node>, {String => Script::Note})]
|
78
|
+
# The root nodes of the arguments.
|
79
|
+
# Keyword arguments are in a hash from names to values.
|
78
80
|
# @raise [Sass::SyntaxError] if the argument list isn't valid SassScript
|
79
81
|
def parse_mixin_include_arglist
|
80
|
-
args = []
|
81
|
-
|
82
|
+
args, keywords = [], {}
|
82
83
|
if try_tok(:lparen)
|
83
|
-
args =
|
84
|
+
args, keywords = mixin_arglist || [[], {}]
|
84
85
|
assert_tok(:rparen)
|
85
86
|
end
|
86
87
|
assert_done
|
87
88
|
|
88
89
|
args.each {|a| a.options = @options}
|
89
|
-
|
90
|
+
keywords.each {|k, v| v.options = @options}
|
91
|
+
return args, keywords
|
90
92
|
rescue Sass::SyntaxError => e
|
91
93
|
e.modify_backtrace :line => @lexer.line, :filename => @options[:filename]
|
92
94
|
raise e
|
@@ -254,9 +256,9 @@ RUBY
|
|
254
256
|
|
255
257
|
def funcall
|
256
258
|
return raw unless tok = try_tok(:funcall)
|
257
|
-
args = fn_arglist || []
|
259
|
+
args, keywords = fn_arglist || [[], {}]
|
258
260
|
assert_tok(:rparen)
|
259
|
-
node(Script::Funcall.new(tok.value, args))
|
261
|
+
node(Script::Funcall.new(tok.value, args, keywords))
|
260
262
|
end
|
261
263
|
|
262
264
|
def defn_arglist!(must_have_default)
|
@@ -289,15 +291,48 @@ RUBY
|
|
289
291
|
end
|
290
292
|
|
291
293
|
def fn_arglist
|
292
|
-
|
293
|
-
|
294
|
-
|
294
|
+
arglist(:fn_arglist, :equals)
|
295
|
+
end
|
296
|
+
|
297
|
+
def mixin_arglist
|
298
|
+
arglist(:mixin_arglist, :interpolation)
|
299
|
+
end
|
300
|
+
|
301
|
+
def arglist(type, subexpr)
|
302
|
+
return unless e = send(subexpr)
|
303
|
+
if @lexer.peek && @lexer.peek.type == :colon
|
304
|
+
name = e
|
305
|
+
@lexer.expected!("comma") unless name.is_a?(Variable)
|
306
|
+
assert_tok(:colon)
|
307
|
+
keywords = {name.underscored_name => assert_expr(subexpr, EXPR_NAMES[type])}
|
308
|
+
end
|
309
|
+
|
310
|
+
unless try_tok(:comma)
|
311
|
+
return [], keywords if keywords
|
312
|
+
return [e], {}
|
313
|
+
end
|
314
|
+
|
315
|
+
other_args, other_keywords = assert_expr(type)
|
316
|
+
if keywords
|
317
|
+
if other_keywords[name.underscored_name]
|
318
|
+
raise SyntaxError.new("Keyword argument \"#{name.to_sass}\" passed more than once")
|
319
|
+
end
|
320
|
+
return other_args, keywords.merge(other_keywords)
|
321
|
+
else
|
322
|
+
return [e, *other_args], other_keywords
|
323
|
+
end
|
295
324
|
end
|
296
325
|
|
297
|
-
def
|
298
|
-
return unless
|
299
|
-
|
300
|
-
|
326
|
+
def keyword_arglist
|
327
|
+
return unless var = try_tok(:const)
|
328
|
+
unless try_tok(:colon)
|
329
|
+
return_tok!
|
330
|
+
return
|
331
|
+
end
|
332
|
+
name = var[1]
|
333
|
+
value = interpolation
|
334
|
+
return {name => value} unless try_tok(:comma)
|
335
|
+
{name => value}.merge(assert_expr(:keyword_arglist))
|
301
336
|
end
|
302
337
|
|
303
338
|
def raw
|
@@ -359,13 +394,13 @@ RUBY
|
|
359
394
|
EXPR_NAMES = {
|
360
395
|
:string => "string",
|
361
396
|
:default => "expression (e.g. 1px, bold)",
|
362
|
-
:
|
397
|
+
:mixin_arglist => "mixin argument",
|
363
398
|
:fn_arglist => "function argument",
|
364
399
|
}
|
365
400
|
|
366
|
-
def assert_expr(name)
|
401
|
+
def assert_expr(name, expected = nil)
|
367
402
|
(e = send(name)) && (return e)
|
368
|
-
@lexer.expected!(EXPR_NAMES[name] || EXPR_NAMES[:default])
|
403
|
+
@lexer.expected!(expected || EXPR_NAMES[name] || EXPR_NAMES[:default])
|
369
404
|
end
|
370
405
|
|
371
406
|
def assert_tok(*names)
|
data/lib/sass/script/variable.rb
CHANGED
@@ -7,9 +7,15 @@ module Sass
|
|
7
7
|
# @return [String]
|
8
8
|
attr_reader :name
|
9
9
|
|
10
|
+
# The underscored name of the variable.
|
11
|
+
#
|
12
|
+
# @return [String]
|
13
|
+
attr_reader :underscored_name
|
14
|
+
|
10
15
|
# @param name [String] See \{#name}
|
11
16
|
def initialize(name)
|
12
17
|
@name = name
|
18
|
+
@underscored_name = name.gsub(/-/,"_")
|
13
19
|
super()
|
14
20
|
end
|
15
21
|
|
data/lib/sass/scss/parser.rb
CHANGED
@@ -138,9 +138,9 @@ module Sass
|
|
138
138
|
|
139
139
|
def include_directive
|
140
140
|
name = tok! IDENT
|
141
|
-
args = sass_script(:parse_mixin_include_arglist)
|
141
|
+
args, keywords = sass_script(:parse_mixin_include_arglist)
|
142
142
|
ss
|
143
|
-
node(Sass::Tree::MixinNode.new(name, args))
|
143
|
+
node(Sass::Tree::MixinNode.new(name, args, keywords))
|
144
144
|
end
|
145
145
|
|
146
146
|
def debug_directive
|
data/lib/sass/tree/mixin_node.rb
CHANGED
@@ -11,13 +11,16 @@ module Sass::Tree
|
|
11
11
|
def options=(opts)
|
12
12
|
super
|
13
13
|
@args.each {|a| a.context = :equals} if opts[:sass2]
|
14
|
+
@keywords.each {|k, v| v.context = :equals} if opts[:sass2]
|
14
15
|
end
|
15
16
|
|
16
17
|
# @param name [String] The name of the mixin
|
17
18
|
# @param args [Array<Script::Node>] The arguments to the mixin
|
18
|
-
|
19
|
+
# @param keywords [{String => Script::Node}] A hash from keyword argument names to values
|
20
|
+
def initialize(name, args, keywords)
|
19
21
|
@name = name
|
20
22
|
@args = args
|
23
|
+
@keywords = keywords
|
21
24
|
super()
|
22
25
|
end
|
23
26
|
|
@@ -42,8 +45,12 @@ module Sass::Tree
|
|
42
45
|
|
43
46
|
# @see Node#to_src
|
44
47
|
def to_src(tabs, opts, fmt)
|
45
|
-
|
46
|
-
|
48
|
+
unless @args.empty? && @keywords.empty?
|
49
|
+
args = @args.map {|a| a.to_sass(opts)}.join(", ")
|
50
|
+
keywords = @keywords.map {|k, v| "$#{dasherize(k, opts)}: #{v.to_sass(opts)}"}.join(', ')
|
51
|
+
arglist = "(#{args}#{', ' unless args.empty? || keywords.empty?}#{keywords})"
|
52
|
+
end
|
53
|
+
"#{' ' * tabs}#{fmt == :sass ? '+' : '@include '}#{dasherize(@name, opts)}#{arglist}#{semi fmt}\n"
|
47
54
|
end
|
48
55
|
|
49
56
|
# @see Node#_cssize
|
@@ -73,15 +80,28 @@ module Sass::Tree
|
|
73
80
|
original_env.prepare_frame(:mixin => @name)
|
74
81
|
raise Sass::SyntaxError.new("Undefined mixin '#{@name}'.") unless mixin = environment.mixin(@name)
|
75
82
|
|
76
|
-
|
83
|
+
passed_args = @args.dup
|
84
|
+
passed_keywords = @keywords.dup
|
85
|
+
|
86
|
+
raise Sass::SyntaxError.new(<<END.gsub("\n", "")) if mixin.args.size < passed_args.size
|
77
87
|
Mixin #{@name} takes #{mixin.args.size} argument#{'s' if mixin.args.size != 1}
|
78
88
|
but #{@args.size} #{@args.size == 1 ? 'was' : 'were'} passed.
|
79
89
|
END
|
80
|
-
|
90
|
+
|
91
|
+
passed_keywords.each do |name, value|
|
92
|
+
# TODO: Make this fast
|
93
|
+
unless mixin.args.find {|(var, default)| var.underscored_name == name}
|
94
|
+
raise Sass::SyntaxError.new("Mixin #{@name} doesn't have an argument named $#{name}")
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
environment = mixin.args.zip(passed_args).
|
81
99
|
inject(Sass::Environment.new(mixin.environment)) do |env, ((var, default), value)|
|
82
100
|
env.set_local_var(var.name,
|
83
101
|
if value
|
84
102
|
value.perform(environment)
|
103
|
+
elsif kv = passed_keywords[var.underscored_name]
|
104
|
+
kv.perform(env)
|
85
105
|
elsif default
|
86
106
|
val = default.perform(env)
|
87
107
|
if default.context == :equals && val.is_a?(Sass::Script::String)
|
@@ -859,6 +859,20 @@ foo {
|
|
859
859
|
SCSS
|
860
860
|
end
|
861
861
|
|
862
|
+
def test_mixin_include_with_keyword_args
|
863
|
+
assert_renders <<SASS, <<SCSS
|
864
|
+
foo
|
865
|
+
+foo-bar(12px, "blaz", $blip: blap, $bloop: blop)
|
866
|
+
+foo-bar($blip: blap, $bloop: blop)
|
867
|
+
a: blip
|
868
|
+
SASS
|
869
|
+
foo {
|
870
|
+
@include foo-bar(12px, "blaz", $blip: blap, $bloop: blop);
|
871
|
+
@include foo-bar($blip: blap, $bloop: blop);
|
872
|
+
a: blip; }
|
873
|
+
SCSS
|
874
|
+
end
|
875
|
+
|
862
876
|
def test_variable_definition
|
863
877
|
assert_renders <<SASS, <<SCSS
|
864
878
|
$var1: 12px + 15px
|
data/test/sass/engine_test.rb
CHANGED
@@ -94,6 +94,7 @@ MSG
|
|
94
94
|
"a-\#{$b\n c: d" => ['Invalid CSS after "a-#{$b": expected "}", was ""', 1],
|
95
95
|
"=a($b = 1, $c)" => "Required argument $c must come before any optional arguments.",
|
96
96
|
"=a($b = 1)\n a: $b\ndiv\n +a(1,2)" => "Mixin a takes 1 argument but 2 were passed.",
|
97
|
+
"=a($b: 1)\n a: $b\ndiv\n +a(1,$c: 3)" => "Mixin a doesn't have an argument named $c",
|
97
98
|
"=a($b)\n a: $b\ndiv\n +a" => "Mixin a is missing parameter $b.",
|
98
99
|
"@else\n a\n b: c" => ["@else must come after @if.", 1],
|
99
100
|
"@if false\n@else foo" => "Invalid else directive '@else foo': expected 'if <expr>'.",
|
@@ -115,6 +116,16 @@ MSG
|
|
115
116
|
'@warn' => "Invalid warn directive '@warn': expected expression.",
|
116
117
|
%Q{@warn "a message"\n "nested message"} => "Illegal nesting: Nothing may be nested beneath warn directives.",
|
117
118
|
"/* foo\n bar\n baz" => "Inconsistent indentation: previous line was indented by 4 spaces, but this line was indented by 2 spaces.",
|
119
|
+
'+foo(1 + 1: 2)' => 'Invalid CSS after "(1 + 1": expected comma, was ": 2)"',
|
120
|
+
'+foo($var: )' => 'Invalid CSS after "($var: ": expected mixin argument, was ")"',
|
121
|
+
'+foo($var: a, $var: b)' => 'Keyword argument "$var" passed more than once',
|
122
|
+
'+foo($var-var: a, $var_var: b)' => 'Keyword argument "$var-var" passed more than once',
|
123
|
+
'+foo($var_var: a, $var-var: b)' => 'Keyword argument "$var_var" passed more than once',
|
124
|
+
"a\n b: foo(1 + 1: 2)" => 'Invalid CSS after "foo(1 + 1": expected comma, was ": 2)"',
|
125
|
+
"a\n b: foo($var: )" => 'Invalid CSS after "foo($var: ": expected function argument, was ")"',
|
126
|
+
"a\n b: foo($var: a, $var: b)" => 'Keyword argument "$var" passed more than once',
|
127
|
+
"a\n b: foo($var-var: a, $var_var: b)" => 'Keyword argument "$var-var" passed more than once',
|
128
|
+
"a\n b: foo($var_var: a, $var-var: b)" => 'Keyword argument "$var_var" passed more than once',
|
118
129
|
|
119
130
|
# Regression tests
|
120
131
|
"a\n b:\n c\n d" => ["Illegal nesting: Only properties may be nested beneath properties.", 3],
|
@@ -2101,6 +2112,70 @@ CSS
|
|
2101
2112
|
SASS
|
2102
2113
|
end
|
2103
2114
|
|
2115
|
+
def test_mixin_with_keyword_args
|
2116
|
+
assert_equal <<CSS, render(<<SASS)
|
2117
|
+
.mixed {
|
2118
|
+
required: foo;
|
2119
|
+
arg1: default-val1;
|
2120
|
+
arg2: non-default-val2; }
|
2121
|
+
CSS
|
2122
|
+
=a-mixin($required, $arg1: default-val1, $arg2: default-val2)
|
2123
|
+
required: $required
|
2124
|
+
arg1: $arg1
|
2125
|
+
arg2: $arg2
|
2126
|
+
.mixed
|
2127
|
+
+a-mixin(foo, $arg2: non-default-val2)
|
2128
|
+
SASS
|
2129
|
+
end
|
2130
|
+
|
2131
|
+
def test_mixin_keyword_args_handle_variable_underscore_dash_equivalence
|
2132
|
+
assert_equal <<CSS, render(<<SASS)
|
2133
|
+
.mixed {
|
2134
|
+
required: foo;
|
2135
|
+
arg1: non-default-val1;
|
2136
|
+
arg2: non-default-val2; }
|
2137
|
+
CSS
|
2138
|
+
=a-mixin($required, $arg-1: default-val1, $arg_2: default-val2)
|
2139
|
+
required: $required
|
2140
|
+
arg1: $arg_1
|
2141
|
+
arg2: $arg-2
|
2142
|
+
.mixed
|
2143
|
+
+a-mixin(foo, $arg-2: non-default-val2, $arg_1: non-default-val1)
|
2144
|
+
SASS
|
2145
|
+
end
|
2146
|
+
|
2147
|
+
def test_passing_required_args_as_a_keyword_arg
|
2148
|
+
assert_equal <<CSS, render(<<SASS)
|
2149
|
+
.mixed {
|
2150
|
+
required: foo;
|
2151
|
+
arg1: default-val1;
|
2152
|
+
arg2: default-val2; }
|
2153
|
+
CSS
|
2154
|
+
=a-mixin($required, $arg1: default-val1, $arg2: default-val2)
|
2155
|
+
required: $required
|
2156
|
+
arg1: $arg1
|
2157
|
+
arg2: $arg2
|
2158
|
+
.mixed
|
2159
|
+
+a-mixin($required: foo)
|
2160
|
+
SASS
|
2161
|
+
end
|
2162
|
+
|
2163
|
+
def test_passing_all_as_keyword_args_in_opposite_order
|
2164
|
+
assert_equal <<CSS, render(<<SASS)
|
2165
|
+
.mixed {
|
2166
|
+
required: foo;
|
2167
|
+
arg1: non-default-val1;
|
2168
|
+
arg2: non-default-val2; }
|
2169
|
+
CSS
|
2170
|
+
=a-mixin($required, $arg1: default-val1, $arg2: default-val2)
|
2171
|
+
required: $required
|
2172
|
+
arg1: $arg1
|
2173
|
+
arg2: $arg2
|
2174
|
+
.mixed
|
2175
|
+
+a-mixin($arg2: non-default-val2, $arg1: non-default-val1, $required: foo)
|
2176
|
+
SASS
|
2177
|
+
end
|
2178
|
+
|
2104
2179
|
def test_function_output_with_comma
|
2105
2180
|
assert_equal <<CSS, render(<<SASS)
|
2106
2181
|
foo {
|
data/test/sass/functions_test.rb
CHANGED
@@ -3,6 +3,22 @@ require 'test/unit'
|
|
3
3
|
require File.dirname(__FILE__) + '/../test_helper'
|
4
4
|
require 'sass/script'
|
5
5
|
|
6
|
+
module Sass::Script::Functions
|
7
|
+
def no_kw_args
|
8
|
+
Sass::Script::String.new("no-kw-args")
|
9
|
+
end
|
10
|
+
|
11
|
+
def only_var_args(*args)
|
12
|
+
Sass::Script::String.new("only-var-args("+args.map{|a| a.plus(Sass::Script::Number.new(1)).to_s }.join(", ")+")")
|
13
|
+
end
|
14
|
+
declare :only_var_args, [], :var_args => true
|
15
|
+
|
16
|
+
def only_kw_args(kwargs)
|
17
|
+
Sass::Script::String.new("only-kw-args("+kwargs.keys.join(", ")+")")
|
18
|
+
end
|
19
|
+
declare :only_kw_args, [], :var_kwargs => true
|
20
|
+
end
|
21
|
+
|
6
22
|
module Sass::Script::Functions::UserFunctions
|
7
23
|
def call_options_on_new_literal
|
8
24
|
str = Sass::Script::String.new("foo")
|
@@ -50,6 +66,10 @@ class SassFunctionTest < Test::Unit::TestCase
|
|
50
66
|
end
|
51
67
|
end
|
52
68
|
|
69
|
+
def test_hsl_kwargs
|
70
|
+
assert_equal "#33cccc", evaluate("hsl($hue: 180, $saturation: 60%, $lightness: 50%)")
|
71
|
+
end
|
72
|
+
|
53
73
|
def test_hsl_checks_bounds
|
54
74
|
assert_error_message("Saturation -114 must be between 0% and 100% for `hsl'", "hsl(10, -114, 12)");
|
55
75
|
assert_error_message("Lightness 256 must be between 0% and 100% for `hsl'", "hsl(10, 10, 256%)");
|
@@ -65,6 +85,7 @@ class SassFunctionTest < Test::Unit::TestCase
|
|
65
85
|
assert_equal "rgba(51, 204, 204, 0.4)", evaluate("hsla(180, 60%, 50%, 0.4)")
|
66
86
|
assert_equal "#33cccc", evaluate("hsla(180, 60%, 50%, 1)")
|
67
87
|
assert_equal "rgba(51, 204, 204, 0)", evaluate("hsla(180, 60%, 50%, 0)")
|
88
|
+
assert_equal "rgba(51, 204, 204, 0.4)", evaluate("hsla($hue: 180, $saturation: 60%, $lightness: 50%, $alpha: 0.4)")
|
68
89
|
end
|
69
90
|
|
70
91
|
def test_hsla_checks_bounds
|
@@ -85,6 +106,7 @@ class SassFunctionTest < Test::Unit::TestCase
|
|
85
106
|
assert_equal("50%", evaluate("percentage(.5)"))
|
86
107
|
assert_equal("100%", evaluate("percentage(1)"))
|
87
108
|
assert_equal("25%", evaluate("percentage(25px / 100px)"))
|
109
|
+
assert_equal("50%", evaluate("percentage($value: 0.5)"))
|
88
110
|
end
|
89
111
|
|
90
112
|
def test_percentage_checks_types
|
@@ -97,6 +119,7 @@ class SassFunctionTest < Test::Unit::TestCase
|
|
97
119
|
assert_equal("5", evaluate("round(4.8)"))
|
98
120
|
assert_equal("5px", evaluate("round(4.8px)"))
|
99
121
|
assert_equal("5px", evaluate("round(5.49px)"))
|
122
|
+
assert_equal("5px", evaluate("round($value: 5.49px)"))
|
100
123
|
|
101
124
|
assert_error_message("#cccccc is not a number for `round'", "round(#ccc)")
|
102
125
|
end
|
@@ -104,6 +127,7 @@ class SassFunctionTest < Test::Unit::TestCase
|
|
104
127
|
def test_floor
|
105
128
|
assert_equal("4", evaluate("floor(4.8)"))
|
106
129
|
assert_equal("4px", evaluate("floor(4.8px)"))
|
130
|
+
assert_equal("4px", evaluate("floor($value: 4.8px)"))
|
107
131
|
|
108
132
|
assert_error_message("\"foo\" is not a number for `floor'", "floor(\"foo\")")
|
109
133
|
end
|
@@ -111,6 +135,7 @@ class SassFunctionTest < Test::Unit::TestCase
|
|
111
135
|
def test_ceil
|
112
136
|
assert_equal("5", evaluate("ceil(4.1)"))
|
113
137
|
assert_equal("5px", evaluate("ceil(4.8px)"))
|
138
|
+
assert_equal("5px", evaluate("ceil($value: 4.8px)"))
|
114
139
|
|
115
140
|
assert_error_message("\"a\" is not a number for `ceil'", "ceil(\"a\")")
|
116
141
|
end
|
@@ -120,6 +145,7 @@ class SassFunctionTest < Test::Unit::TestCase
|
|
120
145
|
assert_equal("5px", evaluate("abs(-5px)"))
|
121
146
|
assert_equal("5", evaluate("abs(5)"))
|
122
147
|
assert_equal("5px", evaluate("abs(5px)"))
|
148
|
+
assert_equal("5px", evaluate("abs($value: 5px)"))
|
123
149
|
|
124
150
|
assert_error_message("#aaaaaa is not a number for `abs'", "abs(#aaa)")
|
125
151
|
end
|
@@ -128,6 +154,7 @@ class SassFunctionTest < Test::Unit::TestCase
|
|
128
154
|
assert_equal("#123456", evaluate("rgb(18, 52, 86)"))
|
129
155
|
assert_equal("#beaded", evaluate("rgb(190, 173, 237)"))
|
130
156
|
assert_equal("#00ff7f", evaluate("rgb(0, 255, 127)"))
|
157
|
+
assert_equal("#00ff7f", evaluate("rgb($red: 0, $green: 255, $blue: 127)"))
|
131
158
|
end
|
132
159
|
|
133
160
|
def test_rgb_percent
|
@@ -169,6 +196,7 @@ class SassFunctionTest < Test::Unit::TestCase
|
|
169
196
|
assert_equal("rgba(18, 52, 86, 0.5)", evaluate("rgba(18, 52, 86, 0.5)"))
|
170
197
|
assert_equal("#beaded", evaluate("rgba(190, 173, 237, 1)"))
|
171
198
|
assert_equal("rgba(0, 255, 127, 0)", evaluate("rgba(0, 255, 127, 0)"))
|
199
|
+
assert_equal("rgba(0, 255, 127, 0)", evaluate("rgba($red: 0, $green: 255, $blue: 127, $alpha: 0)"))
|
172
200
|
end
|
173
201
|
|
174
202
|
def test_rgb_tests_bounds
|
@@ -198,6 +226,7 @@ class SassFunctionTest < Test::Unit::TestCase
|
|
198
226
|
def test_rgba_with_color
|
199
227
|
assert_equal "rgba(16, 32, 48, 0.5)", evaluate("rgba(#102030, 0.5)")
|
200
228
|
assert_equal "rgba(0, 0, 255, 0.5)", evaluate("rgba(blue, 0.5)")
|
229
|
+
assert_equal "rgba(0, 0, 255, 0.5)", evaluate("rgba($color: blue, $alpha: 0.5)")
|
201
230
|
end
|
202
231
|
|
203
232
|
def test_rgba_with_color_tests_types
|
@@ -214,6 +243,7 @@ class SassFunctionTest < Test::Unit::TestCase
|
|
214
243
|
|
215
244
|
def test_red
|
216
245
|
assert_equal("18", evaluate("red(#123456)"))
|
246
|
+
assert_equal("18", evaluate("red($color: #123456)"))
|
217
247
|
end
|
218
248
|
|
219
249
|
def test_red_exception
|
@@ -222,6 +252,7 @@ class SassFunctionTest < Test::Unit::TestCase
|
|
222
252
|
|
223
253
|
def test_green
|
224
254
|
assert_equal("52", evaluate("green(#123456)"))
|
255
|
+
assert_equal("52", evaluate("green($color: #123456)"))
|
225
256
|
end
|
226
257
|
|
227
258
|
def test_green_exception
|
@@ -230,6 +261,7 @@ class SassFunctionTest < Test::Unit::TestCase
|
|
230
261
|
|
231
262
|
def test_blue
|
232
263
|
assert_equal("86", evaluate("blue(#123456)"))
|
264
|
+
assert_equal("86", evaluate("blue($color: #123456)"))
|
233
265
|
end
|
234
266
|
|
235
267
|
def test_blue_exception
|
@@ -238,6 +270,7 @@ class SassFunctionTest < Test::Unit::TestCase
|
|
238
270
|
|
239
271
|
def test_hue
|
240
272
|
assert_equal("18deg", evaluate("hue(hsl(18, 50%, 20%))"))
|
273
|
+
assert_equal("18deg", evaluate("hue($color: hsl(18, 50%, 20%))"))
|
241
274
|
end
|
242
275
|
|
243
276
|
def test_hue_exception
|
@@ -247,6 +280,7 @@ class SassFunctionTest < Test::Unit::TestCase
|
|
247
280
|
def test_saturation
|
248
281
|
assert_equal("52%", evaluate("saturation(hsl(20, 52%, 20%))"))
|
249
282
|
assert_equal("52%", evaluate("saturation(hsl(20, 52, 20%))"))
|
283
|
+
assert_equal("52%", evaluate("saturation($color: hsl(20, 52, 20%))"))
|
250
284
|
end
|
251
285
|
|
252
286
|
def test_saturation_exception
|
@@ -256,6 +290,7 @@ class SassFunctionTest < Test::Unit::TestCase
|
|
256
290
|
def test_lightness
|
257
291
|
assert_equal("86%", evaluate("lightness(hsl(120, 50%, 86%))"))
|
258
292
|
assert_equal("86%", evaluate("lightness(hsl(120, 50%, 86))"))
|
293
|
+
assert_equal("86%", evaluate("lightness($color: hsl(120, 50%, 86))"))
|
259
294
|
end
|
260
295
|
|
261
296
|
def test_lightness_exception
|
@@ -266,6 +301,7 @@ class SassFunctionTest < Test::Unit::TestCase
|
|
266
301
|
assert_equal("1", evaluate("alpha(#123456)"))
|
267
302
|
assert_equal("0.34", evaluate("alpha(rgba(0, 1, 2, 0.34))"))
|
268
303
|
assert_equal("0", evaluate("alpha(hsla(0, 1, 2, 0))"))
|
304
|
+
assert_equal("0", evaluate("alpha($color: hsla(0, 1, 2, 0))"))
|
269
305
|
end
|
270
306
|
|
271
307
|
def test_alpha_exception
|
@@ -279,6 +315,8 @@ class SassFunctionTest < Test::Unit::TestCase
|
|
279
315
|
assert_equal("black", evaluate("fade_in(rgba(0, 0, 0, 0.2), 0.8)"))
|
280
316
|
assert_equal("black", evaluate("opacify(rgba(0, 0, 0, 0.2), 1)"))
|
281
317
|
assert_equal("rgba(0, 0, 0, 0.2)", evaluate("opacify(rgba(0, 0, 0, 0.2), 0%)"))
|
318
|
+
assert_equal("rgba(0, 0, 0, 0.2)", evaluate("opacify($color: rgba(0, 0, 0, 0.2), $amount: 0%)"))
|
319
|
+
assert_equal("rgba(0, 0, 0, 0.2)", evaluate("fade-in($color: rgba(0, 0, 0, 0.2), $amount: 0%)"))
|
282
320
|
end
|
283
321
|
|
284
322
|
def test_opacify_tests_bounds
|
@@ -300,6 +338,8 @@ class SassFunctionTest < Test::Unit::TestCase
|
|
300
338
|
assert_equal("rgba(0, 0, 0, 0)", evaluate("fade_out(rgba(0, 0, 0, 0.2), 0.2)"))
|
301
339
|
assert_equal("rgba(0, 0, 0, 0)", evaluate("transparentize(rgba(0, 0, 0, 0.2), 1)"))
|
302
340
|
assert_equal("rgba(0, 0, 0, 0.2)", evaluate("transparentize(rgba(0, 0, 0, 0.2), 0)"))
|
341
|
+
assert_equal("rgba(0, 0, 0, 0.2)", evaluate("transparentize($color: rgba(0, 0, 0, 0.2), $amount: 0)"))
|
342
|
+
assert_equal("rgba(0, 0, 0, 0.2)", evaluate("fade-out($color: rgba(0, 0, 0, 0.2), $amount: 0)"))
|
303
343
|
end
|
304
344
|
|
305
345
|
def test_transparentize_tests_bounds
|
@@ -321,6 +361,7 @@ class SassFunctionTest < Test::Unit::TestCase
|
|
321
361
|
assert_equal("white", evaluate("lighten(#800, 100%)"))
|
322
362
|
assert_equal("#880000", evaluate("lighten(#800, 0%)"))
|
323
363
|
assert_equal("rgba(238, 0, 0, 0.5)", evaluate("lighten(rgba(136, 0, 0, 0.5), 20%)"))
|
364
|
+
assert_equal("rgba(238, 0, 0, 0.5)", evaluate("lighten($color: rgba(136, 0, 0, 0.5), $amount: 20%)"))
|
324
365
|
end
|
325
366
|
|
326
367
|
def test_lighten_tests_bounds
|
@@ -342,6 +383,7 @@ class SassFunctionTest < Test::Unit::TestCase
|
|
342
383
|
assert_equal("black", evaluate("darken(#800, 100%)"))
|
343
384
|
assert_equal("#880000", evaluate("darken(#800, 0%)"))
|
344
385
|
assert_equal("rgba(34, 0, 0, 0.5)", evaluate("darken(rgba(136, 0, 0, 0.5), 20%)"))
|
386
|
+
assert_equal("rgba(34, 0, 0, 0.5)", evaluate("darken($color: rgba(136, 0, 0, 0.5), $amount: 20%)"))
|
345
387
|
end
|
346
388
|
|
347
389
|
def test_darken_tests_bounds
|
@@ -364,6 +406,7 @@ class SassFunctionTest < Test::Unit::TestCase
|
|
364
406
|
assert_equal("#33ff33", evaluate("saturate(#8a8, 100%)"))
|
365
407
|
assert_equal("#88aa88", evaluate("saturate(#8a8, 0%)"))
|
366
408
|
assert_equal("rgba(158, 63, 63, 0.5)", evaluate("saturate(rgba(136, 85, 85, 0.5), 20%)"))
|
409
|
+
assert_equal("rgba(158, 63, 63, 0.5)", evaluate("saturate($color: rgba(136, 85, 85, 0.5), $amount: 20%)"))
|
367
410
|
end
|
368
411
|
|
369
412
|
def test_saturate_tests_bounds
|
@@ -386,6 +429,7 @@ class SassFunctionTest < Test::Unit::TestCase
|
|
386
429
|
assert_equal("#999999", evaluate("desaturate(#8a8, 100%)"))
|
387
430
|
assert_equal("#88aa88", evaluate("desaturate(#8a8, 0%)"))
|
388
431
|
assert_equal("rgba(114, 107, 107, 0.5)", evaluate("desaturate(rgba(136, 85, 85, 0.5), 20%)"))
|
432
|
+
assert_equal("rgba(114, 107, 107, 0.5)", evaluate("desaturate($color: rgba(136, 85, 85, 0.5), $amount: 20%)"))
|
389
433
|
end
|
390
434
|
|
391
435
|
def test_desaturate_tests_bounds
|
@@ -409,6 +453,7 @@ class SassFunctionTest < Test::Unit::TestCase
|
|
409
453
|
assert_equal("#88aa88", evaluate("adjust-hue(#8a8, 360deg)"))
|
410
454
|
assert_equal("#88aa88", evaluate("adjust-hue(#8a8, 0deg)"))
|
411
455
|
assert_equal("rgba(136, 106, 17, 0.5)", evaluate("adjust-hue(rgba(136, 17, 17, 0.5), 45deg)"))
|
456
|
+
assert_equal("rgba(136, 106, 17, 0.5)", evaluate("adjust-hue($color: rgba(136, 17, 17, 0.5), $degrees: 45deg)"))
|
412
457
|
end
|
413
458
|
|
414
459
|
def test_adjust_hue_tests_types
|
@@ -430,6 +475,7 @@ class SassFunctionTest < Test::Unit::TestCase
|
|
430
475
|
assert_equal("blue", evaluate("mix(transparentize(#f00, 1), #00f, 0%)"))
|
431
476
|
assert_equal("rgba(0, 0, 255, 0)", evaluate("mix(#f00, transparentize(#00f, 1), 0%)"))
|
432
477
|
assert_equal("rgba(255, 0, 0, 0)", evaluate("mix(transparentize(#f00, 1), #00f, 100%)"))
|
478
|
+
assert_equal("rgba(255, 0, 0, 0)", evaluate("mix($color-1: transparentize(#f00, 1), $color-2: #00f, $weight: 100%)"))
|
433
479
|
end
|
434
480
|
|
435
481
|
def test_mix_tests_types
|
@@ -451,6 +497,7 @@ class SassFunctionTest < Test::Unit::TestCase
|
|
451
497
|
assert_equal("gray", evaluate("grayscale(#00f)"))
|
452
498
|
assert_equal("white", evaluate("grayscale(white)"))
|
453
499
|
assert_equal("black", evaluate("grayscale(black)"))
|
500
|
+
assert_equal("black", evaluate("grayscale($color: black)"))
|
454
501
|
end
|
455
502
|
|
456
503
|
def tets_grayscale_tests_types
|
@@ -463,6 +510,7 @@ class SassFunctionTest < Test::Unit::TestCase
|
|
463
510
|
assert_equal("red", evaluate("complement(aqua)"))
|
464
511
|
assert_equal("white", evaluate("complement(white)"))
|
465
512
|
assert_equal("black", evaluate("complement(black)"))
|
513
|
+
assert_equal("black", evaluate("complement($color: black)"))
|
466
514
|
end
|
467
515
|
|
468
516
|
def tets_complement_tests_types
|
@@ -481,6 +529,7 @@ class SassFunctionTest < Test::Unit::TestCase
|
|
481
529
|
def test_unquote
|
482
530
|
assert_equal('foo', evaluate('unquote("foo")'))
|
483
531
|
assert_equal('foo', evaluate('unquote(foo)'))
|
532
|
+
assert_equal('foo', evaluate('unquote($string: foo)'))
|
484
533
|
end
|
485
534
|
|
486
535
|
def test_unquote_tests_type
|
@@ -490,6 +539,7 @@ class SassFunctionTest < Test::Unit::TestCase
|
|
490
539
|
def test_quote
|
491
540
|
assert_equal('"foo"', evaluate('quote(foo)'))
|
492
541
|
assert_equal('"foo"', evaluate('quote("foo")'))
|
542
|
+
assert_equal('"foo"', evaluate('quote($string: "foo")'))
|
493
543
|
end
|
494
544
|
|
495
545
|
def test_quote_tests_type
|
@@ -520,6 +570,7 @@ MSG
|
|
520
570
|
assert_equal("number", evaluate("type-of(1px)"))
|
521
571
|
assert_equal("bool", evaluate("type-of(true)"))
|
522
572
|
assert_equal("color", evaluate("type-of(#fff)"))
|
573
|
+
assert_equal("color", evaluate("type-of($value: #fff)"))
|
523
574
|
end
|
524
575
|
|
525
576
|
def test_unit
|
@@ -528,12 +579,14 @@ MSG
|
|
528
579
|
assert_equal(%Q{"em*px"}, evaluate("unit(10px * 5em)"))
|
529
580
|
assert_equal(%Q{"em*px"}, evaluate("unit(5em * 10px)"))
|
530
581
|
assert_equal(%Q{"em*px/cm*rem"}, evaluate("unit(10px * 5em / 30cm / 1rem)"))
|
582
|
+
assert_equal(%Q{"px"}, evaluate("unit($number: 100px)"))
|
531
583
|
assert_error_message("#ff0000 is not a number for `unit'", "unit(#f00)")
|
532
584
|
end
|
533
585
|
|
534
586
|
def test_unitless
|
535
587
|
assert_equal(%Q{true}, evaluate("unitless(100)"))
|
536
588
|
assert_equal(%Q{false}, evaluate("unitless(100px)"))
|
589
|
+
assert_equal(%Q{false}, evaluate("unitless($number: 100px)"))
|
537
590
|
assert_error_message("#ff0000 is not a number for `unitless'", "unitless(#f00)")
|
538
591
|
end
|
539
592
|
|
@@ -541,10 +594,44 @@ MSG
|
|
541
594
|
assert_equal(%Q{true}, evaluate("comparable(2px, 1px)"))
|
542
595
|
assert_equal(%Q{true}, evaluate("comparable(10cm, 3mm)"))
|
543
596
|
assert_equal(%Q{false}, evaluate("comparable(100px, 3em)"))
|
597
|
+
assert_equal(%Q{false}, evaluate("comparable($number-1: 100px, $number-2: 3em)"))
|
544
598
|
assert_error_message("#ff0000 is not a number for `comparable'", "comparable(#f00, 1px)")
|
545
599
|
assert_error_message("#ff0000 is not a number for `comparable'", "comparable(1px, #f00)")
|
546
600
|
end
|
547
601
|
|
602
|
+
def test_keyword_args_rgb
|
603
|
+
assert_equal(%Q{white}, evaluate("rgb($red: 255, $green: 255, $blue: 255)"))
|
604
|
+
end
|
605
|
+
|
606
|
+
def test_keyword_args_rgba
|
607
|
+
assert_equal(%Q{rgba(255, 255, 255, 0.5)}, evaluate("rgba($red: 255, $green: 255, $blue: 255, $alpha: 0.5)"))
|
608
|
+
assert_equal(%Q{rgba(255, 255, 255, 0.5)}, evaluate("rgba($color: #fff, $alpha: 0.5)"))
|
609
|
+
end
|
610
|
+
|
611
|
+
def test_keyword_args_rgba_with_extra_args
|
612
|
+
assert_equal(%Q{rgba(255, 255, 255, 0.5)}, evaluate("rgba($red: 255, $green: 255, $blue: 255, $alpha: 0.5, $extra: error)"))
|
613
|
+
rescue Sass::SyntaxError => e
|
614
|
+
assert_equal("Function rgba doesn't take an argument named $extra", e.message)
|
615
|
+
end
|
616
|
+
|
617
|
+
def test_keyword_args_must_have_signature
|
618
|
+
evaluate("no-kw-args($fake: value)")
|
619
|
+
rescue Sass::SyntaxError => e
|
620
|
+
assert_equal("Function no_kw_args doesn't support keyword arguments", e.message)
|
621
|
+
end
|
622
|
+
|
623
|
+
def test_keyword_args_with_missing_argument
|
624
|
+
evaluate("rgb($red: 255, $green: 255)")
|
625
|
+
rescue Sass::SyntaxError => e
|
626
|
+
assert_equal("Function rgb requires an argument named $blue", e.message)
|
627
|
+
end
|
628
|
+
|
629
|
+
def test_only_var_args
|
630
|
+
assert_equal "only-var-args(2px, 3px, 4px)", evaluate("only-var-args(1px, 2px, 3px)")
|
631
|
+
end
|
632
|
+
def test_only_kw_args
|
633
|
+
assert_equal "only-kw-args(a, b, c)", evaluate("only-kw-args($a: 1, $b: 2, $c: 3)")
|
634
|
+
end
|
548
635
|
private
|
549
636
|
|
550
637
|
def evaluate(value)
|