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