#!perl

# t/error-logger.t #

#   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#
#   Copyright © 2015 Van de Bugger
#
#   This file is part of perl-Dist-Zilla-Role-ErrorLogger.
#
#   perl-Dist-Zilla-Role-ErrorLogger is free software: you can redistribute it and/or modify it
#   under the terms of the GNU General Public License as published by the Free Software Foundation,
#   either version 3 of the License, or (at your option) any later version.
#
#   perl-Dist-Zilla-Role-ErrorLogger 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 GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License along with
#   perl-Dist-Zilla-Role-ErrorLogger. If not, see <http://www.gnu.org/licenses/>.
#
#   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

use strict;
use warnings;
use autodie ':all';

use Test::DZil;
use Test::Fatal;
use Test::More;

use Software::License::GPL_3::or_later;
    # `t/dist/dust.ini` uses this license, but it is not detected by `AutoPrereqs` plugin.
    # Let us help it by explicit using the module.

use lib 't/lib';    # Make ErrorLoggerTestPlugin accessible.

our $Test;

my $prefix = qr{^\[ErrorLoggerTestPlugin\] };   # Prefix of messages printed by the test plugin.
my $fatal  = 'info';                            # Level of messages used by `log_fatal`.

sub get_events($) {
    my ( $tzil ) = @_;
    my @events =
        map(
            { message => $_->{ message } =~ s{$prefix}{}r, level => $_->{ level } },
            grep(
                $_->{ message } =~ $prefix,
                @{ $tzil->chrome->logger->events }
            )
        );
    return \@events;
};

plan tests => 4;

subtest success => sub {
    plan tests => 8;
    my $tzil = Builder->from_config( { dist_root => 't/dist' } );
    local $Test = sub {
        my ( $self ) = @_;
        my $rc;
        is( $self->error_count, 0, 'error count inited to zero' );
        $self->abort_if_error();
        pass( 'not yet aborted' );
        $rc = $self->log_error( 'the first error' );
        ok( $rc, 'log_error returns true value' );
        is( $self->error_count, 1, 'error count bumped' );
        $rc = $self->log_error( 'another error' );
        ok( $rc, 'log_error returns true value again' );
        is( $self->error_count, 2, 'error count bumped again' );
    };
    is( exception { $tzil->build }, undef, 'build must be successful' );
    is_deeply(
        get_events( $tzil ),
        [
            { message => 'the first error', level => 'error' },
            { message => 'another error'  , level => 'error' },
        ],
        'expected error messages'
    );
    done_testing();
};

subtest failure => sub {
    plan tests => 3;
    my $tzil = Builder->from_config( { dist_root => 't/dist' } );
    $Test = sub {
        my ( $self ) = @_;
        $self->abort_if_error();
        pass( 'not yet aborted' );
        $self->log_error( 'error' );
        $self->abort_if_error();                                # Default abort message
        fail( 'must be aborted before this point' );
    };
    like(
        exception { $tzil->build; },
        qr{${prefix}Aborting\.\.\.},
        'build must fail'
    );
    is_deeply(
        get_events( $tzil ),
        [
            { message => 'error',       level => 'error' },
            { message => 'Aborting...', level => $fatal  },     # Default abort message.
        ],
        'error messages are in place'
    );
    done_testing();
};

subtest custom_abort_message => sub {
    plan tests => 2;
    my $tzil = Builder->from_config( { dist_root => 't/dist' } );
    $Test = sub {
        my ( $self ) = @_;
        $self->log_error( 'error' );
        $self->abort_if_error( 'Custom abort' );                # Custom abort message.
        fail( 'must be aborted before this point' );
    };
    like(
        exception { $tzil->build; },
        qr{${prefix}Custom abort},
        'build must fail'
    );
    is_deeply(
        get_events( $tzil ),
        [
            { message => 'error',        level => 'error' },
            { message => 'Custom abort', level => $fatal  },    # Custom abort message.
        ],
        'error messages are in place'
    );
    done_testing();
};

subtest log_arguments => sub {
    plan tests => 4;
    my $tzil = Builder->from_config( { dist_root => 't/dist' } );
    $Test = sub {
        my ( $self ) = @_;
        my ( $args, $orig );
        $args = { prefix => 'pfx1: ' };
        $orig = { %$args };
        $self->log_error( $args, 'error' );                     # Error message with custom prefix.
        is_deeply( $args, $orig, 'args are not changed' );
        $args = { prefix => 'pfx2: ', level => 'info' };
        $orig = { %$args };
        $self->log_error( $args, 'another' );                   # With custom prefix and level.
        is_deeply( $args, $orig, 'args are not changed again' );
    };
    is(
        exception { $tzil->build; },
        undef,
        'build must complete successfully'
    );
    is_deeply(
        get_events( $tzil ),
        [
            { message => 'pfx1: error',   level => 'error' },   # Error message with custom prefix.
            { message => 'pfx2: another', level => 'info'  },   # With custom prefix and level.
        ],
        'error messages are in place'
    );
    done_testing();
};

done_testing();

exit( 0 );

# end of file #
