Skip to content

Commit

Permalink
This extends starcktrace.t to show more clearly why @db::args can not
Browse files Browse the repository at this point in the history
be visible during test_exceptin tests. Implement explicit hiding of
@db::args by simply emptying the global (this looks like a safe thing
to do).
  • Loading branch information
ribasushi committed Oct 1, 2010
1 parent 2f6200a commit 23e5d84
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 13 deletions.
30 changes: 25 additions & 5 deletions lib/Test/Exception.pm
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,32 @@ sub _quiet_caller (;$) { ## no critic Prototypes
if ( CORE::caller() eq 'DB' ) {
# passthrough the @DB::args trick
package DB;
if( wantarray and !@_ ) {
return (CORE::caller($height))[0..2];
}
else {
return CORE::caller($height);
if( wantarray ) {
if ( !@_ ) {
return (CORE::caller($height))[0..2];
}
else {
# If we got here, we are within a Test::Exception test, and
# something is producing a stacktrace. In case this is a full
# trace (i.e. confess() ), we have to make sure that the sub
# args are not visible. If we do not do this, and the test in
# question is throws_ok() with a regex, it will end up matching
# against itself in the args to throws_ok().
#
# While it is possible (and maybe wise), to test if we are
# indeed running under throws_ok (by crawling the stack right
# up from here), the old behavior of Test::Exception was to
# simply obliterate @DB::args altogether in _quiet_caller, so
# we are just preserving the behavior to avoid surprises
#
my @frame_info = CORE::caller($height);
@DB::args = ();
return @frame_info;
}
}

# fallback if nothing above returns
return CORE::caller($height);
}
else {
if( wantarray and !@_ ) {
Expand Down
36 changes: 28 additions & 8 deletions t/stacktrace.t
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,35 @@ use strict;
use warnings;
use Sub::Uplevel;
use Carp;
use Test::Builder::Tester tests => 2;
use Test::Builder::Tester tests => 3;
use Test::More;

BEGIN { use_ok( 'Test::Exception' ) };

test_out('not ok 1 - threw /fribble/');
test_fail(+1);
throws_ok { confess('died') } '/fribble/';
my $exception = $@;
test_diag('expecting: /fribble/');
test_diag(split /\n/, "found: $exception");
test_test('regex in stacktrace ignored');
# This test in essence makes sure that no false
# positives are encountered due to @DB::args being part
# of the stacktrace
# The test seems rather complex due to the fact that
# we make a really tricky stacktrace

test_false_positive($_) for ('/fribble/', qr/fribble/);

sub throw { confess ('something unexpected') }
sub try { throw->(@_) }
sub test_false_positive {
my $test_against_desc = my $test_against = shift;

if (my $ref = ref ($test_against) ) {
$test_against_desc = "$ref ($test_against_desc)"
if $test_against_desc !~ /^\Q$ref\E/;
}

test_out("not ok 1 - threw $test_against_desc");
test_fail(+1);
throws_ok { try ('fribble') } $test_against;
my $exception = $@;

test_diag("expecting: $test_against_desc");
test_diag(split /\n/, "found: $exception");
test_test("$test_against_desc in stacktrace ignored");
}

0 comments on commit 23e5d84

Please sign in to comment.