t/unit/MGH_Biostat/TravEpi/SimpleRulesBase/Rotator.t


#!/usr/bin/env perl
use Modern::Perl '2013';
use Test2::V0;
use Test2::Tools::Spec;

BEGIN {
    $main::__TIMEVAL    = 1552881600;                        # 2019-03-18-00-00-00
    *CORE::GLOBAL::time = sub { return $main::__TIMEVAL; }
}

use MGH_Biostat::TravEpi::SimpleRulesBase::Rotator;
use Path::Tiny;

describe 'new' => sub {
    before_each 'reset_time' => sub {
        $main::__TIMEVAL = 1552881600;                       # 2019-03-18-00-00
    };

    tests 'parameters' => sub {

        like(
            dies { MGH_Biostat::TravEpi::SimpleRulesBase::Rotator->new() },
            qr/^No file template/,
            'requires file template'
        );

        my $r = MGH_Biostat::TravEpi::SimpleRulesBase::Rotator->new(
            'template' => '/some/path',
        );

        is(
            $r,
            object {
                prop blessed     => 'MGH_Biostat::TravEpi::SimpleRulesBase::Rotator';
                field 'template' => '/some/path';
                end;
            },
            'object looks right!'
        );
    };
};

describe 'print' => sub {
    before_each 'reset_time' => sub {
        $main::__TIMEVAL = 1552881600;    # 2019-03-18-00-00
    };

    tests 'prints' => sub {
        my $path_data = {};
        my $path_mock = mock 'Path::Tiny' => (
            override => [
                'append_utf8' => sub {
                    my $self = shift;
                    $path_data->{ $self->[ 0 ] } .= join( "" => @_ );
                },
            ],
        );

        my $r = MGH_Biostat::TravEpi::SimpleRulesBase::Rotator->new(
            'template' => 'template-%Y-%m-%d-%H-%M',
        );

        $main::__TIMEVAL = 1552881600;    # 2019-03-18-00-00
        $r->print("foo\n");
        $r->print("bar\n");
        is( $path_data->{'template-2019-03-18-00-00'}, "foo\nbar\n", "prints ok" );

        $main::__TIMEVAL = 1552881700;    # 2019-03-18-00-01
        $r->print("baz\n");
        $r->print("qux\n");
        is( $path_data->{'template-2019-03-18-00-01'}, "baz\nqux\n", "prints to next file ok" );

    };

    tests 'warns on error' => sub {
        my $path_mock = mock 'Path::Tiny' => (
            override => [
                'append_utf8' => sub { die "I failed"; },
            ],
        );
        my $r = MGH_Biostat::TravEpi::SimpleRulesBase::Rotator->new(
            'template' => 'template-%Y-%m-%d-%H-%M',
        );

        $main::__TIMEVAL = 1552881600;    # 2019-03-18-00-00
        like(
            warning { $r->print("foo"); },
            qr/^\QCould not write data to template-2019-03-18-00-00: foo\E/,
            'warns on failure'
        );
    };

    tests 'handles dst' => sub {
        my $path_data = {};
        my $path_mock = mock 'Path::Tiny' => (
            override => [
                'append_utf8' => sub {
                    my $self = shift;
                    $path_data->{ $self->[ 0 ] } .= join( "" => @_ );
                },
            ],
        );

        my $r = MGH_Biostat::TravEpi::SimpleRulesBase::Rotator->new(
            'template' => 'template-%Y-%m-%d-%H-%M',
        );

        $main::__TIMEVAL = 1552199400;    # 2019-03-10-01-30, just before DST
        $r->print("Just before DST\n");
        $main::__TIMEVAL = 1552203000;    # 2019-03-10-03-30, skipped an hour due to DST
        $r->print("Skipped an hour\n");
        $main::__TIMEVAL = 1572755400;    # 2019-11-03-00-30, before DST
        $r->print("Just before the other DST\n");
        $main::__TIMEVAL = 1572759000;    # 2019-11-03-01-30, first time through
        $r->print("First time through\n");
        $main::__TIMEVAL = 1572762600;    # 2019-11-03-01-30, second time through
        $r->print("Second time through\n");
        $main::__TIMEVAL = 1572766200;    # 2019-11-03-02-30, after DST
        $r->print("Repeated an hour\n");

        is(
            $path_data,
            hash {
                field 'template-2019-03-10-01-30' => "Just before DST\n";
                field 'template-2019-03-10-03-30' => "Skipped an hour\n";
                field 'template-2019-11-03-00-30' => "Just before the other DST\n";
                field 'template-2019-11-03-01-30' => "First time through\nSecond time through\n";
                field 'template-2019-11-03-02-30' => "Repeated an hour\n";
                end;
            },
            "printed to the proper files"
        );

    };
};

done_testing();