Acme-Sort-Sleep
view release on metacpan or search on metacpan
local/lib/perl5/Test/Exception.pm view on Meta::CPAN
Test::Exception - Test exception-based code
=head1 SYNOPSIS
use Test::More tests => 5;
use Test::Exception;
# or if you don't need Test::More
use Test::Exception tests => 5;
# then...
# Check that the stringified exception matches given regex
throws_ok { $foo->method } qr/division by zero/, 'zero caught okay';
# Check an exception of the given class (or subclass) is thrown
throws_ok { $foo->method } 'Error::Simple', 'simple error thrown';
# all Test::Exceptions subroutines are guaranteed to preserve the state
# of $@ so you can do things like this after throws_ok and dies_ok
like $@, 'what the stringified exception should look like';
# Check that something died - we do not care why
dies_ok { $foo->method } 'expecting to die';
# Check that something did not die
lives_ok { $foo->method } 'expecting to live';
# Check that a test runs without an exception
lives_and { is $foo->method, 42 } 'method is 42';
# or if you don't like prototyped functions
throws_ok( sub { $foo->method }, qr/division by zero/,
'zero caught okay' );
throws_ok( sub { $foo->method }, 'Error::Simple',
'simple error thrown' );
dies_ok( sub { $foo->method }, 'expecting to die' );
lives_ok( sub { $foo->method }, 'expecting to live' );
lives_and( sub { is $foo->method, 42 }, 'method is 42' );
=head1 DESCRIPTION
This module provides a few convenience methods for testing exception based code. It is built with
L<Test::Builder> and plays happily with L<Test::More> and friends.
If you are not already familiar with L<Test::More> now would be the time to go take a look.
You can specify the test plan when you C<use Test::Exception> in the same way as C<use Test::More>.
See L<Test::More> for details.
NOTE: Test::Exception only checks for exceptions. It will ignore other methods of stopping
program execution - including exit(). If you have an exit() in evalled code Test::Exception
will not catch this with any of its testing functions.
NOTE: This module uses L<Sub::Uplevel> and relies on overriding
C<CORE::GLOBAL::caller> to hide your test blocks from the call stack. If this
use of global overrides concerns you, the L<Test::Fatal> module offers a more
minimalist alternative.
=cut
sub _quiet_caller (;$) { ## no critic Prototypes
my $height = $_[0];
$height++;
if ( CORE::caller() eq 'DB' ) {
# passthrough the @DB::args trick
package DB;
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 !@_ ) {
return (CORE::caller($height))[0..2];
}
else {
return CORE::caller($height);
}
}
}
sub _try_as_caller {
my $coderef = shift;
# local works here because Sub::Uplevel has already overridden caller
local *CORE::GLOBAL::caller;
{ no warnings 'redefine'; *CORE::GLOBAL::caller = \&_quiet_caller; }
eval { uplevel 3, $coderef };
return $@;
};
( run in 1.904 second using v1.01-cache-2.11-cpan-39bf76dae61 )