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 )