Some more tests for \N
[p5sagit/p5-mst-13.2.git] / t / op / smartmatch.t
CommitLineData
0d863452 1#!./perl
2
3BEGIN {
4 chdir 't';
5 @INC = '../lib';
6 require './test.pl';
7}
8use strict;
289d21b2 9use warnings;
10no warnings 'uninitialized';
0d863452 11
12use Tie::Array;
13use Tie::Hash;
b15feb55 14use Tie::RefHash;
0d863452 15
0d863452 16# Predeclare vars used in the tests:
031a44ed 17my @empty;
18my %empty;
015eb7b9 19my @sparse; $sparse[2] = 2;
031a44ed 20
0d863452 21my $deep1 = []; push @$deep1, \$deep1;
22my $deep2 = []; push @$deep2, \$deep2;
23
0d863452 24my @nums = (1..10);
25tie my @tied_nums, 'Tie::StdArray';
26@tied_nums = (1..10);
27
28my %hash = (foo => 17, bar => 23);
29tie my %tied_hash, 'Tie::StdHash';
30%tied_hash = %hash;
31
1cfb7049 32{
33 package Test::Object::NoOverload;
34 sub new { bless { key => 1 } }
35}
36
37{
90a32bcb 38 package Test::Object::WithOverload;
2522c35a 39 sub new { bless { key => 'magic' } }
2c9d2554 40 use overload '~~' => sub {
41 my %hash = %{ $_[0] };
42 if ($_[2]) { # arguments reversed ?
43 return $_[1] eq reverse $hash{key};
44 }
45 else {
46 return $_[1] eq $hash{key};
47 }
48 };
0483c672 49 use overload '""' => sub { "stringified" };
90a32bcb 50 use overload 'eq' => sub {"$_[0]" eq "$_[1]"};
1cfb7049 51}
52
90a32bcb 53our $ov_obj = Test::Object::WithOverload->new;
1cfb7049 54our $obj = Test::Object::NoOverload->new;
1cfb7049 55
b15feb55 56tie my %refh, 'Tie::RefHash';
57$refh{$ov_obj} = 1;
58
73aec0b1 59my @keyandmore = qw(key and more);
60my @fooormore = qw(foo or more);
61my %keyandmore = map { $_ => 0 } @keyandmore;
62my %fooormore = map { $_ => 0 } @fooormore;
63
0d863452 64# Load and run the tests
532217f1 65plan tests => 294;
0d863452 66
9e079ace 67while (<DATA>) {
68 next if /^#/ || !/\S/;
69 chomp;
73aec0b1 70 my ($yn, $left, $right, $note) = split /\t+/;
0d863452 71
73aec0b1 72 local $::TODO = $note =~ /TODO/;
0d863452 73
85af77a5 74 die "Bad test spec: ($yn, $left, $right)" if $yn =~ /[^!@=]/;
9e079ace 75
0d863452 76 my $tstr = "$left ~~ $right";
9e079ace 77
85af77a5 78 test_again:
289d21b2 79 my $res;
80 if ($note =~ /NOWARNINGS/) {
81 $res = eval "no warnings; $tstr";
82 }
83 else {
84 $res = eval $tstr;
85 }
0d863452 86
a86f5011 87 chomp $@;
88
85af77a5 89 if ( $yn =~ /@/ ) {
9e079ace 90 ok( $@ ne '', "$tstr dies" )
91 and print "# \$\@ was: $@\n";
a86f5011 92 } else {
85af77a5 93 my $test_name = $tstr . ($yn =~ /!/ ? " does not match" : " matches");
a86f5011 94 if ( $@ ne '' ) {
9e079ace 95 fail($test_name);
96 print "# \$\@ was: $@\n";
a86f5011 97 } else {
85af77a5 98 ok( ($yn =~ /!/ xor $res), $test_name );
a86f5011 99 }
100 }
85af77a5 101
102 if ( $yn =~ s/=// ) {
103 $tstr = "$right ~~ $left";
104 goto test_again;
105 }
0d863452 106}
107
0d863452 108sub foo {}
73aec0b1 109sub bar {42}
110sub gorch {42}
1cfb7049 111sub fatal {die "fatal sub\n"}
0d863452 112
0cfbf1ea 113# to test constant folding
18d11902 114sub FALSE() { 0 }
115sub TRUE() { 1 }
2522c35a 116sub NOT_DEF() { undef }
0d863452 117
e5de85fa 118# Prefix character :
119# - expected to match
120# ! - expected to not match
121# @ - expected to be a compilation failure
85af77a5 122# = - expected to match symmetrically (runs test twice)
73aec0b1 123# Data types to test :
85af77a5 124# undef
73aec0b1 125# Object-overloaded
126# Object
73aec0b1 127# Coderef
128# Hash
129# Hashref
130# Array
131# Arrayref
85af77a5 132# Tied arrays and hashes
133# Arrays that reference themselves
73aec0b1 134# Regex (// and qr//)
85af77a5 135# Range
73aec0b1 136# Num
137# Str
85af77a5 138# Other syntactic items of interest:
139# Constants
140# Values returned by a sub call
0d863452 141__DATA__
85af77a5 142# Any ~~ undef
ad0781bc 143! $ov_obj undef
85af77a5 144! $obj undef
145! sub {} undef
146! %hash undef
147! \%hash undef
148! {} undef
149! @nums undef
150! \@nums undef
151! [] undef
152! %tied_hash undef
153! @tied_nums undef
154! $deep1 undef
155! /foo/ undef
156! qr/foo/ undef
157! 21..30 undef
158! 189 undef
159! "foo" undef
160! "" undef
161! !1 undef
162 undef undef
62ec5f58 163 (my $u) undef
2522c35a 164 NOT_DEF undef
165 &NOT_DEF undef
85af77a5 166
167# Any ~~ object overloaded
ad0781bc 168! \&fatal $ov_obj
2c9d2554 169 'cigam' $ov_obj
170! 'cigam on' $ov_obj
532217f1 171! ['cigam'] $ov_obj
172! ['stringified'] $ov_obj
173! { cigam => 1 } $ov_obj
174! { stringified => 1 } $ov_obj
ad0781bc 175! $obj $ov_obj
176! undef $ov_obj
1cfb7049 177
178# regular object
ad0781bc 179@ $obj $obj
6d743019 180@ $ov_obj $obj
2c9d2554 181=@ \&fatal $obj
ad0781bc 182@ \&FALSE $obj
183@ \&foo $obj
184@ sub { 1 } $obj
185@ sub { 0 } $obj
186@ %keyandmore $obj
187@ {"key" => 1} $obj
188@ @fooormore $obj
189@ ["key" => 1] $obj
190@ /key/ $obj
191@ qr/key/ $obj
192@ "key" $obj
193@ FALSE $obj
194
195# object (overloaded or not) ~~ Any
0483c672 196 $obj qr/NoOverload/
197 $ov_obj qr/^stringified$/
532217f1 198= "$ov_obj" "stringified"
199!= $ov_obj "stringified"
2c9d2554 200 $ov_obj 'magic'
201! $ov_obj 'not magic'
1cfb7049 202
a4a197da 203# ~~ Coderef
204 sub{0} sub { ref $_[0] eq "CODE" }
205 %fooormore sub { $_[0] =~ /^(foo|or|more)$/ }
206! %fooormore sub { $_[0] =~ /^(foo|or|less)$/ }
207 \%fooormore sub { $_[0] =~ /^(foo|or|more)$/ }
208! \%fooormore sub { $_[0] =~ /^(foo|or|less)$/ }
209 +{%fooormore} sub { $_[0] =~ /^(foo|or|more)$/ }
210! +{%fooormore} sub { $_[0] =~ /^(foo|or|less)$/ }
211 @fooormore sub { $_[0] =~ /^(foo|or|more)$/ }
212! @fooormore sub { $_[0] =~ /^(foo|or|less)$/ }
213 \@fooormore sub { $_[0] =~ /^(foo|or|more)$/ }
214! \@fooormore sub { $_[0] =~ /^(foo|or|less)$/ }
215 [@fooormore] sub { $_[0] =~ /^(foo|or|more)$/ }
216! [@fooormore] sub { $_[0] =~ /^(foo|or|less)$/ }
217 %fooormore sub{@_==1}
218 @fooormore sub{@_==1}
219 "foo" sub { $_[0] =~ /^(foo|or|more)$/ }
220! "more" sub { $_[0] =~ /^(foo|or|less)$/ }
73aec0b1 221 /fooormore/ sub{ref $_[0] eq 'Regexp'}
a4a197da 222 qr/fooormore/ sub{ref $_[0] eq 'Regexp'}
223 1 sub{shift}
224! 0 sub{shift}
225! undef sub{shift}
226 undef sub{not shift}
031a44ed 227 NOT_DEF sub{not shift}
228 &NOT_DEF sub{not shift}
a4a197da 229 FALSE sub{not shift}
230 [1] \&bar
231 {a=>1} \&bar
232 qr// \&bar
233! [1] \&foo
234! {a=>1} \&foo
41e726ac 235 $obj sub { ref($_[0]) =~ /NoOverload/ }
90a32bcb 236 $ov_obj sub { ref($_[0]) =~ /WithOverload/ }
a4a197da 237# empty stuff matches, because the sub is never called:
07edf497 238 [] \&foo
239 {} \&foo
031a44ed 240 @empty \&foo
241 %empty \&foo
a4a197da 242! qr// \&foo
243! undef \&foo
244 undef \&bar
245@ undef \&fatal
246@ 1 \&fatal
247@ [1] \&fatal
203d1e89 248@ {a=>1} \&fatal
a4a197da 249@ "foo" \&fatal
250@ qr// \&fatal
203d1e89 251# sub is not called on empty hashes / arrays
07edf497 252 [] \&fatal
253 +{} \&fatal
031a44ed 254 @empty \&fatal
255 %empty \&fatal
532217f1 256# sub is not special on the left
257 sub {0} qr/^CODE/
258 sub {0} sub { ref shift eq "CODE" }
0d863452 259
0d863452 260# HASH ref against:
261# - another hash ref
262 {} {}
2a37c5e7 263=! {} {1 => 2}
0d863452 264 {1 => 2} {1 => 2}
265 {1 => 2} {1 => 3}
031a44ed 266=! {1 => 2} {2 => 3}
267= \%main:: {map {$_ => 'x'} keys %main::}
0d863452 268
269# - tied hash ref
2522c35a 270= \%hash \%tied_hash
0d863452 271 \%tied_hash \%tied_hash
031a44ed 272!= {"a"=>"b"} \%tied_hash
273= %hash %tied_hash
274 %tied_hash %tied_hash
275!= {"a"=>"b"} %tied_hash
b15feb55 276 $ov_obj %refh
277! "$ov_obj" %refh
278 [$ov_obj] %refh
279! ["$ov_obj"] %refh
280 %refh %refh
0d863452 281
282# - an array ref
031a44ed 283# (since this is symmetrical, tests as well hash~~array)
284= [keys %main::] \%::
285= [qw[STDIN STDOUT]] \%::
286=! [] \%::
287=! [""] {}
288=! [] {}
289=! @empty {}
290= [undef] {"" => 1}
291= [""] {"" => 1}
292= ["foo"] { foo => 1 }
293= ["foo", "bar"] { foo => 1 }
294= ["foo", "bar"] \%hash
295= ["foo"] \%hash
296=! ["quux"] \%hash
297= [qw(foo quux)] \%hash
298= @fooormore { foo => 1, or => 2, more => 3 }
299= @fooormore %fooormore
300= @fooormore \%fooormore
301= \@fooormore %fooormore
0d863452 302
303# - a regex
ea0c2dbd 304= qr/^(fo[ox])$/ {foo => 1}
305= /^(fo[ox])$/ %fooormore
031a44ed 306=! qr/[13579]$/ +{0..99}
ea0c2dbd 307=! qr/a*/ {}
031a44ed 308= qr/a*/ {b=>2}
ea0c2dbd 309= qr/B/i {b=>2}
310= /B/i {b=>2}
311=! qr/a+/ {b=>2}
312= qr/^à/ {"à"=>2}
0d863452 313
031a44ed 314# - a scalar
2e0e16c9 315 "foo" +{foo => 1, bar => 2}
031a44ed 316 "foo" %fooormore
2e0e16c9 317! "baz" +{foo => 1, bar => 2}
031a44ed 318! "boz" %fooormore
319! 1 +{foo => 1, bar => 2}
320! 1 %fooormore
321 1 { 1 => 3 }
322 1.0 { 1 => 3 }
323! "1.0" { 1 => 3 }
324! "1.0" { 1.0 => 3 }
325 "1.0" { "1.0" => 3 }
326 "à" { "à" => "À" }
0d863452 327
61a621c6 328# - undef
2522c35a 329! undef { hop => 'zouu' }
61a621c6 330! undef %hash
331! undef +{"" => "empty key"}
2a37c5e7 332! undef {}
0d863452 333
334# ARRAY ref against:
335# - another array ref
1cfb7049 336 [] []
2522c35a 337=! [] [1]
ea0c2dbd 338 [["foo"], ["bar"]] [qr/o/, qr/a/]
339! [["foo"], ["bar"]] [qr/ARRAY/, qr/ARRAY/]
0d863452 340 ["foo", "bar"] [qr/o/, qr/a/]
031a44ed 341! [qr/o/, qr/a/] ["foo", "bar"]
2522c35a 342 ["foo", "bar"] [["foo"], ["bar"]]
71b0fb34 343! ["foo", "bar"] [qr/o/, "foo"]
2522c35a 344 ["foo", undef, "bar"] [qr/o/, undef, "bar"]
345 ["foo", undef, "bar"] [qr/o/, "", "bar"]
346! ["foo", "", "bar"] [qr/o/, undef, "bar"]
1cfb7049 347 $deep1 $deep1
031a44ed 348 @$deep1 @$deep1
1cfb7049 349! $deep1 $deep2
0d863452 350
031a44ed 351= \@nums \@tied_nums
352= @nums \@tied_nums
353= \@nums @tied_nums
354= @nums @tied_nums
355
d0b243e3 356# - an object
357! $obj @fooormore
41e726ac 358 $obj [sub{ref shift}]
d0b243e3 359
0d863452 360# - a regex
ea0c2dbd 361= qr/x/ [qw(foo bar baz quux)]
362=! qr/y/ [qw(foo bar baz quux)]
363= /x/ [qw(foo bar baz quux)]
364=! /y/ [qw(foo bar baz quux)]
365= /FOO/i @fooormore
366=! /bar/ @fooormore
0d863452 367
368# - a number
015eb7b9 369 2 [qw(1.00 2.00)]
b0138e99 370 2 [qw(foo 2)]
371 2.0_0e+0 [qw(foo 2)]
372! 2 [qw(1foo bar2)]
0d863452 373
374# - a string
b0138e99 375! "2" [qw(1foo 2bar)]
376 "2bar" [qw(1foo 2bar)]
0d863452 377
015eb7b9 378# - undef
379 undef [1, 2, undef, 4]
380! undef [1, 2, [undef], 4]
381! undef @fooormore
382 undef @sparse
383
384# - nested arrays and ~~ distributivity
385 11 [[11]]
386! 11 [[12]]
387 "foo" [{foo => "bar"}]
388! "bar" [{foo => "bar"}]
389
0d863452 390# Number against number
391 2 2
33ed63a2 392 20 2_0
0d863452 393! 2 3
18d11902 394 0 FALSE
395 3-2 TRUE
33ed63a2 396 undef 0
0d863452 397
398# Number against string
33ed63a2 399= 2 "2"
400= 2 "2.0"
0d863452 401! 2 "2bananas"
289d21b2 402!= 2_3 "2_3" NOWARNINGS
18d11902 403 FALSE "0"
0d863452 404
405# Regex against string
a566f585 406 "x" qr/x/
407! "x" qr/y/
0d863452 408
409# Regex against number
410 12345 qr/3/
2522c35a 411! 12345 qr/7/
0d863452 412
031a44ed 413# array/hash against string
d444f7e3 414 @fooormore "".\@fooormore
415! @keyandmore "".\@fooormore
416 %fooormore "".\%fooormore
417! %keyandmore "".\%fooormore
f1bef09e 418
0d863452 419# Test the implicit referencing
b0138e99 420 7 @nums
0d863452 421 @nums \@nums
422! @nums \\@nums
423 @nums [1..10]
424! @nums [0..9]
425
2e0e16c9 426 "foo" %hash
427 /bar/ %hash
428 [qw(bar)] %hash
429! [qw(a b c)] %hash
71b0fb34 430 %hash %hash
fceebc47 431 %hash +{%hash}
73aec0b1 432 %hash \%hash
71b0fb34 433 %hash %tied_hash
434 %tied_hash %tied_hash
435 %hash { foo => 5, bar => 10 }
436! %hash { foo => 5, bar => 10, quux => 15 }
437
438 @nums { 1, '', 2, '' }
439 @nums { 1, '', 12, '' }
440! @nums { 11, '', 12, '' }