App-GHGen
view release on metacpan or search on metacpan
t/function.t view on Meta::CPAN
# No recognisable package manager -> no cache step created.
my $unknown = App::GHGen::Fixer::detect_and_create_cache_step([{ run => 'make all' }]);
ok(!defined $unknown, 'unrecognised step returns undef');
};
subtest 'Fixer::add_permissions - idempotent permission insertion' => sub {
my $workflow = { name => 'Test' };
my $added = App::GHGen::Fixer::add_permissions($workflow);
is($added, 1, 'returns 1 when permissions were added');
is($workflow->{permissions}{contents}, 'read', 'sets contents: read permission');
# Calling again must not double-apply.
my $added2 = App::GHGen::Fixer::add_permissions($workflow);
is($added2, 0, 'returns 0 when permissions already present');
};
subtest 'Fixer::add_concurrency - idempotent concurrency insertion' => sub {
my $workflow = { name => 'Test' };
is(App::GHGen::Fixer::add_concurrency($workflow), 1, 'adds concurrency, returns 1');
ok(defined $workflow->{concurrency}, 'concurrency key now present');
is(App::GHGen::Fixer::add_concurrency($workflow), 0, 'no-ops when already present');
};
subtest 'Fixer::add_trigger_filters - restricts broad push triggers' => sub {
# Array-form broad trigger.
my $array_wf = { on => [qw(push pull_request)] };
my $changed = App::GHGen::Fixer::add_trigger_filters($array_wf);
is($changed, 1, 'array push trigger was modified');
ok(ref $array_wf->{on} eq 'HASH', 'on key converted to hash form after fix');
# Already-filtered workflow must not be modified.
my $filtered_wf = { on => { push => { branches => ['main'] } } };
is(
App::GHGen::Fixer::add_trigger_filters($filtered_wf),
0,
'already-filtered trigger is not modified',
);
};
subtest 'Fixer::add_missing_timeout - inserts timeout on jobs lacking it' => sub {
my $workflow = {
jobs => {
a => { 'runs-on' => 'ubuntu-latest' }, # no timeout
b => { 'runs-on' => 'ubuntu-latest', 'timeout-minutes' => 60 }, # already set
},
};
my $count = App::GHGen::Fixer::add_missing_timeout($workflow);
is($count, 1, 'exactly one job received a timeout');
ok(exists $workflow->{jobs}{a}{'timeout-minutes'}, 'job a now has timeout-minutes');
is($workflow->{jobs}{b}{'timeout-minutes'}, 60, 'job b timeout unchanged');
};
subtest 'Fixer::update_runners - upgrades known outdated runner strings' => sub {
my $workflow = {
jobs => {
test => { 'runs-on' => 'ubuntu-18.04' },
},
};
my $count = App::GHGen::Fixer::update_runners($workflow);
is($count, 1, 'one runner was updated');
is(
$workflow->{jobs}{test}{'runs-on'},
'ubuntu-latest',
'ubuntu-18.04 was updated to ubuntu-latest',
);
# Current runner must not be changed.
my $current = { jobs => { test => { 'runs-on' => 'ubuntu-latest' } } };
is(App::GHGen::Fixer::update_runners($current), 0, 'current runner not touched');
};
subtest 'Fixer::fix_unpinned_actions - replaces @master and @main with versions' => sub {
my $workflow = {
jobs => { test => { steps => [
{ uses => 'actions/checkout@main' },
{ uses => 'some-other/action@master' },
{ uses => 'pinned/action@v5' },
]}},
};
my $count = App::GHGen::Fixer::fix_unpinned_actions($workflow);
is($count, 2, 'two unpinned actions were fixed');
for my $step (@{$workflow->{jobs}{test}{steps}}) {
unlike($step->{uses}, qr/\@(master|main)$/, "step $step->{uses} is now pinned");
}
};
subtest 'Fixer::update_actions - upgrades outdated action versions' => sub {
my $workflow = {
jobs => { test => { steps => [
{ uses => $C{OLD_CHECKOUT_V3} },
{ uses => $C{OLD_CACHE_V3} },
{ uses => $C{LATEST_CHECKOUT} }, # already current
]}},
};
my $count = App::GHGen::Fixer::update_actions($workflow);
is($count, 2, 'two outdated actions were upgraded');
is(
$workflow->{jobs}{test}{steps}[0]{uses},
$C{LATEST_CHECKOUT},
'checkout@v3 upgraded to checkout@v6',
);
};
subtest 'Fixer::add_caching - inserts cache step after checkout' => sub {
my $workflow = {
jobs => { test => { steps => [
{ uses => 'actions/checkout@v6' },
{ run => 'npm ci' },
{ run => 'npm test' },
]}},
};
my $count = App::GHGen::Fixer::add_caching($workflow);
is($count, 1, 'one cache step was inserted');
my @steps = @{$workflow->{jobs}{test}{steps}};
ok(
(grep { $_->{uses} && $_->{uses} =~ /actions\/cache/ } @steps),
'workflow now contains a cache step',
);
# Second call must be a no-op because caching is already present.
is(App::GHGen::Fixer::add_caching($workflow), 0, 'second add_caching call is a no-op');
};
( run in 1.783 second using v1.01-cache-2.11-cpan-81fc1098f69 )