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.
Files changed (76) hide show
  1. checksums.yaml +15 -0
  2. data/CONTRIBUTING +1 -1
  3. data/README.md +7 -7
  4. data/Rakefile +4 -2
  5. data/VERSION +1 -1
  6. data/VERSION_DATE +1 -1
  7. data/bin/sass +5 -1
  8. data/bin/sass-convert +5 -1
  9. data/bin/scss +5 -1
  10. data/ext/mkrf_conf.rb +23 -0
  11. data/lib/sass/css.rb +1 -1
  12. data/lib/sass/engine.rb +19 -9
  13. data/lib/sass/environment.rb +8 -0
  14. data/lib/sass/exec.rb +4 -4
  15. data/lib/sass/features.rb +0 -1
  16. data/lib/sass/importers/base.rb +13 -6
  17. data/lib/sass/importers/deprecated_path.rb +8 -2
  18. data/lib/sass/importers/filesystem.rb +33 -7
  19. data/lib/sass/logger.rb +1 -4
  20. data/lib/sass/logger/base.rb +0 -2
  21. data/lib/sass/logger/log_level.rb +0 -2
  22. data/lib/sass/plugin.rb +2 -2
  23. data/lib/sass/plugin/compiler.rb +23 -11
  24. data/lib/sass/plugin/configuration.rb +0 -1
  25. data/lib/sass/railtie.rb +1 -0
  26. data/lib/sass/script/css_lexer.rb +0 -1
  27. data/lib/sass/script/css_parser.rb +0 -1
  28. data/lib/sass/script/functions.rb +158 -96
  29. data/lib/sass/script/lexer.rb +29 -35
  30. data/lib/sass/script/parser.rb +10 -3
  31. data/lib/sass/script/tree.rb +0 -1
  32. data/lib/sass/script/tree/funcall.rb +21 -5
  33. data/lib/sass/script/tree/list_literal.rb +0 -1
  34. data/lib/sass/script/value/arg_list.rb +7 -3
  35. data/lib/sass/script/value/bool.rb +0 -1
  36. data/lib/sass/script/value/null.rb +0 -1
  37. data/lib/sass/script/value/number.rb +2 -6
  38. data/lib/sass/scss/css_parser.rb +0 -1
  39. data/lib/sass/scss/parser.rb +5 -5
  40. data/lib/sass/scss/script_lexer.rb +0 -1
  41. data/lib/sass/scss/script_parser.rb +0 -1
  42. data/lib/sass/selector.rb +11 -1
  43. data/lib/sass/selector/comma_sequence.rb +3 -4
  44. data/lib/sass/selector/sequence.rb +11 -7
  45. data/lib/sass/selector/simple_sequence.rb +42 -11
  46. data/lib/sass/source/map.rb +6 -19
  47. data/lib/sass/tree/at_root_node.rb +1 -1
  48. data/lib/sass/tree/mixin_node.rb +2 -2
  49. data/lib/sass/tree/prop_node.rb +0 -1
  50. data/lib/sass/tree/variable_node.rb +0 -5
  51. data/lib/sass/tree/visitors/check_nesting.rb +0 -1
  52. data/lib/sass/tree/visitors/convert.rb +2 -2
  53. data/lib/sass/tree/visitors/cssize.rb +184 -84
  54. data/lib/sass/tree/visitors/deep_copy.rb +0 -1
  55. data/lib/sass/tree/visitors/perform.rb +14 -44
  56. data/lib/sass/util.rb +59 -12
  57. data/lib/sass/util/cross_platform_random.rb +19 -0
  58. data/lib/sass/util/normalized_map.rb +17 -1
  59. data/test/sass/compiler_test.rb +10 -0
  60. data/test/sass/conversion_test.rb +36 -0
  61. data/test/sass/css2sass_test.rb +19 -0
  62. data/test/sass/engine_test.rb +54 -105
  63. data/test/sass/functions_test.rb +233 -26
  64. data/test/sass/importer_test.rb +72 -10
  65. data/test/sass/plugin_test.rb +14 -0
  66. data/test/sass/script_conversion_test.rb +4 -4
  67. data/test/sass/script_test.rb +58 -21
  68. data/test/sass/scss/css_test.rb +8 -1
  69. data/test/sass/scss/scss_test.rb +376 -179
  70. data/test/sass/source_map_test.rb +8 -0
  71. data/test/sass/templates/subdir/import_up1.scss +1 -0
  72. data/test/sass/templates/subdir/import_up2.scss +1 -0
  73. data/test/sass/util_test.rb +16 -0
  74. data/test/test_helper.rb +12 -4
  75. metadata +269 -287
  76. data/lib/sass/script/tree/selector.rb +0 -30
@@ -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($value: 0.5)"))
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("$value: 25px is not a unitless number for `percentage'", "percentage(25px)")
128
- assert_error_message("$value: #cccccc is not a unitless number for `percentage'", "percentage(#ccc)")
129
- assert_error_message("$value: \"string\" is not a unitless number for `percentage'", %Q{percentage("string")})
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($value: 5.49px)"))
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($value: 4.8px)"))
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($value: 4.8px)"))
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($value: 5px)"))
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($color-1: transparentize(#f00, 1), $color-2: #00f, $weight: 100%)"))
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("$color-1: \"foo\" is not a color for `mix'", "mix(\"foo\", #f00, 10%)")
807
- assert_error_message("$color-2: \"foo\" is not a color for `mix'", "mix(#f00, \"foo\", 10%)")
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('0', evaluate('str-index(abcd, X)'))
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($number-1: 100px, $number-2: 3em)"))
1021
- assert_error_message("$number-1: #ff0000 is not a number for `comparable'", "comparable(#f00, 1px)")
1022
- assert_error_message("$number-2: #ff0000 is not a number for `comparable'", "comparable(1px, #f00)")
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("false", evaluate("index(1px solid blue, 1em)"))
1182
- assert_equal("false", evaluate("index(1px solid blue, notfound)"))
1183
- assert_equal("false", evaluate("index(1px, #00f)"))
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("false", evaluate("index((foo: bar, bar: baz), (foo: bar))"))
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("(1 2 3) is not a variable argument list for `keywords'", "keywords(1 2 3)")
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 test_existence_functions_check_argument_type
1564
- assert_error_message("2px is not a string for `function-exists'", "function-exists(2px)")
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
 
@@ -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 => 'sass/style.scss',
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