NAME

Test::Dist::Zilla - Test your Dist::Zilla plugin

VERSION

Version v0.4.4, released on 2016-12-28 19:48 UTC.

SYNOPSIS

package Test::Dist::Zilla::Build;

use namespace::autoclean;
use Test::Routine;
use Test::Deep qw{ cmp_deeply };

with 'Test::Dist::Zilla';

test 'Build' => sub {
    my ( $self ) = @_;
    my $expected = $self->expected;
    $self->build();
    cmp_deeply( $self->exception, $expected->{ exception } );
    if ( exists( $expected->{ messages } ) ) {
        cmp_deeply( $self->messages, $expected->{ messages } );
    };
};

1;

DESCRIPTION

This is a Test::Routine-based role. It does not provide any test routines, but it establishes infrastructure for writing tests on Dist::Zilla and its plugins. A test written with Test::Dist::Zila does not require external source files (which are usually placed into corpus/ directory) — all the source files (including dist.ini) for the test are generated on-the-fly in a temporary directory.

The role is not intended to be used directly in tests. Instead, it serves as a base for other more specific roles, for example, Test::Dist::Zilla::Build.

OBJECT ATTRIBUTES

dist

Hash of distribution options: name, version abstract, etc. to write to the test's dist.ini. This attribute is passed to dist_ini as \%root_config argument, see "dist_ini" in Test::DZil.

HashRef. Default value can be overridden by defining _build_dist builder.

Examples:

sub _build_dist { {
    name     => 'Assa',
    version  => '0.007',
    author   => 'John Doe',
    ...
} };

run_me {
    dist => {
        name     => 'Shooba',
        version  => 'v0.7.0',
        author   => 'John Doe, Jr.',
        ...
    },
    ...
};

TODO: Merge specified keys into default?

plugins

Plugin configuration to write to the test's dist.ini. Attribute is passed to dist_ini as @plugins argument, see "dist_ini" in Test::DZil.

ArrayRef, optional. Default value is empty array (i. e. no plugins), it can be overridden by defining _build_plugins builder.

Examples:

sub _build_plugin { [
    'GatherDir',
    'Manifest',
    'MetaJSON',
] };

run_me {
    plugins => [
        'GatherDir',
        [ 'PodWeaver' => {
            'replacer' => 'replace_with_comment',
        } ],
    ],
    ...
};

files

Hash of source files to add to the test's distribution source. Keys are file names, values are file contents. A file content may be specified by a (possibly multi-line) string or by array of lines (newlines are optional and will be appended if missed).

Note: Explicitly specified dist.ini file overrides dist and plugins attributes.

HashRef, optional, default value is empty hash (i. e. no files).

Examples:

sub _build_files { {
    'lib/Assa.pm' => [
        'package Assa;',
        '# VERSION',
        '1;',
    ],
    'Changes'  => "Release history for Dist-Zilla-Plugin-Assa\n\n",
    'MANIFEST' => [ qw{ lib/Assa.pm Changes MANIFEST } ],
} };

run_me {
    files => {
        'lib/Assa.pod' => [ ... ],
        ...
    },
    ...
};

tzil

Test-enabled Dist::Zilla instance (or DieHard "survivor" object, if Dist::Zilla constructing fails).

By default Dist::Zilla instance is created by calling Builder->from_config( ... ) with appropriate arguments. Thanks to Dist::Zilla::Tester::DieHard, it is never dies even if constructing fails, so $self->tzil->log_message returns the log messages anyway.

Note: Avoid calling build and release on tzil:

$self->tzil->build();       # NOT recommended
$self->tzil->release();     # NOT recommended

Call build and release directly on $self instead:

$self->build();             # recommended
$self->release();           # recommended

See build and release method descriptions for difference.

Examples:

use Path::Tiny;
test 'Check META.json' => sub {
    my ( $self ) = @_;
    $self->skip_if_exception();
    my $built_in = path( $self->tzil->built_in );
    my $json = $built_in->child( 'META.json' )->slurp_utf8;
    cmp_deeply( $json, $self->expected->{ json } );
};

exception

Exception occurred, or undef is no exception was occurred.

test 'Post-build' => sub {
    my ( $self ) = @_;
    cmp_deeply( $self->exception, $self->expected->{ exception } );
    ...
};

expected

A hash of expected outcomes. Test::Dist::Zilla itself does not use this attribute, but more specific roles may do. For example, Test::Dizt::Zilla::Build uses exception and messages keys, Test::Dizt::Zilla::BuiltFiles uses files key.

HashRef, required.

Examples:

run_me {
    ...,
    expected => {
        exception => "Aborting...\n",
        messages  => [
            '[Plugin] Oops, something goes wrong...',
        ],
    },
};

message_filter

If message_filter is defined, it is used by default messages implementation to filter the actual log messages. message_filter function is called once with list of all the log messages. The function is expected to return a list of messages (possibly, grepped and/or edited).

Note: message_filter value is a function, not method — messages method does not pass $self reference to the message_filter.

If messages method is overridden, the attribute may be used or ignored — it depends on new messages implementation.

Maybe[CodeRef], optional. There is no default message filter — messages method returns all the messages intact. Default message filter may be set by defining _build_message_filter builder.

Examples:

Pass messages only from Manifest plugin and filter out all other messages:

sub _build_message_filter {
    sub { grep( { $_ =~ m{^\[Manifest\] } ) @_ ) };
};

Drop plugin names from messages:

run_me {
    message_filter => sub { map( { $_ =~ s{^\[.*?\] }{}r ) @_ ) },
    ...
};

OBJECT METHODS

build

release

The methods call same-name method on tzil, catch exception if any thrown, and save the caught exception in the exception attribute for further analysis.

Avoid calling these methods on tzil — some tests may rely on method modifiers, which are applicable to $self->method() but not to $self->tzil->method().

Examples:

test Build => sub {
    my ( $self ) = @_;
    $self->build();     # == dzil build
    ...
};

test Release => sub {
    my ( $self ) = @_;
    $self->release();   # == dzil release
    ...
};

messages

This method is assumed to return ArrayRef of Dist::Zilla log messages. It may be complete log as it is or not — the method may filter out and/or edit actual messages to make them more suitable for comparing with expected messages.

Default implementation filters the actual messages with the message_filter (if it is defined). If default behaviour is not suitable, the method can be overridden.

Examples:

cmp_deeply( $self->messages, $self->expected->{ messages } );

skip_if_exception

This convenience method makes test routines a bit shorter. Instead of writing

if ( defined( $self->exception ) ) {
    plan skip_all => 'exception occurred';
};

you can write just

$self->skip_if_exception;

VARIABLES

$Cleanup

Dist::Zilla::Tester creates distribution source and build directories in a temporary directory, and then unconditionally cleans it up. Sometimes (especially in case of test failure) such behavior may be not desirable — you may want to look at source or built files for troubleshooting purposes.

Test::Dist::Zilla provides control over temporary directory via $Test::Dist::Zilla::Cleanup package variable:

0

Never clean up temporary directory.

1

Clean up temporary directory only if the test is passed (it is default).

2

Always clean up temporary directory.

If temporary directory is going to remain, the test output will contain diagnostic message like this one:

# tempdir: tmp/AKrvBhhM4M

to help you identify the temporary directory created for the test.

Note: Controlling temporary directory requires Dist::Zilla 5.021 or newer.

SEE ALSO

Test::Dist::Zilla::Build
Test::Dist::Zilla::BuiltFiles
Test::Dist::Zilla::Release
Test::Routine
Dist::Zilla
Dist::Zilla::Tester::DieHard
"dist_ini" in Test::DZil

AUTHOR

Van de Bugger <van.de.bugger@gmail.com>

COPYRIGHT AND LICENSE

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.