sass 3.3.0.rc.2 → 3.3.0.rc.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/CONTRIBUTING +1 -1
- data/README.md +7 -7
- data/Rakefile +4 -2
- data/VERSION +1 -1
- data/VERSION_DATE +1 -1
- data/bin/sass +5 -1
- data/bin/sass-convert +5 -1
- data/bin/scss +5 -1
- data/ext/mkrf_conf.rb +23 -0
- data/lib/sass/css.rb +1 -1
- data/lib/sass/engine.rb +19 -9
- data/lib/sass/environment.rb +8 -0
- data/lib/sass/exec.rb +4 -4
- data/lib/sass/features.rb +0 -1
- data/lib/sass/importers/base.rb +13 -6
- data/lib/sass/importers/deprecated_path.rb +8 -2
- data/lib/sass/importers/filesystem.rb +33 -7
- data/lib/sass/logger.rb +1 -4
- data/lib/sass/logger/base.rb +0 -2
- data/lib/sass/logger/log_level.rb +0 -2
- data/lib/sass/plugin.rb +2 -2
- data/lib/sass/plugin/compiler.rb +23 -11
- data/lib/sass/plugin/configuration.rb +0 -1
- data/lib/sass/railtie.rb +1 -0
- data/lib/sass/script/css_lexer.rb +0 -1
- data/lib/sass/script/css_parser.rb +0 -1
- data/lib/sass/script/functions.rb +158 -96
- data/lib/sass/script/lexer.rb +29 -35
- data/lib/sass/script/parser.rb +10 -3
- data/lib/sass/script/tree.rb +0 -1
- data/lib/sass/script/tree/funcall.rb +21 -5
- data/lib/sass/script/tree/list_literal.rb +0 -1
- data/lib/sass/script/value/arg_list.rb +7 -3
- data/lib/sass/script/value/bool.rb +0 -1
- data/lib/sass/script/value/null.rb +0 -1
- data/lib/sass/script/value/number.rb +2 -6
- data/lib/sass/scss/css_parser.rb +0 -1
- data/lib/sass/scss/parser.rb +5 -5
- data/lib/sass/scss/script_lexer.rb +0 -1
- data/lib/sass/scss/script_parser.rb +0 -1
- data/lib/sass/selector.rb +11 -1
- data/lib/sass/selector/comma_sequence.rb +3 -4
- data/lib/sass/selector/sequence.rb +11 -7
- data/lib/sass/selector/simple_sequence.rb +42 -11
- data/lib/sass/source/map.rb +6 -19
- data/lib/sass/tree/at_root_node.rb +1 -1
- data/lib/sass/tree/mixin_node.rb +2 -2
- data/lib/sass/tree/prop_node.rb +0 -1
- data/lib/sass/tree/variable_node.rb +0 -5
- data/lib/sass/tree/visitors/check_nesting.rb +0 -1
- data/lib/sass/tree/visitors/convert.rb +2 -2
- data/lib/sass/tree/visitors/cssize.rb +184 -84
- data/lib/sass/tree/visitors/deep_copy.rb +0 -1
- data/lib/sass/tree/visitors/perform.rb +14 -44
- data/lib/sass/util.rb +59 -12
- data/lib/sass/util/cross_platform_random.rb +19 -0
- data/lib/sass/util/normalized_map.rb +17 -1
- data/test/sass/compiler_test.rb +10 -0
- data/test/sass/conversion_test.rb +36 -0
- data/test/sass/css2sass_test.rb +19 -0
- data/test/sass/engine_test.rb +54 -105
- data/test/sass/functions_test.rb +233 -26
- data/test/sass/importer_test.rb +72 -10
- data/test/sass/plugin_test.rb +14 -0
- data/test/sass/script_conversion_test.rb +4 -4
- data/test/sass/script_test.rb +58 -21
- data/test/sass/scss/css_test.rb +8 -1
- data/test/sass/scss/scss_test.rb +376 -179
- data/test/sass/source_map_test.rb +8 -0
- data/test/sass/templates/subdir/import_up1.scss +1 -0
- data/test/sass/templates/subdir/import_up2.scss +1 -0
- data/test/sass/util_test.rb +16 -0
- data/test/test_helper.rb +12 -4
- metadata +269 -287
- data/lib/sass/script/tree/selector.rb +0 -30
data/test/sass/functions_test.rb
CHANGED
@@ -120,37 +120,67 @@ class SassFunctionTest < Test::Unit::TestCase
|
|
120
120
|
assert_equal("50%", evaluate("percentage(.5)"))
|
121
121
|
assert_equal("100%", evaluate("percentage(1)"))
|
122
122
|
assert_equal("25%", evaluate("percentage(25px / 100px)"))
|
123
|
-
assert_equal("50%", evaluate("percentage($
|
123
|
+
assert_equal("50%", evaluate("percentage($number: 0.5)"))
|
124
|
+
end
|
125
|
+
|
126
|
+
def test_percentage_deprecated_arg_name
|
127
|
+
assert_warning(<<WARNING) {assert_equal("50%", evaluate("percentage($value: 0.5)"))}
|
128
|
+
DEPRECATION WARNING: The `$value' argument for `percentage()' has been renamed to `$number'.
|
129
|
+
WARNING
|
124
130
|
end
|
125
131
|
|
126
132
|
def test_percentage_checks_types
|
127
|
-
assert_error_message("$
|
128
|
-
assert_error_message("$
|
129
|
-
assert_error_message("$
|
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")})
|
130
136
|
end
|
131
137
|
|
132
138
|
def test_round
|
133
139
|
assert_equal("5", evaluate("round(4.8)"))
|
134
140
|
assert_equal("5px", evaluate("round(4.8px)"))
|
135
141
|
assert_equal("5px", evaluate("round(5.49px)"))
|
136
|
-
assert_equal("5px", evaluate("round($
|
142
|
+
assert_equal("5px", evaluate("round($number: 5.49px)"))
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_round_deprecated_arg_name
|
146
|
+
assert_warning(<<WARNING) {assert_equal("5px", evaluate("round($value: 5.49px)"))}
|
147
|
+
DEPRECATION WARNING: The `$value' argument for `round()' has been renamed to `$number'.
|
148
|
+
WARNING
|
149
|
+
end
|
137
150
|
|
151
|
+
def test_round_checks_types
|
138
152
|
assert_error_message("$value: #cccccc is not a number for `round'", "round(#ccc)")
|
139
153
|
end
|
140
154
|
|
141
155
|
def test_floor
|
142
156
|
assert_equal("4", evaluate("floor(4.8)"))
|
143
157
|
assert_equal("4px", evaluate("floor(4.8px)"))
|
144
|
-
assert_equal("4px", evaluate("floor($
|
158
|
+
assert_equal("4px", evaluate("floor($number: 4.8px)"))
|
159
|
+
end
|
160
|
+
|
161
|
+
def test_floor_deprecated_arg_name
|
162
|
+
assert_warning(<<WARNING) {assert_equal("4px", evaluate("floor($value: 4.8px)"))}
|
163
|
+
DEPRECATION WARNING: The `$value' argument for `floor()' has been renamed to `$number'.
|
164
|
+
WARNING
|
165
|
+
end
|
145
166
|
|
167
|
+
def test_floor_checks_types
|
146
168
|
assert_error_message("$value: \"foo\" is not a number for `floor'", "floor(\"foo\")")
|
147
169
|
end
|
148
170
|
|
149
171
|
def test_ceil
|
150
172
|
assert_equal("5", evaluate("ceil(4.1)"))
|
151
173
|
assert_equal("5px", evaluate("ceil(4.8px)"))
|
152
|
-
assert_equal("5px", evaluate("ceil($
|
174
|
+
assert_equal("5px", evaluate("ceil($number: 4.8px)"))
|
175
|
+
end
|
153
176
|
|
177
|
+
def test_ceil_deprecated_arg_name
|
178
|
+
assert_warning(<<WARNING) {assert_equal("5px", evaluate("ceil($value: 4.8px)"))}
|
179
|
+
DEPRECATION WARNING: The `$value' argument for `ceil()' has been renamed to `$number'.
|
180
|
+
WARNING
|
181
|
+
end
|
182
|
+
|
183
|
+
def test_ceil_checks_types
|
154
184
|
assert_error_message("$value: \"a\" is not a number for `ceil'", "ceil(\"a\")")
|
155
185
|
end
|
156
186
|
|
@@ -159,8 +189,16 @@ class SassFunctionTest < Test::Unit::TestCase
|
|
159
189
|
assert_equal("5px", evaluate("abs(-5px)"))
|
160
190
|
assert_equal("5", evaluate("abs(5)"))
|
161
191
|
assert_equal("5px", evaluate("abs(5px)"))
|
162
|
-
assert_equal("5px", evaluate("abs($
|
192
|
+
assert_equal("5px", evaluate("abs($number: 5px)"))
|
193
|
+
end
|
194
|
+
|
195
|
+
def test_abs_deprecated_arg_name
|
196
|
+
assert_warning(<<WARNING) {assert_equal("5px", evaluate("abs($value: 5px)"))}
|
197
|
+
DEPRECATION WARNING: The `$value' argument for `abs()' has been renamed to `$number'.
|
198
|
+
WARNING
|
199
|
+
end
|
163
200
|
|
201
|
+
def test_abs_checks_types
|
164
202
|
assert_error_message("$value: #aaaaaa is not a number for `abs'", "abs(#aaa)")
|
165
203
|
end
|
166
204
|
|
@@ -799,12 +837,38 @@ class SassFunctionTest < Test::Unit::TestCase
|
|
799
837
|
assert_equal("blue", evaluate("mix(transparentize(#f00, 1), #00f, 0%)"))
|
800
838
|
assert_equal("rgba(0, 0, 255, 0)", evaluate("mix(#f00, transparentize(#00f, 1), 0%)"))
|
801
839
|
assert_equal("rgba(255, 0, 0, 0)", evaluate("mix(transparentize(#f00, 1), #00f, 100%)"))
|
802
|
-
assert_equal("rgba(255, 0, 0, 0)", evaluate("mix($
|
840
|
+
assert_equal("rgba(255, 0, 0, 0)", evaluate("mix($color1: transparentize(#f00, 1), $color2: #00f, $weight: 100%)"))
|
841
|
+
end
|
842
|
+
|
843
|
+
def test_mix_deprecated_arg_name
|
844
|
+
assert_warning <<WARNING do
|
845
|
+
DEPRECATION WARNING: The `$color-1' argument for `mix()' has been renamed to `$color1'.
|
846
|
+
DEPRECATION WARNING: The `$color-2' argument for `mix()' has been renamed to `$color2'.
|
847
|
+
WARNING
|
848
|
+
assert_equal("rgba(255, 0, 0, 0)",
|
849
|
+
evaluate("mix($color-1: transparentize(#f00, 1), $color-2: #00f, $weight: 100%)"))
|
850
|
+
end
|
851
|
+
|
852
|
+
assert_warning <<WARNING do
|
853
|
+
DEPRECATION WARNING: The `$color-1' argument for `mix()' has been renamed to `$color1'.
|
854
|
+
DEPRECATION WARNING: The `$color-2' argument for `mix()' has been renamed to `$color2'.
|
855
|
+
WARNING
|
856
|
+
assert_equal("rgba(0, 0, 255, 0.5)",
|
857
|
+
evaluate("mix($color-1: transparentize(#f00, 1), $color-2: #00f)"))
|
858
|
+
end
|
859
|
+
|
860
|
+
assert_warning <<WARNING do
|
861
|
+
DEPRECATION WARNING: The `$color_1' argument for `mix()' has been renamed to `$color1'.
|
862
|
+
DEPRECATION WARNING: The `$color_2' argument for `mix()' has been renamed to `$color2'.
|
863
|
+
WARNING
|
864
|
+
assert_equal("rgba(0, 0, 255, 0.5)",
|
865
|
+
evaluate("mix($color_1: transparentize(#f00, 1), $color_2: #00f)"))
|
866
|
+
end
|
803
867
|
end
|
804
868
|
|
805
869
|
def test_mix_tests_types
|
806
|
-
assert_error_message("$
|
807
|
-
assert_error_message("$
|
870
|
+
assert_error_message("$color1: \"foo\" is not a color for `mix'", "mix(\"foo\", #f00, 10%)")
|
871
|
+
assert_error_message("$color2: \"foo\" is not a color for `mix'", "mix(#f00, \"foo\", 10%)")
|
808
872
|
assert_error_message("$weight: \"foo\" is not a number for `mix'", "mix(#f00, #baf, \"foo\")")
|
809
873
|
end
|
810
874
|
|
@@ -904,7 +968,7 @@ class SassFunctionTest < Test::Unit::TestCase
|
|
904
968
|
def test_str_index
|
905
969
|
assert_equal('1', evaluate('str-index(abcd, a)'))
|
906
970
|
assert_equal('1', evaluate('str-index(abcd, ab)'))
|
907
|
-
assert_equal(
|
971
|
+
assert_equal(Sass::Script::Value::Null.new, perform('str-index(abcd, X)'))
|
908
972
|
assert_equal('3', evaluate('str-index(abcd, c)'))
|
909
973
|
end
|
910
974
|
|
@@ -1017,9 +1081,28 @@ MSG
|
|
1017
1081
|
assert_equal(%Q{true}, evaluate("comparable(2px, 1px)"))
|
1018
1082
|
assert_equal(%Q{true}, evaluate("comparable(10cm, 3mm)"))
|
1019
1083
|
assert_equal(%Q{false}, evaluate("comparable(100px, 3em)"))
|
1020
|
-
assert_equal(%Q{false}, evaluate("comparable($
|
1021
|
-
|
1022
|
-
|
1084
|
+
assert_equal(%Q{false}, evaluate("comparable($number1: 100px, $number2: 3em)"))
|
1085
|
+
end
|
1086
|
+
|
1087
|
+
def test_comparable_deprecated_arg_name
|
1088
|
+
assert_warning <<WARNING do
|
1089
|
+
DEPRECATION WARNING: The `$number-1' argument for `comparable()' has been renamed to `$number1'.
|
1090
|
+
DEPRECATION WARNING: The `$number-2' argument for `comparable()' has been renamed to `$number2'.
|
1091
|
+
WARNING
|
1092
|
+
assert_equal("false", evaluate("comparable($number-1: 100px, $number-2: 3em)"))
|
1093
|
+
end
|
1094
|
+
|
1095
|
+
assert_warning <<WARNING do
|
1096
|
+
DEPRECATION WARNING: The `$number_1' argument for `comparable()' has been renamed to `$number1'.
|
1097
|
+
DEPRECATION WARNING: The `$number_2' argument for `comparable()' has been renamed to `$number2'.
|
1098
|
+
WARNING
|
1099
|
+
assert_equal("false", evaluate("comparable($number_1: 100px, $number_2: 3em)"))
|
1100
|
+
end
|
1101
|
+
end
|
1102
|
+
|
1103
|
+
def test_comparable_checks_types
|
1104
|
+
assert_error_message("$number1: #ff0000 is not a number for `comparable'", "comparable(#f00, 1px)")
|
1105
|
+
assert_error_message("$number2: #ff0000 is not a number for `comparable'", "comparable(1px, #f00)")
|
1023
1106
|
end
|
1024
1107
|
|
1025
1108
|
def test_length
|
@@ -1174,16 +1257,17 @@ MSG
|
|
1174
1257
|
end
|
1175
1258
|
|
1176
1259
|
def test_index
|
1260
|
+
null = Sass::Script::Value::Null.new
|
1177
1261
|
assert_equal("1", evaluate("index(1px solid blue, 1px)"))
|
1178
1262
|
assert_equal("2", evaluate("index(1px solid blue, solid)"))
|
1179
1263
|
assert_equal("3", evaluate("index(1px solid blue, #00f)"))
|
1180
1264
|
assert_equal("1", evaluate("index(1px, 1px)"))
|
1181
|
-
assert_equal(
|
1182
|
-
assert_equal(
|
1183
|
-
assert_equal(
|
1265
|
+
assert_equal(null, perform("index(1px solid blue, 1em)"))
|
1266
|
+
assert_equal(null, perform("index(1px solid blue, notfound)"))
|
1267
|
+
assert_equal(null, perform("index(1px, #00f)"))
|
1184
1268
|
|
1185
1269
|
assert_equal("1", evaluate("index((foo: bar, bar: baz), (foo bar))"))
|
1186
|
-
assert_equal(
|
1270
|
+
assert_equal(null, perform("index((foo: bar, bar: baz), (foo: bar))"))
|
1187
1271
|
end
|
1188
1272
|
|
1189
1273
|
def test_list_separator
|
@@ -1312,7 +1396,9 @@ SCSS
|
|
1312
1396
|
assert_equal "2", evaluate("map-get((foo: 1, bar: 2), bar)")
|
1313
1397
|
assert_equal "null", perform("map-get((foo: 1, bar: 2), baz)").to_sass
|
1314
1398
|
assert_equal "null", perform("map-get((), foo)").to_sass
|
1399
|
+
end
|
1315
1400
|
|
1401
|
+
def test_map_get_deprecation_warning
|
1316
1402
|
assert_warning(<<WARNING) do
|
1317
1403
|
DEPRECATION WARNING: Passing lists of pairs to map-get is deprecated and will
|
1318
1404
|
be removed in future versions of Sass. Use Sass maps instead. For details, see
|
@@ -1322,6 +1408,10 @@ WARNING
|
|
1322
1408
|
end
|
1323
1409
|
end
|
1324
1410
|
|
1411
|
+
def test_map_get_checks_type
|
1412
|
+
assert_error_message("$map: 12 is not a map for `map-get'", "map-get(12, bar)")
|
1413
|
+
end
|
1414
|
+
|
1325
1415
|
def test_map_merge
|
1326
1416
|
assert_equal("(foo: 1, bar: 2, baz: 3)",
|
1327
1417
|
perform("map-merge((foo: 1, bar: 2), (baz: 3))").to_sass)
|
@@ -1329,7 +1419,9 @@ WARNING
|
|
1329
1419
|
perform("map-merge((), (foo: 1, bar: 2))").to_sass)
|
1330
1420
|
assert_equal("(foo: 1, bar: 2)",
|
1331
1421
|
perform("map-merge((foo: 1, bar: 2), ())").to_sass)
|
1422
|
+
end
|
1332
1423
|
|
1424
|
+
def test_map_merge_deprecation_warning
|
1333
1425
|
assert_warning(<<WARNING) do
|
1334
1426
|
DEPRECATION WARNING: Passing lists of pairs to map-merge is deprecated and will
|
1335
1427
|
be removed in future versions of Sass. Use Sass maps instead. For details, see
|
@@ -1349,11 +1441,39 @@ WARNING
|
|
1349
1441
|
end
|
1350
1442
|
end
|
1351
1443
|
|
1444
|
+
def test_map_merge_checks_type
|
1445
|
+
assert_error_message("$map1: 12 is not a map for `map-merge'", "map-merge(12, (foo: 1))")
|
1446
|
+
assert_error_message("$map2: 12 is not a map for `map-merge'", "map-merge((foo: 1), 12)")
|
1447
|
+
end
|
1448
|
+
|
1449
|
+
def test_map_remove
|
1450
|
+
assert_equal("(foo: 1, baz: 3)",
|
1451
|
+
perform("map-remove((foo: 1, bar: 2, baz: 3), bar)").to_sass)
|
1452
|
+
assert_equal("()", perform("map-remove((), foo)").to_sass)
|
1453
|
+
end
|
1454
|
+
|
1455
|
+
def test_map_remove_deprecation_warning
|
1456
|
+
assert_warning(<<WARNING) do
|
1457
|
+
DEPRECATION WARNING: Passing lists of pairs to map-remove is deprecated and will
|
1458
|
+
be removed in future versions of Sass. Use Sass maps instead. For details, see
|
1459
|
+
http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#maps.
|
1460
|
+
WARNING
|
1461
|
+
assert_equal("(foo: 1, baz: 3)",
|
1462
|
+
perform("map-remove((foo 1, bar 2, baz 3), bar)").to_sass)
|
1463
|
+
end
|
1464
|
+
end
|
1465
|
+
|
1466
|
+
def test_map_remove_checks_type
|
1467
|
+
assert_error_message("$map: 12 is not a map for `map-remove'", "map-remove(12, foo)")
|
1468
|
+
end
|
1469
|
+
|
1352
1470
|
def test_map_keys
|
1353
1471
|
assert_equal("foo, bar",
|
1354
1472
|
perform("map-keys((foo: 1, bar: 2))").to_sass)
|
1355
1473
|
assert_equal("()", perform("map-keys(())").to_sass)
|
1474
|
+
end
|
1356
1475
|
|
1476
|
+
def test_map_keys_deprecation_warning
|
1357
1477
|
assert_warning(<<WARNING) do
|
1358
1478
|
DEPRECATION WARNING: Passing lists of pairs to map-keys is deprecated and will
|
1359
1479
|
be removed in future versions of Sass. Use Sass maps instead. For details, see
|
@@ -1364,12 +1484,18 @@ WARNING
|
|
1364
1484
|
end
|
1365
1485
|
end
|
1366
1486
|
|
1487
|
+
def test_map_keys_checks_type
|
1488
|
+
assert_error_message("$map: 12 is not a map for `map-keys'", "map-keys(12)")
|
1489
|
+
end
|
1490
|
+
|
1367
1491
|
def test_map_values
|
1368
1492
|
assert_equal("1, 2", perform("map-values((foo: 1, bar: 2))").to_sass)
|
1369
1493
|
assert_equal("1, 2, 2",
|
1370
1494
|
perform("map-values((foo: 1, bar: 2, baz: 2))").to_sass)
|
1371
1495
|
assert_equal("()", perform("map-values(())").to_sass)
|
1496
|
+
end
|
1372
1497
|
|
1498
|
+
def test_map_values_deprecation_warning
|
1373
1499
|
assert_warning(<<WARNING) do
|
1374
1500
|
DEPRECATION WARNING: Passing lists of pairs to map-values is deprecated and will
|
1375
1501
|
be removed in future versions of Sass. Use Sass maps instead. For details, see
|
@@ -1379,11 +1505,17 @@ WARNING
|
|
1379
1505
|
end
|
1380
1506
|
end
|
1381
1507
|
|
1508
|
+
def test_map_values_checks_type
|
1509
|
+
assert_error_message("$map: 12 is not a map for `map-values'", "map-values(12)")
|
1510
|
+
end
|
1511
|
+
|
1382
1512
|
def test_map_has_key
|
1383
1513
|
assert_equal "true", evaluate("map-has-key((foo: 1, bar: 1), foo)")
|
1384
1514
|
assert_equal "false", evaluate("map-has-key((foo: 1, bar: 1), baz)")
|
1385
1515
|
assert_equal "false", evaluate("map-has-key((), foo)")
|
1516
|
+
end
|
1386
1517
|
|
1518
|
+
def test_map_has_key_deprecation_warning
|
1387
1519
|
assert_warning(<<WARNING) do
|
1388
1520
|
DEPRECATION WARNING: Passing lists of pairs to map-has-key is deprecated and will
|
1389
1521
|
be removed in future versions of Sass. Use Sass maps instead. For details, see
|
@@ -1393,10 +1525,15 @@ WARNING
|
|
1393
1525
|
end
|
1394
1526
|
end
|
1395
1527
|
|
1528
|
+
def test_map_has_key_checks_type
|
1529
|
+
assert_error_message("$map: 12 is not a map for `map-has-key'", "map-has-key(12, foo)")
|
1530
|
+
end
|
1531
|
+
|
1396
1532
|
def test_keywords
|
1397
1533
|
# The actual functionality is tested in tests where real arglists are passed.
|
1398
|
-
assert_error_message("12 is not a variable argument list for `keywords'", "keywords(12)")
|
1399
|
-
assert_error_message(
|
1534
|
+
assert_error_message("$args: 12 is not a variable argument list for `keywords'", "keywords(12)")
|
1535
|
+
assert_error_message(
|
1536
|
+
"$args: (1 2 3) is not a variable argument list for `keywords'", "keywords(1 2 3)")
|
1400
1537
|
end
|
1401
1538
|
|
1402
1539
|
def test_partial_list_of_pairs_doesnt_work_as_a_map
|
@@ -1462,6 +1599,27 @@ WARNING
|
|
1462
1599
|
env("fn" => Sass::Script::String.new("lighten"))))
|
1463
1600
|
end
|
1464
1601
|
|
1602
|
+
def test_call_uses_local_scope
|
1603
|
+
assert_equal <<CSS, render(<<SCSS)
|
1604
|
+
.first-scope {
|
1605
|
+
a: local; }
|
1606
|
+
|
1607
|
+
.second-scope {
|
1608
|
+
a: global; }
|
1609
|
+
CSS
|
1610
|
+
@function foo() {@return global}
|
1611
|
+
|
1612
|
+
.first-scope {
|
1613
|
+
@function foo() {@return local}
|
1614
|
+
a: call(foo);
|
1615
|
+
}
|
1616
|
+
|
1617
|
+
.second-scope {
|
1618
|
+
a: call(foo);
|
1619
|
+
}
|
1620
|
+
SCSS
|
1621
|
+
end
|
1622
|
+
|
1465
1623
|
def test_call_unknown_function
|
1466
1624
|
assert_equal evaluate("unknown(red, blue)"), evaluate("call(unknown, red, blue)")
|
1467
1625
|
end
|
@@ -1495,6 +1653,10 @@ $global-var: has-value;
|
|
1495
1653
|
SCSS
|
1496
1654
|
end
|
1497
1655
|
|
1656
|
+
def test_variable_exists_checks_type
|
1657
|
+
assert_error_message("$name: 1 is not a string for `variable-exists'", "variable-exists(1)")
|
1658
|
+
end
|
1659
|
+
|
1498
1660
|
def test_global_variable_exists
|
1499
1661
|
assert_equal <<CSS, render(<<SCSS)
|
1500
1662
|
.test {
|
@@ -1524,6 +1686,11 @@ $named: global-variable-exists($name: g);
|
|
1524
1686
|
SCSS
|
1525
1687
|
end
|
1526
1688
|
|
1689
|
+
def test_global_variable_exists_checks_type
|
1690
|
+
assert_error_message("$name: 1 is not a string for `global-variable-exists'",
|
1691
|
+
"global-variable-exists(1)")
|
1692
|
+
end
|
1693
|
+
|
1527
1694
|
def test_function_exists
|
1528
1695
|
# built-ins
|
1529
1696
|
assert_equal "true", evaluate("function-exists(lighten)")
|
@@ -1543,6 +1710,10 @@ CSS
|
|
1543
1710
|
SCSS
|
1544
1711
|
end
|
1545
1712
|
|
1713
|
+
def test_function_exists_checks_type
|
1714
|
+
assert_error_message("$name: 1 is not a string for `function-exists'", "function-exists(1)")
|
1715
|
+
end
|
1716
|
+
|
1546
1717
|
def test_mixin_exists
|
1547
1718
|
assert_equal "false", evaluate("mixin-exists(foo)")
|
1548
1719
|
# with named argument
|
@@ -1560,11 +1731,8 @@ CSS
|
|
1560
1731
|
SCSS
|
1561
1732
|
end
|
1562
1733
|
|
1563
|
-
def
|
1564
|
-
assert_error_message("
|
1565
|
-
assert_error_message("2px is not a string for `mixin-exists'", "mixin-exists(2px)")
|
1566
|
-
assert_error_message("2px is not a string for `global-variable-exists'", "global-variable-exists(2px)")
|
1567
|
-
assert_error_message("2px is not a string for `variable-exists'", "variable-exists(2px)")
|
1734
|
+
def test_mixin_exists_checks_type
|
1735
|
+
assert_error_message("$name: 1 is not a string for `mixin-exists'", "mixin-exists(1)")
|
1568
1736
|
end
|
1569
1737
|
|
1570
1738
|
def test_inspect
|
@@ -1574,6 +1742,45 @@ SCSS
|
|
1574
1742
|
assert_equal "(a: 1, b: 2)", evaluate("inspect((a: 1, b: 2))")
|
1575
1743
|
end
|
1576
1744
|
|
1745
|
+
def test_random
|
1746
|
+
Sass::Script::Functions.random_seed = 1
|
1747
|
+
assert_equal "0.41702", evaluate("random()")
|
1748
|
+
assert_equal "13", evaluate("random(100)")
|
1749
|
+
end
|
1750
|
+
|
1751
|
+
def test_random_works_without_a_seed
|
1752
|
+
if Sass::Script::Functions.instance_variable_defined?("@random_number_generator")
|
1753
|
+
Sass::Script::Functions.send(:remove_instance_variable, "@random_number_generator")
|
1754
|
+
end
|
1755
|
+
|
1756
|
+
result = perform("random()")
|
1757
|
+
assert_kind_of Sass::Script::Number, result
|
1758
|
+
assert result.value >= 0, "Random number was below 0"
|
1759
|
+
assert result.value <= 1, "Random number was above 1"
|
1760
|
+
end
|
1761
|
+
|
1762
|
+
def test_random_with_limit_one
|
1763
|
+
# Passing 1 as the limit should always return 1, since limit calls return
|
1764
|
+
# integers from 1 to the argument, so when the argument is 1, its a predicatble
|
1765
|
+
# outcome
|
1766
|
+
assert "1", evaluate("random(1)")
|
1767
|
+
end
|
1768
|
+
|
1769
|
+
def test_random_with_limit_too_low
|
1770
|
+
assert_error_message("$limit 0 must be greater than or equal to 1 for `random'", "random(0)")
|
1771
|
+
end
|
1772
|
+
|
1773
|
+
def test_random_with_non_integer_limit
|
1774
|
+
assert_error_message("Expected $limit to be an integer but got 1.5 for `random'", "random(1.5)")
|
1775
|
+
end
|
1776
|
+
|
1777
|
+
# This could *possibly* fail, but exceedingly unlikely
|
1778
|
+
def test_random_is_semi_unique
|
1779
|
+
if Sass::Script::Functions.instance_variable_defined?("@random_number_generator")
|
1780
|
+
Sass::Script::Functions.send(:remove_instance_variable, "@random_number_generator")
|
1781
|
+
end
|
1782
|
+
assert_not_equal evaluate("random()"), evaluate("random()")
|
1783
|
+
end
|
1577
1784
|
|
1578
1785
|
## Regression Tests
|
1579
1786
|
|
data/test/sass/importer_test.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
require File.dirname(__FILE__) + '/../test_helper'
|
3
3
|
require File.dirname(__FILE__) + '/test_helper'
|
4
|
-
|
4
|
+
require 'mock_importer'
|
5
5
|
require 'sass/plugin'
|
6
6
|
|
7
7
|
class ImporterTest < Test::Unit::TestCase
|
8
|
-
|
8
|
+
|
9
9
|
class FruitImporter < Sass::Importers::Base
|
10
10
|
def find(name, context = nil)
|
11
11
|
fruit = parse(name)
|
@@ -31,7 +31,7 @@ class ImporterTest < Test::Unit::TestCase
|
|
31
31
|
[self.class.name, name]
|
32
32
|
end
|
33
33
|
|
34
|
-
def public_url(name)
|
34
|
+
def public_url(name, sourcemap_directory = nil)
|
35
35
|
"http://#{parse(name)}.example.com/style.scss"
|
36
36
|
end
|
37
37
|
|
@@ -42,6 +42,18 @@ class ImporterTest < Test::Unit::TestCase
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
+
class NoPublicUrlImporter < FruitImporter
|
46
|
+
def public_url(name, sourcemap_directory = nil)
|
47
|
+
nil
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def parse(name)
|
53
|
+
name[%r{ephemeral/(\w+)(\.s[ac]ss)?}, 1]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
45
57
|
# This class proves that you can override the extension scheme for importers
|
46
58
|
class ReversedExtImporter < Sass::Importers::Filesystem
|
47
59
|
def extensions
|
@@ -207,15 +219,61 @@ SCSS
|
|
207
219
|
"version": 3,
|
208
220
|
"mappings": "AAAA,QAAS;EACP,KAAK,EAAE,IAAI",
|
209
221
|
"sources": ["http://orange.example.com/style.scss"],
|
222
|
+
"names": [],
|
210
223
|
"file": "css_uri"
|
211
224
|
}
|
212
225
|
JSON
|
213
226
|
end
|
214
227
|
|
228
|
+
def test_source_map_with_only_css_uri_can_have_no_public_url_without_warning
|
229
|
+
ephemeral_importer = NoPublicUrlImporter.new
|
230
|
+
mock_importer = MockImporter.new
|
231
|
+
def mock_importer.public_url(name, sourcemap_directory = nil)
|
232
|
+
"css_uri"
|
233
|
+
end
|
234
|
+
|
235
|
+
options = {
|
236
|
+
:filename => filename_for_test,
|
237
|
+
:sourcemap_filename => sourcemap_filename_for_test,
|
238
|
+
:importer => mock_importer,
|
239
|
+
:syntax => :scss,
|
240
|
+
:load_paths => [ephemeral_importer],
|
241
|
+
:cache => false
|
242
|
+
}
|
243
|
+
|
244
|
+
engine = Sass::Engine.new(<<SCSS, options)
|
245
|
+
@import "ephemeral/orange";
|
246
|
+
.orange {
|
247
|
+
@include orange;
|
248
|
+
}
|
249
|
+
SCSS
|
250
|
+
|
251
|
+
assert_warning("") do
|
252
|
+
css_output, sourcemap = engine.render_with_sourcemap('sourcemap_uri')
|
253
|
+
assert_equal <<CSS.strip, css_output.strip
|
254
|
+
.orange {
|
255
|
+
color: orange; }
|
256
|
+
|
257
|
+
/*# sourceMappingURL=sourcemap_uri */
|
258
|
+
CSS
|
259
|
+
map = sourcemap.to_json(:css_uri => 'css_uri')
|
260
|
+
assert_equal <<JSON.strip, map
|
261
|
+
{
|
262
|
+
"version": 3,
|
263
|
+
"mappings": "AACA,OAAQ",
|
264
|
+
"sources": ["css_uri"],
|
265
|
+
"names": [],
|
266
|
+
"file": "css_uri"
|
267
|
+
}
|
268
|
+
JSON
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
215
272
|
def test_source_map_with_only_css_uri_doesnt_support_filesystem_importer
|
216
273
|
file_system_importer = Sass::Importers::Filesystem.new('.')
|
217
274
|
options = {
|
218
275
|
:filename => filename_for_test(:scss),
|
276
|
+
:sourcemap_filename => sourcemap_filename_for_test,
|
219
277
|
:importer => file_system_importer,
|
220
278
|
:syntax => :scss
|
221
279
|
}
|
@@ -229,7 +287,6 @@ SCSS
|
|
229
287
|
assert_warning(<<WARNING) {sourcemap.to_json(:css_uri => 'css_uri')}
|
230
288
|
WARNING: Couldn't determine public URL for "#{filename_for_test(:scss)}" while generating sourcemap.
|
231
289
|
Without a public URL, there's nothing for the source map to link to.
|
232
|
-
Custom importers should define the #public_url method.
|
233
290
|
WARNING
|
234
291
|
end
|
235
292
|
|
@@ -237,6 +294,7 @@ WARNING
|
|
237
294
|
file_system_importer = Sass::Importers::Filesystem.new('.')
|
238
295
|
options = {
|
239
296
|
:filename => filename_for_test(:scss),
|
297
|
+
:sourcemap_filename => sourcemap_filename_for_test,
|
240
298
|
:importer => file_system_importer,
|
241
299
|
:syntax => :scss
|
242
300
|
}
|
@@ -250,14 +308,16 @@ SCSS
|
|
250
308
|
assert_warning(<<WARNING) {sourcemap.to_json(:css_uri => 'css_uri', :css_path => 'css_path')}
|
251
309
|
WARNING: Couldn't determine public URL for "#{filename_for_test(:scss)}" while generating sourcemap.
|
252
310
|
Without a public URL, there's nothing for the source map to link to.
|
253
|
-
Custom importers should define the #public_url method.
|
254
311
|
WARNING
|
255
312
|
end
|
256
313
|
|
257
314
|
def test_source_map_with_css_uri_and_sourcemap_path_supports_filesystem_importer
|
258
315
|
file_system_importer = Sass::Importers::Filesystem.new('.')
|
316
|
+
css_uri = 'css_uri'
|
317
|
+
sourcemap_path = 'map/style.map'
|
259
318
|
options = {
|
260
319
|
:filename => 'sass/style.scss',
|
320
|
+
:sourcemap_filename => sourcemap_path,
|
261
321
|
:importer => file_system_importer,
|
262
322
|
:syntax => :scss
|
263
323
|
}
|
@@ -270,13 +330,12 @@ SCSS
|
|
270
330
|
|
271
331
|
|
272
332
|
rendered, sourcemap = engine.render_with_sourcemap('http://map.example.com/map/style.map')
|
273
|
-
css_uri = 'css_uri'
|
274
|
-
sourcemap_path = 'map/style.map'
|
275
333
|
assert_equal <<JSON.strip, sourcemap.to_json(:css_uri => css_uri, :sourcemap_path => sourcemap_path)
|
276
334
|
{
|
277
335
|
"version": 3,
|
278
336
|
"mappings": "AAAA,IAAK;EAAC,CAAC,EAAE,CAAC",
|
279
337
|
"sources": ["../sass/style.scss"],
|
338
|
+
"names": [],
|
280
339
|
"file": "css_uri"
|
281
340
|
}
|
282
341
|
JSON
|
@@ -284,8 +343,12 @@ JSON
|
|
284
343
|
|
285
344
|
def test_source_map_with_css_path_and_sourcemap_path_supports_file_system_importer
|
286
345
|
file_system_importer = Sass::Importers::Filesystem.new('.')
|
346
|
+
sass_path = 'sass/style.scss'
|
347
|
+
css_path = 'static/style.css'
|
348
|
+
sourcemap_path = 'map/style.map'
|
287
349
|
options = {
|
288
|
-
:filename =>
|
350
|
+
:filename => sass_path,
|
351
|
+
:sourcemap_filename => sourcemap_path,
|
289
352
|
:importer => file_system_importer,
|
290
353
|
:syntax => :scss
|
291
354
|
}
|
@@ -295,13 +358,12 @@ JSON
|
|
295
358
|
SCSS
|
296
359
|
|
297
360
|
_, sourcemap = engine.render_with_sourcemap('http://map.example.com/map/style.map')
|
298
|
-
css_path = 'static/style.css'
|
299
|
-
sourcemap_path = 'map/style.map'
|
300
361
|
assert_equal <<JSON.strip, sourcemap.to_json(:css_path => css_path, :sourcemap_path => sourcemap_path)
|
301
362
|
{
|
302
363
|
"version": 3,
|
303
364
|
"mappings": "AAAA,IAAK;EAAC,CAAC,EAAE,CAAC",
|
304
365
|
"sources": ["../sass/style.scss"],
|
366
|
+
"names": [],
|
305
367
|
"file": "../static/style.css"
|
306
368
|
}
|
307
369
|
JSON
|