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