Dist::Zilla::Tester::DieHard - Die hard Dist::Zilla, but save the messages
Version v0.6.4, released on 2016-12-18 08:53 UTC.
Dist-Zilla-Tester-DieHard (or shortly DieHard) is a Dist::Zilla testing tool, it extends standard Dist::Zilla::Tester. If Dist::Zilla dies in construction, DieHard survives itself and saves the logger to let you analyze the messages.
Dist-Zilla-Tester-DieHard
DieHard
Dist::Zilla
Dist::Zilla::Tester
Use Dist::Zilla::Tester::DieHard instead of Dist::Zilla::Tester:
Dist::Zilla::Tester::DieHard
use Dist::Zilla::Tester::DieHard; # instead of Dist::Zilla::Tester use Test::Deep qw{ cmp_deeply }; use Test::Fatal; use Test::More; my $tzil = Builder->from_config( \%args ); my $ex = exception { $tzil->build(); }; is( $ex, $expected_exception, 'check status' ); cmd_deeply( $tzil->log_messages, $expected_messages, 'check log messages' );
Dist::Zilla::Tester::DieHard (or, for brevity just DieHard) extends Dist::Zilla::Tester. If Dist::Zilla dies in construction, DieHard catches the exception, saves the exception and Dist::Zilla logger, and returns a "survivor" object.
The returned survivor will fail in build (or release) method: it just rethrows the saved exception. However, such "delayed death" saves log messages for analysis:
build
release
my $tzil = Builder->from_config( … ); # ^ Construction never fails, # it always returns an object, # either builder or survivor. my $ex = exception { $tzil->build(); }; # or $tzil->release(); # ^ Builder does build, # survivor rethrows the saved exception. is( $ex, $expected_exception, 'check status' ); cmd_deeply( $tzil->log_messages, $expected_messages, 'check log messages' ); # ^ In *any* case we can check log messages.
Survivor
Survivor is shortened name of real class. Full class name is Dist::Zilla::Tester::DieHard::Survivor.
Dist::Zilla::Tester::DieHard::Survivor
Following methods can be called on Survivor object: clear_log_events, log_events, log_messages.
clear_log_events
log_events
log_messages
build, release methods rethrow the saved exception.
Regular Dist::Zilla::Tester (as of v5.039) is not documented, so and I have to study its sources to find out features it provides.
I have implemented only part of Dist::Zilla::Tester features, shown in "SYNOPSIS" and "DESCRIPTION". Minter is not (yet?) implemented — I do not need it (yet?). Probably there are other not (yet?) implemented features I am not aware of.
Minter
Implementation is simpler if Survivor saves not logger, but entire chrome (logger is a part of chrome). In such a case Survivor can consume Dist::Zilla::Tester::_Role and get bunch of methods "for free".
Dist::Zilla::Tester::_Role
most_recent_log_events
Dist::Zilla::Tester 5.040 introduced most_recent_log_events function which can be used to retrieve log events even if builder construction failed. However:
This module was implemented and released before DIst::Zilla 5.040.
DIst::Zilla
most_recent_log_events is not documented.
Using most_recent_log_events requires revisiting existing test code, while DieHard does not.
Usually I test my Dist::Zilla plugins in such a way:
... use Dist::Zilla::Tester; use Test::Deep qw{ cmp_deeply }; use Test::Fatal; use Test::More; my $tzil = Builder->from_config( ... ); my $exception = exception { $tzil->build(); }; if ( $expected_success ) { is( $exception, undef, 'status' ); } else { like( $exception, qr{...}, 'status' ); }; cmd_deeply( $tzil->log_messages, $expected_messages, 'log messages' ); ...
The approach works well, until Dist::Zilla dies in from_config (e. g. if a plugin throws an exception in its construction).
from_config
A straightforward attempt to catch exception thrown in from_config:
my $tzil; my $exception = exception { $tzil = Builder->from_config( … ); }; if ( $expected_success ) { is( $exception, undef, 'status' ); } else { like( $exception, qr{…}, 'status' ); };
works but… from_config dies leaving $tzil undefined, log_messages method is called on undefined value definitely fails:
$tzil
cmd_deeply( $tzil->log_messages, $expected_messages, 'log messages' ); # ^^^^^^^^^^^^^^^^^^^ # Oops: $tzil undefined.
Dist::Zilla dies, and all the messages logged by either Dist::Zilla or its plugins are buried with Dist::Zilla.
Using Dist::Zilla::Tester::DieHard instead of regular Dist::Zilla::Tester solves this problem: even if a plugin throws an exception in constructor, Builder->from_config does not die but returns a "survivor" object which can be used to retrieve log messages.
Builder->from_config
Van de Bugger <van.de.bugger@gmail.com>
Copyright (C) 2015, 2016 Van de Bugger
License GPLv3+: The GNU General Public License version 3 or later <http://www.gnu.org/licenses/gpl-3.0.txt>.
This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.
To install Dist::Zilla::Tester::DieHard, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Dist::Zilla::Tester::DieHard
CPAN shell
perl -MCPAN -e shell install Dist::Zilla::Tester::DieHard
For more information on module installation, please visit the detailed CPAN module installation guide.