1#!./perl -w 2 3BEGIN { 4 chdir '..' if -d '../pod' && -d '../t'; 5 @INC = 'lib'; 6 require './t/test.pl'; 7 plan(29); 8} 9 10BEGIN { 11 my $w; 12 $SIG{__WARN__} = sub { $w = shift }; 13 use_ok('diagnostics'); 14 is $w, undef, 'no warnings when loading diagnostics.pm'; 15} 16 17require base; 18 19eval { 20 'base'->import(qw(I::do::not::exist)); 21}; 22 23like( $@, qr/^Base class package "I::do::not::exist" is empty/, 24 'diagnostics not tripped up by "use base qw(Dont::Exist)"'); 25 26open *whatever, ">", \my $warning 27 or die "Couldn't redirect STDERR to var: $!"; 28my $old_stderr = *STDERR{IO}; 29*STDERR = *whatever{IO}; 30 31# Test for %.0f patterns in perldiag, added in 5.11.0 32warn('gmtime(nan) too large'); 33like $warning, qr/\(W overflow\) You called/, '%0.f patterns'; 34 35# L<foo/bar> links 36seek STDERR, 0,0; 37$warning = ''; 38warn("accept() on closed socket spanner"); 39like $warning, qr/"accept" in perlfunc/, 'L<foo/bar> links'; 40 41# L<foo|bar/baz> links 42seek STDERR, 0,0; 43$warning = ''; 44warn 45 'Lexing code attempted to stuff non-Latin-1 character into Latin-1 input'; 46like $warning, qr/lex_stuff_pvn or similar/, 'L<foo|bar/baz>'; 47 48# Multiple messages with the same description 49seek STDERR, 0,0; 50$warning = ''; 51warn 'Deep recursion on anonymous subroutine'; 52like $warning, qr/W recursion/, 53 'Message sharing its description with the following message'; 54seek STDERR, 0,0; 55$warning = ''; 56warn 'Deep recursion on subroutine "foo"'; 57like $warning, qr/W recursion/, 58 'Message sharing its description with the preceding message'; 59 60# Periods at end of entries in perldiag.pod get matched correctly 61seek STDERR, 0,0; 62$warning = ''; 63warn "Execution of -e aborted due to compilation errors.\n"; 64like $warning, qr/The final summary message/, 'Periods at end of line'; 65 66# Test for %d/%u 67seek STDERR, 0,0; 68$warning = ''; 69warn "Bad arg length for us, is 4, should be 42"; 70like $warning, qr/In C parlance/, '%u works'; 71 72# Test for %X 73seek STDERR, 0,0; 74$warning = ''; 75warn "Unicode surrogate U+C0FFEE is illegal in UTF-8"; 76like $warning, qr/You had a UTF-16 surrogate/, '%X'; 77 78# Test for %p 79seek STDERR, 0,0; 80$warning = ''; 81warn "Slab leaked from cv fadedc0ffee"; 82like $warning, qr/bookkeeping of op trees/, '%p'; 83 84# Strip S<> 85seek STDERR, 0,0; 86$warning = ''; 87warn "syntax error"; 88like $warning, qr/cybernetic version of 20 questions/s, 'strip S<>'; 89 90# Errors ending with dots 91seek STDERR, 0,0; 92$warning = ''; 93warn "I had compilation errors.\n"; 94like $warning, qr/final summary message/, 'dotty errors'; 95 96# Multiline errors 97seek STDERR, 0,0; 98$warning = ''; 99warn "Attempt to reload weapon aborted.\nCompilation failed in require"; 100like $warning, 101 qr/You tried to load a file.*Perl could not compile/s, 102 'multiline errors'; 103 104# Multiline entry in perldiag.pod 105seek STDERR, 0,0; 106$warning = ''; 107warn "Using just the first character returned by \\N{} in character class in regex; marked by <-- HERE in m/%s/"; 108like $warning, 109 qr/A charnames handler may return a sequence/s, 110 'multi-line entries in perldiag.pod match'; 111 112# ; at end of entry in perldiag.pod 113seek STDERR, 0,0; 114$warning = ''; 115warn "Perl folding rules are not up-to-date for 0xA; please use the perlbug utility to report; in regex; marked by <-- HERE in m/\ <-- HERE q/"; 116like $warning, 117 qr/You used a regular expression with case-insensitive matching/s, 118 '; works at the end of entries in perldiag.pod'; 119 120# Differences in spaces in warnings (Why not be nice and accept them?) 121seek STDERR, 0,0; 122$warning = ''; 123warn "Assignment to both a list and a scalar\n"; 124like $warning, 125 qr/2nd and 3rd/s, 126 'spaces in warnings are matched lightly'; 127 128# Differences in spaces in warnings with a period at the end 129seek STDERR, 0,0; 130$warning = ''; 131warn "perl: warning: Setting locale failed.\n"; 132like $warning, 133 qr/The whole warning/s, 134 'spaces in warnings with periods at the end are matched lightly'; 135 136# Wrapped links 137SKIP: { 138skip("We no longer have any multi-line links", 1); 139seek STDERR, 0,0; 140$warning = ''; 141warn "Argument \"%s\" treated as 0 in increment (++)"; 142like $warning, 143 qr/Auto-increment.*Auto-decrement/s, 144 'multiline links are not truncated'; 145} 146 147{ 148# Find last warning in perldiag.pod, and last items if any 149 my $lw; 150 my $inlast; 151 my $item; 152 153 open(my $f, '<', "pod/perldiag.pod") 154 or die "failed to open pod/perldiag.pod for reading: $!"; 155 156 while (<$f>) { 157 if ( /^=item\s+(.*)/) { 158 $lw = $1; 159 } elsif (/^=back/) { 160 $inlast = 1; 161 } elsif ($inlast) { 162 # Skip headings 163 next if /^=/; 164 165 # Strip specials 166 $_ =~ s/\w<(.*?)>/$1/g; 167 168 # And whitespace 169 $_ =~ s/(^\s+|\s+$)//g; 170 171 if ($_) { 172 $item = $_; 173 174 last; 175 } 176 } 177 } 178 close($f); 179 180 ok($item, "(sanity...) found an item to check with ($item)"); 181 seek STDERR, 0,0; 182 $warning = ''; 183 warn $lw; 184 ok($warning, '(sanity...) got a warning'); 185 unlike $warning, 186 qr/\Q$item\E/, 187 "Junk after =back doesn't show up in last warning"; 188} 189 190*STDERR = $old_stderr; 191 192# These tests use a panic under the hope that the description is not likely 193# to change. 194@runperl_args = ( 195 switches => [ '-Ilib', '-Mdiagnostics' ], 196 stderr => 1, 197 nolib => 1, # -I../lib would go outside the build dir 198); 199$subs = 200 "sub foo{bar()}sub bar{baz()}sub baz{die q _panic: gremlins_}foo()"; 201is runperl(@runperl_args, prog => $subs), 202 << 'EOT', 'internal error with backtrace'; 203panic: gremlins at -e line 1 (#1) 204 (P) An internal error. 205 206Uncaught exception from user code: 207 panic: gremlins at -e line 1. 208 main::baz() called at -e line 1 209 main::bar() called at -e line 1 210 main::foo() called at -e line 1 211EOT 212is runperl(@runperl_args, prog => $subs =~ s/panic\K/k/r), 213 << 'EOU', 'user error with backtrace'; 214Uncaught exception from user code: 215 panick: gremlins at -e line 1. 216 main::baz() called at -e line 1 217 main::bar() called at -e line 1 218 main::foo() called at -e line 1 219EOU 220is runperl(@runperl_args, prog => 'die q _panic: gremlins_'), 221 << 'EOV', 'no backtrace from top-level internal error'; 222panic: gremlins at -e line 1 (#1) 223 (P) An internal error. 224 225Uncaught exception from user code: 226 panic: gremlins at -e line 1. 227EOV 228is runperl(@runperl_args, prog => 'die q _panick: gremlins_'), 229 << 'EOW', 'no backtrace from top-level user error'; 230Uncaught exception from user code: 231 panick: gremlins at -e line 1. 232EOW 233like runperl( 234 @runperl_args, 235 prog => $subs =~ 236 s[q _panic: gremlins_] 237 [qq _Attempt to reload foo aborted.\\nCompilation failed in require_]r, 238 ), 239 qr/Uncaught exception from user code: 240 Attempt to reload foo aborted\. 241 Compilation failed in require at -e line \d+\. 242 main::baz\(\) called at -e line \d+ 243 main::bar\(\) called at -e line \d+ 244 main::foo\(\) called at -e line \d+ 245/, 'backtrace from multiline error'; 246is runperl(@runperl_args, prog => 'BEGIN { die q _panic: gremlins_ }'), 247 << 'EOX', 'BEGIN{die} does not suppress diagnostics'; 248panic: gremlins at -e line 1. 249BEGIN failed--compilation aborted at -e line 1 (#1) 250 (P) An internal error. 251 252Uncaught exception from user code: 253 panic: gremlins at -e line 1. 254 BEGIN failed--compilation aborted at -e line 1. 255EOX 256