App-GHGen
view release on metacpan or search on metacpan
t/extended_tests.t view on Meta::CPAN
# POD FORMAL SPEC: list context â ranked by descending score.
my $tmp = tempdir(CLEANUP => 1);
with_dir($tmp, sub {
# Perl project: cpanfile + Makefile.PL
path('cpanfile')->spew_utf8("requires 'strict';\n");
path('Makefile.PL')->spew_utf8("use ExtUtils::MakeMaker;\n");
my @results = detect_project_type();
ok(@results >= 1, 'list context returns at least one detection');
is($results[0]->{type}, 'perl', 'top-ranked type is perl');
for my $i (1 .. $#results) {
cmp_ok($results[$i]->{score}, '<=', $results[$i-1]->{score},
"result[$i] score <= result[" . ($i-1) . "] score (descending)");
}
});
};
# =============================================================================
# 4. App::GHGen::Fixer â uncovered helpers
# =============================================================================
subtest 'Fixer::detect_and_create_cache_step - Go (go build) returns correct cache step' => sub {
# Covers the Go branch in detect_and_create_cache_step.
my $steps = [{ run => 'go build ./...' }];
my $step = App::GHGen::Fixer::detect_and_create_cache_step($steps);
ok(defined $step, 'cache step created for Go project');
like($step->{with}{path}, qr|go/pkg/mod|, 'Go cache uses ~/go/pkg/mod path');
like($step->{with}{key}, qr/go\.sum/, 'Go cache key hashes go.sum');
};
subtest 'Fixer::detect_and_create_cache_step - setup-go action triggers Go cache' => sub {
my $steps = [{ uses => 'actions/setup-go@v5' }];
my $step = App::GHGen::Fixer::detect_and_create_cache_step($steps);
ok(defined $step, 'setup-go action triggers Go cache creation');
like($step->{with}{path}, qr|go/pkg/mod|, 'correct path for setup-go');
};
subtest 'Fixer::detect_and_create_cache_step - no matching steps returns undef' => sub {
# Branch: none of the known patterns â return undef.
my $steps = [{ run => 'echo hello' }];
my $step = App::GHGen::Fixer::detect_and_create_cache_step($steps);
is($step, undef, 'unrecognised steps produce no cache step');
};
subtest 'Fixer::add_caching - job already with cache step is skipped' => sub {
# LCSAJ: $has_cache is true â next â $modified stays 0.
my $wf = {
jobs => {
build => {
steps => [
{ uses => "$CACHE_ACTION\@v5" },
{ run => 'npm ci' },
],
},
},
};
my $result = App::GHGen::Fixer::add_caching($wf);
is($result, 0, 'job already with cache skipped; count stays 0');
};
subtest 'Fixer::add_trigger_filters - HASH on with push as bare string (truthy scalar)' => sub {
# Branch: ref $on->{push} eq '' with a truthy value â expand push to branches filter.
# Note: the implementation tests $on->{push} && ref $on->{push} eq '', so the
# scalar must be truthy (empty string is falsy and falls through).
my $wf = { on => { push => '*' }, jobs => {} };
my $n = App::GHGen::Fixer::add_trigger_filters($wf);
is($n, 1, 'truthy scalar push value gets expanded');
is(ref $wf->{on}{push}, 'HASH', 'push is now a HASH with filters');
is_deeply($wf->{on}{push}{branches}, ['main', 'master'], 'default branches added');
};
subtest 'Fixer::add_trigger_filters - no on key returns 0' => sub {
my $wf = { jobs => {} };
my $n = App::GHGen::Fixer::add_trigger_filters($wf);
is($n, 0, 'missing on key returns 0 modifications');
};
subtest 'Fixer::update_runners - windows-2016 upgraded to windows-latest' => sub {
my $wf = {
jobs => {
build => { 'runs-on' => 'windows-2016', steps => [] },
},
};
my $n = App::GHGen::Fixer::update_runners($wf);
is($n, 1, 'one runner updated');
is($wf->{jobs}{build}{'runs-on'}, 'windows-latest', 'windows-2016 â windows-latest');
};
subtest 'Fixer::update_runners - runner not in update table is unchanged' => sub {
my $wf = { jobs => { build => { 'runs-on' => 'ubuntu-latest', steps => [] } } };
my $n = App::GHGen::Fixer::update_runners($wf);
is($n, 0, 'current runner string produces no modifications');
};
subtest 'Fixer::get_latest_version - unknown action returns fallback v4' => sub {
# POD: unknown action â 'v4' fallback.
my $ver = App::GHGen::Fixer::get_latest_version('some/unknown-action');
is($ver, 'v4', 'unknown action returns v4 fallback');
};
subtest 'Fixer::apply_fixes - security/permissions branch fires add_permissions' => sub {
# Route to add_permissions via apply_fixes.
my $wf = { jobs => { build => { steps => [] } } };
my @issues = ({ type => $ISSUE_TYPE{SEC}, message => 'Missing permissions block' });
my $n = apply_fixes($wf, \@issues);
is($n, 1, 'one fix applied');
ok(exists $wf->{permissions}, 'permissions key inserted');
is($wf->{permissions}{contents}, 'read', 'contents: read set');
};
subtest 'Fixer::apply_fixes - maintenance/outdated action branch fires update_actions' => sub {
my $wf = {
jobs => {
build => {
steps => [{ uses => 'actions/cache@v3' }],
},
},
};
my @issues = ({ type => $ISSUE_TYPE{MAINT}, message => '1 outdated action(s)' });
my $n = apply_fixes($wf, \@issues);
is($n, 1, 'one action updated');
is($wf->{jobs}{build}{steps}[0]{uses}, 'actions/cache@v5', 'cache upgraded to v5');
};
subtest 'Fixer::apply_fixes - performance/missing timeout fires add_missing_timeout' => sub {
my $wf = {
jobs => {
( run in 0.358 second using v1.01-cache-2.11-cpan-9169edd2b0e )