Hi,
I've encountered a little problem using dies-ok() from the Test module;
The case was that I made an error within the block used as the first
argument to dies-ok. In that particular case the perl6 compiler hurled
an exception and dies-ok accepted it as an ok action which was not ok
because the real test was not performed.
I have reverted to the try/catch methods I used before because I can
then test the
exception object in $_ for its type and message.
Perhaps dies-ok could be extended to do these test for me, testing any
field in the object available. Something like;
dies-ok {... test ... }, '...description...', :name<...exception object
name...>, :message<...>;
where :name tests the exception object for its name(.^name) and :message
tests the payload of the object by calling the message method when
available. Maybe some other less common methods of the exception object
can be tested this way. The named attributes can be optional to revert
to old behaviour.
The code below can also be found at
https://gist.github.com/MARTIMM/747ccf562b18e42235efe7623673978d
use v6;
use Test;
#--
d-ok( {die 'oh oh 0';}, 'oh oh 0');
d-ok( {die 'oh oh 1';}, 'oh oh 1', :name);
d-ok( {die 'oh oh 2';}, 'oh oh 2', :message);
d-ok( {die 'oh oh 3';}, 'oh oh 3', :name, :message );
d-ok( {die 'oh oh 4';}, 'oh oh 4', :name, :message(/ '4' $/) );
# Dies without knowing that the method Lisp does not exist!
d-ok( {'oh oh 5'.split('o').Lisp;}, 'oh oh 5');
# When :message or :name is used the result would fail showing a modified
description
d-ok( {'oh oh 6'.split('o').Lisp;}, 'oh oh 6', :name);
# Other examples with mistakes in what the name or messages should be
d-ok( {die 'oh oh 7';}, 'oh oh 7', :name);
d-ok( {die 'oh oh 8';}, 'oh oh 8', :message);
d-ok( {die 'oh oh 9';}, 'oh oh 9', :name, :message(/ '4' $/) );
#--
# alternative dies-ok. Returns a list which must be flattened to be used with
(n)ok.
# :message can be a string or regex. name and message are optional.
sub d-ok ( Code:D $code, Str $description is copy, Str :$name, :$message ) {
my Bool $dies-ok = False;
try {
$code();
CATCH {
default {
$dies-ok = True;
if ? $name {
$dies-ok = .^name eq $name;
$description = .^name ~ ': ' ~ .message unless $dies-ok;
}
if $dies-ok and $message ~~ Str and ? $message {
$dies-ok = .message() eq $message;
$description = .^name ~ ': ' ~ .message unless $dies-ok;
}
if $dies-ok and $message ~~ Regex {
$dies-ok = ?(.message() ~~ $message);
$description = .^name ~ ': ' ~ .message unless $dies-ok;
}
}
}
}
ok $dies-ok, $description;
}
#--
done-testing;
Giving the following results;
prove6 -v t/dies-ok.t
t/dies-ok.t ..
ok 1 - oh oh 0
ok 2 - oh oh 1
ok 3 - oh oh 2
ok 4 - oh oh 3
ok 5 - oh oh 4
ok 6 - oh oh 5
not ok 7 - X::Method::NotFound: No such method 'Lisp' for invocant of type 'Seq'
# Failed test 'X::Method::NotFound: No such method 'Lisp' for invocant of type
'Seq''
# at t/100-fromfile.t line 90
not ok 8 - X::AdHoc: oh oh 7
# Failed test 'X::AdHoc: oh oh 7'
# at t/100-fromfile.t line 90
not ok 9 - X::AdHoc: oh oh 8
# Failed test 'X::AdHoc: oh oh 8'
# at t/100-fromfile.t line 90
not ok 10 - X::AdHoc: oh oh 9
# Failed test 'X::AdHoc: oh oh 9'
# at t/100-fromfile.t line 90
1..10
# Looks like you failed 4 tests of 10
Dubious, test returned 4 (wstat 1024, 0x400)
Failed 4/10 subtests
Test Summary Report
---
t/dies-ok.t (Wstat: 1024 Tests: 10 Failed: 4)
Failed tests: 7-10
Non-zero exit status: 4
Files=1, Tests=10, 0 wallclock secs ( 0.02 usr 0.00 sys + 0.30 cusr 0.02
csys = 0.34 CPU)
Result: FAIL
The last 4 descriptions are changed by the sub to make it clear that the
exception name and/or message are different. Note that test 6 is
successful even when something different is meant, test 7 shows that the
method was non existent. This could have been a typo which would
otherwise go undetected.
Regards,
Marcel