sass 3.3.14 → 3.4.0.rc.1
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 +4 -4
- data/MIT-LICENSE +1 -1
- data/README.md +5 -5
- data/VERSION +1 -1
- data/VERSION_DATE +1 -1
- data/VERSION_NAME +1 -1
- data/bin/sass +1 -1
- data/bin/scss +1 -1
- data/lib/sass.rb +0 -5
- data/lib/sass/css.rb +1 -3
- data/lib/sass/engine.rb +28 -39
- data/lib/sass/environment.rb +13 -17
- data/lib/sass/error.rb +6 -9
- data/lib/sass/exec.rb +5 -771
- data/lib/sass/exec/base.rb +187 -0
- data/lib/sass/exec/sass_convert.rb +264 -0
- data/lib/sass/exec/sass_scss.rb +419 -0
- data/lib/sass/features.rb +6 -0
- data/lib/sass/importers.rb +0 -1
- data/lib/sass/importers/base.rb +5 -1
- data/lib/sass/importers/filesystem.rb +4 -21
- data/lib/sass/media.rb +1 -4
- data/lib/sass/plugin/compiler.rb +32 -136
- data/lib/sass/script/css_lexer.rb +1 -1
- data/lib/sass/script/functions.rb +363 -39
- data/lib/sass/script/lexer.rb +68 -50
- data/lib/sass/script/parser.rb +29 -14
- data/lib/sass/script/tree.rb +1 -0
- data/lib/sass/script/tree/funcall.rb +1 -1
- data/lib/sass/script/tree/interpolation.rb +19 -1
- data/lib/sass/script/tree/selector.rb +26 -0
- data/lib/sass/script/value.rb +0 -1
- data/lib/sass/script/value/bool.rb +0 -5
- data/lib/sass/script/value/color.rb +32 -12
- data/lib/sass/script/value/helpers.rb +107 -0
- data/lib/sass/script/value/list.rb +0 -15
- data/lib/sass/script/value/null.rb +0 -5
- data/lib/sass/script/value/number.rb +60 -14
- data/lib/sass/script/value/string.rb +53 -9
- data/lib/sass/scss/css_parser.rb +8 -2
- data/lib/sass/scss/parser.rb +175 -319
- data/lib/sass/scss/rx.rb +14 -5
- data/lib/sass/scss/static_parser.rb +298 -1
- data/lib/sass/selector.rb +56 -193
- data/lib/sass/selector/abstract_sequence.rb +28 -13
- data/lib/sass/selector/comma_sequence.rb +91 -12
- data/lib/sass/selector/pseudo.rb +256 -0
- data/lib/sass/selector/sequence.rb +99 -31
- data/lib/sass/selector/simple.rb +14 -25
- data/lib/sass/selector/simple_sequence.rb +101 -37
- data/lib/sass/shared.rb +1 -1
- data/lib/sass/source/map.rb +23 -9
- data/lib/sass/stack.rb +0 -6
- data/lib/sass/supports.rb +1 -1
- data/lib/sass/tree/at_root_node.rb +1 -0
- data/lib/sass/tree/directive_node.rb +7 -1
- data/lib/sass/tree/error_node.rb +18 -0
- data/lib/sass/tree/keyframe_rule_node.rb +15 -0
- data/lib/sass/tree/prop_node.rb +1 -1
- data/lib/sass/tree/rule_node.rb +11 -6
- data/lib/sass/tree/visitors/check_nesting.rb +3 -4
- data/lib/sass/tree/visitors/convert.rb +8 -17
- data/lib/sass/tree/visitors/cssize.rb +12 -24
- data/lib/sass/tree/visitors/deep_copy.rb +5 -0
- data/lib/sass/tree/visitors/perform.rb +43 -28
- data/lib/sass/tree/visitors/set_options.rb +5 -0
- data/lib/sass/tree/visitors/to_css.rb +14 -13
- data/lib/sass/util.rb +94 -90
- data/test/sass/cache_test.rb +1 -1
- data/test/sass/callbacks_test.rb +1 -1
- data/test/sass/compiler_test.rb +5 -14
- data/test/sass/conversion_test.rb +47 -1
- data/test/sass/css2sass_test.rb +3 -3
- data/test/sass/encoding_test.rb +219 -0
- data/test/sass/engine_test.rb +128 -191
- data/test/sass/exec_test.rb +2 -2
- data/test/sass/extend_test.rb +234 -17
- data/test/sass/functions_test.rb +268 -213
- data/test/sass/importer_test.rb +31 -21
- data/test/sass/logger_test.rb +1 -1
- data/test/sass/more_results/more_import.css +1 -1
- data/test/sass/plugin_test.rb +12 -11
- data/test/sass/results/compact.css +1 -1
- data/test/sass/results/complex.css +4 -4
- data/test/sass/results/expanded.css +1 -1
- data/test/sass/results/import.css +1 -1
- data/test/sass/results/import_charset_ibm866.css +2 -2
- data/test/sass/results/mixins.css +17 -17
- data/test/sass/results/nested.css +1 -1
- data/test/sass/results/parent_ref.css +2 -2
- data/test/sass/results/script.css +3 -3
- data/test/sass/results/scss_import.css +1 -1
- data/test/sass/script_conversion_test.rb +7 -4
- data/test/sass/script_test.rb +202 -79
- data/test/sass/scss/css_test.rb +95 -25
- data/test/sass/scss/rx_test.rb +4 -4
- data/test/sass/scss/scss_test.rb +363 -19
- data/test/sass/source_map_test.rb +48 -41
- data/test/sass/superselector_test.rb +191 -0
- data/test/sass/templates/scss_import.scss +2 -1
- data/test/sass/test_helper.rb +1 -1
- data/test/sass/util/multibyte_string_scanner_test.rb +1 -1
- data/test/sass/util/normalized_map_test.rb +1 -1
- data/test/sass/util/subset_map_test.rb +2 -2
- data/test/sass/util_test.rb +1 -1
- data/test/sass/value_helpers_test.rb +3 -3
- data/test/test_helper.rb +2 -2
- metadata +30 -7
- data/lib/sass/importers/deprecated_path.rb +0 -51
- data/lib/sass/script/value/deprecated_false.rb +0 -55
data/test/sass/exec_test.rb
CHANGED
@@ -3,7 +3,7 @@ require File.dirname(__FILE__) + '/../test_helper'
|
|
3
3
|
require 'sass/util/test'
|
4
4
|
require 'tmpdir'
|
5
5
|
|
6
|
-
class ExecTest < Test
|
6
|
+
class ExecTest < MiniTest::Test
|
7
7
|
include Sass::Util::Test
|
8
8
|
|
9
9
|
def setup
|
@@ -19,7 +19,7 @@ class ExecTest < Test::Unit::TestCase
|
|
19
19
|
src = get_path("src.scss")
|
20
20
|
dest = get_path("dest.css")
|
21
21
|
write(src, ".ruleset { margin: 0 }")
|
22
|
-
assert(exec(*%w[scss -t expanded --unix-newlines].push(src, dest)))
|
22
|
+
assert(exec(*%w[scss --sourcemap=none -t expanded --unix-newlines].push(src, dest)))
|
23
23
|
assert_equal(".ruleset {\n margin: 0;\n}\n", read(dest))
|
24
24
|
end
|
25
25
|
|
data/test/sass/extend_test.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
require File.dirname(__FILE__) + '/../test_helper'
|
3
3
|
|
4
|
-
class ExtendTest < Test
|
4
|
+
class ExtendTest < MiniTest::Test
|
5
5
|
def test_basic
|
6
6
|
assert_equal <<CSS, render(<<SCSS)
|
7
7
|
.foo, .bar {
|
@@ -310,9 +310,183 @@ SCSS
|
|
310
310
|
end
|
311
311
|
|
312
312
|
def test_negation_unification
|
313
|
-
|
314
|
-
|
315
|
-
|
313
|
+
assert_extends ':not(.foo).baz', ':not(.bar) {@extend .baz}', ':not(.foo).baz, :not(.foo):not(.bar)'
|
314
|
+
# Unifying to :not(.foo) here would reduce the specificity of the original selector.
|
315
|
+
assert_extends ':not(.foo).baz', ':not(.foo) {@extend .baz}', ':not(.foo).baz, :not(.foo)'
|
316
|
+
end
|
317
|
+
|
318
|
+
def test_prefixed_pseudoclass_unification
|
319
|
+
assert_unification(
|
320
|
+
':nth-child(2n+1 of .foo).baz',
|
321
|
+
':nth-child(2n of .foo) {@extend .baz}',
|
322
|
+
':nth-child(2n+1 of .foo).baz, :nth-child(2n+1 of .foo):nth-child(2n of .foo)')
|
323
|
+
|
324
|
+
assert_unification(
|
325
|
+
':nth-child(2n+1 of .foo).baz',
|
326
|
+
':nth-child(2n+1 of .bar) {@extend .baz}',
|
327
|
+
':nth-child(2n+1 of .foo).baz, :nth-child(2n+1 of .foo):nth-child(2n+1 of .bar)')
|
328
|
+
|
329
|
+
assert_unification(
|
330
|
+
':nth-child(2n+1 of .foo).baz',
|
331
|
+
':nth-child(2n+1 of .foo) {@extend .baz}',
|
332
|
+
':nth-child(2n+1 of .foo)')
|
333
|
+
end
|
334
|
+
|
335
|
+
def test_extend_into_not
|
336
|
+
assert_extends(':not(.foo)', '.x {@extend .foo}', ':not(.foo, .x)')
|
337
|
+
assert_extends(':not(.foo.bar)', '.x {@extend .bar}', ':not(.foo.bar, .foo.x)')
|
338
|
+
assert_extends(
|
339
|
+
':not(.foo.bar, .baz.bar)',
|
340
|
+
'.x {@extend .bar}',
|
341
|
+
':not(.foo.bar, .foo.x, .baz.bar, .baz.x)')
|
342
|
+
end
|
343
|
+
|
344
|
+
def test_extend_into_mergeable_pseudoclasses
|
345
|
+
assert_extends(':matches(.foo)', '.x {@extend .foo}', ':matches(.foo, .x)')
|
346
|
+
assert_extends(':matches(.foo.bar)', '.x {@extend .bar}', ':matches(.foo.bar, .foo.x)')
|
347
|
+
assert_extends(
|
348
|
+
':matches(.foo.bar, .baz.bar)',
|
349
|
+
'.x {@extend .bar}',
|
350
|
+
':matches(.foo.bar, .foo.x, .baz.bar, .baz.x)')
|
351
|
+
|
352
|
+
assert_extends(':-moz-any(.foo)', '.x {@extend .foo}', ':-moz-any(.foo, .x)')
|
353
|
+
assert_extends(':current(.foo)', '.x {@extend .foo}', ':current(.foo, .x)')
|
354
|
+
assert_extends(':has(.foo)', '.x {@extend .foo}', ':has(.foo, .x)')
|
355
|
+
assert_extends(':host(.foo)', '.x {@extend .foo}', ':host(.foo, .x)')
|
356
|
+
assert_extends(':host-context(.foo)', '.x {@extend .foo}', ':host-context(.foo, .x)')
|
357
|
+
assert_extends(':nth-child(n of .foo)', '.x {@extend .foo}', ':nth-child(n of .foo, .x)')
|
358
|
+
assert_extends(
|
359
|
+
':nth-last-child(n of .foo)',
|
360
|
+
'.x {@extend .foo}',
|
361
|
+
':nth-last-child(n of .foo, .x)')
|
362
|
+
end
|
363
|
+
|
364
|
+
def test_complex_extend_into_pseudoclass
|
365
|
+
assert_extends(':not(.bar)', '.x .y {@extend .bar}', ':not(.bar, .x .y)')
|
366
|
+
assert_extends(':matches(.bar)', '.x .y {@extend .bar}', ':matches(.bar, .x .y)')
|
367
|
+
assert_extends(':current(.bar)', '.x .y {@extend .bar}', ':current(.bar, .x .y)')
|
368
|
+
assert_extends(':has(.bar)', '.x .y {@extend .bar}', ':has(.bar, .x .y)')
|
369
|
+
assert_extends(':host(.bar)', '.x .y {@extend .bar}', ':host(.bar, .x .y)')
|
370
|
+
assert_extends(':host-context(.bar)', '.x .y {@extend .bar}', ':host-context(.bar, .x .y)')
|
371
|
+
assert_extends(
|
372
|
+
':-moz-any(.bar)',
|
373
|
+
'.x .y {@extend .bar}',
|
374
|
+
':-moz-any(.bar, .x .y)')
|
375
|
+
assert_extends(
|
376
|
+
':nth-child(n of .bar)',
|
377
|
+
'.x .y {@extend .bar}',
|
378
|
+
':nth-child(n of .bar, .x .y)')
|
379
|
+
assert_extends(
|
380
|
+
':nth-last-child(n of .bar)',
|
381
|
+
'.x .y {@extend .bar}',
|
382
|
+
':nth-last-child(n of .bar, .x .y)')
|
383
|
+
end
|
384
|
+
|
385
|
+
def test_extend_over_selector_pseudoclass
|
386
|
+
assert_extends(':not(.foo)', '.x {@extend :not(.foo)}', ':not(.foo), .x')
|
387
|
+
assert_extends(
|
388
|
+
':matches(.foo, .bar)',
|
389
|
+
'.x {@extend :matches(.foo, .bar)}',
|
390
|
+
':matches(.foo, .bar), .x')
|
391
|
+
end
|
392
|
+
|
393
|
+
def test_matches_within_not
|
394
|
+
assert_extends(
|
395
|
+
':not(.foo, .bar)',
|
396
|
+
':matches(.x, .y) {@extend .foo}',
|
397
|
+
':not(.foo, .x, .y, .bar)')
|
398
|
+
end
|
399
|
+
|
400
|
+
def test_pseudoclasses_merge
|
401
|
+
assert_extends(':matches(.foo)', ':matches(.bar) {@extend .foo}', ':matches(.foo, .bar)')
|
402
|
+
assert_extends(':-moz-any(.foo)', ':-moz-any(.bar) {@extend .foo}', ':-moz-any(.foo, .bar)')
|
403
|
+
assert_extends(':current(.foo)', ':current(.bar) {@extend .foo}', ':current(.foo, .bar)')
|
404
|
+
assert_extends(
|
405
|
+
':nth-child(n of .foo)',
|
406
|
+
':nth-child(n of .bar) {@extend .foo}',
|
407
|
+
':nth-child(n of .foo, .bar)')
|
408
|
+
assert_extends(
|
409
|
+
':nth-last-child(n of .foo)',
|
410
|
+
':nth-last-child(n of .bar) {@extend .foo}',
|
411
|
+
':nth-last-child(n of .foo, .bar)')
|
412
|
+
end
|
413
|
+
|
414
|
+
def test_nesting_pseudoclasses_merge
|
415
|
+
assert_extends(':has(.foo)', ':has(.bar) {@extend .foo}', ':has(.foo, :has(.bar))')
|
416
|
+
assert_extends(':host(.foo)', ':host(.bar) {@extend .foo}', ':host(.foo, :host(.bar))')
|
417
|
+
assert_extends(
|
418
|
+
':host-context(.foo)',
|
419
|
+
':host-context(.bar) {@extend .foo}',
|
420
|
+
':host-context(.foo, :host-context(.bar))')
|
421
|
+
end
|
422
|
+
|
423
|
+
def test_not_unifies_with_unique_values
|
424
|
+
assert_unification('foo', ':not(bar) {@extend foo}', ':not(bar)')
|
425
|
+
assert_unification('#foo', ':not(#bar) {@extend #foo}', ':not(#bar)')
|
426
|
+
end
|
427
|
+
|
428
|
+
def test_not_adds_no_specificity
|
429
|
+
assert_specificity_equals(':not(.foo)', '.foo')
|
430
|
+
end
|
431
|
+
|
432
|
+
def test_matches_has_a_specificity_range
|
433
|
+
# `:matches(.foo, #bar)` has minimum specificity equal to that of `.foo`,
|
434
|
+
# which means `:matches(.foo, #bar) .a` can have less specificity than
|
435
|
+
# `#b.a`. Thus the selector generated by `#b.a` should be preserved.
|
436
|
+
assert_equal <<CSS, render(<<SCSS)
|
437
|
+
:matches(.foo, #bar) .a, :matches(.foo, #bar) #b.a {
|
438
|
+
a: b; }
|
439
|
+
CSS
|
440
|
+
:matches(.foo, #bar) %x {a: b}
|
441
|
+
.a {@extend %x}
|
442
|
+
#b.a {@extend %x}
|
443
|
+
SCSS
|
444
|
+
|
445
|
+
# `:matches(.foo, #bar)` has maximum specificity equal to that of `#bar`,
|
446
|
+
# which means `:matches(.foo, #bar).b` can have greater specificity than `.a
|
447
|
+
# .b`. Thus the selector generated by `:matches(.foo, #bar).b` should be
|
448
|
+
# preserved.
|
449
|
+
assert_equal <<CSS, render(<<SCSS)
|
450
|
+
.a .b, .a .b:matches(.foo, #bar) {
|
451
|
+
a: b; }
|
452
|
+
CSS
|
453
|
+
.a %x {a: b}
|
454
|
+
.b {@extend %x}
|
455
|
+
.b:matches(.foo, #bar) {@extend %x}
|
456
|
+
SCSS
|
457
|
+
end
|
458
|
+
|
459
|
+
def test_extend_into_not_and_normal_extend
|
460
|
+
assert_equal <<CSS, render(<<SCSS)
|
461
|
+
.x:not(.y, .bar), .foo:not(.y, .bar) {
|
462
|
+
a: b; }
|
463
|
+
CSS
|
464
|
+
.x:not(.y) {a: b}
|
465
|
+
.foo {@extend .x}
|
466
|
+
.bar {@extend .y}
|
467
|
+
SCSS
|
468
|
+
end
|
469
|
+
|
470
|
+
def test_extend_into_matches_and_normal_extend
|
471
|
+
assert_equal <<CSS, render(<<SCSS)
|
472
|
+
.x:matches(.y, .bar), .foo:matches(.y, .bar) {
|
473
|
+
a: b; }
|
474
|
+
CSS
|
475
|
+
.x:matches(.y) {a: b}
|
476
|
+
.foo {@extend .x}
|
477
|
+
.bar {@extend .y}
|
478
|
+
SCSS
|
479
|
+
end
|
480
|
+
|
481
|
+
def test_multilayer_pseudoclass_extend
|
482
|
+
assert_equal <<CSS, render(<<SCSS)
|
483
|
+
:matches(.x, .foo, .bar) {
|
484
|
+
a: b; }
|
485
|
+
CSS
|
486
|
+
:matches(.x) {a: b}
|
487
|
+
.foo {@extend .x}
|
488
|
+
.bar {@extend .foo}
|
489
|
+
SCSS
|
316
490
|
end
|
317
491
|
|
318
492
|
def test_comma_extendee
|
@@ -516,7 +690,7 @@ SCSS
|
|
516
690
|
end
|
517
691
|
|
518
692
|
def test_nested_extender_with_trailing_child_selector
|
519
|
-
|
693
|
+
assert_raises(Sass::SyntaxError, "bar > can't extend: invalid selector") do
|
520
694
|
render("bar > {@extend .baz}")
|
521
695
|
end
|
522
696
|
end
|
@@ -650,10 +824,10 @@ SCSS
|
|
650
824
|
|
651
825
|
def test_basic_extend_loop
|
652
826
|
assert_equal <<CSS, render(<<SCSS)
|
653
|
-
.
|
827
|
+
.foo, .bar {
|
654
828
|
a: b; }
|
655
829
|
|
656
|
-
.
|
830
|
+
.bar, .foo {
|
657
831
|
c: d; }
|
658
832
|
CSS
|
659
833
|
.foo {a: b; @extend .bar}
|
@@ -663,13 +837,13 @@ SCSS
|
|
663
837
|
|
664
838
|
def test_three_level_extend_loop
|
665
839
|
assert_equal <<CSS, render(<<SCSS)
|
666
|
-
.
|
840
|
+
.foo, .baz, .bar {
|
667
841
|
a: b; }
|
668
842
|
|
669
|
-
.
|
843
|
+
.bar, .foo, .baz {
|
670
844
|
c: d; }
|
671
845
|
|
672
|
-
.
|
846
|
+
.baz, .bar, .foo {
|
673
847
|
e: f; }
|
674
848
|
CSS
|
675
849
|
.foo {a: b; @extend .bar}
|
@@ -692,6 +866,18 @@ CSS
|
|
692
866
|
SCSS
|
693
867
|
end
|
694
868
|
|
869
|
+
def test_cross_loop
|
870
|
+
# The first law of extend means the selector should stick around.
|
871
|
+
assert_equal <<CSS, render(<<SCSS)
|
872
|
+
.foo.bar, .foo, .bar {
|
873
|
+
a: b; }
|
874
|
+
CSS
|
875
|
+
.foo.bar {a: b}
|
876
|
+
.foo {@extend .bar}
|
877
|
+
.bar {@extend .foo}
|
878
|
+
SCSS
|
879
|
+
end
|
880
|
+
|
695
881
|
def test_multiple_extender_merges_with_superset_selector
|
696
882
|
assert_equal <<CSS, render(<<SCSS)
|
697
883
|
a.bar.baz, a.foo {
|
@@ -830,6 +1016,17 @@ $foo: foo;
|
|
830
1016
|
SCSS
|
831
1017
|
end
|
832
1018
|
|
1019
|
+
def test_placeholder_in_selector_pseudoclass
|
1020
|
+
assert_equal <<CSS, render(<<SCSS)
|
1021
|
+
:matches(.bar, .baz) {
|
1022
|
+
color: blue; }
|
1023
|
+
CSS
|
1024
|
+
:matches(%foo) {color: blue}
|
1025
|
+
.bar {@extend %foo}
|
1026
|
+
.baz {@extend %foo}
|
1027
|
+
SCSS
|
1028
|
+
end
|
1029
|
+
|
833
1030
|
def test_media_in_placeholder_selector
|
834
1031
|
assert_equal <<CSS, render(<<SCSS)
|
835
1032
|
.baz {
|
@@ -1005,7 +1202,7 @@ SCSS
|
|
1005
1202
|
end
|
1006
1203
|
|
1007
1204
|
def test_extend_with_subject_transfers_subject_to_extender
|
1008
|
-
assert_equal(<<CSS, render(<<SCSS))
|
1205
|
+
silence_warnings {assert_equal(<<CSS, render(<<SCSS))}
|
1009
1206
|
foo bar! baz, foo .bip .bap! baz, .bip foo .bap! baz {
|
1010
1207
|
a: b; }
|
1011
1208
|
CSS
|
@@ -1013,7 +1210,7 @@ foo bar! baz {a: b}
|
|
1013
1210
|
.bip .bap {@extend bar}
|
1014
1211
|
SCSS
|
1015
1212
|
|
1016
|
-
assert_equal(<<CSS, render(<<SCSS))
|
1213
|
+
silence_warnings {assert_equal(<<CSS, render(<<SCSS))}
|
1017
1214
|
foo.x bar.y! baz.z, foo.x .bip bar.bap! baz.z, .bip foo.x bar.bap! baz.z {
|
1018
1215
|
a: b; }
|
1019
1216
|
CSS
|
@@ -1023,7 +1220,7 @@ SCSS
|
|
1023
1220
|
end
|
1024
1221
|
|
1025
1222
|
def test_extend_with_subject_retains_subject_on_target
|
1026
|
-
assert_equal(<<CSS, render(<<SCSS))
|
1223
|
+
silence_warnings {assert_equal(<<CSS, render(<<SCSS))}
|
1027
1224
|
.foo! .bar, .foo! .bip .bap, .bip .foo! .bap {
|
1028
1225
|
a: b; }
|
1029
1226
|
CSS
|
@@ -1033,7 +1230,7 @@ SCSS
|
|
1033
1230
|
end
|
1034
1231
|
|
1035
1232
|
def test_extend_with_subject_transfers_subject_to_target
|
1036
|
-
assert_equal(<<CSS, render(<<SCSS))
|
1233
|
+
silence_warnings {assert_equal(<<CSS, render(<<SCSS))}
|
1037
1234
|
a.foo .bar, .bip a.bap! .bar {
|
1038
1235
|
a: b; }
|
1039
1236
|
CSS
|
@@ -1043,7 +1240,7 @@ SCSS
|
|
1043
1240
|
end
|
1044
1241
|
|
1045
1242
|
def test_extend_with_subject_retains_subject_on_extender
|
1046
|
-
assert_equal(<<CSS, render(<<SCSS))
|
1243
|
+
silence_warnings {assert_equal(<<CSS, render(<<SCSS))}
|
1047
1244
|
.foo .bar, .foo .bip! .bap, .bip! .foo .bap {
|
1048
1245
|
a: b; }
|
1049
1246
|
CSS
|
@@ -1053,7 +1250,7 @@ SCSS
|
|
1053
1250
|
end
|
1054
1251
|
|
1055
1252
|
def test_extend_with_subject_fails_with_conflicting_subject
|
1056
|
-
assert_equal(<<CSS, render(<<SCSS))
|
1253
|
+
silence_warnings {assert_equal(<<CSS, render(<<SCSS))}
|
1057
1254
|
x! .bar {
|
1058
1255
|
a: b; }
|
1059
1256
|
CSS
|
@@ -1408,7 +1605,7 @@ Use "@extend #{target} !optional" if the extend should be able to fail.
|
|
1408
1605
|
ERR
|
1409
1606
|
end
|
1410
1607
|
|
1411
|
-
def assert_unification(selector, extension, unified)
|
1608
|
+
def assert_unification(selector, extension, unified, nested = true)
|
1412
1609
|
# Do some trickery so the first law of extend doesn't get in our way.
|
1413
1610
|
assert_extends(
|
1414
1611
|
"%-a #{selector}",
|
@@ -1416,6 +1613,22 @@ ERR
|
|
1416
1613
|
unified.split(', ').map {|s| "-a #{s}"}.join(', '))
|
1417
1614
|
end
|
1418
1615
|
|
1616
|
+
def assert_specificity_equals(sel1, sel2)
|
1617
|
+
assert_specificity_gte(sel1, sel2)
|
1618
|
+
assert_specificity_gte(sel2, sel1)
|
1619
|
+
end
|
1620
|
+
|
1621
|
+
def assert_specificity_gte(sel1, sel2)
|
1622
|
+
assert_equal <<CSS, render(<<SCSS)
|
1623
|
+
#{sel1} .a {
|
1624
|
+
a: b; }
|
1625
|
+
CSS
|
1626
|
+
#{sel1} %-a {a: b}
|
1627
|
+
.a {@extend %-a}
|
1628
|
+
#{sel2}.a {@extend %-a}
|
1629
|
+
SCSS
|
1630
|
+
end
|
1631
|
+
|
1419
1632
|
def render_unification(selector, extension)
|
1420
1633
|
render_extends(
|
1421
1634
|
"%-a #{selector}",
|
@@ -1429,6 +1642,10 @@ ERR
|
|
1429
1642
|
CSS
|
1430
1643
|
end
|
1431
1644
|
|
1645
|
+
def assert_extends_to_nothing(selector, extension)
|
1646
|
+
assert_equal '', render_extends(selector, extension)
|
1647
|
+
end
|
1648
|
+
|
1432
1649
|
def render_extends(selector, extension)
|
1433
1650
|
render(<<SCSS)
|
1434
1651
|
#{selector} {a: b}
|
data/test/sass/functions_test.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
require '
|
2
|
+
require 'minitest/autorun'
|
3
3
|
require File.dirname(__FILE__) + '/../test_helper'
|
4
4
|
require File.dirname(__FILE__) + '/test_helper'
|
5
5
|
require 'sass/script'
|
@@ -19,6 +19,12 @@ module Sass::Script::Functions
|
|
19
19
|
Sass::Script::Value::String.new("only-kw-args(" + kwargs.keys.map {|a| a.to_s}.sort.join(", ") + ")")
|
20
20
|
end
|
21
21
|
declare :only_kw_args, [], :var_kwargs => true
|
22
|
+
|
23
|
+
def deprecated_arg_fn(arg1, arg2, arg3 = nil)
|
24
|
+
Sass::Script::Value::List.new([arg1, arg2, arg3 || Sass::Script::Value::Null.new], :space)
|
25
|
+
end
|
26
|
+
declare :deprecated_arg_fn, [:arg1, :arg2, :arg3], :deprecated => [:arg_1, :arg_2, :arg3]
|
27
|
+
declare :deprecated_arg_fn, [:arg1, :arg2], :deprecated => [:arg_1, :arg_2]
|
22
28
|
end
|
23
29
|
|
24
30
|
module Sass::Script::Functions::UserFunctions
|
@@ -45,7 +51,7 @@ module Sass::Script::Functions
|
|
45
51
|
include Sass::Script::Functions::UserFunctions
|
46
52
|
end
|
47
53
|
|
48
|
-
class SassFunctionTest < Test
|
54
|
+
class SassFunctionTest < MiniTest::Test
|
49
55
|
# Tests taken from:
|
50
56
|
# http://www.w3.org/Style/CSS/Test/CSS3/Color/20070927/html4/t040204-hsl-h-rotating-b.htm
|
51
57
|
# http://www.w3.org/Style/CSS/Test/CSS3/Color/20070927/html4/t040204-hsl-values-b.htm
|
@@ -123,12 +129,6 @@ class SassFunctionTest < Test::Unit::TestCase
|
|
123
129
|
assert_equal("50%", evaluate("percentage($number: 0.5)"))
|
124
130
|
end
|
125
131
|
|
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
|
130
|
-
end
|
131
|
-
|
132
132
|
def test_percentage_checks_types
|
133
133
|
assert_error_message("$number: 25px is not a unitless number for `percentage'", "percentage(25px)")
|
134
134
|
assert_error_message("$number: #cccccc is not a unitless number for `percentage'", "percentage(#ccc)")
|
@@ -142,12 +142,6 @@ WARNING
|
|
142
142
|
assert_equal("5px", evaluate("round($number: 5.49px)"))
|
143
143
|
end
|
144
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
|
150
|
-
|
151
145
|
def test_round_checks_types
|
152
146
|
assert_error_message("$value: #cccccc is not a number for `round'", "round(#ccc)")
|
153
147
|
end
|
@@ -158,12 +152,6 @@ WARNING
|
|
158
152
|
assert_equal("4px", evaluate("floor($number: 4.8px)"))
|
159
153
|
end
|
160
154
|
|
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
|
166
|
-
|
167
155
|
def test_floor_checks_types
|
168
156
|
assert_error_message("$value: \"foo\" is not a number for `floor'", "floor(\"foo\")")
|
169
157
|
end
|
@@ -174,12 +162,6 @@ WARNING
|
|
174
162
|
assert_equal("5px", evaluate("ceil($number: 4.8px)"))
|
175
163
|
end
|
176
164
|
|
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
165
|
def test_ceil_checks_types
|
184
166
|
assert_error_message("$value: \"a\" is not a number for `ceil'", "ceil(\"a\")")
|
185
167
|
end
|
@@ -192,12 +174,6 @@ WARNING
|
|
192
174
|
assert_equal("5px", evaluate("abs($number: 5px)"))
|
193
175
|
end
|
194
176
|
|
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
|
200
|
-
|
201
177
|
def test_abs_checks_types
|
202
178
|
assert_error_message("$value: #aaaaaa is not a number for `abs'", "abs(#aaa)")
|
203
179
|
end
|
@@ -840,32 +816,6 @@ WARNING
|
|
840
816
|
assert_equal("rgba(255, 0, 0, 0)", evaluate("mix($color1: transparentize(#f00, 1), $color2: #00f, $weight: 100%)"))
|
841
817
|
end
|
842
818
|
|
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
|
867
|
-
end
|
868
|
-
|
869
819
|
def test_mix_tests_types
|
870
820
|
assert_error_message("$color1: \"foo\" is not a color for `mix'", "mix(\"foo\", #f00, 10%)")
|
871
821
|
assert_error_message("$color2: \"foo\" is not a color for `mix'", "mix(#f00, \"foo\", 10%)")
|
@@ -995,7 +945,6 @@ WARNING
|
|
995
945
|
assert_equal('ab', evaluate('str-slice(abcd,1,2)')) # for completeness
|
996
946
|
assert_equal('abcd', evaluate('str-slice(abcd,1,4)')) # at the end points
|
997
947
|
assert_equal('abcd', evaluate('str-slice(abcd,0,4)')) # when start is before the start of the string
|
998
|
-
assert_equal('', evaluate('str-slice(abcd,1,0)')) # when end is before the start of the string
|
999
948
|
assert_equal('abcd', evaluate('str-slice(abcd,1,100)')) # when end is past the end of the string
|
1000
949
|
assert_equal('', evaluate('str-slice(abcd,2,1)')) # when end is before start
|
1001
950
|
assert_equal('"bc"', evaluate('str-slice("abcd",2,3)')) # when used with a quoted string
|
@@ -1085,22 +1034,6 @@ MSG
|
|
1085
1034
|
assert_equal(%Q{false}, evaluate("comparable($number1: 100px, $number2: 3em)"))
|
1086
1035
|
end
|
1087
1036
|
|
1088
|
-
def test_comparable_deprecated_arg_name
|
1089
|
-
assert_warning <<WARNING do
|
1090
|
-
DEPRECATION WARNING: The `$number-1' argument for `comparable()' has been renamed to `$number1'.
|
1091
|
-
DEPRECATION WARNING: The `$number-2' argument for `comparable()' has been renamed to `$number2'.
|
1092
|
-
WARNING
|
1093
|
-
assert_equal("false", evaluate("comparable($number-1: 100px, $number-2: 3em)"))
|
1094
|
-
end
|
1095
|
-
|
1096
|
-
assert_warning <<WARNING do
|
1097
|
-
DEPRECATION WARNING: The `$number_1' argument for `comparable()' has been renamed to `$number1'.
|
1098
|
-
DEPRECATION WARNING: The `$number_2' argument for `comparable()' has been renamed to `$number2'.
|
1099
|
-
WARNING
|
1100
|
-
assert_equal("false", evaluate("comparable($number_1: 100px, $number_2: 3em)"))
|
1101
|
-
end
|
1102
|
-
end
|
1103
|
-
|
1104
1037
|
def test_comparable_checks_types
|
1105
1038
|
assert_error_message("$number1: #ff0000 is not a number for `comparable'", "comparable(#f00, 1px)")
|
1106
1039
|
assert_error_message("$number2: #ff0000 is not a number for `comparable'", "comparable(1px, #f00)")
|
@@ -1258,76 +1191,17 @@ WARNING
|
|
1258
1191
|
end
|
1259
1192
|
|
1260
1193
|
def test_index
|
1194
|
+
null = Sass::Script::Value::Null.new
|
1261
1195
|
assert_equal("1", evaluate("index(1px solid blue, 1px)"))
|
1262
1196
|
assert_equal("2", evaluate("index(1px solid blue, solid)"))
|
1263
1197
|
assert_equal("3", evaluate("index(1px solid blue, #00f)"))
|
1264
1198
|
assert_equal("1", evaluate("index(1px, 1px)"))
|
1265
|
-
assert_equal(
|
1266
|
-
assert_equal(
|
1267
|
-
assert_equal(
|
1199
|
+
assert_equal(null, perform("index(1px solid blue, 1em)"))
|
1200
|
+
assert_equal(null, perform("index(1px solid blue, notfound)"))
|
1201
|
+
assert_equal(null, perform("index(1px, #00f)"))
|
1268
1202
|
|
1269
1203
|
assert_equal("1", evaluate("index((foo: bar, bar: baz), (foo bar))"))
|
1270
|
-
assert_equal(
|
1271
|
-
end
|
1272
|
-
|
1273
|
-
def test_index_deprecation_warning
|
1274
|
-
assert_warning(<<WARNING) do
|
1275
|
-
DEPRECATION WARNING: The return value of index() will change from "false" to
|
1276
|
-
"null" in future versions of Sass. For compatibility, avoid using "== false" on
|
1277
|
-
the return value. For example, instead of "@if index(...) == false", just write
|
1278
|
-
"@if not index(...)".
|
1279
|
-
WARNING
|
1280
|
-
assert_equal("true", evaluate("index(1, 2 3 4) == false"))
|
1281
|
-
end
|
1282
|
-
|
1283
|
-
assert_warning(<<WARNING) do
|
1284
|
-
DEPRECATION WARNING: The return value of index() will change from "false" to
|
1285
|
-
"null" in future versions of Sass. For compatibility, avoid using "!= null" on
|
1286
|
-
the return value.
|
1287
|
-
WARNING
|
1288
|
-
assert_equal("true", evaluate("index(1, 2 3 4) != null"))
|
1289
|
-
end
|
1290
|
-
|
1291
|
-
assert_warning(<<WARNING) do
|
1292
|
-
DEPRECATION WARNING: The return value of index() will change from "false" to
|
1293
|
-
"null" in future versions of Sass. For compatibility, avoid using "== false" on
|
1294
|
-
the return value. For example, instead of "@if index(...) == false", just write
|
1295
|
-
"@if not index(...)".
|
1296
|
-
WARNING
|
1297
|
-
assert_equal("true", evaluate("false == index(1, 2 3 4)"))
|
1298
|
-
end
|
1299
|
-
|
1300
|
-
assert_warning(<<WARNING) do
|
1301
|
-
DEPRECATION WARNING: The return value of index() will change from "false" to
|
1302
|
-
"null" in future versions of Sass. For compatibility, avoid using "!= null" on
|
1303
|
-
the return value.
|
1304
|
-
WARNING
|
1305
|
-
assert_equal("true", evaluate("null != index(1, 2 3 4)"))
|
1306
|
-
end
|
1307
|
-
end
|
1308
|
-
|
1309
|
-
def test_index_deprecation_warning_is_only_emitted_once_per_call
|
1310
|
-
assert_warning(<<WARNING) do
|
1311
|
-
DEPRECATION WARNING: The return value of index() will change from "false" to
|
1312
|
-
"null" in future versions of Sass. For compatibility, avoid using "== false" on
|
1313
|
-
the return value. For example, instead of "@if index(...) == false", just write
|
1314
|
-
"@if not index(...)".
|
1315
|
-
on line 3 of test_index_deprecation_warning_is_only_emitted_once_per_call_inline.scss
|
1316
|
-
DEPRECATION WARNING: The return value of index() will change from "false" to
|
1317
|
-
"null" in future versions of Sass. For compatibility, avoid using "== false" on
|
1318
|
-
the return value. For example, instead of "@if index(...) == false", just write
|
1319
|
-
"@if not index(...)".
|
1320
|
-
on line 6 of test_index_deprecation_warning_is_only_emitted_once_per_call_inline.scss
|
1321
|
-
WARNING
|
1322
|
-
render(<<SCSS)
|
1323
|
-
@for $i from 1 to 10 {
|
1324
|
-
$var1: index(1, 2 3 4);
|
1325
|
-
$var2: $var1 == false;
|
1326
|
-
$var3: $var1 != null;
|
1327
|
-
}
|
1328
|
-
$var4: index(1, 2 3 4) == false;
|
1329
|
-
SCSS
|
1330
|
-
end
|
1204
|
+
assert_equal(null, perform("index((foo: bar, bar: baz), (foo: bar))"))
|
1331
1205
|
end
|
1332
1206
|
|
1333
1207
|
def test_list_separator
|
@@ -1447,7 +1321,7 @@ SCSS
|
|
1447
1321
|
50.times do
|
1448
1322
|
last_id, current_id = current_id, evaluate("unique-id()")
|
1449
1323
|
assert_match(/u[a-z0-9]{8}/, current_id)
|
1450
|
-
|
1324
|
+
refute_equal last_id, current_id
|
1451
1325
|
end
|
1452
1326
|
end
|
1453
1327
|
|
@@ -1458,16 +1332,6 @@ SCSS
|
|
1458
1332
|
assert_equal "null", perform("map-get((), foo)").to_sass
|
1459
1333
|
end
|
1460
1334
|
|
1461
|
-
def test_map_get_deprecation_warning
|
1462
|
-
assert_warning(<<WARNING) do
|
1463
|
-
DEPRECATION WARNING: Passing lists of pairs to map-get is deprecated and will
|
1464
|
-
be removed in future versions of Sass. Use Sass maps instead. For details, see
|
1465
|
-
http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#maps.
|
1466
|
-
WARNING
|
1467
|
-
assert_equal "1", evaluate("map-get((foo 1) (bar 2), foo)")
|
1468
|
-
end
|
1469
|
-
end
|
1470
|
-
|
1471
1335
|
def test_map_get_checks_type
|
1472
1336
|
assert_error_message("$map: 12 is not a map for `map-get'", "map-get(12, bar)")
|
1473
1337
|
end
|
@@ -1481,26 +1345,6 @@ WARNING
|
|
1481
1345
|
perform("map-merge((foo: 1, bar: 2), ())").to_sass)
|
1482
1346
|
end
|
1483
1347
|
|
1484
|
-
def test_map_merge_deprecation_warning
|
1485
|
-
assert_warning(<<WARNING) do
|
1486
|
-
DEPRECATION WARNING: Passing lists of pairs to map-merge is deprecated and will
|
1487
|
-
be removed in future versions of Sass. Use Sass maps instead. For details, see
|
1488
|
-
http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#maps.
|
1489
|
-
WARNING
|
1490
|
-
assert_equal("(foo: 1, bar: 2, baz: 3)",
|
1491
|
-
perform("map-merge((foo 1, bar 2), (baz: 3))").to_sass)
|
1492
|
-
end
|
1493
|
-
|
1494
|
-
assert_warning(<<WARNING) do
|
1495
|
-
DEPRECATION WARNING: Passing lists of pairs to map-merge is deprecated and will
|
1496
|
-
be removed in future versions of Sass. Use Sass maps instead. For details, see
|
1497
|
-
http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#maps.
|
1498
|
-
WARNING
|
1499
|
-
assert_equal("(baz: 3, foo: 1, bar: 2)",
|
1500
|
-
perform("map-merge((baz: 3), (foo 1, bar 2))").to_sass)
|
1501
|
-
end
|
1502
|
-
end
|
1503
|
-
|
1504
1348
|
def test_map_merge_checks_type
|
1505
1349
|
assert_error_message("$map1: 12 is not a map for `map-merge'", "map-merge(12, (foo: 1))")
|
1506
1350
|
assert_error_message("$map2: 12 is not a map for `map-merge'", "map-merge((foo: 1), 12)")
|
@@ -1509,18 +1353,12 @@ WARNING
|
|
1509
1353
|
def test_map_remove
|
1510
1354
|
assert_equal("(foo: 1, baz: 3)",
|
1511
1355
|
perform("map-remove((foo: 1, bar: 2, baz: 3), bar)").to_sass)
|
1356
|
+
assert_equal("(foo: 1, baz: 3)",
|
1357
|
+
perform("map-remove($map: (foo: 1, bar: 2, baz: 3), $key: bar)").to_sass)
|
1358
|
+
assert_equal("()",
|
1359
|
+
perform("map-remove((foo: 1, bar: 2, baz: 3), foo, bar, baz)").to_sass)
|
1512
1360
|
assert_equal("()", perform("map-remove((), foo)").to_sass)
|
1513
|
-
|
1514
|
-
|
1515
|
-
def test_map_remove_deprecation_warning
|
1516
|
-
assert_warning(<<WARNING) do
|
1517
|
-
DEPRECATION WARNING: Passing lists of pairs to map-remove is deprecated and will
|
1518
|
-
be removed in future versions of Sass. Use Sass maps instead. For details, see
|
1519
|
-
http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#maps.
|
1520
|
-
WARNING
|
1521
|
-
assert_equal("(foo: 1, baz: 3)",
|
1522
|
-
perform("map-remove((foo 1, bar 2, baz 3), bar)").to_sass)
|
1523
|
-
end
|
1361
|
+
assert_equal("()", perform("map-remove((), foo, bar)").to_sass)
|
1524
1362
|
end
|
1525
1363
|
|
1526
1364
|
def test_map_remove_checks_type
|
@@ -1533,17 +1371,6 @@ WARNING
|
|
1533
1371
|
assert_equal("()", perform("map-keys(())").to_sass)
|
1534
1372
|
end
|
1535
1373
|
|
1536
|
-
def test_map_keys_deprecation_warning
|
1537
|
-
assert_warning(<<WARNING) do
|
1538
|
-
DEPRECATION WARNING: Passing lists of pairs to map-keys is deprecated and will
|
1539
|
-
be removed in future versions of Sass. Use Sass maps instead. For details, see
|
1540
|
-
http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#maps.
|
1541
|
-
WARNING
|
1542
|
-
assert_equal("foo, bar",
|
1543
|
-
perform("map-keys((foo 1, bar 2))").to_sass)
|
1544
|
-
end
|
1545
|
-
end
|
1546
|
-
|
1547
1374
|
def test_map_keys_checks_type
|
1548
1375
|
assert_error_message("$map: 12 is not a map for `map-keys'", "map-keys(12)")
|
1549
1376
|
end
|
@@ -1555,16 +1382,6 @@ WARNING
|
|
1555
1382
|
assert_equal("()", perform("map-values(())").to_sass)
|
1556
1383
|
end
|
1557
1384
|
|
1558
|
-
def test_map_values_deprecation_warning
|
1559
|
-
assert_warning(<<WARNING) do
|
1560
|
-
DEPRECATION WARNING: Passing lists of pairs to map-values is deprecated and will
|
1561
|
-
be removed in future versions of Sass. Use Sass maps instead. For details, see
|
1562
|
-
http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#maps.
|
1563
|
-
WARNING
|
1564
|
-
assert_equal("1, 2", perform("map-values((foo 1, bar 2))").to_sass)
|
1565
|
-
end
|
1566
|
-
end
|
1567
|
-
|
1568
1385
|
def test_map_values_checks_type
|
1569
1386
|
assert_error_message("$map: 12 is not a map for `map-values'", "map-values(12)")
|
1570
1387
|
end
|
@@ -1575,16 +1392,6 @@ WARNING
|
|
1575
1392
|
assert_equal "false", evaluate("map-has-key((), foo)")
|
1576
1393
|
end
|
1577
1394
|
|
1578
|
-
def test_map_has_key_deprecation_warning
|
1579
|
-
assert_warning(<<WARNING) do
|
1580
|
-
DEPRECATION WARNING: Passing lists of pairs to map-has-key is deprecated and will
|
1581
|
-
be removed in future versions of Sass. Use Sass maps instead. For details, see
|
1582
|
-
http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#maps.
|
1583
|
-
WARNING
|
1584
|
-
assert_equal("true", evaluate("map-has-key((foo 1, bar 1), foo)"))
|
1585
|
-
end
|
1586
|
-
end
|
1587
|
-
|
1588
1395
|
def test_map_has_key_checks_type
|
1589
1396
|
assert_error_message("$map: 12 is not a map for `map-has-key'", "map-has-key(12, foo)")
|
1590
1397
|
end
|
@@ -1839,7 +1646,255 @@ SCSS
|
|
1839
1646
|
if Sass::Script::Functions.instance_variable_defined?("@random_number_generator")
|
1840
1647
|
Sass::Script::Functions.send(:remove_instance_variable, "@random_number_generator")
|
1841
1648
|
end
|
1842
|
-
|
1649
|
+
refute_equal evaluate("random()"), evaluate("random()")
|
1650
|
+
end
|
1651
|
+
|
1652
|
+
def test_deprecated_arg_names
|
1653
|
+
assert_warning <<WARNING do
|
1654
|
+
DEPRECATION WARNING: The `$arg-1' argument for `deprecated-arg-fn()' has been renamed to `$arg1'.
|
1655
|
+
DEPRECATION WARNING: The `$arg-2' argument for `deprecated-arg-fn()' has been renamed to `$arg2'.
|
1656
|
+
WARNING
|
1657
|
+
assert_equal("1 2 3",
|
1658
|
+
evaluate("deprecated-arg-fn($arg-1: 1, $arg-2: 2, $arg3: 3)"))
|
1659
|
+
end
|
1660
|
+
|
1661
|
+
assert_warning <<WARNING do
|
1662
|
+
DEPRECATION WARNING: The `$arg-1' argument for `deprecated-arg-fn()' has been renamed to `$arg1'.
|
1663
|
+
DEPRECATION WARNING: The `$arg-2' argument for `deprecated-arg-fn()' has been renamed to `$arg2'.
|
1664
|
+
WARNING
|
1665
|
+
assert_equal("1 2",
|
1666
|
+
evaluate("deprecated-arg-fn($arg-1: 1, $arg-2: 2)"))
|
1667
|
+
end
|
1668
|
+
|
1669
|
+
assert_warning <<WARNING do
|
1670
|
+
DEPRECATION WARNING: The `$arg_1' argument for `deprecated-arg-fn()' has been renamed to `$arg1'.
|
1671
|
+
DEPRECATION WARNING: The `$arg_2' argument for `deprecated-arg-fn()' has been renamed to `$arg2'.
|
1672
|
+
WARNING
|
1673
|
+
assert_equal("1 2",
|
1674
|
+
evaluate("deprecated-arg-fn($arg_1: 1, $arg_2: 2)"))
|
1675
|
+
end
|
1676
|
+
end
|
1677
|
+
|
1678
|
+
def test_non_deprecated_arg_names
|
1679
|
+
assert_equal("1 2 3", evaluate("deprecated-arg-fn($arg1: 1, $arg2: 2, $arg3: 3)"))
|
1680
|
+
assert_equal("1 2", evaluate("deprecated-arg-fn($arg1: 1, $arg2: 2)"))
|
1681
|
+
end
|
1682
|
+
|
1683
|
+
## Selector Functions
|
1684
|
+
|
1685
|
+
def test_selector_argument_parsing
|
1686
|
+
assert_equal("true", evaluate("selector-parse('.foo') == (join(('.foo',), (), space),)"))
|
1687
|
+
assert_equal("true", evaluate("selector-parse('.foo .bar') == ('.foo' '.bar',)"))
|
1688
|
+
assert_equal("true",
|
1689
|
+
evaluate("selector-parse('.foo .bar, .baz .bang') == ('.foo' '.bar', '.baz' '.bang')"))
|
1690
|
+
|
1691
|
+
assert_equal(".foo %bar", evaluate("selector-parse('.foo %bar')"))
|
1692
|
+
|
1693
|
+
assert_equal("true",
|
1694
|
+
evaluate("selector-parse(('.foo', '.bar')) == selector-parse('.foo, .bar')"))
|
1695
|
+
assert_equal("true",
|
1696
|
+
evaluate("selector-parse('.foo' '.bar') == selector-parse('.foo .bar')"))
|
1697
|
+
|
1698
|
+
assert_equal("true", evaluate("selector-parse(('.foo' '.bar', '.baz' '.bang')) == " +
|
1699
|
+
"selector-parse('.foo .bar, .baz .bang')"))
|
1700
|
+
assert_equal("true", evaluate("selector-parse(('.foo .bar', '.baz .bang')) == " +
|
1701
|
+
"selector-parse('.foo .bar, .baz .bang')"))
|
1702
|
+
|
1703
|
+
# This may throw an error in the future.
|
1704
|
+
assert_equal("true", evaluate("selector-parse(('.foo, .bar' '.baz, .bang')) == " +
|
1705
|
+
"selector-parse('.foo, .bar .baz, .bang')"))
|
1706
|
+
end
|
1707
|
+
|
1708
|
+
def test_selector_argument_validation
|
1709
|
+
assert_error_message("$selector: 12 is not a valid selector: it must be a string,\n" +
|
1710
|
+
"a list of strings, or a list of lists of strings for `selector-parse'", "selector-parse(12)")
|
1711
|
+
assert_error_message("$selector: (((\".foo\" \".bar\"), \".baz\") (\".bang\", \".qux\")) is not a valid selector: it must be a string,\n" +
|
1712
|
+
"a list of strings, or a list of lists of strings for `selector-parse'",
|
1713
|
+
"selector-parse(('.foo' '.bar', '.baz') ('.bang', '.qux'))")
|
1714
|
+
assert_error_message("$selector: \".#\" is not a valid selector: Invalid CSS after \".\": " +
|
1715
|
+
"expected class name, was \"#\" for `selector-parse'", "selector-parse('.#')")
|
1716
|
+
assert_error_message("$selector: \"&.foo\" is not a valid selector: Invalid CSS after \"\": " +
|
1717
|
+
"expected selector, was \"&.foo\" for `selector-parse'", "selector-parse('&.foo')")
|
1718
|
+
end
|
1719
|
+
|
1720
|
+
def test_selector_nest
|
1721
|
+
assert_equal(".foo", evaluate("selector-nest('.foo')"))
|
1722
|
+
assert_equal(".foo .bar", evaluate("selector-nest('.foo', '.bar')"))
|
1723
|
+
assert_equal(".foo .bar .baz", evaluate("selector-nest('.foo', '.bar', '.baz')"))
|
1724
|
+
assert_equal(".a .foo .b .bar", evaluate("selector-nest('.a .foo', '.b .bar')"))
|
1725
|
+
assert_equal(".foo.bar", evaluate("selector-nest('.foo', '&.bar')"))
|
1726
|
+
assert_equal(".baz .foo.bar", evaluate("selector-nest('.foo', '&.bar', '.baz &')"))
|
1727
|
+
end
|
1728
|
+
|
1729
|
+
def test_selector_nest_checks_types
|
1730
|
+
assert_error_message("$selectors: 12 is not a valid selector: it must be a string,\n" +
|
1731
|
+
"a list of strings, or a list of lists of strings for `selector-nest'",
|
1732
|
+
"selector-nest(12)")
|
1733
|
+
assert_error_message("$selectors: 12 is not a valid selector: it must be a string,\n" +
|
1734
|
+
"a list of strings, or a list of lists of strings for `selector-nest'",
|
1735
|
+
"selector-nest('.foo', 12)")
|
1736
|
+
end
|
1737
|
+
|
1738
|
+
def test_selector_nest_argument_validation
|
1739
|
+
assert_error_message("$selectors: At least one selector must be passed for `selector-nest'",
|
1740
|
+
"selector-nest()")
|
1741
|
+
end
|
1742
|
+
|
1743
|
+
def test_selector_append
|
1744
|
+
assert_equal(".foo.bar", evaluate("selector-append('.foo', '.bar')"))
|
1745
|
+
assert_equal(".a .foo.b .bar", evaluate("selector-append('.a .foo', '.b .bar')"))
|
1746
|
+
assert_equal(".foo-suffix", evaluate("selector-append('.foo', '-suffix')"))
|
1747
|
+
assert_equal(".foo.bar, .foo-suffix", evaluate("selector-append('.foo', '.bar, -suffix')"))
|
1748
|
+
assert_equal(".foo--suffix", evaluate("selector-append('.foo', '--suffix')"))
|
1749
|
+
assert_equal(".foo.bar, .foo--suffix", evaluate("selector-append('.foo', '.bar, --suffix')"))
|
1750
|
+
end
|
1751
|
+
|
1752
|
+
def test_selector_append_checks_types
|
1753
|
+
assert_error_message("$selectors: 12 is not a valid selector: it must be a string,\n" +
|
1754
|
+
"a list of strings, or a list of lists of strings for `selector-append'",
|
1755
|
+
"selector-append(12)")
|
1756
|
+
assert_error_message("$selectors: 12 is not a valid selector: it must be a string,\n" +
|
1757
|
+
"a list of strings, or a list of lists of strings for `selector-append'",
|
1758
|
+
"selector-append('.foo', 12)")
|
1759
|
+
end
|
1760
|
+
|
1761
|
+
def test_selector_append_errors
|
1762
|
+
assert_error_message("$selectors: At least one selector must be passed for `selector-append'",
|
1763
|
+
"selector-append()")
|
1764
|
+
assert_error_message("Can't append \"> .bar\" to \".foo\" for `selector-append'",
|
1765
|
+
"selector-append('.foo', '> .bar')")
|
1766
|
+
assert_error_message("Can't append \"*.bar\" to \".foo\" for `selector-append'",
|
1767
|
+
"selector-append('.foo', '*.bar')")
|
1768
|
+
assert_error_message("Can't append \"ns|suffix\" to \".foo\" for `selector-append'",
|
1769
|
+
"selector-append('.foo', 'ns|suffix')")
|
1770
|
+
end
|
1771
|
+
|
1772
|
+
def test_selector_extend
|
1773
|
+
assert_equal(".foo .x, .foo .a .bar, .a .foo .bar",
|
1774
|
+
evaluate("selector-extend('.foo .x', '.x', '.a .bar')"))
|
1775
|
+
assert_equal(".foo .x, .foo .bang, .x.bar, .bar.bang",
|
1776
|
+
evaluate("selector-extend('.foo .x, .x.bar', '.x', '.bang')"))
|
1777
|
+
assert_equal(".y .x, .foo .x, .y .foo, .foo .foo",
|
1778
|
+
evaluate("selector-extend('.y .x', '.x, .y', '.foo')"))
|
1779
|
+
assert_equal(".foo .x, .foo .bar, .foo .bang",
|
1780
|
+
evaluate("selector-extend('.foo .x', '.x', '.bar, .bang')"))
|
1781
|
+
assert_equal(".foo.x, .foo",
|
1782
|
+
evaluate("selector-extend('.foo.x', '.x', '.foo')"))
|
1783
|
+
end
|
1784
|
+
|
1785
|
+
def test_selector_extend_checks_types
|
1786
|
+
assert_error_message("$selector: 12 is not a valid selector: it must be a string,\n" +
|
1787
|
+
"a list of strings, or a list of lists of strings for `selector-extend'",
|
1788
|
+
"selector-extend(12, '.foo', '.bar')")
|
1789
|
+
assert_error_message("$extendee: 12 is not a valid selector: it must be a string,\n" +
|
1790
|
+
"a list of strings, or a list of lists of strings for `selector-extend'",
|
1791
|
+
"selector-extend('.foo', 12, '.bar')")
|
1792
|
+
assert_error_message("$extender: 12 is not a valid selector: it must be a string,\n" +
|
1793
|
+
"a list of strings, or a list of lists of strings for `selector-extend'",
|
1794
|
+
"selector-extend('.foo', '.bar', 12)")
|
1795
|
+
end
|
1796
|
+
|
1797
|
+
def test_selector_extend_errors
|
1798
|
+
assert_error_message("Can't extend .bar .baz: can't extend nested selectors for " +
|
1799
|
+
"`selector-extend'", "selector-extend('.foo', '.bar .baz', '.bang')")
|
1800
|
+
assert_error_message("Can't extend >: invalid selector for `selector-extend'",
|
1801
|
+
"selector-extend('.foo', '>', '.bang')")
|
1802
|
+
assert_error_message(".bang > can't extend: invalid selector for `selector-extend'",
|
1803
|
+
"selector-extend('.foo', '.bar', '.bang >')")
|
1804
|
+
end
|
1805
|
+
|
1806
|
+
def test_selector_replace
|
1807
|
+
assert_equal(".bar", evaluate("selector-replace('.foo', '.foo', '.bar')"))
|
1808
|
+
assert_equal(".foo.baz", evaluate("selector-replace('.foo.bar', '.bar', '.baz')"))
|
1809
|
+
assert_equal(".a .foo.baz", evaluate("selector-replace('.foo.bar', '.bar', '.a .baz')"))
|
1810
|
+
assert_equal(".foo.bar", evaluate("selector-replace('.foo.bar', '.baz.bar', '.qux')"))
|
1811
|
+
assert_equal(".bar.qux", evaluate("selector-replace('.foo.bar.baz', '.foo.baz', '.qux')"))
|
1812
|
+
|
1813
|
+
assert_equal(":not(.bar)", evaluate("selector-replace(':not(.foo)', '.foo', '.bar')"))
|
1814
|
+
assert_equal(".bar", evaluate("selector-replace(':not(.foo)', ':not(.foo)', '.bar')"))
|
1815
|
+
end
|
1816
|
+
|
1817
|
+
def test_selector_replace_checks_types
|
1818
|
+
assert_error_message("$selector: 12 is not a valid selector: it must be a string,\n" +
|
1819
|
+
"a list of strings, or a list of lists of strings for `selector-replace'",
|
1820
|
+
"selector-replace(12, '.foo', '.bar')")
|
1821
|
+
assert_error_message("$original: 12 is not a valid selector: it must be a string,\n" +
|
1822
|
+
"a list of strings, or a list of lists of strings for `selector-replace'",
|
1823
|
+
"selector-replace('.foo', 12, '.bar')")
|
1824
|
+
assert_error_message("$replacement: 12 is not a valid selector: it must be a string,\n" +
|
1825
|
+
"a list of strings, or a list of lists of strings for `selector-replace'",
|
1826
|
+
"selector-replace('.foo', '.bar', 12)")
|
1827
|
+
end
|
1828
|
+
|
1829
|
+
def test_selector_replace_errors
|
1830
|
+
assert_error_message("Can't extend .bar .baz: can't extend nested selectors for " +
|
1831
|
+
"`selector-replace'", "selector-replace('.foo', '.bar .baz', '.bang')")
|
1832
|
+
assert_error_message("Can't extend >: invalid selector for `selector-replace'",
|
1833
|
+
"selector-replace('.foo', '>', '.bang')")
|
1834
|
+
assert_error_message(".bang > can't extend: invalid selector for `selector-replace'",
|
1835
|
+
"selector-replace('.foo', '.bar', '.bang >')")
|
1836
|
+
end
|
1837
|
+
|
1838
|
+
def test_selector_unify
|
1839
|
+
assert_equal(".foo", evaluate("selector-unify('.foo', '.foo')"))
|
1840
|
+
assert_equal(".foo.bar", evaluate("selector-unify('.foo', '.bar')"))
|
1841
|
+
assert_equal(".foo.bar.baz", evaluate("selector-unify('.foo.bar', '.bar.baz')"))
|
1842
|
+
assert_equal(".a .b .foo.bar, .b .a .foo.bar", evaluate("selector-unify('.a .foo', '.b .bar')"))
|
1843
|
+
assert_equal(".a .foo.bar", evaluate("selector-unify('.a .foo', '.a .bar')"))
|
1844
|
+
assert_equal("", evaluate("selector-unify('p', 'a')"))
|
1845
|
+
assert_equal("", evaluate("selector-unify('.foo >', '.bar')"))
|
1846
|
+
assert_equal("", evaluate("selector-unify('.foo', '.bar >')"))
|
1847
|
+
assert_equal(".foo.baz, .foo.bang, .bar.baz, .bar.bang",
|
1848
|
+
evaluate("selector-unify('.foo, .bar', '.baz, .bang')"))
|
1849
|
+
end
|
1850
|
+
|
1851
|
+
def test_selector_unify_checks_types
|
1852
|
+
assert_error_message("$selector1: 12 is not a valid selector: it must be a string,\n" +
|
1853
|
+
"a list of strings, or a list of lists of strings for `selector-unify'",
|
1854
|
+
"selector-unify(12, '.foo')")
|
1855
|
+
assert_error_message("$selector2: 12 is not a valid selector: it must be a string,\n" +
|
1856
|
+
"a list of strings, or a list of lists of strings for `selector-unify'",
|
1857
|
+
"selector-unify('.foo', 12)")
|
1858
|
+
end
|
1859
|
+
|
1860
|
+
def test_simple_selectors
|
1861
|
+
assert_equal('(.foo,)', evaluate("inspect(simple-selectors('.foo'))"))
|
1862
|
+
assert_equal('.foo, .bar', evaluate("inspect(simple-selectors('.foo.bar'))"))
|
1863
|
+
assert_equal('.foo, .bar, :pseudo("flip, flap")',
|
1864
|
+
evaluate("inspect(simple-selectors('.foo.bar:pseudo(\"flip, flap\")'))"))
|
1865
|
+
end
|
1866
|
+
|
1867
|
+
def test_simple_selectors_checks_types
|
1868
|
+
assert_error_message("$selector: 12 is not a string for `simple-selectors'",
|
1869
|
+
"simple-selectors(12)")
|
1870
|
+
end
|
1871
|
+
|
1872
|
+
def test_simple_selectors_errors
|
1873
|
+
assert_error_message("$selector: \".foo .bar\" is not a compound selector for `simple-selectors'",
|
1874
|
+
"simple-selectors('.foo .bar')")
|
1875
|
+
assert_error_message("$selector: \".foo,.bar\" is not a compound selector for `simple-selectors'",
|
1876
|
+
"simple-selectors('.foo,.bar')")
|
1877
|
+
assert_error_message("$selector: \".#\" is not a valid selector: Invalid CSS after \".\": " +
|
1878
|
+
"expected class name, was \"#\" for `simple-selectors'", "simple-selectors('.#')")
|
1879
|
+
end
|
1880
|
+
|
1881
|
+
def test_is_superselector
|
1882
|
+
assert_equal("true", evaluate("is-superselector('.foo', '.foo.bar')"))
|
1883
|
+
assert_equal("false", evaluate("is-superselector('.foo.bar', '.foo')"))
|
1884
|
+
assert_equal("true", evaluate("is-superselector('.foo', '.foo')"))
|
1885
|
+
assert_equal("true", evaluate("is-superselector('.bar', '.foo .bar')"))
|
1886
|
+
assert_equal("false", evaluate("is-superselector('.foo .bar', '.bar')"))
|
1887
|
+
assert_equal("true", evaluate("is-superselector('.foo .bar', '.foo > .bar')"))
|
1888
|
+
assert_equal("false", evaluate("is-superselector('.foo > .bar', '.foo .bar')"))
|
1889
|
+
end
|
1890
|
+
|
1891
|
+
def test_is_superselector_checks_types
|
1892
|
+
assert_error_message("$super: 12 is not a valid selector: it must be a string,\n" +
|
1893
|
+
"a list of strings, or a list of lists of strings for `is-superselector'",
|
1894
|
+
"is-superselector(12, '.foo')")
|
1895
|
+
assert_error_message("$sub: 12 is not a valid selector: it must be a string,\n" +
|
1896
|
+
"a list of strings, or a list of lists of strings for `is-superselector'",
|
1897
|
+
"is-superselector('.foo', 12)")
|
1843
1898
|
end
|
1844
1899
|
|
1845
1900
|
## Regression Tests
|