util(
$_
)
for
qw/warning_is warnings_are warning_like capture_warnings/
;
tester(
$_
)
for
qw/warnings_like warnings_exist/
;
sub
capture_warnings(&) {
my
(
$sub
) =
@_
;
my
@warns
;
local
$SIG
{ __WARN__ } =
sub
{
push
@warns
=>
@_
};
$sub
->();
return
@warns
}
sub
warning_is(&$;$) {
my
(
$sub
,
$match
,
$name
) =
@_
;
my
@warns
= capture_warnings( \
&$sub
);
return
result(
pass
=> 0,
name
=>
$name
,
stderr
=> [
"Too many warnings:"
,
map
{
"\t$_"
}
@warns
],
)
if
@warns
> 1;
return
is(
$warns
[0],
$match
,
$name
);
}
sub
warnings_are(&$;$) {
my
(
$sub
,
$matches
,
$name
) =
@_
;
my
@warns
= capture_warnings( \
&$sub
);
return
is_deeply( \
@warns
,
$matches
,
$name
);
}
sub
warning_like(&$;$) {
my
(
$sub
,
$match
,
$name
) =
@_
;
my
@warns
= capture_warnings( \
&$sub
);
return
result(
pass
=> 0,
name
=>
$name
,
stderr
=> [
"Too many warnings:"
,
map
{
"\t$_"
}
@warns
],
)
if
@warns
> 1;
return
result(
pass
=> 0,
name
=>
$name
,
stderr
=> [
"Did not warn as expected"
],
)
if
!
@warns
;
return
like(
$warns
[0],
$match
,
$name
);
}
sub
warnings_like(&$;$) {
my
(
$sub
,
$matches
,
$name
) =
@_
;
my
@warns
= capture_warnings( \
&$sub
);
return
result(
pass
=> 0,
name
=>
$name
,
stderr
=> [
"Wrong number of warnings:"
,
map
{
"\t$_"
}
@warns
],
)
if
@warns
!=
@$matches
;
my
@fail
;
for
my
$i
( 0 .. (
@warns
- 1 )) {
next
if
$warns
[
$i
] =~
$matches
->[
$i
];
push
@fail
=>
"'"
.
$warns
[
$i
] .
"' does not match '"
.
$matches
->[
$i
] .
"'"
;
}
result(
pass
=>
@fail
? 0 : 1,
name
=>
$name
,
@fail
? (
stderr
=> \
@fail
) : (),
);
}
sub
warnings_exist(&$;$) {
my
(
$sub
,
$in
,
$name
) =
@_
;
my
$matches
=
ref
(
$in
) eq
'ARRAY'
?
$in
: [
$in
];
my
@warns
= capture_warnings( \
&$sub
);
my
%found
;
my
@extra
;
for
my
$warn
(
@warns
) {
my
$matched
= 0;
for
my
$match
(
@$matches
) {
if
(
ref
(
$match
) ?
$warn
=~
$match
:
$match
eq
$warn
) {
$found
{
$match
}++;
$matched
++;
}
}
push
@extra
=>
$warn
unless
$matched
;
}
my
@missing
=
grep
{ !
$found
{
$_
} }
@$matches
;
result(
pass
=>
@missing
? 0 : 1,
name
=>
$name
,
stderr
=> [
@missing
? (
"Missing warnings:"
,
map
{
"\t$_"
}
@missing
)
: (),
(
@missing
&&
@extra
) ? (
"Extra warnings (not an error):"
,
map
{
"\t$_"
}
@extra
)
: (),
]
);
}
1;
=head1 NAME
Fennec::Assert::Core::Warn - Tools
for
testing warnings
=head1 DESCRIPTION
This library provides functions that are useful in testing code that throws
warnings. This library provides everything L<Test::Warn> does plus some
bonuses.
=head1 SYNOPSIS
my
@warnings
= capture_warnings {
warn
'a'
;
warn
'b'
;
};
warning_is {
warn
'xxx'
}
"xxx at ..."
,
"Name"
;
warnings_are {
warn
'xxx'
;
warn
'yyy'
; }
[
'xxx at ...'
,
'yyy at ...'
],
"Name"
;
warning_like {
warn
'xxx'
}
qr/^xxx at/
,
"Name"
;
warnings_like {
warn
'xxx'
;
warn
'yyy'
}
[
qr/^xxx/
,
qr/^yyy/
],
"Name"
;
warnings_exist {
warn
'xxx'
;
warn
'yyy'
}
[
qr/^xxx/
,
'yyy at ...'
],
"Name"
;
=head1 EXPORTS
=over 4
=item
@list
= capture_warnings {
warn
'xxx'
}
Capture the generated warnings to
do
with
as you please.
=item warning_is { ... }
$want
,
$name
Check that the thrown warning is what you want.
=item warnings_are { ... } \
@want
,
$name
Check that the thrown warnings are what you want.
=item warning_like { ... }
$regex
,
$name
Check that the thrown warning matches
$regex
.
=item warnings_like { ... } [
$regex
, ... ],
$name
Check that the thrown warnings match the list of regexes.
=item warnings_exist { ... } [
$string
,
$regex
, ... ],
$name
Check that at least 1 warning matches
for
each
string and regex provided.
=back
=head1 AUTHORS
Chad Granum L<exodist7
@gmail
.com>
=head1 COPYRIGHT
Copyright (C) 2010 Chad Granum
Fennec is free software; Standard perl licence.
Fennec is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the license
for
more details.