package LPSC::Builder::TestRunner; use v5.30.0; use strict; use warnings; use DB_File; use Params::ValidationCompiler qw/validation_for/; use Types::Standard qw/ArrayRef Str Bool/; use Getopt::Long::Descriptive; use Path::Tiny qw/path/; use Capture::Tiny qw/tee_merged/; use Term::ANSIColor qw/color/; my $db_file = path($0)->parent->child('test.db'); my @errors; my $ERROR_CODE_SOME_TEST_FAILED = 500; { my $validator = validation_for( params => { test_files => { type => ArrayRef [Str], }, clean => { type => Bool, }, halt => { type => Bool, }, } ); sub new { my $class = shift; my $self = bless {}, $class; my %params = $validator->(@_); my $test_files = $params{test_files}; $self->{test_files} = [@$test_files]; $self->_options->{halt} = $params{halt}; $self->_options->{clean} = $params{clean}; return $self; } } sub _options { my $self = shift; if ( !defined $self->{options} ) { $self->{options} = {}; } return $self->{options}; } sub run { my $self = shift; if ( $self->_options->{clean} ) { my %test_files_success_status; tie %test_files_success_status, 'DB_File', $db_file; %test_files_success_status = (); untie %test_files_success_status; } for my $test_file ( @{ $self->{test_files} } ) { if ( $self->_test_already_succeded($test_file) ) { say omited() . "$test_file last test was successful."; next; } my $return_code; my ($merged) = tee_merged { $return_code = system $test_file; }; my %test_files_success_status; tie %test_files_success_status, 'DB_File', $db_file; $test_files_success_status{$test_file} = !$return_code; if ($return_code) { push @errors, error() . "File $test_file\n" . $merged; if ( $self->_options->{halt} ) { $self->show_errors; } } } $self->show_errors; } sub show_errors { for my $error (@errors) { say $error; } if (@errors) { exit $ERROR_CODE_SOME_TEST_FAILED; } exit 0; } sub omited { return color('blue') . '[[OMITED]] ' . reset_color(); } sub error { return color('red') . '[[ERROR]] ' . reset_color(); } sub reset_color { return color('reset'); } sub _test_already_succeded { my $self = shift; my $test = shift; my %test_files_success_status; tie %test_files_success_status, 'DB_File', $db_file; return $test_files_success_status{$test}; } 1;