Accumulated uncommitted work: GHOST Web backend, WebGL/GPU web layer, web workflow engine and protocol, tooling, docs and task records. Large generated evidence, user-testing archives, build snapshots and imported test assets remain untracked. Co-Authored-By: Claude Code <noreply@anthropic.com>
56 lines
4.9 KiB
JavaScript
56 lines
4.9 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { coverageBaseline, caseEvidence, canonicalPath } from '../../../tools/web/coverage-baseline.mjs';
|
|
import { digest } from '../../../tools/web/workflow-case-lib.mjs';
|
|
const sourceHash = digest('source'), proofHash = digest('proof');
|
|
const treeHash = digest(`a.cc\0${sourceHash}\n`);
|
|
test('equivalent absolute and relative input paths have one identity', () => {
|
|
assert.equal(canonicalPath('/workspace', '/workspace/cases/result.json'), canonicalPath('/workspace', './cases/result.json'));
|
|
assert.equal(canonicalPath('/workspace', 'cases/../cases/result.json'), 'cases/result.json');
|
|
assert.throws(() => canonicalPath('/workspace', 123), /string/);
|
|
});
|
|
const receipt = () => ({ cases: [{ kind: 'minimal', status: 'PASS', inputs: [{ path: 'input', sha256: proofHash }], artifacts: [{ path: 'output', sha256: proofHash }], process: { code: 0, timedOut: false, cancelled: false }, result: { passed: true, tests: 2 } }], remainingGates: ['production'] });
|
|
function fixture() {
|
|
const catalog = { entries: [{ id: 'op:a' }], unitCount: 1 };
|
|
const binding = { evidenceManifest: { path: 'manifest', sha256: proofHash }, productionEvidence: { path: 'production', sha256: proofHash }, sourceTreeSha256: treeHash };
|
|
const inventory = { authority: { sourceTreeSha256: treeHash }, sourceFiles: [{ path: 'a', sourcePath: 'a.cc', sha256: sourceHash }], units: [{ id: 'op:a', coverageStatus: 'VERIFIED', coverage: binding }] };
|
|
const historical = { references: [], driftedArtifacts: 183 };
|
|
const observed = new Map([['a', sourceHash], ['manifest', proofHash], ['production', proofHash]]);
|
|
return { catalog, inventory, historical, observed, run() { return coverageBaseline(this.catalog, this.inventory, this.historical, file => this.observed.get(file) ?? null); } };
|
|
}
|
|
test('matching receipts and source scope yield current coverage with stable identity', () => {
|
|
const f = fixture(), first = f.run(); assert.equal(first.unitCount, 1); assert.equal(first.verifiedUnits, 1);
|
|
assert.equal(first.history.oldDriftedArtifacts, 183); assert.equal(first.integrity.driftedArtifacts, 0);
|
|
assert.deepEqual(f.run(), first);
|
|
});
|
|
test('changed and missing receipt files never inherit a historical pass', () => {
|
|
const f = fixture(); f.observed.set('production', digest('changed')); assert.equal(f.run().verifiedUnits, 0); assert.equal(f.run().integrity.driftedArtifacts, 1);
|
|
f.observed.delete('production'); assert.equal(f.run().verifiedUnits, 0); assert.equal(f.run().integrity.missingArtifacts, 1);
|
|
});
|
|
test('matching receipt bytes do not prove behavior on changed source', () => {
|
|
const f = fixture(); f.observed.set('a', digest('new source')); const result = f.run();
|
|
assert.equal(result.history.referenceValidUnits, 1); assert.equal(result.verifiedUnits, 0);
|
|
assert.equal(result.source.changedFiles, 1); assert.ok(result.evidence[0].reasons.includes('SOURCE_VERSION_UNBOUND'));
|
|
});
|
|
test('all unmatched units remain in the shared denominator', () => {
|
|
const f = fixture(); f.catalog.entries.push({ id: 'route-only' }); f.inventory.units.push({ id: 'inventory-only' });
|
|
const result = f.run(); assert.equal(result.unitCount, 3); assert.equal(result.unverifiedUnits, 2); assert.deepEqual(result.reconciliation.catalogOnly, ['route-only']); assert.deepEqual(result.reconciliation.inventoryOnly, ['inventory-only']);
|
|
});
|
|
test('malformed IDs, duplicate IDs and inconsistent inventory identity fail closed', () => {
|
|
const f = fixture(); f.catalog.entries.push({ id: 'op:a' }); assert.throws(() => f.run(), /duplicate/);
|
|
f.catalog.entries.pop(); f.catalog.entries[0].id = 42; assert.throws(() => f.run(), /string/);
|
|
f.catalog.entries[0].id = 'op:a'; f.inventory.authority.sourceTreeSha256 = digest('wrong inventory');
|
|
const result = f.run(); assert.equal(result.verifiedUnits, 0); assert.ok(result.evidence[0].reasons.includes('INVENTORY_SNAPSHOT_INVALID'));
|
|
});
|
|
test('case facts require real numeric exit/test counts and preserve remaining gates', () => {
|
|
const r = receipt(), valid = caseEvidence(r, () => proofHash); assert.equal(valid.cases[0].currentSelectedTests, 2); assert.equal(valid.acceptance, 'NOT_CLAIMED'); assert.deepEqual(valid.remainingGates, ['production']);
|
|
r.cases[0].process.code = '0'; assert.equal(caseEvidence(r, () => proofHash).cases[0].currentSelectedTests, 0);
|
|
r.cases[0].process.code = 0; r.cases[0].result.tests = '2'; assert.equal(caseEvidence(r, () => proofHash).cases[0].currentSelectedTests, 0);
|
|
});
|
|
test('case input changes, missing artifacts and unknown hash types invalidate reuse', () => {
|
|
const r = receipt(); assert.equal(caseEvidence(r, file => file === 'input' ? digest('changed') : proofHash).cases[0].eligible, false);
|
|
assert.equal(caseEvidence(r, () => null).cases[0].eligible, false);
|
|
assert.throws(() => caseEvidence(r, () => 123)); r.cases[0].artifacts = [];
|
|
assert.equal(caseEvidence(r, () => proofHash).cases[0].eligible, false);
|
|
});
|