Remove special case for coderefs with empty prototypes in smart match
[p5sagit/p5-mst-13.2.git] / t / op / smartmatch.t
1 #!./perl
2
3 BEGIN {
4     chdir 't';
5     @INC = '../lib';
6     require './test.pl';
7 }
8 use strict;
9
10 use Tie::Array;
11 use Tie::Hash;
12
13 # Predeclare vars used in the tests:
14 my $deep1 = []; push @$deep1, \$deep1;
15 my $deep2 = []; push @$deep2, \$deep2;
16
17 my @nums = (1..10);
18 tie my @tied_nums, 'Tie::StdArray';
19 @tied_nums =  (1..10);
20
21 my %hash = (foo => 17, bar => 23);
22 tie my %tied_hash, 'Tie::StdHash';
23 %tied_hash = %hash;
24
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
36 our $ov_obj = Test::Object::CopyOverload->new;
37 our $obj = Test::Object::NoOverload->new;
38
39 my @keyandmore = qw(key and more);
40 my @fooormore = qw(foo or more);
41 my %keyandmore = map { $_ => 0 } @keyandmore;
42 my %fooormore = map { $_ => 0 } @fooormore;
43
44 # Load and run the tests
45 plan "no_plan";
46
47 while (<DATA>) {
48     next if /^#/ || !/\S/;
49     chomp;
50     my ($yn, $left, $right, $note) = split /\t+/;
51
52     local $::TODO = $note =~ /TODO/;
53     match_test($yn, $left, $right);
54     match_test($yn, $right, $left);
55 }
56
57 sub match_test {
58     my ($yn, $left, $right) = @_;
59
60     die "Bad test spec: ($yn, $left, $right)"
61         unless $yn eq "" || $yn eq "!" || $yn eq '@';
62
63     my $tstr = "$left ~~ $right";
64
65     my $res = eval $tstr;
66
67     chomp $@;
68
69     if ( $yn eq '@' ) {
70         ok( $@ ne '', "$tstr dies" )
71             and print "# \$\@ was: $@\n";
72     } else {
73         my $test_name = $tstr . ($yn eq '!' ? " does not match" : " matches");
74         if ( $@ ne '' ) {
75             fail($test_name);
76             print "# \$\@ was: $@\n";
77         } else {
78             ok( ($yn eq '!' xor $res), $test_name );
79         }
80     }
81 }
82
83
84
85 sub foo {}
86 sub bar {42}
87 sub gorch {42}
88 sub fatal {die "fatal sub\n"}
89
90 sub a_const() {die "const\n" if @_; "a constant"}
91 sub b_const() {die "const\n" if @_; "a constant"}
92 sub FALSE() { 0 }
93 sub TRUE() { 1 }
94 sub TWO() { 1 }
95
96 # Prefix character :
97 #   - expected to match
98 # ! - expected to not match
99 # @ - expected to be a compilation failure
100 # Data types to test :
101 #   Object-overloaded
102 #   Object
103 #   Code
104 #   Code()
105 #   Coderef
106 #   Hash
107 #   Hashref
108 #   Array
109 #   Arrayref
110 #   Regex (// and qr//)
111 #   Num
112 #   Str
113 #   undef
114 __DATA__
115 # OBJECT
116 # - overloaded
117         $ov_obj         "key"
118 !       $ov_obj         "foo"
119         $ov_obj         {"key" => 1}
120         $ov_obj         {"key" => 1, bar => 2}          TODO
121 !       $ov_obj         {"foo" => 1}
122         $ov_obj         ["key" => 1]
123 !       $ov_obj         ["foo" => 1]
124         $ov_obj         @keyandmore
125 !       $ov_obj         @fooormore
126         $ov_obj         %keyandmore                     TODO
127 !       $ov_obj         %fooormore
128         $ov_obj         /key/
129 !       $ov_obj         /foo/
130         $ov_obj         qr/Key/i
131 !       $ov_obj         qr/foo/
132         $ov_obj         sub { shift ~~ "key" }
133 !       $ov_obj         sub { shift eq "key" }
134 !       $ov_obj         sub { shift ~~ "foo" }
135 !       $ov_obj         \&foo
136         $ov_obj         \&bar
137 @       $ov_obj         \&fatal
138 !       $ov_obj         FALSE
139 !       $ov_obj         \&FALSE
140 !       $ov_obj         undef
141         $ov_obj         $ov_obj
142
143 # regular object
144 @       $obj    "key"
145 @       $obj    {"key" => 1}
146 @       $obj    ["key" => 1]
147 @       $obj    /key/
148 @       $obj    qr/key/
149 @       $obj    sub { 1 }
150 @       $obj    sub { 0 }
151 @       $obj    \&foo
152 @       $obj    \&fatal
153 @       $obj    FALSE
154 @       $obj    \&FALSE
155 !       $obj    undef
156 @       $obj    $obj
157
158 # CODE ref against argument
159 #  - arg is code ref
160 !       \&foo           sub {}
161
162 # - arg is not code ref
163         1       sub{shift}
164 !       0       sub{shift}
165 !       undef   sub{shift}
166         undef   sub{not shift}
167         FALSE   sub{not shift}
168         1       sub{scalar @_}
169         []      \&bar
170         {}      \&bar
171         qr//    \&bar
172 !       []      \&foo
173 !       {}      \&foo
174 !       qr//    \&foo
175 !       undef   \&foo
176         undef   \&bar
177 @       undef   \&fatal
178 @       1       \&fatal
179 @       []      \&fatal
180 @       "foo"   \&fatal
181 @       qr//    \&fatal
182 # pass argument by reference
183         @fooormore      sub{scalar @_ == 1}
184         @fooormore      sub{"@_" =~ /ARRAY/}
185         %fooormore      sub{"@_" =~ /HASH/}
186         /fooormore/     sub{ref $_[0] eq 'Regexp'}
187
188 # - null-prototyped subs
189         a_const         "a constant"
190         a_const         a_const
191         a_const         b_const
192 !       undef           \&FALSE
193         undef           \&TRUE
194 !       0               \&FALSE
195         0               \&TRUE
196 !       1               \&FALSE
197         1               \&TRUE
198 !       \&FALSE         \&foo
199
200 # - non-null-prototyped subs
201         bar             gorch
202 @       fatal           bar
203
204 # HASH ref against:
205 #   - another hash ref
206         {}              {}
207 !       {}              {1 => 2}
208         {1 => 2}        {1 => 2}
209         {1 => 2}        {1 => 3}
210 !       {1 => 2}        {2 => 3}
211         \%main::        {map {$_ => 'x'} keys %main::}
212
213 #  - tied hash ref
214         \%hash          \%tied_hash
215         \%tied_hash     \%tied_hash
216
217 #  - an array ref
218         \%::            [keys %main::]
219 !       \%::            []
220         {"" => 1}       [undef]
221         { foo => 1 }    ["foo"]
222         { foo => 1 }    ["foo", "bar"]
223         \%hash          ["foo", "bar"]
224         \%hash          ["foo"]
225 !       \%hash          ["quux"]
226         \%hash          [qw(foo quux)]
227
228 #  - a regex
229         {foo => 1}      qr/^(fo[ox])$/
230 !       +{0..99}        qr/[13579]$/
231
232 #  - a string
233         +{foo => 1, bar => 2}   "foo"
234 !       +{foo => 1, bar => 2}   "baz"
235
236
237 # ARRAY ref against:
238 #  - another array ref
239         []                      []
240 !       []                      [1]
241         [["foo"], ["bar"]]      [qr/o/, qr/a/]
242         ["foo", "bar"]          [qr/o/, qr/a/]
243 !       ["foo", "bar"]          [qr/o/, "foo"]
244         $deep1                  $deep1
245 !       $deep1                  $deep2
246
247         \@nums                  \@tied_nums
248
249 #  - a regex
250         [qw(foo bar baz quux)]  qr/x/
251 !       [qw(foo bar baz quux)]  qr/y/
252
253 # - a number
254         [qw(1foo 2bar)]         2
255         [qw(foo 2)]             2
256         [qw(foo 2)]             2.0_0e+0
257 !       [qw(1foo bar2)]         2
258
259 # - a string
260 !       [qw(1foo 2bar)]         "2"
261         [qw(1foo 2bar)]         "2bar"
262
263 # Number against number
264         2               2
265 !       2               3
266         0               FALSE
267         3-2             TRUE
268
269 # Number against string
270         2               "2"
271         2               "2.0"
272 !       2               "2bananas"
273 !       2_3             "2_3"
274         FALSE           "0"
275
276 # Regex against string
277         qr/x/           "x"
278 !       qr/y/           "x"
279
280 # Regex against number
281         12345           qr/3/
282
283
284 # Test the implicit referencing
285         @nums           7
286         @nums           \@nums
287 !       @nums           \\@nums
288         @nums           [1..10]
289 !       @nums           [0..9]
290
291         %hash           "foo"
292         %hash           /bar/
293         %hash           [qw(bar)]
294 !       %hash           [qw(a b c)]
295         %hash           %hash
296         %hash           +{%hash}
297         %hash           \%hash
298         %hash           %tied_hash
299         %tied_hash      %tied_hash
300         %hash           { foo => 5, bar => 10 }
301 !       %hash           { foo => 5, bar => 10, quux => 15 }
302
303         @nums           {  1, '',  2, '' }
304         @nums           {  1, '', 12, '' }
305 !       @nums           { 11, '', 12, '' }
306
307 # UNDEF
308 !       3               undef
309 !       1               undef
310 !       []              undef
311 !       {}              undef
312 !       \%::main        undef
313 !       [1,2]           undef
314 !       %hash           undef
315 !       @nums           undef
316 !       "foo"           undef
317 !       ""              undef
318 !       !1              undef
319 !       \&foo           undef
320 !       sub { }         undef
321         undef           undef
322         $::undef        undef