File: 02_uplevel.t

package info (click to toggle)
libsub-uplevel-perl 0.2800-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 260 kB
  • sloc: perl: 671; makefile: 2
file content (211 lines) | stat: -rw-r--r-- 4,566 bytes parent folder | download | duplicates (3)
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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
#!/usr/bin/perl

use strict;
BEGIN { $^W = 1 }

use Test::More tests => 23;

BEGIN { use_ok('Sub::Uplevel'); }
can_ok('Sub::Uplevel', 'uplevel');
can_ok(__PACKAGE__, 'uplevel');

#line 11
ok( !caller,                         "top-level caller() not screwed up" );

eval { die };
is( $@, "Died at $0 line 13.\n",           'die() not screwed up' );

sub foo {
    join " - ", caller;
}

sub bar {
    uplevel(1, \&foo);
}

#line 25
is( bar(), "main - $0 - 25",    'uplevel()' );


# Sure, but does it fool die?
sub try_die {
    die "You must die!  I alone am best!";
}

sub wrap_die {
    uplevel(1, \&try_die);
}

# line 38
eval { wrap_die() };
is( $@, "You must die!  I alone am best! at $0 line 30.\n", 'die() fooled' );


# how about warn?
sub try_warn {
    warn "HA!  You don't fool me!";
}

sub wrap_warn {
    uplevel(1, \&try_warn);
}


my $warning;
{ 
    local $SIG{__WARN__} = sub { $warning = join '', @_ };
#line 56
    wrap_warn();
}
is( $warning, "HA!  You don't fool me! at $0 line 44.\n", 'warn() fooled' );


# Carp?
use Carp;
sub try_croak {
# line 64
    croak("Now we can fool croak!");
}

sub wrap_croak {
# line 68
    uplevel(shift, \&try_croak);
}


# depending on perl version, we could get 'require 0' or 'eval {...}'
# in the stack. This test used to be 'require 0' for <= 5.006, but
# it broke on 5.005_05 test release, so we'll just take either
# line 72
eval { wrap_croak(1) };
my $croak_regex = quotemeta( <<"CARP" );
Now we can fool croak! at $0 line 64
	main::wrap_croak(1) called at $0 line 72
CARP
$croak_regex =~ s/64/64\.?/; # Perl 5.15 series Carp adds period
$croak_regex .= '\t(require 0|eval \{\.\.\.\})'
                . quotemeta( " called at $0 line 72" );
like( $@, "/$croak_regex/", 'croak() fooled');

# Try to wrap higher -- this may have been a problem that was exposed on
# Test Exception
# line 75
eval { wrap_croak(2) };
$croak_regex = quotemeta( <<"CARP" );
Now we can fool croak! at $0 line 64
CARP
$croak_regex =~ s/64/64\.?/; # Perl 5.15 series Carp adds period
like( $@, "/$croak_regex/", 'croak() fooled');

#line 79
ok( !caller,                                "caller() not screwed up" );

eval { die "Dying" };
is( $@, "Dying at $0 line 81.\n",           'die() not screwed up' );



# how about carp?
sub try_carp {
# line 88
    carp "HA!  Even carp is fooled!";
}

sub wrap_carp {
    uplevel(1, \&try_carp);
}


$warning = '';
{ 
    local $SIG{__WARN__} = sub { $warning = join '', @_ };
#line 98
    wrap_carp();
}
my $carp_regex = quotemeta( <<"CARP" );
HA!  Even carp is fooled! at $0 line 88
	main::wrap_carp() called at $0 line 98
CARP
$carp_regex =~ s/88/88\.?/; # Perl 5.15 series Carp adds period
like( $warning, "/$carp_regex/", 'carp() fooled' );


use lib 't/lib';
use Foo;
can_ok( 'main', 'fooble' );

#line 114
sub core_caller_check {
    return CORE::caller(0);
}

sub caller_check {
    return caller(shift);
}

is_deeply(   [ ( caller_check(0), 0, 4 )[0 .. 3] ], 
             ['main', $0, 122, 'main::caller_check' ],
    'caller check' );

is( (() = caller_check(0)), (() = core_caller_check(0)) ,
    "caller() with args returns right number of values"
);

sub core_caller_no_args {
    return CORE::caller();
}

sub caller_no_args {
    return caller();
}

is( (() = caller_no_args()), (() = core_caller_no_args()),
    "caller() with no args returns right number of values"
);

sub deep_caller {
    return caller(1);
}

sub check_deep_caller {
    deep_caller();
}

#line 134
is_deeply([(check_deep_caller)[0..2]], ['main', $0, 134], 'shallow caller' );

sub deeper { deep_caller() }        # caller 0
sub still_deeper { deeper() }       # caller 1 -- should give this line, 137
sub ever_deeper  { still_deeper() } # caller 2

is_deeply([(ever_deeper)[0..2]], ['main', $0, 137], 'deep caller()' );

# This uplevel() should not effect deep_caller's caller(1).
sub yet_deeper { uplevel( 1, \&ever_deeper) }
is_deeply([(yet_deeper)[0..2]],  ['main', $0, 137],  'deep caller() + uplevel' );

sub target { caller }
sub yarrow { uplevel( 1, \&target ) }
sub hock   { uplevel( 1, \&yarrow ) }

is_deeply([(hock)], ['main', $0, 150],  'nested uplevel()s' );

# Deep caller inside uplevel
package Delegator; 
# line 159
sub delegate { main::caller_check(shift) }
    
package Wrapper;
use Sub::Uplevel;
sub wrap { uplevel( 1, \&Delegator::delegate, @_ ) }

package main;

is( (Wrapper::wrap(0))[0], 'Delegator', 
    'deep caller check of parent sees real calling package' 
);

is( (Wrapper::wrap(1))[0], 'main', 
    'deep caller check of grandparent sees package above uplevel' 
);