Test that in "~~ sub", the sub is not called on empty hashes and arrays
[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;
32 sub new { bless { key => 1 } }
33 use overload '~~' => sub { my %hash = %{ $_[0] }; %hash ~~ $_[1] };
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
82
83
84sub foo {}
73aec0b1 85sub bar {42}
86sub gorch {42}
1cfb7049 87sub fatal {die "fatal sub\n"}
0d863452 88
18d11902 89sub FALSE() { 0 }
90sub TRUE() { 1 }
91sub TWO() { 1 }
0d863452 92
e5de85fa 93# Prefix character :
94# - expected to match
95# ! - expected to not match
96# @ - expected to be a compilation failure
85af77a5 97# = - expected to match symmetrically (runs test twice)
73aec0b1 98# Data types to test :
85af77a5 99# undef
73aec0b1 100# Object-overloaded
101# Object
73aec0b1 102# Coderef
103# Hash
104# Hashref
105# Array
106# Arrayref
85af77a5 107# Tied arrays and hashes
108# Arrays that reference themselves
73aec0b1 109# Regex (// and qr//)
85af77a5 110# Range
73aec0b1 111# Num
112# Str
85af77a5 113# Other syntactic items of interest:
114# Constants
115# Values returned by a sub call
0d863452 116__DATA__
85af77a5 117# Any ~~ undef
33570f8b 118! $ov_obj undef
85af77a5 119! $obj undef
120! sub {} undef
121! %hash undef
122! \%hash undef
123! {} undef
124! @nums undef
125! \@nums undef
126! [] undef
127! %tied_hash undef
128! @tied_nums undef
129! $deep1 undef
130! /foo/ undef
131! qr/foo/ undef
132! 21..30 undef
133! 189 undef
134! "foo" undef
135! "" undef
136! !1 undef
137 undef undef
62ec5f58 138 (my $u) undef
85af77a5 139
140# Any ~~ object overloaded
141# object overloaded ~~ Any
4cbab0e9 142 $ov_obj $ov_obj
85af77a5 143=@ $ov_obj \&fatal
144=! $ov_obj \&FALSE
145=! $ov_obj \&foo
146= $ov_obj \&bar
147= $ov_obj sub { shift ~~ "key" }
a4a197da 148=! $ov_obj sub { shift ne "key" }
85af77a5 149=! $ov_obj sub { shift ~~ "foo" }
150= $ov_obj %keyandmore TODO
151=! $ov_obj %fooormore
152= $ov_obj {"key" => 1}
153= $ov_obj {"key" => 1, bar => 2} TODO
154=! $ov_obj {"foo" => 1}
155= $ov_obj @keyandmore
156=! $ov_obj @fooormore
157= $ov_obj ["key" => 1]
158=! $ov_obj ["foo" => 1]
159= $ov_obj /key/
160=! $ov_obj /foo/
161= $ov_obj qr/Key/i
162=! $ov_obj qr/foo/
163= $ov_obj "key"
164=! $ov_obj "foo"
165=! $ov_obj FALSE
1cfb7049 166
167# regular object
85af77a5 168=@ $obj $ov_obj
169=@ $obj $obj
170=@ $obj \&fatal
171=@ $obj \&FALSE
172=@ $obj \&foo
173=@ $obj sub { 1 }
174=@ $obj sub { 0 }
175=@ $obj %keyandmore
176=@ $obj {"key" => 1}
177=@ $obj @fooormore
178=@ $obj ["key" => 1]
179=@ $obj /key/
180=@ $obj qr/key/
181=@ $obj "key"
182=@ $obj FALSE
1cfb7049 183
a4a197da 184# ~~ Coderef
185 sub{0} sub { ref $_[0] eq "CODE" }
186 %fooormore sub { $_[0] =~ /^(foo|or|more)$/ }
187! %fooormore sub { $_[0] =~ /^(foo|or|less)$/ }
188 \%fooormore sub { $_[0] =~ /^(foo|or|more)$/ }
189! \%fooormore sub { $_[0] =~ /^(foo|or|less)$/ }
190 +{%fooormore} sub { $_[0] =~ /^(foo|or|more)$/ }
191! +{%fooormore} sub { $_[0] =~ /^(foo|or|less)$/ }
192 @fooormore sub { $_[0] =~ /^(foo|or|more)$/ }
193! @fooormore sub { $_[0] =~ /^(foo|or|less)$/ }
194 \@fooormore sub { $_[0] =~ /^(foo|or|more)$/ }
195! \@fooormore sub { $_[0] =~ /^(foo|or|less)$/ }
196 [@fooormore] sub { $_[0] =~ /^(foo|or|more)$/ }
197! [@fooormore] sub { $_[0] =~ /^(foo|or|less)$/ }
198 %fooormore sub{@_==1}
199 @fooormore sub{@_==1}
200 "foo" sub { $_[0] =~ /^(foo|or|more)$/ }
201! "more" sub { $_[0] =~ /^(foo|or|less)$/ }
73aec0b1 202 /fooormore/ sub{ref $_[0] eq 'Regexp'}
a4a197da 203 qr/fooormore/ sub{ref $_[0] eq 'Regexp'}
204 1 sub{shift}
205! 0 sub{shift}
206! undef sub{shift}
207 undef sub{not shift}
208 FALSE sub{not shift}
209 [1] \&bar
210 {a=>1} \&bar
211 qr// \&bar
212! [1] \&foo
213! {a=>1} \&foo
214# empty stuff matches, because the sub is never called:
215 [] \&foo
216 {} \&foo
217! qr// \&foo
218! undef \&foo
219 undef \&bar
220@ undef \&fatal
221@ 1 \&fatal
222@ [1] \&fatal
203d1e89 223@ {a=>1} \&fatal
a4a197da 224@ "foo" \&fatal
225@ qr// \&fatal
203d1e89 226# sub is not called on empty hashes / arrays
227 [] \&fatal
228 +{} \&fatal
0d863452 229
230# - null-prototyped subs
18d11902 231! undef \&FALSE
232 undef \&TRUE
233! 0 \&FALSE
234 0 \&TRUE
235! 1 \&FALSE
236 1 \&TRUE
18d11902 237! \&FALSE \&foo
1cfb7049 238
239# - non-null-prototyped subs
1cfb7049 240 bar gorch
241@ fatal bar
0d863452 242
243# HASH ref against:
244# - another hash ref
245 {} {}
246! {} {1 => 2}
247 {1 => 2} {1 => 2}
248 {1 => 2} {1 => 3}
249! {1 => 2} {2 => 3}
250 \%main:: {map {$_ => 'x'} keys %main::}
251
252# - tied hash ref
253 \%hash \%tied_hash
254 \%tied_hash \%tied_hash
255
256# - an array ref
257 \%:: [keys %main::]
258! \%:: []
259 {"" => 1} [undef]
71b0fb34 260 { foo => 1 } ["foo"]
261 { foo => 1 } ["foo", "bar"]
262 \%hash ["foo", "bar"]
263 \%hash ["foo"]
264! \%hash ["quux"]
265 \%hash [qw(foo quux)]
0d863452 266
267# - a regex
268 {foo => 1} qr/^(fo[ox])$/
fceebc47 269! +{0..99} qr/[13579]$/
0d863452 270
271# - a string
272 +{foo => 1, bar => 2} "foo"
273! +{foo => 1, bar => 2} "baz"
274
275
276# ARRAY ref against:
277# - another array ref
1cfb7049 278 [] []
279! [] [1]
0d863452 280 [["foo"], ["bar"]] [qr/o/, qr/a/]
281 ["foo", "bar"] [qr/o/, qr/a/]
71b0fb34 282! ["foo", "bar"] [qr/o/, "foo"]
1cfb7049 283 $deep1 $deep1
284! $deep1 $deep2
0d863452 285
1cfb7049 286 \@nums \@tied_nums
0d863452 287
288# - a regex
289 [qw(foo bar baz quux)] qr/x/
290! [qw(foo bar baz quux)] qr/y/
291
292# - a number
293 [qw(1foo 2bar)] 2
25a0c96d 294 [qw(foo 2)] 2
295 [qw(foo 2)] 2.0_0e+0
296! [qw(1foo bar2)] 2
0d863452 297
298# - a string
299! [qw(1foo 2bar)] "2"
25a0c96d 300 [qw(1foo 2bar)] "2bar"
0d863452 301
302# Number against number
303 2 2
304! 2 3
18d11902 305 0 FALSE
306 3-2 TRUE
0d863452 307
308# Number against string
309 2 "2"
310 2 "2.0"
311! 2 "2bananas"
312! 2_3 "2_3"
18d11902 313 FALSE "0"
0d863452 314
315# Regex against string
316 qr/x/ "x"
317! qr/y/ "x"
318
319# Regex against number
320 12345 qr/3/
321
322
323# Test the implicit referencing
324 @nums 7
325 @nums \@nums
326! @nums \\@nums
327 @nums [1..10]
328! @nums [0..9]
329
330 %hash "foo"
331 %hash /bar/
71b0fb34 332 %hash [qw(bar)]
333! %hash [qw(a b c)]
334 %hash %hash
fceebc47 335 %hash +{%hash}
73aec0b1 336 %hash \%hash
71b0fb34 337 %hash %tied_hash
338 %tied_hash %tied_hash
339 %hash { foo => 5, bar => 10 }
340! %hash { foo => 5, bar => 10, quux => 15 }
341
342 @nums { 1, '', 2, '' }
343 @nums { 1, '', 12, '' }
344! @nums { 11, '', 12, '' }