test: base-red coverage additions (unreproduced head, unresolved head, readPause, wait unconfigured)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
garrytanandcapy-ai[bot] committed 2026-10-29 16:27:40 +00:00
1 parent 5876005f73
commit 289aeda443
1 file changed
+45
+45
View File
@@ -184,3 +184,48 @@ describe('policy', () => {
expect(codes(POLICY, null)).toEqual(['POLICY_INVALID@base_red']);
});
});
describe('coverage audit additions', () => {
// Generated by /ship Step 7 coverage audit (PR #3611).
// Value: protects=a failure reproduced at base but not by the restricted run at the PR head stays in-branch, and one unreproduced case keeps the whole verdict in-branch;
// fails_when=the head reproduction or the every-case aggregation is dropped, so a PR that changes behaviour is paused as base-red; why_new=existing tests vary only the base run, with one case;
// seam=none; no_claim=real test runners (shell scripts stand in for the lane's tests)
test('a case the head run does not reproduce, or a case the base output never names, keeps the verdict in-branch', () => {
fixture();
write('pr-only.txt', 'x\n'); git('add', '-A'); git('commit', '-qm', 'pr: marker');
const headPasses = classifyBaseRed({ repoRoot: work, base: 'main', head: 'HEAD', evidence: evidence(), policy: { ...POLICY, select: `[ -f pr-only.txt ] && { echo "(pass) totals add up"; exit 0; }; ${SELECT}` } });
expect([headPasses.code, headPasses.cases[0]!.reason]).toEqual(['IN_BRANCH', 'the restricted command passes at head']);
const ghost = { id: 'ghost case', file: 't/sum.test.sh', signature: 'error: expected 3 got 4' };
const mixed = classifyBaseRed({ repoRoot: work, base: 'main', head: 'HEAD', evidence: evidence({ total: 2, failures: [evidence().failures[0]!, ghost] }), policy: POLICY });
expect(mixed.code).toBe('IN_BRANCH');
expect(mixed.cases.map(c => c.verdict)).toEqual(['BASE_RED', 'IN_BRANCH']);
expect(mixed.cases[1]!.reason).toStartWith('fails without naming this test at base ');
});
// Generated by /ship Step 7 coverage audit (PR #3611).
// Value: protects=an unresolvable PR head is BASE_RED_REPRO_ERROR with every case in-branch and nothing run; fails_when=the commit-resolution guard is removed or inverted;
// why_new=no existing test resolves a missing commit; seam=none; no_claim=none beyond protects
test('an unresolvable head is a reproduction error that runs nothing', () => {
fixture();
const a = counting();
const r = classifyBaseRed({ repoRoot: work, base: 'main', head: 'no-such-ref', evidence: evidence(), policy: POLICY, runner: a.runner });
expect([r.code, r.cases.every(c => c.verdict === 'IN_BRANCH'), a.calls]).toEqual(['BASE_RED_REPRO_ERROR', true, []]);
});
// Generated by /ship Step 7 coverage audit (PR #3611).
// Value: protects=readPause rejects missing or non-pause files, and wait refuses BASE_RED_UNCONFIGURED once the base no longer declares base_red;
// fails_when=readPause accepts any JSON or wait polls without a usable base policy; why_new=existing tests read only valid pauses and never run the wait CLI;
// seam=none; no_claim=remote fetch over a network (local bare origin)
test('readPause rejects non-pause files and the wait CLI refuses when the base declares no base_red', () => {
fixture({ policy: null });
const bogus = path.join(root, 'bogus.json');
fs.writeFileSync(bogus, JSON.stringify({ kind: 'other', schema_version: 1, cases: [] }));
expect(readPause(bogus)).toContain('is not a base-red pause record');
expect(readPause(path.join(root, 'missing.json'))).toStartWith('cannot read ');
const pauseFile = path.join(root, 'pause.json');
fs.writeFileSync(pauseFile, JSON.stringify({ schema_version: 1, kind: 'base-red-pause', branch: 'feat', head: git('rev-parse', 'HEAD'), base: 'main', base_sha: git('rev-parse', 'origin/main'), lane: 'tests', cases: evidence().failures, created_at: '2026-10-29T00:00:00Z', expires_at: '2999-01-01T00:00:00Z' }));
const w = spawnSync('bun', [path.join(ROOT, 'bin', 'gstack-base-red'), 'wait', '--pause', pauseFile, '--timeout', '30', '--poll', '5'], { cwd: work, encoding: 'utf8', timeout: 60_000, env: { ...process.env, ...ID, GSTACK_STATE_ROOT: state } });
expect(w.status).toBe(EXIT.refused);
expect(w.stderr).toContain('BASE_RED_UNCONFIGURED');
});
});