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 )