5
package Test::Exception;
7
use Sub::Uplevel qw( uplevel );
8
use base qw( Exporter );
10
our $VERSION = '0.29';
11
our @EXPORT = qw(dies_ok lives_ok throws_ok lives_and);
13
my $Tester = Test::Builder->new;
19
$Tester->exported_to( $package );
22
$self->export_to_level( 1, $self, $_ ) foreach @EXPORT;
27
sub _quiet_caller (;$) { ## no critic Prototypes
30
if( wantarray and !@_ ) {
31
return (CORE::caller($height))[0..2];
34
return CORE::caller($height);
41
# local works here because Sub::Uplevel has already overridden caller
42
local *CORE::GLOBAL::caller;
43
{ no warnings 'redefine'; *CORE::GLOBAL::caller = \&_quiet_caller; }
45
eval { uplevel 3, $coderef };
51
my $exception = shift;
52
return ref $exception || $exception ne '';
56
sub _exception_as_string {
57
my ( $prefix, $exception ) = @_;
58
return "$prefix normal exit" unless _is_exception( $exception );
59
my $class = ref $exception;
60
$exception = "$class ($exception)"
61
if $class && "$exception" !~ m/^\Q$class/;
63
return "$prefix $exception";
70
sub throws_ok (&$;$) {
71
my ( $coderef, $expecting, $description ) = @_;
72
unless (defined $expecting) {
74
Carp::croak( "throws_ok: must pass exception class/object or regex" );
76
$description = _exception_as_string( "threw", $expecting )
77
unless defined $description;
78
my $exception = _try_as_caller( $coderef );
79
my $regex = $Tester->maybe_regex( $expecting );
81
? ( $exception =~ m/$regex/ )
83
$exception->isa( ref $expecting ? ref $expecting : $expecting )
85
$Tester->ok( $ok, $description );
87
$Tester->diag( _exception_as_string( "expecting:", $expecting ) );
88
$Tester->diag( _exception_as_string( "found:", $exception ) );
98
my ( $coderef, $description ) = @_;
99
my $exception = _try_as_caller( $coderef );
100
my $ok = $Tester->ok( _is_exception($exception), $description );
109
my ( $coderef, $description ) = @_;
110
my $exception = _try_as_caller( $coderef );
111
my $ok = $Tester->ok( ! _is_exception( $exception ), $description );
112
$Tester->diag( _exception_as_string( "died:", $exception ) ) unless $ok;
120
sub lives_and (&;$) {
121
my ( $test, $description ) = @_;
123
local $Test::Builder::Level = $Test::Builder::Level + 1;
124
my $ok = \&Test::Builder::ok;
126
local *Test::Builder::ok = sub {
127
$_[2] = $description unless defined $_[2];
131
eval { $test->() } and return 1;
134
if ( _is_exception( $exception ) ) {
135
$Tester->ok( 0, $description );
136
$Tester->diag( _exception_as_string( "died:", $exception ) );