mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-12 19:44:48 +01:00
129 lines
7.9 KiB
TypeScript
129 lines
7.9 KiB
TypeScript
import { expect, test } from 'bun:test';
|
|
import { coverageAuditVerdict } from './helpers/coverage-audit-evidence';
|
|
import fixture from './fixtures/coverage-audit-af.json';
|
|
import { E2E_TOUCHFILES } from './helpers/touchfiles';
|
|
|
|
const actual = (index: number) => structuredClone(fixture.rows[index]!);
|
|
const files = (row: typeof fixture.rows[number]) => ({cwd:row.cwd,
|
|
source:{path:`${row.cwd}/src/billing.ts`,content:fixture.files.source},
|
|
tests:{path:`${row.cwd}/test/billing.test.ts`,content:fixture.files.tests}});
|
|
for (let i=0;i<fixture.rows.length;i++) test(`AF exact public coverage audit ${i+1} binds delivered files and seeded diagram`, () => {
|
|
const row=actual(i); expect(coverageAuditVerdict(row.result, files(row))).toEqual({sourceRead:true,testsRead:true,diagram:true,passed:true,failures:[]});
|
|
});
|
|
|
|
function delivered(command: string, mutate?: (events: any[]) => void) {
|
|
const row=actual(2), session=row.sessionId;
|
|
const transcript:any[]=[
|
|
{type:'system',subtype:'init',session_id:session,cwd:row.cwd},
|
|
{type:'assistant',session_id:session,parent_tool_use_id:null,message:{role:'assistant',content:[{type:'tool_use',id:'read-pair',name:'Bash',input:{command}}]}},
|
|
{type:'user',session_id:session,parent_tool_use_id:null,message:{role:'user',content:[{type:'tool_result',tool_use_id:'read-pair',is_error:false,content:fixture.files.source+'\n----\n'+fixture.files.tests}]}},
|
|
];
|
|
mutate?.(transcript);
|
|
return coverageAuditVerdict({...row.result,transcript},files(row));
|
|
}
|
|
const both = 'cat -n src/billing.ts && cat -n test/billing.test.ts';
|
|
|
|
test('AF complete literal reads permit a successful chain and one leading owned cwd assertion', () => {
|
|
const cwd=actual(2).cwd;
|
|
for (const command of [both, `cd ${cwd}; cat -n src/billing.ts; cat -n test/billing.test.ts`, `cd '${cwd}' && ${both}`, 'cat -n src/billing.ts; echo ----; cat -n test/billing.test.ts']) {
|
|
const v=delivered(command); expect(v.sourceRead).toBe(true); expect(v.testsRead).toBe(true); expect(v.passed).toBe(true);
|
|
}
|
|
});
|
|
|
|
test('AF the new conditional-chain grammar conservatively rejects mixed separators', () => {
|
|
const v=delivered(`cd ${actual(2).cwd}; ${both}`);
|
|
expect(v.sourceRead).toBe(false); expect(v.testsRead).toBe(false);
|
|
});
|
|
|
|
test('AF read recognition rejects foreign or midstream cwd changes and nonliteral targets', () => {
|
|
const cwd=actual(2).cwd;
|
|
for (const command of [`cd /foreign; ${both}`, `cat -n src/billing.ts; cd /foreign; cat -n test/billing.test.ts`,
|
|
`cat -n src/billing.ts; cd ${cwd}; cat -n test/billing.test.ts`, `cd "$PWD"; ${both}`, `cd ${cwd}/..; ${both}`]) {
|
|
const v=delivered(command); expect(v.sourceRead).toBe(false); expect(v.testsRead).toBe(false);
|
|
}
|
|
});
|
|
|
|
test('AF a printed, conditional or skipped read cannot borrow delivered-looking file contents', () => {
|
|
for (const command of [`false && ${both}`, `if false; then ${both}; fi`, `echo '${both}'`, `exit; ${both}`,
|
|
`# ${both}`, `cat <<'EOF'\n${both}\nEOF`, `(${both})`, `f() { ${both}; }`, `printf '%s' '${both}'`,
|
|
`printf expected; false && ${both}; true`, `${both} > result.txt`]) {
|
|
const v=delivered(command); expect(v.sourceRead).toBe(false); expect(v.testsRead).toBe(false);
|
|
}
|
|
});
|
|
|
|
test('AF an owned cwd does not authorize mutations or interpreters around a read', () => {
|
|
for (const neighbor of ['rm -f src/billing.ts', 'python3 -c "pass"', 'echo fake > src/billing.ts',
|
|
'grep data backup.txt | tee src/billing.ts', 'git diff --output=src/billing.ts',
|
|
"git diff '--output=src/billing.ts'", "git diff --output'='src/billing.ts",
|
|
'git diff --out=src/billing.ts', 'git diff --ext-diff']) {
|
|
const result = delivered(`cd ${actual(2).cwd}; ${neighbor}; cat src/billing.ts; cat test/billing.test.ts`);
|
|
expect(result.sourceRead).toBe(false); expect(result.testsRead).toBe(false);
|
|
}
|
|
});
|
|
|
|
test('AF added command forms retain exact parent request/result success and delivered-content binding', () => {
|
|
const mutations:Array<(events:any[])=>void>=[
|
|
e=>{e[0].cwd='/foreign';}, e=>{e[2].session_id='foreign';},
|
|
e=>{e[1].parent_tool_use_id='child';}, e=>{e[2].message.content[0].is_error=true;},
|
|
e=>{e[2].message.content[0].tool_use_id='unpaired';},
|
|
e=>{e[2].message.content[0].content='The two filenames were read.';},
|
|
];
|
|
for (const mutate of mutations) { const v=delivered(both,mutate); expect(v.sourceRead).toBe(false); expect(v.testsRead).toBe(false); }
|
|
const onlySource=delivered(both,e=>{e[2].message.content[0].content=fixture.files.source;});
|
|
expect(onlySource.sourceRead).toBe(true); expect(onlySource.testsRead).toBe(false);
|
|
});
|
|
|
|
const flat = (legend = 'Legend: [✓] tested [✗] GAP') => `\`\`\`text\n${legend}\nprocessPayment(amount, currency)\n├── [✓] happy path USD\nrefundPayment(paymentId, reason)\n└── [✗] happy path refund\n\`\`\``;
|
|
function diagram(output:string) { const row=actual(0);return coverageAuditVerdict({...row.result,output},files(row)).diagram; }
|
|
|
|
test('AF flat function roots and same-block legend symbols preserve seeded coverage ownership', () => {
|
|
expect(diagram(flat())).toBe(true);
|
|
expect(diagram(flat().replaceAll('✓','✔').replaceAll('✗','✘'))).toBe(true);
|
|
expect(diagram(flat().replace('processPayment(amount, currency)\n├── [✓] happy path USD\nrefundPayment(paymentId, reason)\n└── [✗] happy path refund',
|
|
'refundPayment(paymentId, reason)\n├── [✗] happy path refund\nprocessPayment(amount, currency)\n└── [✓] happy path USD'))).toBe(true);
|
|
});
|
|
|
|
test('AF symbol-only markers need an unambiguous legend in their own diagram block', () => {
|
|
for (const output of [flat(''),flat('Legend: [✓] GAP [✗] tested'),flat('Legend: [✓] tested [✗] tested'),
|
|
flat('Legend: [✓] tested [✗] GAP [✗] tested'),
|
|
`\`\`\`text\nLegend: [✓] tested [✗] GAP\n\`\`\`\n${flat('')}`]) expect(diagram(output)).toBe(false);
|
|
});
|
|
|
|
test('AF flat roots cannot borrow another function subtree or a quoted/example diagram', () => {
|
|
for (const output of [
|
|
flat().replace('├── [✓] happy path USD','├── untested amount guard\nunrelatedHelper()\n└── [✓] happy path USD'),
|
|
flat().replace('refundPayment(paymentId, reason)','unrelatedRefund(paymentId, reason)'),
|
|
flat().replace('processPayment(amount, currency)','processPaymentOther(amount, currency)'),
|
|
flat().split('\n').map(line=>'> '+line).join('\n'),
|
|
'````markdown\n'+flat()+'\n````',
|
|
flat().replace('Legend:','Example diagram:\nLegend:'),
|
|
]) expect(diagram(output)).toBe(false);
|
|
});
|
|
|
|
test('AF a legend cannot override an explicitly negated marker on its own branch', () => {
|
|
for (const output of [
|
|
flat().replace('[✗] happy path refund','not [✗] happy path refund'),
|
|
flat().replace('[✗] happy path refund','[✗] is false; this branch is tested'),
|
|
flat().replace('[✓] happy path USD','not [✓] happy path USD'),
|
|
]) expect(diagram(output)).toBe(false);
|
|
});
|
|
|
|
test('AF coverage fixtures and controls select only the two existing coverage-audit owners', () => {
|
|
for (const file of ['test/coverage-audit-af.test.ts','test/fixtures/coverage-audit-af.json']) {
|
|
expect(Object.entries(E2E_TOUCHFILES).filter(([,paths])=>paths.includes(file)).map(([name])=>name).sort()).toEqual(['plan-eng-coverage-audit','review-coverage-audit']);
|
|
}
|
|
});
|
|
|
|
|
|
test('AF symbol gaps retain affirmative legend ownership and reject same-branch contradictions', () => {
|
|
for (const output of [
|
|
flat().replace('[✗] happy path refund', '[✗] happy path refund (marker is incorrect; this branch is fully tested)'),
|
|
flat().replace('[✗] happy path refund', '[✗] happy path refund — no coverage gap exists'),
|
|
flat('An unproven hypothesis: [✓] tested [✗] GAP'),
|
|
flat("The source says '[✓] tested [✗] GAP'"),
|
|
]) expect(diagram(output)).toBe(false);
|
|
expect(diagram(flat())).toBe(true);
|
|
expect(diagram(flat('[✓] tested [✗] GAP'))).toBe(true);
|
|
expect(diagram(flat('src/billing.ts — test coverage map [✓] tested [✗] GAP'))).toBe(true);
|
|
});
|