Skip to content

Instantly share code, notes, and snippets.

@MARTIMM
Last active April 20, 2017 12:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MARTIMM/747ccf562b18e42235efe7623673978d to your computer and use it in GitHub Desktop.
Save MARTIMM/747ccf562b18e42235efe7623673978d to your computer and use it in GitHub Desktop.
try-catch to replace dies-ok test
use v6;
use Test;
#------------------------------------------------------------------------------
d-ok( {die 'oh oh 0';}, 'oh oh 0');
d-ok( {die 'oh oh 1';}, 'oh oh 1', :name<X::AdHoc>);
d-ok( {die 'oh oh 2';}, 'oh oh 2', :message<oh oh 2>);
d-ok( {die 'oh oh 3';}, 'oh oh 3', :name<X::AdHoc>, :message<oh oh 3> );
d-ok( {die 'oh oh 4';}, 'oh oh 4', :name<X::AdHoc>, :message(/ '4' $/) );
# Dies without knowing that the method Lisp does not exist!
d-ok( {die 'oh oh 5'.split('o').Lisp.join(',');}, 'oh oh 5');
# When :message or :name is used the result would fail showing a modified description
d-ok( {die 'oh oh 6'.split('o').Lisp.join(',');}, 'oh oh 6', :name<X::AdHoc>);
# Other examples with mistakes in what the name or messages should be
d-ok( {die 'oh oh 7';}, 'oh oh 7', :name<XX::AdHoc>);
d-ok( {die 'oh oh 8';}, 'oh oh 8', :message<ohhh>);
d-ok( {die 'oh oh 9';}, 'oh oh 9', :name<X::AdHoc>, :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;
@MARTIMM
Copy link
Author

MARTIMM commented Apr 18, 2017

Results are like below;

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.

@MARTIMM
Copy link
Author

MARTIMM commented Apr 20, 2017

Learned a new thing lately;
Much could be done with throws-like()
E.g.

throws-like {die 'oh oh 5'.split(/\s+/).Lisp.join(',');}, X::AdHoc, :message(/'oh,oh'/);

This will fail because the exception is different as well as the message

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment