sass 3.3.0.rc.2 → 3.3.0.rc.3
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 +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
|