use v6-alpha; use Test; plan 56; =kwid This tests the smartmatch operator, defined in L note that ~~ is currently a stub, and is really eq. the reason it's parsed is so that eval '' won't be around everywhere, not for emulation. =cut sub eval_elsewhere($code){ eval($code) } { #L<> sub uhuh { 1 } sub nuhuh { undef } ok((undef ~~ &uhuh), "scalar sub truth"); ok(!(undef ~~ &nuhuh), "negated scalar sub false"); }; my %hash1 is context = ( "foo", "Bar", "blah", "ding"); my %hash2 is context = ( "foo", "zzz", "blah", "frbz"); my %hash3 is context = ( "oink", "da", "blah", "zork"); my %hash4 is context = ( "bink", "yum", "gorch", "zorba"); my %hash5 is context = ( "foo", 1, "bar", 1, "gorch", undef, "baz", undef ); #L<> { ok eval_elsewhere('(%+hash1 ~~ %+hash2)'), "hash keys identical", :todo; ok eval_elsewhere('!(%+hash1 ~~ %+hash4)'), "hash keys differ"; }; #L<> { flunk('FIXME parsefail'); # ok(eval(%hash1 ~~ any(%hash3)), "intersecting keys", :todo); flunk('FIXME parsefail'); # ok(!(%hash1 ~~ any(%hash4)), "no intersecting keys"); }; #L<> { my @true = (); my @sort_of = (); my @false = (); ok((%hash5 ~~ @true), "value slice true", :todo); ok((%hash5 ~~ @sort_of), "value slice partly true", :todo); ok(!(%hash5 ~~ @false), "value slice false"); }; #L<> { ok((%hash1 ~~ any()), "any key exists (but where is it?)", :todo); ok(!(%hash1 ~~ any()), "no listed key exists"); }; #L<> { ok((%hash1 ~~ all()), "all keys exist", :todo); ok(!(%hash1 ~~ all()), "not all keys exist"); }; #Hash Rule hash key grep match if any($_.keys) ~~ /$x/ #L<> { ok((%hash5 ~~ "foo"), "foo exists", :todo); ok((%hash5 ~~ "gorch"), "gorch exists, true although value is false", :todo); ok((%hash5 ~~ "wasabi"), "wasabi does not exist", :todo); }; #L<> { my $string is context = "foo"; ok eval_elsewhere('(%+hash5 ~~ .{$+string})'), 'hash.{Any} truth'; $string = "gorch"; ok eval_elsewhere('!(%+hash5 ~~ .{$+string})'), 'hash.{Any} untruth'; }; #L<> { ok eval_elsewhere('(%+hash5 ~~ .)'), "hash truth"; ok eval_elsewhere('!(%+hash5 ~~ .)'), "hash untruth"; }; #L<> { ok((("blah", "blah") ~~ ("blah", "blah")), "qw/blah blah/ .eq"); ok(!((1, 2) ~~ (1, 1)), "1 2 !~~ 1 1"); }; #L<> { ok(((1, 2) ~~ any(2, 3)), "there is intersection between (1, 2) and (2, 3)", :todo); ok(!((1, 2) ~~ any(3, 4)), "but none between (1, 2) and (3, 4)"); }; # Array Rule array grep match if any(@$_) ~~ /$x/ #L<> { ok(((1, 2) ~~ 1), "(1, 2) contains 1", :todo); ok(!((3, 4, 5) ~~ 2), "(3, 4, 5) doesn't contain 2"); }; #L<> { ok((("foo", "bar", "gorch") ~~ "bar"), "bar is in qw/foo bar gorch/", :todo); ok(!(("x", "y", "z") ~~ "a"), "a is not in qw/x y z/"); }; #L { ok eval('((undef, 1, undef) ~~ .[1])'), "element 1 of (undef, 1, undef) is true"; ok eval('!((undef, undef) ~~ .[0])'), "element 0 of (undef, undef) is false"; }; #L<> { ok((5 ~~ 1 .. 10), "5 is in 1 .. 10", :todo); ok(!(10 ~~ 1 .. 5), "10 is not in 1 .. 5"); ok(!(1 ~~ 5 .. 10), "1 is not i n 5 .. 10"); #ok(!(5 ~~ 5 ^..^ 10), "5 is not in 5 .. 10, exclusive"); # phooey }; #Str StrRange in string range match if $min le $_ le $max #L { ok((1 ~~ { 1 }), "closure truth"); ok((undef ~~ { 1 }), 'ignores $_'); }; #L<> { class Dog {} class Cat {} class Chihuahua is Dog {} # i'm afraid class Pugs will get in the way ;-) ok eval('(Chihuahua ~~ Dog)'), "chihuahua isa dog"; ok eval('!(Chihuahua ~~ Cat)'), "chihuahua is not a cat"; }; #Any Role role playing match if \$_.does(\$x) #L<> { ok((1 ~~ 1), "one is one"); ok(!(2 ~~ 1), "two is not one"); }; #L<> { ok(("foo" ~~ "foo"), "foo eq foo"); ok(!("bar" ~~ "foo"), "!(bar eq foo)"); }; # no objects, no rules # ... staring vin diesel and kevin kostner! (blech) #Any .method method truth* match if $_.method #Any Rule pattern match match if $_ ~~ /$x/ #Any subst substitution match* match if $_ ~~ subst # i don't understand this one #Any boolean simple expression truth* match if true given $_ #L { ok(!("foo" ~~ undef), "foo is not ~~ undef"); ok((undef ~~ undef), "undef is"); }; # does this imply MMD for $_, $x? #Any Any run-time dispatch match if infix:<~~>($_, $x) #L { # representational checks for !~~, rely on ~~ semantics to be correct # assume negated results ok(!("foo" !~~ "foo"), "!(foo ne foo)"); ok(("bar" !~~ "foo"), "bar ne foo)"); ok(!((1, 2) !~~ 1), "(1, 2) contains 1", :todo); ok(((3, 4, 5) !~~ 2), "(3, 4, 5) doesn't contain 2"); flunk('FIXME parsefail'); # ok(!(%hash1 !~~ any(%hash3)), "intersecting keys", :todo); flunk('FIXME parsefail'); # ok((%hash1 !~~ any(%hash4)), "no intersecting keys"); }; { =begin Explanation You may be wondering what the heck is with all these try blocks. Prior to r12503, this test caused a horrible death of Pugs which magically went away when used inside an eval. So the try blocks caught that case. =cut #L my @x = 1..20; my $code = -> $x { $x % 2 }; my @result; my $parsed = 0; try { @result = any(@x) ~~ $code; $parsed = 1; }; ok $parsed, 'C parses'; my @expected_result = grep $code, @x; ok @result ~~ @expected_result, 'C works like C', :todo; my $result = 0; $parsed = 0; try { $result = all(@x) ~~ { $_ < 21 }; $parsed = 1; }; ok $parsed, 'C parses'; ok $result, 'C