App-Project-Doctor
view release on metacpan or search on metacpan
t/extended_tests.t view on Meta::CPAN
use Test::Mockingbird qw(mock_scoped restore_all);
use File::Temp qw(tempdir);
use File::Path qw(make_path);
use File::Spec;
use File::Basename qw(dirname);
use Scalar::Util qw(blessed);
use Readonly;
# ===========================================================================
# Constants
# ===========================================================================
Readonly::Scalar my $CONTEXT => 'App::Project::Doctor::Context';
Readonly::Scalar my $FINDING => 'App::Project::Doctor::Finding';
Readonly::Scalar my $REPORT => 'App::Project::Doctor::Report';
Readonly::Scalar my $FIXER => 'App::Project::Doctor::Fixer';
Readonly::Scalar my $DOCTOR => 'App::Project::Doctor';
Readonly::Scalar my $GHACTIONS => 'App::Project::Doctor::Check::GitHubActions';
Readonly::Scalar my $CHECK_POD => 'App::Project::Doctor::Check::Pod';
Readonly::Scalar my $CHECK_SEC => 'App::Project::Doctor::Check::Security';
Readonly::Scalar my $CHECK_CI => 'App::Project::Doctor::Check::CI';
Readonly::Scalar my $CHECK_TESTS => 'App::Project::Doctor::Check::Tests';
Readonly::Scalar my $SEV_ERROR => 'error';
Readonly::Scalar my $SEV_WARN => 'warning';
Readonly::Scalar my $SEV_PASS => 'pass';
Readonly::Scalar my $SEV_INFO => 'info';
Readonly::Scalar my $WORKFLOW_DIR => '.github/workflows';
Readonly::Scalar my $VALID_MSG => 'Valid message for extended testing.';
# ===========================================================================
# Load modules under test
# ===========================================================================
use_ok $CONTEXT;
use_ok $FINDING;
use_ok $REPORT;
use_ok $FIXER;
use_ok $DOCTOR;
use_ok $GHACTIONS;
use_ok $CHECK_POD;
use_ok $CHECK_SEC;
use_ok $CHECK_CI;
use_ok $CHECK_TESTS;
# Check plugins inherit new() from Check::Base via 'use parent -norequire'.
# Base must be loaded explicitly because -norequire suppresses the automatic
# require that parent would normally issue.
require App::Project::Doctor::Check::Base;
# ===========================================================================
# Test helpers
# ===========================================================================
# Build a temporary distro directory from a hash of relative_path => content.
sub _distro {
my (%files) = @_;
my $dir = tempdir(CLEANUP => 1);
for my $rel (sort keys %files) {
my @parts = split m{/}, $rel;
my $abs = File::Spec->catfile($dir, @parts);
make_path(dirname($abs)) unless -d dirname($abs);
open my $fh, '>', $abs or die "Cannot write $abs: $!";
print $fh $files{$rel};
close $fh;
}
return $dir;
}
sub _ctx {
my $dir = shift // tempdir(CLEANUP => 1);
return $CONTEXT->new(root => $dir);
}
sub _f {
my (%args) = @_;
return $FINDING->new(
message => $VALID_MSG,
check_name => 'ExtTest',
severity => $SEV_INFO,
%args,
);
}
sub _report_with {
my @findings = @_;
my $r = $REPORT->new;
$r->add_findings(@findings) if @findings;
return $r;
}
# ===========================================================================
# Check::GitHubActions -- previously 56% stmt / 33% branch / 0% cond
#
# Strategy: drive every branch by mocking App::Workflow::Lint and App::GHGen
# so tests run without network or real workflow files.
# ===========================================================================
subtest 'GitHubActions::check -- no .github/workflows/ dir returns info' => sub {
# When the workflow directory is entirely absent the check returns an info
# finding; it does NOT emit an error because Check::CI owns that signal.
my $dir = _distro('Makefile.PL' => '');
my @f = $GHACTIONS->new->check($CONTEXT->new(root => $dir));
is( scalar @f, 1, 'single finding' );
is( $f[0]->severity, $SEV_INFO, 'severity is info' );
like($f[0]->message, qr/No .github.workflows/i, 'mentions absent dir' );
ok( !$f[0]->is_fixable, 'no fix when dir is absent' );
};
subtest 'GitHubActions::check -- empty workflows dir returns warning+fix' => sub {
# .github/workflows/ present but no YAML files: warning with a fix that
# generates a default workflow via App::GHGen.
my $dir = _distro(
'Makefile.PL' => '',
"$WORKFLOW_DIR/.gitkeep" => '', # forces the dir without any YAML
);
my @f = $GHACTIONS->new->check($CONTEXT->new(root => $dir));
is( scalar @f, 1, 'single finding' );
is( $f[0]->severity, $SEV_WARN, 'severity is warning' );
ok( $f[0]->is_fixable, 'fix is offered' );
( run in 0.539 second using v1.01-cache-2.11-cpan-af0e5977854 )