sass 3.2.0.alpha.278 → 3.2.0.alpha.291
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/REVISION +1 -1
- data/VERSION +1 -1
- data/VERSION_DATE +1 -1
- data/lib/sass/engine.rb +15 -9
- data/lib/sass/script/arg_list.rb +52 -0
- data/lib/sass/script/funcall.rb +45 -38
- data/lib/sass/script/lexer.rb +1 -0
- data/lib/sass/script/list.rb +1 -1
- data/lib/sass/script/literal.rb +1 -0
- data/lib/sass/script/number.rb +7 -6
- data/lib/sass/script/parser.rb +32 -34
- data/lib/sass/scss/parser.rb +6 -6
- data/lib/sass/tree/function_node.rb +8 -1
- data/lib/sass/tree/mixin_def_node.rb +8 -1
- data/lib/sass/tree/mixin_node.rb +8 -1
- data/lib/sass/tree/visitors/convert.rb +22 -6
- data/lib/sass/tree/visitors/perform.rb +88 -33
- data/test/sass/conversion_test.rb +54 -0
- data/test/sass/engine_test.rb +15 -13
- data/test/sass/functions_test.rb +3 -2
- data/test/sass/results/script.css +1 -1
- data/test/sass/results/units.css +2 -2
- data/test/sass/script_conversion_test.rb +1 -1
- data/test/sass/script_test.rb +2 -1
- data/test/sass/scss/scss_test.rb +359 -1
- metadata +21 -20
data/lib/sass/scss/parser.rb
CHANGED
@@ -170,16 +170,16 @@ module Sass
|
|
170
170
|
|
171
171
|
def mixin_directive
|
172
172
|
name = tok! IDENT
|
173
|
-
args = sass_script(:parse_mixin_definition_arglist)
|
173
|
+
args, splat = sass_script(:parse_mixin_definition_arglist)
|
174
174
|
ss
|
175
|
-
block(node(Sass::Tree::MixinDefNode.new(name, args)), :directive)
|
175
|
+
block(node(Sass::Tree::MixinDefNode.new(name, args, splat)), :directive)
|
176
176
|
end
|
177
177
|
|
178
178
|
def include_directive
|
179
179
|
name = tok! IDENT
|
180
|
-
args, keywords = sass_script(:parse_mixin_include_arglist)
|
180
|
+
args, keywords, splat = sass_script(:parse_mixin_include_arglist)
|
181
181
|
ss
|
182
|
-
include_node = node(Sass::Tree::MixinNode.new(name, args, keywords))
|
182
|
+
include_node = node(Sass::Tree::MixinNode.new(name, args, keywords, splat))
|
183
183
|
if tok?(/\{/)
|
184
184
|
include_node.has_children = true
|
185
185
|
block(include_node, :directive)
|
@@ -195,9 +195,9 @@ module Sass
|
|
195
195
|
|
196
196
|
def function_directive
|
197
197
|
name = tok! IDENT
|
198
|
-
args = sass_script(:parse_function_definition_arglist)
|
198
|
+
args, splat = sass_script(:parse_function_definition_arglist)
|
199
199
|
ss
|
200
|
-
block(node(Sass::Tree::FunctionNode.new(name, args)), :function)
|
200
|
+
block(node(Sass::Tree::FunctionNode.new(name, args, splat)), :function)
|
201
201
|
end
|
202
202
|
|
203
203
|
def return_directive
|
@@ -15,11 +15,18 @@ module Sass
|
|
15
15
|
# @return [Array<Script::Node>]
|
16
16
|
attr_accessor :args
|
17
17
|
|
18
|
+
# The splat argument for this function, if one exists.
|
19
|
+
#
|
20
|
+
# @return [Script::Node?]
|
21
|
+
attr_accessor :splat
|
22
|
+
|
18
23
|
# @param name [String] The function name
|
19
24
|
# @param args [Array<(Script::Node, Script::Node)>] The arguments for the function.
|
20
|
-
|
25
|
+
# @param splat [Script::Node] See \{#splat}
|
26
|
+
def initialize(name, args, splat)
|
21
27
|
@name = name
|
22
28
|
@args = args
|
29
|
+
@splat = splat
|
23
30
|
super()
|
24
31
|
end
|
25
32
|
end
|
@@ -15,15 +15,22 @@ module Sass
|
|
15
15
|
# @return [Array<(Script::Node, Script::Node)>]
|
16
16
|
attr_accessor :args
|
17
17
|
|
18
|
+
# The splat argument for this mixin, if one exists.
|
19
|
+
#
|
20
|
+
# @return [Script::Node?]
|
21
|
+
attr_accessor :splat
|
22
|
+
|
18
23
|
# Whether the mixin uses `@content`. Set during the nesting check phase.
|
19
24
|
# @return [Boolean]
|
20
25
|
attr_accessor :has_content
|
21
26
|
|
22
27
|
# @param name [String] The mixin name
|
23
28
|
# @param args [Array<(Script::Node, Script::Node)>] See \{#args}
|
24
|
-
|
29
|
+
# @param splat [Script::Node] See \{#splat}
|
30
|
+
def initialize(name, args, splat)
|
25
31
|
@name = name
|
26
32
|
@args = args
|
33
|
+
@splat = splat
|
27
34
|
super()
|
28
35
|
end
|
29
36
|
end
|
data/lib/sass/tree/mixin_node.rb
CHANGED
@@ -19,13 +19,20 @@ module Sass::Tree
|
|
19
19
|
# @return [{String => Script::Node}]
|
20
20
|
attr_accessor :keywords
|
21
21
|
|
22
|
+
# The splat argument for this mixin, if one exists.
|
23
|
+
#
|
24
|
+
# @return [Script::Node?]
|
25
|
+
attr_accessor :splat
|
26
|
+
|
22
27
|
# @param name [String] The name of the mixin
|
23
28
|
# @param args [Array<Script::Node>] See \{#args}
|
29
|
+
# @param splat [Script::Node] See \{#splat}
|
24
30
|
# @param keywords [{String => Script::Node}] See \{#keywords}
|
25
|
-
def initialize(name, args, keywords)
|
31
|
+
def initialize(name, args, keywords, splat)
|
26
32
|
@name = name
|
27
33
|
@args = args
|
28
34
|
@keywords = keywords
|
35
|
+
@splat = splat
|
29
36
|
super()
|
30
37
|
end
|
31
38
|
end
|
@@ -121,6 +121,10 @@ class Sass::Tree::Visitors::Convert < Sass::Tree::Visitors::Base
|
|
121
121
|
args = node.args.map do |v, d|
|
122
122
|
d ? "#{v.to_sass(@options)}: #{d.to_sass(@options)}" : v.to_sass(@options)
|
123
123
|
end.join(", ")
|
124
|
+
if node.splat
|
125
|
+
args << ", " unless node.args.empty?
|
126
|
+
args << node.splat.to_sass(@options) << "..."
|
127
|
+
end
|
124
128
|
|
125
129
|
"#{tab_str}@function #{dasherize(node.name)}(#{args})#{yield}"
|
126
130
|
end
|
@@ -167,27 +171,39 @@ class Sass::Tree::Visitors::Convert < Sass::Tree::Visitors::Base
|
|
167
171
|
|
168
172
|
def visit_mixindef(node)
|
169
173
|
args =
|
170
|
-
if node.args.empty?
|
174
|
+
if node.args.empty? && node.splat.nil?
|
171
175
|
""
|
172
176
|
else
|
173
|
-
'('
|
177
|
+
str = '('
|
178
|
+
str << node.args.map do |v, d|
|
174
179
|
if d
|
175
180
|
"#{v.to_sass(@options)}: #{d.to_sass(@options)}"
|
176
181
|
else
|
177
182
|
v.to_sass(@options)
|
178
183
|
end
|
179
|
-
end.join(", ")
|
184
|
+
end.join(", ")
|
185
|
+
|
186
|
+
if node.splat
|
187
|
+
str << ", " unless node.args.empty?
|
188
|
+
str << node.splat.to_sass(@options) << '...'
|
189
|
+
end
|
190
|
+
|
191
|
+
str << ')'
|
180
192
|
end
|
181
|
-
|
193
|
+
|
182
194
|
"#{tab_str}#{@format == :sass ? '=' : '@mixin '}#{dasherize(node.name)}#{args}#{yield}"
|
183
195
|
end
|
184
196
|
|
185
197
|
def visit_mixin(node)
|
186
|
-
unless node.args.empty? && node.keywords.empty?
|
198
|
+
unless node.args.empty? && node.keywords.empty? && node.splat.nil?
|
187
199
|
args = node.args.map {|a| a.to_sass(@options)}.join(", ")
|
188
200
|
keywords = Sass::Util.hash_to_a(node.keywords).
|
189
201
|
map {|k, v| "$#{dasherize(k)}: #{v.to_sass(@options)}"}.join(', ')
|
190
|
-
|
202
|
+
if node.splat
|
203
|
+
splat = (args.empty? && keywords.empty?) ? "" : ", "
|
204
|
+
splat = "#{splat}#{node.splat.to_sass(@options)}..."
|
205
|
+
end
|
206
|
+
arglist = "(#{args}#{', ' unless args.empty? || keywords.empty?}#{keywords}#{splat})"
|
191
207
|
end
|
192
208
|
"#{tab_str}#{@format == :sass ? '+' : '@include '}#{dasherize(node.name)}#{arglist}#{node.has_children ? yield : semi}\n"
|
193
209
|
end
|
@@ -7,6 +7,83 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
|
|
7
7
|
new(environment).send(:visit, root)
|
8
8
|
end
|
9
9
|
|
10
|
+
# @api private
|
11
|
+
def self.perform_arguments(callable, args, keywords, splat)
|
12
|
+
desc = "#{callable.type.capitalize} #{callable.name}"
|
13
|
+
downcase_desc = "#{callable.type} #{callable.name}"
|
14
|
+
|
15
|
+
begin
|
16
|
+
unless keywords.empty?
|
17
|
+
unknown_args = keywords.keys - callable.args.map {|var| var.first.underscored_name}
|
18
|
+
if callable.splat && unknown_args.include?(callable.splat.underscored_name)
|
19
|
+
raise Sass::SyntaxError.new("Argument $#{callable.splat.name} of #{downcase_desc} cannot be used as a named argument.")
|
20
|
+
elsif unknown_args.any?
|
21
|
+
raise Sass::SyntaxError.new("#{desc} doesn't have #{unknown_args.length > 1 ? 'the following arguments:' : 'an argument named'} #{unknown_args.map{|name| "$#{name}"}.join ', '}.")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
rescue Sass::SyntaxError => keyword_exception
|
25
|
+
end
|
26
|
+
|
27
|
+
# If there's no splat, raise the keyword exception immediately. The actual
|
28
|
+
# raising happens in the ensure clause at the end of this function.
|
29
|
+
return if keyword_exception && !callable.splat
|
30
|
+
|
31
|
+
if args.size > callable.args.size && !callable.splat
|
32
|
+
takes = callable.args.size
|
33
|
+
passed = args.size
|
34
|
+
raise Sass::SyntaxError.new(
|
35
|
+
"#{desc} takes #{takes} argument#{'s' unless takes == 1} " +
|
36
|
+
"but #{passed} #{passed == 1 ? 'was' : 'were'} passed.")
|
37
|
+
end
|
38
|
+
|
39
|
+
splat_sep = :comma
|
40
|
+
if splat
|
41
|
+
args += splat.to_a
|
42
|
+
splat_sep = splat.separator if splat.is_a?(Sass::Script::List)
|
43
|
+
# If the splat argument exists, there won't be any keywords passed in
|
44
|
+
# manually, so we can safely overwrite rather than merge here.
|
45
|
+
keywords = splat.keywords if splat.is_a?(Sass::Script::ArgList)
|
46
|
+
end
|
47
|
+
|
48
|
+
keywords = keywords.dup
|
49
|
+
env = Sass::Environment.new(callable.environment)
|
50
|
+
callable.args.zip(args[0...callable.args.length]) do |(var, default), value|
|
51
|
+
if value && keywords.include?(var.underscored_name)
|
52
|
+
raise Sass::SyntaxError.new("#{desc} was passed argument $#{var.name} both by position and by name.")
|
53
|
+
end
|
54
|
+
|
55
|
+
value ||= keywords.delete(var.underscored_name)
|
56
|
+
value ||= default && default.perform(env)
|
57
|
+
raise Sass::SyntaxError.new("#{desc} is missing argument #{var.inspect}.") unless value
|
58
|
+
env.set_local_var(var.name, value)
|
59
|
+
end
|
60
|
+
|
61
|
+
if callable.splat
|
62
|
+
rest = args[callable.args.length..-1]
|
63
|
+
arg_list = Sass::Script::ArgList.new(rest, keywords.dup, splat_sep)
|
64
|
+
arg_list.options = env.options
|
65
|
+
env.set_local_var(callable.splat.name, arg_list)
|
66
|
+
end
|
67
|
+
|
68
|
+
yield env
|
69
|
+
ensure
|
70
|
+
# If there's a keyword exception, we don't want to throw it immediately,
|
71
|
+
# because the invalid keywords may be part of a glob argument that should be
|
72
|
+
# passed on to another function. So we only raise it if we reach the end of
|
73
|
+
# this function *and* the keywords attached to the argument list glob object
|
74
|
+
# haven't been accessed.
|
75
|
+
#
|
76
|
+
# The keyword exception takes precedence over any Sass errors, but not over
|
77
|
+
# non-Sass exceptions.
|
78
|
+
if keyword_exception &&
|
79
|
+
!(arg_list && arg_list.keywords_accessed) &&
|
80
|
+
($!.nil? || $!.is_a?(Sass::SyntaxError))
|
81
|
+
raise keyword_exception
|
82
|
+
elsif $!
|
83
|
+
raise $!
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
10
87
|
protected
|
11
88
|
|
12
89
|
def initialize(env)
|
@@ -114,7 +191,7 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
|
|
114
191
|
def visit_function(node)
|
115
192
|
env = Sass::Environment.new(@environment, node.options)
|
116
193
|
@environment.set_local_function(node.name,
|
117
|
-
Sass::Callable.new(node.name, node.args, env, node.children, !:has_content))
|
194
|
+
Sass::Callable.new(node.name, node.args, node.splat, env, node.children, !:has_content, "function"))
|
118
195
|
[]
|
119
196
|
end
|
120
197
|
|
@@ -157,7 +234,7 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
|
|
157
234
|
def visit_mixindef(node)
|
158
235
|
env = Sass::Environment.new(@environment, node.options)
|
159
236
|
@environment.set_local_mixin(node.name,
|
160
|
-
Sass::Callable.new(node.name, node.args, env, node.children, node.has_content))
|
237
|
+
Sass::Callable.new(node.name, node.args, node.splat, env, node.children, node.has_content, "mixin"))
|
161
238
|
[]
|
162
239
|
end
|
163
240
|
|
@@ -174,40 +251,18 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
|
|
174
251
|
raise Sass::SyntaxError.new(%Q{Mixin "#{node.name}" does not accept a content block.})
|
175
252
|
end
|
176
253
|
|
177
|
-
|
178
|
-
|
254
|
+
args = node.args.map {|a| a.perform(@environment)}
|
255
|
+
keywords = Sass::Util.map_hash(node.keywords) {|k, v| [k, v.perform(@environment)]}
|
256
|
+
splat = node.splat.perform(@environment) if node.splat
|
179
257
|
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
END
|
258
|
+
self.class.perform_arguments(mixin, args, keywords, splat) do |env|
|
259
|
+
env.caller = Sass::Environment.new(@environment)
|
260
|
+
env.content = node.children if node.has_children
|
184
261
|
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
raise Sass::SyntaxError.new("Mixin #{node.name} doesn't have an argument named $#{name}")
|
189
|
-
end
|
190
|
-
end
|
191
|
-
|
192
|
-
environment = mixin.args.zip(passed_args).
|
193
|
-
inject(Sass::Environment.new(mixin.environment)) do |env, ((var, default), value)|
|
194
|
-
env.set_local_var(var.name,
|
195
|
-
if value
|
196
|
-
value.perform(@environment)
|
197
|
-
elsif kv = passed_keywords[var.underscored_name]
|
198
|
-
kv.perform(@environment)
|
199
|
-
elsif default
|
200
|
-
default.perform(env)
|
201
|
-
end)
|
202
|
-
raise Sass::SyntaxError.new("Mixin #{node.name} is missing argument #{var.inspect}.") unless env.var(var.name)
|
203
|
-
env
|
262
|
+
trace_node = Sass::Tree::TraceNode.from_node(node.name, node)
|
263
|
+
with_environment(env) {trace_node.children = mixin.tree.map {|c| visit(c)}.flatten}
|
264
|
+
trace_node
|
204
265
|
end
|
205
|
-
environment.caller = Sass::Environment.new(@environment)
|
206
|
-
environment.content = node.children if node.has_children
|
207
|
-
|
208
|
-
trace_node = Sass::Tree::TraceNode.from_node(node.name, node)
|
209
|
-
with_environment(environment) {trace_node.children = mixin.tree.map {|c| visit(c)}.flatten}
|
210
|
-
trace_node
|
211
266
|
rescue Sass::SyntaxError => e
|
212
267
|
unless include_loop
|
213
268
|
e.modify_backtrace(:mixin => node.name, :line => node.line)
|
@@ -1562,6 +1562,60 @@ foo {
|
|
1562
1562
|
SCSS
|
1563
1563
|
end
|
1564
1564
|
|
1565
|
+
def test_mixin_var_args
|
1566
|
+
assert_scss_to_sass <<SASS, <<SCSS
|
1567
|
+
=foo($args...)
|
1568
|
+
a: b
|
1569
|
+
|
1570
|
+
=bar($a, $args...)
|
1571
|
+
a: b
|
1572
|
+
|
1573
|
+
.foo
|
1574
|
+
+foo($list...)
|
1575
|
+
+bar(1, $list...)
|
1576
|
+
SASS
|
1577
|
+
@mixin foo($args...) {
|
1578
|
+
a: b;
|
1579
|
+
}
|
1580
|
+
|
1581
|
+
@mixin bar($a, $args...) {
|
1582
|
+
a: b;
|
1583
|
+
}
|
1584
|
+
|
1585
|
+
.foo {
|
1586
|
+
@include foo($list...);
|
1587
|
+
@include bar(1, $list...);
|
1588
|
+
}
|
1589
|
+
SCSS
|
1590
|
+
end
|
1591
|
+
|
1592
|
+
def test_function_var_args
|
1593
|
+
assert_scss_to_sass <<SASS, <<SCSS
|
1594
|
+
@function foo($args...)
|
1595
|
+
@return foo
|
1596
|
+
|
1597
|
+
@function bar($a, $args...)
|
1598
|
+
@return bar
|
1599
|
+
|
1600
|
+
.foo
|
1601
|
+
a: foo($list...)
|
1602
|
+
b: bar(1, $list...)
|
1603
|
+
SASS
|
1604
|
+
@function foo($args...) {
|
1605
|
+
@return foo;
|
1606
|
+
}
|
1607
|
+
|
1608
|
+
@function bar($a, $args...) {
|
1609
|
+
@return bar;
|
1610
|
+
}
|
1611
|
+
|
1612
|
+
.foo {
|
1613
|
+
a: foo($list...);
|
1614
|
+
b: bar(1, $list...);
|
1615
|
+
}
|
1616
|
+
SCSS
|
1617
|
+
end
|
1618
|
+
|
1565
1619
|
## Regression Tests
|
1566
1620
|
|
1567
1621
|
def test_media_query_with_expr
|
data/test/sass/engine_test.rb
CHANGED
@@ -93,7 +93,7 @@ MSG
|
|
93
93
|
"a-\#{$b\n c: d" => ['Invalid CSS after "a-#{$b": expected "}", was ""', 1],
|
94
94
|
"=a($b: 1, $c)" => "Required argument $c must come before any optional arguments.",
|
95
95
|
"=a($b: 1)\n a: $b\ndiv\n +a(1,2)" => "Mixin a takes 1 argument but 2 were passed.",
|
96
|
-
"=a($b: 1)\n a: $b\ndiv\n +a(1,$c: 3)" => "Mixin a doesn't have an argument named $c",
|
96
|
+
"=a($b: 1)\n a: $b\ndiv\n +a(1,$c: 3)" => "Mixin a doesn't have an argument named $c.",
|
97
97
|
"=a($b)\n a: $b\ndiv\n +a" => "Mixin a is missing argument $b.",
|
98
98
|
"@function foo()\n 1 + 2" => "Functions can only contain variable declarations and control directives.",
|
99
99
|
"@function foo()\n foo: bar" => "Functions can only contain variable declarations and control directives.",
|
@@ -105,10 +105,10 @@ MSG
|
|
105
105
|
"@function foo($)\n @return 1" => ['Invalid CSS after "(": expected variable (e.g. $foo), was "$)"', 1],
|
106
106
|
"@function foo()\n @return" => 'Invalid @return: expected expression.',
|
107
107
|
"@function foo()\n @return 1\n $var: val" => 'Illegal nesting: Nothing may be nested beneath return directives.',
|
108
|
-
"@function foo($a)\n @return 1\na\n b: foo()" => 'Function foo is missing argument $a',
|
109
|
-
"@function foo()\n @return 1\na\n b: foo(2)" => '
|
110
|
-
"@function foo()\n @return 1\na\n b: foo($a: 1)" => "Function foo doesn't have an argument named $a",
|
111
|
-
"@function foo()\n @return 1\na\n b: foo($a: 1, $b: 2)" => "Function foo doesn't have the following arguments: $a, $b",
|
108
|
+
"@function foo($a)\n @return 1\na\n b: foo()" => 'Function foo is missing argument $a.',
|
109
|
+
"@function foo()\n @return 1\na\n b: foo(2)" => 'Function foo takes 0 arguments but 1 was passed.',
|
110
|
+
"@function foo()\n @return 1\na\n b: foo($a: 1)" => "Function foo doesn't have an argument named $a.",
|
111
|
+
"@function foo()\n @return 1\na\n b: foo($a: 1, $b: 2)" => "Function foo doesn't have the following arguments: $a, $b.",
|
112
112
|
"@return 1" => '@return may only be used within a function.',
|
113
113
|
"@if true\n @return 1" => '@return may only be used within a function.',
|
114
114
|
"@mixin foo\n @return 1\n@include foo" => ['@return may only be used within a function.', 2],
|
@@ -122,7 +122,7 @@ MSG
|
|
122
122
|
'@for $a from "foo" to 1' => '"foo" is not an integer.',
|
123
123
|
'@for $a from 1 to "2"' => '"2" is not an integer.',
|
124
124
|
'@for $a from 1 to "foo"' => '"foo" is not an integer.',
|
125
|
-
'@for $a from 1 to 1.232323' => '1.
|
125
|
+
'@for $a from 1 to 1.232323' => '1.23232 is not an integer.',
|
126
126
|
'@for $a from 1px to 3em' => "Incompatible units: 'em' and 'px'.",
|
127
127
|
'@if' => "Invalid if directive '@if': expected expression.",
|
128
128
|
'@while' => "Invalid while directive '@while': expected expression.",
|
@@ -1294,7 +1294,7 @@ bar
|
|
1294
1294
|
SASS
|
1295
1295
|
flunk("Expected exception")
|
1296
1296
|
rescue Sass::SyntaxError => e
|
1297
|
-
assert_equal("Function plus is missing argument $var1", e.message)
|
1297
|
+
assert_equal("Function plus is missing argument $var1.", e.message)
|
1298
1298
|
end
|
1299
1299
|
|
1300
1300
|
def test_function_with_extra_argument
|
@@ -1307,7 +1307,7 @@ bar
|
|
1307
1307
|
SASS
|
1308
1308
|
flunk("Expected exception")
|
1309
1309
|
rescue Sass::SyntaxError => e
|
1310
|
-
assert_equal("Function plus doesn't have an argument named $var3", e.message)
|
1310
|
+
assert_equal("Function plus doesn't have an argument named $var3.", e.message)
|
1311
1311
|
end
|
1312
1312
|
|
1313
1313
|
def test_function_with_positional_and_keyword_argument
|
@@ -1320,7 +1320,7 @@ bar
|
|
1320
1320
|
SASS
|
1321
1321
|
flunk("Expected exception")
|
1322
1322
|
rescue Sass::SyntaxError => e
|
1323
|
-
assert_equal("Function plus was passed argument $var2 both by position and by name", e.message)
|
1323
|
+
assert_equal("Function plus was passed argument $var2 both by position and by name.", e.message)
|
1324
1324
|
end
|
1325
1325
|
|
1326
1326
|
def test_function_with_keyword_before_positional_argument
|
@@ -1333,7 +1333,7 @@ bar
|
|
1333
1333
|
SASS
|
1334
1334
|
flunk("Expected exception")
|
1335
1335
|
rescue Sass::SyntaxError => e
|
1336
|
-
assert_equal("Positional arguments must come before keyword arguments", e.message)
|
1336
|
+
assert_equal("Positional arguments must come before keyword arguments.", e.message)
|
1337
1337
|
end
|
1338
1338
|
|
1339
1339
|
def test_function_with_if
|
@@ -1759,7 +1759,7 @@ SASS
|
|
1759
1759
|
|
1760
1760
|
def test_loud_comment_is_evaluated
|
1761
1761
|
assert_equal <<CSS, render(<<SASS)
|
1762
|
-
/* Hue: 327.
|
1762
|
+
/* Hue: 327.21649deg */
|
1763
1763
|
CSS
|
1764
1764
|
/*!
|
1765
1765
|
Hue: \#{hue(#f836a0)}
|
@@ -2872,11 +2872,13 @@ SCSS
|
|
2872
2872
|
end
|
2873
2873
|
|
2874
2874
|
def test_deprecated_PRECISION
|
2875
|
-
assert_warning(<<END) {assert_equal
|
2875
|
+
assert_warning(<<END) {assert_equal 100_000.0, Sass::Script::Number::PRECISION}
|
2876
2876
|
Sass::Script::Number::PRECISION is deprecated and will be removed in a future release. Use Sass::Script::Number.precision_factor instead.
|
2877
2877
|
END
|
2878
2878
|
end
|
2879
|
+
|
2879
2880
|
def test_changing_precision
|
2881
|
+
old_precision = Sass::Script::Number.precision
|
2880
2882
|
begin
|
2881
2883
|
Sass::Script::Number.precision = 8
|
2882
2884
|
assert_equal <<CSS, render(<<SASS)
|
@@ -2889,7 +2891,7 @@ div
|
|
2889
2891
|
too-much: 1.000000001
|
2890
2892
|
SASS
|
2891
2893
|
ensure
|
2892
|
-
Sass::Script::Number.precision =
|
2894
|
+
Sass::Script::Number.precision = old_precision
|
2893
2895
|
end
|
2894
2896
|
end
|
2895
2897
|
|