10 no warnings 'uninitialized';
11 no warnings 'experimental::smartmatch';
18 # Predeclare vars used in the tests:
21 my @sparse; $sparse[2] = 2;
23 my $deep1 = []; push @$deep1, $deep1;
24 my $deep2 = []; push @$deep2, $deep2;
27 tie my @tied_nums, 'Tie::StdArray';
30 my %hash = (foo => 17, bar => 23);
31 tie my %tied_hash, 'Tie::StdHash';
35 package Test::Object::NoOverload;
36 sub new { bless { key => 1 } }
40 package Test::Object::StringOverload;
41 use overload '""' => sub { "object" }, fallback => 1;
42 sub new { bless { key => 1 } }
46 package Test::Object::WithOverload;
47 sub new { bless { key => ($_[1] // 'magic') } }
48 use overload '~~' => sub {
49 my %hash = %{ $_[0] };
50 if ($_[2]) { # arguments reversed ?
51 return $_[1] eq reverse $hash{key};
54 return $_[1] eq $hash{key};
57 use overload '""' => sub { "stringified" };
58 use overload 'eq' => sub {"$_[0]" eq "$_[1]"};
61 our $ov_obj = Test::Object::WithOverload->new;
62 our $ov_obj_2 = Test::Object::WithOverload->new("object");
63 our $obj = Test::Object::NoOverload->new;
64 our $str_obj = Test::Object::StringOverload->new;
67 unless (is_miniperl()) {
69 tie %refh, 'Tie::RefHash';
73 my @keyandmore = qw(key and more);
74 my @fooormore = qw(foo or more);
75 my %keyandmore = map { $_ => 0 } @keyandmore;
76 my %fooormore = map { $_ => 0 } @fooormore;
78 # Load and run the tests
83 next if /^#/ || !/\S/;
85 my ($yn, $left, $right, $note) = split /\t+/;
87 local $::TODO = $note =~ /TODO/;
89 die "Bad test spec: ($yn, $left, $right)" if $yn =~ /[^!@=]/;
91 my $tstr = "$left ~~ $right";
95 if ($note =~ /NOWARNINGS/) {
96 $res = eval "no warnings; $tstr";
99 skip_if_miniperl("Doesn't work with miniperl", $yn =~ /=/ ? 2 : 1)
100 if $note =~ /MINISKIP/;
107 ok( $@ ne '', "$tstr dies" )
108 and print "# \$\@ was: $@\n";
110 my $test_name = $tstr . ($yn =~ /!/ ? " does not match" : " matches");
113 print "# \$\@ was: $@\n";
115 ok( ($yn =~ /!/ xor $res), $test_name );
119 if ( $yn =~ s/=// ) {
120 $tstr = "$right ~~ $left";
129 sub fatal {die "fatal sub\n"}
131 # to test constant folding
134 sub NOT_DEF() { undef }
138 # this can but might not crash
139 # This can but might not crash
141 # The second smartmatch would leave a &PL_sv_no on the stack for
142 # each key it checked in %!, this could then cause various types of
143 # crash or assertion failure.
145 # This isn't guaranteed to crash, but if the stack issue is
146 # re-introduced it will probably crash in one of the many smoke
148 fresh_perl_is('print (q(x) ~~ q(x)) | (/x/ ~~ %!)', "1",
149 { switches => [ "-MErrno", "-M-warnings=experimental::smartmatch" ] },
150 "don't fill the stack with rubbish");
154 # [perl #123860] continued;
155 # smartmatch was failing to SPAGAIN after pushing an SV and calling
156 # pp_match, which may have resulted in the stack being realloced
157 # in the meantime. Test this by filling the stack with pregressively
158 # larger amounts of data. At some point the stack will get realloced.
166 my $exp_n = join '-', (@args, $x == 0);
167 my $exp_y = join '-', (@args, $x == 1);
169 my $got_an = join '-', (@args, (/X/ ~~ @a));
170 my $got_ay = join '-', (@args, (/x/ ~~ @a));
171 my $got_hn = join '-', (@args, (/X/ ~~ %h));
172 my $got_hy = join '-', (@args, (/x/ ~~ %h));
174 if ( $exp_n ne $got_an || $exp_n ne $got_hn
175 || $exp_y ne $got_ay || $exp_y ne $got_hy
181 is($bad, -1, "RT 123860: stack realloc");
186 # - expected to match
187 # ! - expected to not match
188 # @ - expected to be a compilation failure
189 # = - expected to match symmetrically (runs test twice)
190 # Data types to test :
199 # Tied arrays and hashes
200 # Arrays that reference themselves
201 # Regex (// and qr//)
205 # Other syntactic items of interest:
207 # Values returned by a sub call
234 # Any ~~ object overloaded
239 ! ['stringified'] $ov_obj
240 ! { cigam => 1 } $ov_obj
241 ! { stringified => 1 } $ov_obj
262 # regular object with "" overload
269 @ %keyandmore $str_obj
270 @ {"object" => 1} $str_obj
271 @ @fooormore $str_obj
272 @ ["object" => 1] $str_obj
274 @ qr/object/ $str_obj
277 # Those will treat the $str_obj as a string because of fallback:
279 # object (overloaded or not) ~~ Any
281 $ov_obj qr/^stringified$/
282 = "$ov_obj" "stringified"
283 = "$str_obj" "object"
284 != $ov_obj "stringified"
287 ! $ov_obj 'not magic'
290 sub{0} sub { ref $_[0] eq "CODE" }
291 %fooormore sub { $_[0] =~ /^(foo|or|more)$/ }
292 ! %fooormore sub { $_[0] =~ /^(foo|or|less)$/ }
293 \%fooormore sub { $_[0] =~ /^(foo|or|more)$/ }
294 ! \%fooormore sub { $_[0] =~ /^(foo|or|less)$/ }
295 +{%fooormore} sub { $_[0] =~ /^(foo|or|more)$/ }
296 ! +{%fooormore} sub { $_[0] =~ /^(foo|or|less)$/ }
297 @fooormore sub { $_[0] =~ /^(foo|or|more)$/ }
298 ! @fooormore sub { $_[0] =~ /^(foo|or|less)$/ }
299 \@fooormore sub { $_[0] =~ /^(foo|or|more)$/ }
300 ! \@fooormore sub { $_[0] =~ /^(foo|or|less)$/ }
301 [@fooormore] sub { $_[0] =~ /^(foo|or|more)$/ }
302 ! [@fooormore] sub { $_[0] =~ /^(foo|or|less)$/ }
303 %fooormore sub{@_==1}
304 @fooormore sub{@_==1}
305 "foo" sub { $_[0] =~ /^(foo|or|more)$/ }
306 ! "more" sub { $_[0] =~ /^(foo|or|less)$/ }
307 /fooormore/ sub{ref $_[0] eq 'Regexp'}
308 qr/fooormore/ sub{ref $_[0] eq 'Regexp'}
313 NOT_DEF sub{not shift}
314 &NOT_DEF sub{not shift}
321 $obj sub { ref($_[0]) =~ /NoOverload/ }
322 $ov_obj sub { ref($_[0]) =~ /WithOverload/ }
323 # empty stuff matches, because the sub is never called:
337 # sub is not called on empty hashes / arrays
342 # sub is not special on the left
344 sub {0} sub { ref shift eq "CODE" }
353 = \%main:: {map {$_ => 'x'} keys %main::}
357 \%tied_hash \%tied_hash
358 != {"a"=>"b"} \%tied_hash
360 %tied_hash %tied_hash
361 != {"a"=>"b"} %tied_hash
362 $ov_obj %refh MINISKIP
363 ! "$ov_obj" %refh MINISKIP
364 [$ov_obj] %refh MINISKIP
365 ! ["$ov_obj"] %refh MINISKIP
369 # (since this is symmetrical, tests as well hash~~array)
370 = [keys %main::] \%::
371 = [qw[STDIN STDOUT]] \%::
378 = ["foo"] { foo => 1 }
379 = ["foo", "bar"] { foo => 1 }
380 = ["foo", "bar"] \%hash
383 = [qw(foo quux)] \%hash
384 = @fooormore { foo => 1, or => 2, more => 3 }
385 = @fooormore %fooormore
386 = @fooormore \%fooormore
387 = \@fooormore %fooormore
390 = qr/^(fo[ox])$/ {foo => 1}
391 = /^(fo[ox])$/ %fooormore
392 =! qr/[13579]$/ +{0..99}
401 "foo" +{foo => 1, bar => 2}
403 ! "baz" +{foo => 1, bar => 2}
405 ! 1 +{foo => 1, bar => 2}
415 ! undef { hop => 'zouu' }
417 ! undef +{"" => "empty key"}
421 # - another array ref
424 [["foo"], ["bar"]] [qr/o/, qr/a/]
425 ! [["foo"], ["bar"]] [qr/ARRAY/, qr/ARRAY/]
426 ["foo", "bar"] [qr/o/, qr/a/]
427 ! [qr/o/, qr/a/] ["foo", "bar"]
428 ["foo", "bar"] [["foo"], ["bar"]]
429 ! ["foo", "bar"] [qr/o/, "foo"]
430 ["foo", undef, "bar"] [qr/o/, undef, "bar"]
431 ! ["foo", undef, "bar"] [qr/o/, "", "bar"]
432 ! ["foo", "", "bar"] [qr/o/, undef, "bar"]
444 $obj [sub{ref shift}]
447 = qr/x/ [qw(foo bar baz quux)]
448 =! qr/y/ [qw(foo bar baz quux)]
449 = /x/ [qw(foo bar baz quux)]
450 =! /y/ [qw(foo bar baz quux)]
461 ! "2" [qw(1foo 2bar)]
462 "2bar" [qw(1foo 2bar)]
465 undef [1, 2, undef, 4]
466 ! undef [1, 2, [undef], 4]
475 # - nested arrays and ~~ distributivity
478 "foo" [{foo => "bar"}]
479 ! "bar" [{foo => "bar"}]
481 # Number against number
490 # Number against string
494 != 2_3 "2_3" NOWARNINGS
499 # Regex against string
503 # Regex against number
507 # array/hash against string
508 @fooormore "".\@fooormore
509 ! @keyandmore "".\@fooormore
510 %fooormore "".\%fooormore
511 ! %keyandmore "".\%fooormore
513 # Test the implicit referencing
528 %tied_hash %tied_hash
529 %hash { foo => 5, bar => 10 }
530 ! %hash { foo => 5, bar => 10, quux => 15 }
532 @nums { 1, '', 2, '' }
533 @nums { 1, '', 12, '' }
534 ! @nums { 11, '', 12, '' }
547 @nums[0..1] @nums[0..1]
550 @keyandmore{qw(not)} [undef]
551 @keyandmore{qw(key)} [0]
553 undef @keyandmore{qw(not)}
554 0 @keyandmore{qw(key and more)}
555 ! 2 @keyandmore{qw(key and)}
557 @fooormore{qw(foo)} @keyandmore{qw(key)}
558 @fooormore{qw(foo or more)} @keyandmore{qw(key and more)}