1*5486feefSafresh1use Test2::Bundle::Extended -target => 'Test2::Tools::Class';
2*5486feefSafresh1
3*5486feefSafresh1{
4*5486feefSafresh1    package Temp;
5*5486feefSafresh1    use Test2::Tools::Class;
6*5486feefSafresh1
7*5486feefSafresh1    main::imported_ok(qw/can_ok isa_ok DOES_ok/);
8*5486feefSafresh1}
9*5486feefSafresh1
10*5486feefSafresh1{
11*5486feefSafresh1    package X;
12*5486feefSafresh1
13*5486feefSafresh1    sub can {
14*5486feefSafresh1        my $thing = pop;
15*5486feefSafresh1        return 1 if $thing =~ m/x/;
16*5486feefSafresh1        return 1 if $thing eq 'DOES';
17*5486feefSafresh1    }
18*5486feefSafresh1
19*5486feefSafresh1    sub isa {
20*5486feefSafresh1        my $thing = pop;
21*5486feefSafresh1        return 1 if $thing =~ m/x/;
22*5486feefSafresh1    }
23*5486feefSafresh1
24*5486feefSafresh1    sub DOES {
25*5486feefSafresh1        my $thing = pop;
26*5486feefSafresh1        return 1 if $thing =~ m/x/;
27*5486feefSafresh1    }
28*5486feefSafresh1}
29*5486feefSafresh1
30*5486feefSafresh1{
31*5486feefSafresh1    package XYZ;
32*5486feefSafresh1    use Carp qw/croak/;
33*5486feefSafresh1    sub isa { croak 'oops' };
34*5486feefSafresh1    sub can { croak 'oops' };
35*5486feefSafresh1    sub DOES { croak 'oops' };
36*5486feefSafresh1}
37*5486feefSafresh1
38*5486feefSafresh1{
39*5486feefSafresh1    package My::String;
40*5486feefSafresh1    use overload '""' => sub { "xxx\nyyy" };
41*5486feefSafresh1
42*5486feefSafresh1    sub DOES { 0 }
43*5486feefSafresh1}
44*5486feefSafresh1
45*5486feefSafresh1like(
46*5486feefSafresh1    intercept {
47*5486feefSafresh1        my $str = bless {}, 'My::String';
48*5486feefSafresh1
49*5486feefSafresh1        isa_ok('X', qw/axe box fox/);
50*5486feefSafresh1        can_ok('X', qw/axe box fox/);
51*5486feefSafresh1        DOES_ok('X', qw/axe box fox/);
52*5486feefSafresh1        isa_ok($str, 'My::String');
53*5486feefSafresh1
54*5486feefSafresh1        isa_ok('X',  qw/foo bar axe box/);
55*5486feefSafresh1        can_ok('X',  qw/foo bar axe box/);
56*5486feefSafresh1        DOES_ok('X', qw/foo bar axe box/);
57*5486feefSafresh1
58*5486feefSafresh1        isa_ok($str, 'X');
59*5486feefSafresh1        can_ok($str, 'X');
60*5486feefSafresh1        DOES_ok($str, 'X');
61*5486feefSafresh1
62*5486feefSafresh1        isa_ok(undef, 'X');
63*5486feefSafresh1        isa_ok('', 'X');
64*5486feefSafresh1        isa_ok({}, 'X');
65*5486feefSafresh1
66*5486feefSafresh1        isa_ok('X',  [qw/axe box fox/], 'alt name');
67*5486feefSafresh1        can_ok('X',  [qw/axe box fox/], 'alt name');
68*5486feefSafresh1        DOES_ok('X', [qw/axe box fox/], 'alt name');
69*5486feefSafresh1
70*5486feefSafresh1        isa_ok('X',  [qw/foo bar axe box/], 'alt name');
71*5486feefSafresh1        can_ok('X',  [qw/foo bar axe box/], 'alt name');
72*5486feefSafresh1        DOES_ok('X', [qw/foo bar axe box/], 'alt name');
73*5486feefSafresh1    },
74*5486feefSafresh1    array {
75*5486feefSafresh1        event Ok => { pass => 1, name => 'X->isa(...)' };
76*5486feefSafresh1        event Ok => { pass => 1, name => 'X->can(...)' };
77*5486feefSafresh1        event Ok => { pass => 1, name => 'X->DOES(...)' };
78*5486feefSafresh1        event Ok => { pass => 1, name => qr/My::String=.*->isa\('My::String'\)/ };
79*5486feefSafresh1
80*5486feefSafresh1        fail_events Ok => sub { call pass => 0 };
81*5486feefSafresh1        event Diag => {message => "Failed: X->isa('foo')"};
82*5486feefSafresh1        event Diag => {message => "Failed: X->isa('bar')"};
83*5486feefSafresh1        fail_events Ok => sub { call pass => 0 };
84*5486feefSafresh1        event Diag => { message => "Failed: X->can('foo')" };
85*5486feefSafresh1        event Diag => { message => "Failed: X->can('bar')" };
86*5486feefSafresh1        fail_events Ok => sub { call pass => 0 };
87*5486feefSafresh1        event Diag => { message => "Failed: X->DOES('foo')" };
88*5486feefSafresh1        event Diag => { message => "Failed: X->DOES('bar')" };
89*5486feefSafresh1
90*5486feefSafresh1        fail_events Ok => sub { call pass => 0 };
91*5486feefSafresh1        event Diag => { message => qr/Failed: My::String=HASH->isa\('X'\)/ };
92*5486feefSafresh1        fail_events Ok => sub { call pass => 0 };
93*5486feefSafresh1        event Diag => { message => qr/Failed: My::String=HASH->can\('X'\)/ };
94*5486feefSafresh1        fail_events Ok => sub { call pass => 0 };
95*5486feefSafresh1        event Diag => { message => qr/Failed: My::String=HASH->DOES\('X'\)/ };
96*5486feefSafresh1
97*5486feefSafresh1        fail_events Ok => sub { call pass => 0 };
98*5486feefSafresh1        event Diag => { message => qr/<undef> is neither a blessed reference or a package name/ };
99*5486feefSafresh1        fail_events Ok => sub { call pass => 0 };
100*5486feefSafresh1        event Diag => { message => qr/'' is neither a blessed reference or a package name/ };
101*5486feefSafresh1        fail_events Ok => sub { call pass => 0 };
102*5486feefSafresh1        event Diag => { message => qr/HASH is neither a blessed reference or a package name/ };
103*5486feefSafresh1
104*5486feefSafresh1        event Ok => { pass => 1, name => 'alt name' };
105*5486feefSafresh1        event Ok => { pass => 1, name => 'alt name' };
106*5486feefSafresh1        event Ok => { pass => 1, name => 'alt name' };
107*5486feefSafresh1
108*5486feefSafresh1        fail_events Ok => sub { call pass => 0; call name => 'alt name' };
109*5486feefSafresh1        event Diag => {message => "Failed: X->isa('foo')"};
110*5486feefSafresh1        event Diag => {message => "Failed: X->isa('bar')"};
111*5486feefSafresh1        fail_events Ok => sub { call pass => 0; call name => 'alt name' };
112*5486feefSafresh1        event Diag => {message => "Failed: X->can('foo')"};
113*5486feefSafresh1        event Diag => {message => "Failed: X->can('bar')"};
114*5486feefSafresh1        fail_events Ok => sub { call pass => 0; call name => 'alt name' };
115*5486feefSafresh1        event Diag => {message => "Failed: X->DOES('foo')"};
116*5486feefSafresh1        event Diag => {message => "Failed: X->DOES('bar')"};
117*5486feefSafresh1
118*5486feefSafresh1        end;
119*5486feefSafresh1    },
120*5486feefSafresh1    "'can/isa/DOES_ok' events"
121*5486feefSafresh1);
122*5486feefSafresh1
123*5486feefSafresh1my $override = UNIVERSAL->can('DOES') ? 1 : 0;
124*5486feefSafresh1note "Will override UNIVERSAL::can to hide 'DOES'" if $override;
125*5486feefSafresh1
126*5486feefSafresh1my $events = intercept {
127*5486feefSafresh1    my $can = \&UNIVERSAL::can;
128*5486feefSafresh1
129*5486feefSafresh1    # If the platform does support 'DOES' lets pretend it doesn't.
130*5486feefSafresh1    no warnings 'redefine';
131*5486feefSafresh1    local *UNIVERSAL::can = sub {
132*5486feefSafresh1        my ($thing, $sub) = @_;
133*5486feefSafresh1        return undef if $sub eq 'DOES';
134*5486feefSafresh1        $thing->$can($sub);
135*5486feefSafresh1    } if $override;
136*5486feefSafresh1
137*5486feefSafresh1    DOES_ok('A::Fake::Package', 'xxx');
138*5486feefSafresh1};
139*5486feefSafresh1
140*5486feefSafresh1like(
141*5486feefSafresh1    $events,
142*5486feefSafresh1    array {
143*5486feefSafresh1        event Skip => {
144*5486feefSafresh1            pass   => 1,
145*5486feefSafresh1            name   => "A::Fake::Package->DOES('xxx')",
146*5486feefSafresh1            reason => "'DOES' is not supported on this platform",
147*5486feefSafresh1        };
148*5486feefSafresh1    },
149*5486feefSafresh1    "Test us skipped when platform does not support 'DOES'"
150*5486feefSafresh1);
151*5486feefSafresh1
152*5486feefSafresh1done_testing;
153