BioPerl-Network
view release on metacpan or search on metacpan
t/lib/Test/Warn.pm view on Meta::CPAN
Have a look to the similar L<Test::Exception> module.
=head1 THANKS
Many thanks to Adrian Howard, chromatic and Michael G. Schwern,
who have given me a lot of ideas.
=head1 AUTHOR
Janek Schleicher, E<lt>bigj AT kamelfreund.deE<gt>
=head1 COPYRIGHT AND LICENSE
Copyright 2002 by Janek Schleicher
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
=cut
package Test::Warn;
use 5.006;
use strict;
use warnings;
use Array::Compare;
use Sub::Uplevel;
our $VERSION = '0.10';
require Exporter;
our @ISA = qw(Exporter);
our %EXPORT_TAGS = ( 'all' => [ qw(
@EXPORT
) ] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw(
warning_is warnings_are
warning_like warnings_like
);
use Test::Builder;
my $Tester = Test::Builder->new;
*warning_is = *warnings_are;
sub warnings_are (&$;$) {
my $block = shift;
my @exp_warning = map {_canonical_exp_warning($_)}
_to_array_if_necessary( shift() || [] );
my $testname = shift;
my @got_warning = ();
local $SIG{__WARN__} = sub {
my ($called_from) = caller(0); # to find out Carping methods
push @got_warning, _canonical_got_warning($called_from, shift());
};
uplevel 2,$block;
my $ok = _cmp_is( \@got_warning, \@exp_warning );
$Tester->ok( $ok, $testname );
$ok or _diag_found_warning(@got_warning),
_diag_exp_warning(@exp_warning);
return $ok;
}
*warning_like = *warnings_like;
sub warnings_like (&$;$) {
my $block = shift;
my @exp_warning = map {_canonical_exp_warning($_)}
_to_array_if_necessary( shift() || [] );
my $testname = shift;
my @got_warning = ();
local $SIG{__WARN__} = sub {
my ($called_from) = caller(0); # to find out Carping methods
push @got_warning, _canonical_got_warning($called_from, shift());
};
uplevel 2,$block;
my $ok = _cmp_like( \@got_warning, \@exp_warning );
$Tester->ok( $ok, $testname );
$ok or _diag_found_warning(@got_warning),
_diag_exp_warning(@exp_warning);
return $ok;
}
sub _to_array_if_necessary {
return (ref($_[0]) eq 'ARRAY') ? @{$_[0]} : ($_[0]);
}
sub _canonical_got_warning {
my ($called_from, $msg) = @_;
my $warn_kind = $called_from eq 'Carp' ? 'carped' : 'warn';
my @warning_stack = split /\n/, $msg; # some stuff of uplevel is included
return {$warn_kind => $warning_stack[0]}; # return only the real message
}
sub _canonical_exp_warning {
my ($exp) = @_;
if (ref($exp) eq 'HASH') { # could be {carped => ...}
my $to_carp = $exp->{carped} or return; # undefined message are ignored
return (ref($to_carp) eq 'ARRAY') # is {carped => [ ..., ...] }
? map({ {carped => $_} } grep {defined $_} @$to_carp)
: +{carped => $to_carp};
}
return {warn => $exp};
}
sub _cmp_got_to_exp_warning {
my ($got_kind, $got_msg) = %{ shift() };
my ($exp_kind, $exp_msg) = %{ shift() };
return 0 if ($got_kind eq 'warn') && ($exp_kind eq 'carped');
my $cmp = $got_msg =~ /^\Q$exp_msg\E at \S+ line \d+\.?$/;
return $cmp;
}
sub _cmp_got_to_exp_warning_like {
my ($got_kind, $got_msg) = %{ shift() };
my ($exp_kind, $exp_msg) = %{ shift() };
return 0 if ($got_kind eq 'warn') && ($exp_kind eq 'carped');
if (my $re = $Tester->maybe_regex($exp_msg)) {
my $cmp = $got_msg =~ /$re/;
return $cmp;
} else {
return Test::Warn::Categorization::warning_like_category($got_msg,$exp_msg);
}
}
sub _cmp_is {
my @got = @{ shift() };
my @exp = @{ shift() };
scalar @got == scalar @exp or return 0;
my $cmp = 1;
$cmp &&= _cmp_got_to_exp_warning($got[$_],$exp[$_]) for (0 .. $#got);
( run in 0.987 second using v1.01-cache-2.11-cpan-5b529ec07f3 )