summaryrefslogtreecommitdiffstats
path: root/t/rjbs.t
blob: b94e8938c616f0002f5085db856a3888a48109e7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#!/usr/bin/env perl
use strict;
use warnings;
use Test::More;

use smartmatch 'rjbs';

{
    package SmartOverload;
    use overload '~~' => sub {
        no warnings 'uninitialized';
        return $_[1] eq ${ $_[0] };
    }, fallback => 1;
}

{
    package RegexOverload;
    use overload 'qr' => sub {
        return $_[0]->[0];
    }, fallback => 1;
}

{
    package StringOverload;
    use overload '""' => sub {
        return $_[0]->{val};
    }, fallback => 1;
}

sub smart  { my $val = shift; bless \$val,           SmartOverload::  }
sub regex  { my $val = shift; bless [qr/$val/],      RegexOverload::  }
sub string { my $val = shift; bless { val => $val }, StringOverload:: }

my @tests = (
    # undef
    [ 1,     undef,        undef ],
    [ 0,     '',           undef ],
    [ 0,     0,            undef ],
    [ 0,     '0',          undef ],
    [ 0,     '0.0',        undef ],
    [ 0,     '0 but true', undef ],
    [ 0,     1,            undef ],
    [ 0,     'x',          undef ],
    [ 0,     [],           undef ],
    [ 0,     {},           undef ],
    [ 0,     sub {},       undef ],
    [ 0,     smart(''),    undef ],
    [ 0,     regex(''),    undef ],
    [ 0,     string(''),   undef ],
    # smart match overload
    [ 1,     "smart",         smart('smart') ],
    [ 1,     string('smart'), smart('smart') ],
    [ 0,     "SMART",         smart('smart') ],
    [ 0,     string('SMART'), smart('smart') ],
    [ 0,     smart('smart'),  smart('smart') ],
    [ 0,     undef,           smart('smart') ],
    [ 0,     1,               smart('smart') ],
    # regex
    [ 0,     undef,         qr/a/             ],
    [ 1,     undef,         qr/a?/            ],
    [ 1,     "foo",         qr/f/             ],
    [ 0,     "foo",         qr/g/             ],
    [ 1,     1,             qr/1/             ],
    [ 0,     ['z'],         qr/z/             ],
    [ 1,     ['z'],         qr/^ARRAY/        ],
    [ 0,     {'y' => 'y'},  qr/y/             ],
    [ 1,     {'y' => 'y'},  qr/^HASH/         ],
    [ 1,     string('foo'), qr/^foo$/         ],
    [ 0,     regex('foo'),  qr/foo/           ],
    [ 1,     regex('foo'),  qr/^Regex/        ],
    [ 1,     qr/foo/,       qr/\(\?\^\:foo\)/ ],
    # regex overload
    [ 0,     undef,         regex('a')             ],
    [ 1,     undef,         regex('a?')            ],
    [ 1,     "foo",         regex('f')             ],
    [ 0,     "foo",         regex('g')             ],
    [ 1,     1,             regex('1')             ],
    [ 0,     ['z'],         regex('z')             ],
    [ 1,     ['z'],         regex('^ARRAY')        ],
    [ 0,     {'y' => 'y'},  regex('y')             ],
    [ 1,     {'y' => 'y'},  regex('^HASH')         ],
    [ 1,     string('foo'), regex('^foo$')         ],
    [ 0,     regex('foo'),  regex('foo')           ],
    [ 1,     regex('foo'),  regex('^Regex')        ],
    [ 1,     qr/foo/,       regex('\(\?\^\:foo\)') ],
    # code
    [ 1,     undef,        sub { 1 }                    ],
    [ 1,     '',           sub { 1 }                    ],
    [ 1,     0,            sub { 1 }                    ],
    [ 1,     '0',          sub { 1 }                    ],
    [ 1,     '0.0',        sub { 1 }                    ],
    [ 1,     '0 but true', sub { 1 }                    ],
    [ 1,     1,            sub { 1 }                    ],
    [ 1,     'x',          sub { 1 }                    ],
    [ 1,     [],           sub { 1 }                    ],
    [ 1,     {},           sub { 1 }                    ],
    [ 1,     sub {},       sub { 1 }                    ],
    [ 1,     smart(''),    sub { 1 }                    ],
    [ 1,     regex(''),    sub { 1 }                    ],
    [ 1,     string(''),   sub { 1 }                    ],
    [ 0,     undef,        sub { 0 }                    ],
    [ 0,     '',           sub { 0 }                    ],
    [ 0,     0,            sub { 0 }                    ],
    [ 0,     '0',          sub { 0 }                    ],
    [ 0,     '0.0',        sub { 0 }                    ],
    [ 0,     '0 but true', sub { 0 }                    ],
    [ 0,     1,            sub { 0 }                    ],
    [ 0,     'x',          sub { 0 }                    ],
    [ 0,     [],           sub { 0 }                    ],
    [ 0,     {},           sub { 0 }                    ],
    [ 0,     sub {},       sub { 0 }                    ],
    [ 0,     smart(''),    sub { 0 }                    ],
    [ 0,     regex(''),    sub { 0 }                    ],
    [ 0,     string(''),   sub { 0 }                    ],
    [ 1,     ['a', 'b'],   sub { ref $_[0] eq 'ARRAY' } ],
    [ 1,     ['a', 'b'],   sub { $_[0]->[0] eq 'a' }    ],
    [ 1,     string('x'),  sub { $_[0] eq 'x' }         ],
    [ 1,     smart('x'),   sub { 'x' ~~ $_[0] }         ],
    [ 0,     smart('x'),   sub { 'y' ~~ $_[0] }         ],
    # any
    [ 'die', undef, ''           ],
    [ 'die', undef, 0            ],
    [ 'die', undef, '0'          ],
    [ 'die', undef, '0.0'        ],
    [ 'die', undef, '0 but true' ],
    [ 'die', undef, 1            ],
    [ 'die', undef, 'x'          ],
    [ 'die', undef, []           ],
    [ 'die', undef, {}           ],
    [ 0,     undef, sub {}       ],
    [ 1,     undef, smart('')    ],
    [ 1,     undef, regex('')    ],
    [ 'die', undef, string('')   ],
);

for my $test (@tests) {
    # shut up warnings about undef =~ regex
    $SIG{__WARN__} = sub { } unless defined $test->[1];

    if ($test->[0] eq 'die') {
        ok(!eval { $test->[1] ~~ $test->[2]; 1 });
        like($@, qr/invalid smart match/);
    }
    elsif ($test->[0]) {
        ok($test->[1] ~~ $test->[2]);
    }
    else {
        ok(!($test->[1] ~~ $test->[2]));
    }

    delete $SIG{__WARN__};
}

done_testing;