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