test(voyage): Group C.8 SC6 round-trip via readAndUpdate (1bc37231)

This commit is contained in:
Kjell Tore Guttormsen 2026-05-10 21:48:21 +02:00
commit ffabd7820e

View file

@ -12,9 +12,12 @@
import { test } from 'node:test';
import { strict as assert } from 'node:assert';
import { readFileSync } from 'node:fs';
import { readFileSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { dirname, resolve, join } from 'node:path';
import { fileURLToPath } from 'node:url';
import { readAndUpdate } from '../../lib/util/markdown-write.mjs';
import { parseDocument } from '../../lib/util/frontmatter.mjs';
const __dirname = dirname(fileURLToPath(import.meta.url));
const ROOT = resolve(__dirname, '..', '..');
@ -255,3 +258,34 @@ test('Group C.7 — fixture plan parses with anchors at block boundaries (v4.3 S
assert.match(planText, /<!--\s*voyage:anchor\s+id="ANN-0001"\s+target="step-1-sentinel-touch"\s+line="\d+"\s*-->/, 'ANN-0001 anchor required');
assert.match(planText, /<!--\s*voyage:anchor\s+id="ANN-0002"\s+target="step-2-sentinel-touch-paired"\s+line="\d+"\s*-->/, 'ANN-0002 anchor required');
});
// Group C.8 — SC6 round-trip: readAndUpdate raises revision to 1 + populates
// source_annotations + annotation_digest (finding 1bc37231). Verifies the
// trekrevise mutation contract end-to-end against a tmpdir copy of the
// pre-annotate plan fixture.
test('Group C.8 — SC6 round-trip: readAndUpdate raises revision to 1, source_annotations populated (1bc37231)', () => {
const tmpDir = mkdtempSync(join(tmpdir(), 'voyage-c8-'));
const tmpPath = join(tmpDir, 'plan.md');
try {
writeFileSync(tmpPath, readFileSync(PLAN_FIXTURE, 'utf-8'));
const bundle = JSON.parse(readFileSync(BUNDLE, 'utf-8'));
const result = readAndUpdate(tmpPath, ({ frontmatter, body }) => {
frontmatter.revision = (frontmatter.revision || 0) + 1;
frontmatter.source_annotations = bundle.annotations;
frontmatter.annotation_digest = computeAnnotationDigest(bundle.annotations);
return { frontmatter, body };
});
assert.equal(result.valid, true, `readAndUpdate must return valid: ${JSON.stringify(result.errors || [])}`);
const parsed = parseDocument(readFileSync(tmpPath, 'utf-8'));
assert.equal(parsed.valid, true, `re-parsed file must be valid: ${JSON.stringify(parsed.errors || [])}`);
const fm = parsed.parsed.frontmatter;
assert.equal(fm.revision, 1, 'revision must be 1 after first round-trip');
assert.equal(Array.isArray(fm.source_annotations), true, 'source_annotations must be array');
assert.equal(fm.source_annotations.length, 2, 'source_annotations must have 2 entries from bundle fixture');
assert.match(fm.annotation_digest, /^[0-9a-f]{16}$/, 'annotation_digest must be 16-hex-char SHA-256 prefix');
} finally {
rmSync(tmpDir, { recursive: true, force: true });
}
});