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 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267
|
#!./perl -w
BEGIN {
chdir '..' if -d '../pod' && -d '../t';
@INC = 'lib';
require './t/test.pl';
plan(31);
}
BEGIN {
my $w;
$SIG{__WARN__} = sub { $w = shift };
use_ok('diagnostics');
is $w, undef, 'no warnings when loading diagnostics.pm';
}
require base;
eval {
'base'->import(qw(I::do::not::exist));
};
like( $@, qr/^Base class package "I::do::not::exist" is empty/,
'diagnostics not tripped up by "use base qw(Dont::Exist)"');
open *whatever, ">", \my $warning
or die "Couldn't redirect STDERR to var: $!";
my $old_stderr = *STDERR{IO};
*STDERR = *whatever{IO};
# Test for %.0f patterns in perldiag, added in 5.11.0
warn('gmtime(nan) too large');
like $warning, qr/\(W overflow\) You called/, '%0.f patterns';
# L<foo/bar> links
seek STDERR, 0,0;
$warning = '';
warn("accept() on closed socket spanner");
like $warning, qr/"accept" in perlfunc/, 'L<foo/bar> links';
# L<foo|bar/baz> links
seek STDERR, 0,0;
$warning = '';
warn
'Lexing code attempted to stuff non-Latin-1 character into Latin-1 input';
like $warning, qr/lex_stuff_pvn or similar/, 'L<foo|bar/baz>';
# Multiple messages with the same description
seek STDERR, 0,0;
$warning = '';
warn 'Deep recursion on anonymous subroutine';
like $warning, qr/W recursion/,
'Message sharing its description with the following message';
seek STDERR, 0,0;
$warning = '';
warn 'Deep recursion on subroutine "foo"';
like $warning, qr/W recursion/,
'Message sharing its description with the preceding message';
# Periods at end of entries in perldiag.pod get matched correctly
seek STDERR, 0,0;
$warning = '';
warn "Execution of -e aborted due to compilation errors.\n";
like $warning, qr/The final summary message/, 'Periods at end of line';
# Test for %d/%u
seek STDERR, 0,0;
$warning = '';
warn "Bad arg length for us, is 4, should be 42";
like $warning, qr/In C parlance/, '%u works';
# Test for %X
seek STDERR, 0,0;
$warning = '';
warn "Unicode surrogate U+C0FFEE is illegal in UTF-8";
like $warning, qr/You had a UTF-16 surrogate/, '%X';
# Test for %p
seek STDERR, 0,0;
$warning = '';
warn "Slab leaked from cv fadedc0ffee";
like $warning, qr/bookkeeping of op trees/, '%p';
# Strip S<>
seek STDERR, 0,0;
$warning = '';
warn "syntax error";
like $warning, qr/cybernetic version of 20 questions/s, 'strip S<>';
# Errors ending with dots
seek STDERR, 0,0;
$warning = '';
warn "I had compilation errors.\n";
like $warning, qr/final summary message/, 'dotty errors';
# Multiline errors
seek STDERR, 0,0;
$warning = '';
warn "Attempt to reload weapon aborted.\nCompilation failed in require";
like $warning,
qr/You tried to load a file.*Perl could not compile/s,
'multiline errors';
# Multiline entry in perldiag.pod
seek STDERR, 0,0;
$warning = '';
warn "Using just the first character returned by \\N{} in character class in regex; marked by <-- HERE in m/%s/";
like $warning,
qr/Named Unicode character escapes/s,
'multi-line entries in perldiag.pod match';
# ; at end of entry in perldiag.pod
seek STDERR, 0,0;
$warning = '';
warn "Perl folding rules are not up-to-date for 0x0A; please use the perlbug utility to report; in regex; marked by <-- HERE in m/\ <-- HERE q/";
like $warning,
qr/You used a regular expression with case-insensitive matching/s,
'; works at the end of entries in perldiag.pod';
# Differences in spaces in warnings (Why not be nice and accept them?)
seek STDERR, 0,0;
$warning = '';
warn "Assignment to both a list and a scalar\n";
like $warning,
qr/2nd and 3rd/s,
'spaces in warnings are matched lightly';
# Differences in spaces in warnings with a period at the end
seek STDERR, 0,0;
$warning = '';
warn "perl: warning: Setting locale failed.\n";
like $warning,
qr/The whole warning/s,
'spaces in warnings with periods at the end are matched lightly';
# Wrapped links
seek STDERR, 0,0;
$warning = '';
warn "Argument \"%s\" treated as 0 in increment (++)";
like $warning,
qr/Auto-increment.*Auto-decrement/s,
'multiline links are not truncated';
{
# Find last warning in perldiag.pod, and last items if any
my $lw;
my $over_level = 0;
my $inlast;
my $item;
my $items_not_in_overs = 0;
open(my $f, '<', "pod/perldiag.pod")
or die "failed to open pod/perldiag.pod for reading: $!";
while (<$f>) {
# We only look for entries (=item lines) in the first level of =overs
if ( /^=over\b/) {
$over_level++;
} elsif ( /^=item\s+(.*)/) {
if ($over_level < 1) {
$items_not_in_overs++;
}
elsif ($over_level == 1) {
$lw = $1;
}
} elsif (/^=back\b/) {
$inlast = 1 if $over_level == 1;
$over_level--;
} elsif ($inlast) {
# Skip headings
next if /^=/;
# Strip specials
$_ =~ s/\w<(.*?)>/$1/g;
# And whitespace
$_ =~ s/(^\s+|\s+$)//g;
if ($_) {
$item = $_;
last;
}
}
}
close($f);
is($over_level, 0, "(sanity...) =over balanced with =back (off by $over_level)");
is($items_not_in_overs, 0, "(sanity...) all =item lines are within =over..=back blocks");
ok($item, "(sanity...) found an item to check with ($item)");
seek STDERR, 0,0;
$warning = '';
warn $lw;
ok($warning, '(sanity...) got a warning');
unlike $warning,
qr/\Q$item\E/,
"Junk after =back doesn't show up in last warning";
}
*STDERR = $old_stderr;
# These tests use a panic under the hope that the description is not likely
# to change.
@runperl_args = (
switches => [ '-Ilib', '-Mdiagnostics' ],
stderr => 1,
nolib => 1, # -I../lib would go outside the build dir
);
$subs =
"sub foo{bar()}sub bar{baz()}sub baz{die q _panic: gremlins_}foo()";
is runperl(@runperl_args, prog => $subs),
<< 'EOT', 'internal error with backtrace';
panic: gremlins at -e line 1 (#1)
(P) An internal error.
Uncaught exception from user code:
panic: gremlins at -e line 1.
main::baz() called at -e line 1
main::bar() called at -e line 1
main::foo() called at -e line 1
EOT
is runperl(@runperl_args, prog => $subs =~ s/panic\K/k/r),
<< 'EOU', 'user error with backtrace';
Uncaught exception from user code:
panick: gremlins at -e line 1.
main::baz() called at -e line 1
main::bar() called at -e line 1
main::foo() called at -e line 1
EOU
is runperl(@runperl_args, prog => 'die q _panic: gremlins_'),
<< 'EOV', 'no backtrace from top-level internal error';
panic: gremlins at -e line 1 (#1)
(P) An internal error.
Uncaught exception from user code:
panic: gremlins at -e line 1.
EOV
is runperl(@runperl_args, prog => 'die q _panick: gremlins_'),
<< 'EOW', 'no backtrace from top-level user error';
Uncaught exception from user code:
panick: gremlins at -e line 1.
EOW
like runperl(
@runperl_args,
prog => $subs =~
s[q _panic: gremlins_]
[qq _Attempt to reload foo aborted.\\nCompilation failed in require_]r,
),
qr/Uncaught exception from user code:
Attempt to reload foo aborted\.
Compilation failed in require at -e line \d+\.
main::baz\(\) called at -e line \d+
main::bar\(\) called at -e line \d+
main::foo\(\) called at -e line \d+
/, 'backtrace from multiline error';
is runperl(@runperl_args, prog => 'BEGIN { die q _panic: gremlins_ }'),
<< 'EOX', 'BEGIN{die} does not suppress diagnostics';
panic: gremlins at -e line 1.
BEGIN failed--compilation aborted at -e line 1 (#1)
(P) An internal error.
Uncaught exception from user code:
panic: gremlins at -e line 1.
BEGIN failed--compilation aborted at -e line 1.
EOX
|