// test-apply-o2-ratified.test.mjs — R11 §9.4, the apply half. // // The driver edits PUBLICLY DISTRIBUTED KB files, so every invariant that stands // between a ratified string and a write is tested here: exactly-once anchoring, // deletion-only, composition of two edits in one file, and idempotency. import { test } from 'node:test'; import assert from 'node:assert/strict'; import { applyEdit, amendedRemainder, reduceSharePointOnly, RATIFIED } from '../../scripts/kb-eval/apply-o2-ratified.mjs'; const FILE = ['# Title', '', 'alpha', 'BLOCK line one', 'BLOCK line two', '', 'omega', ''].join('\n'); test('applyEdit replaces the anchored block and leaves the rest byte-identical', () => { const out = applyEdit(FILE, 'BLOCK line one\nBLOCK line two', 'BLOCK line one'); assert.equal(out, ['# Title', '', 'alpha', 'BLOCK line one', '', 'omega', ''].join('\n')); }); test('applyEdit throws when the verbatim does not occur', () => { assert.throws(() => applyEdit(FILE, 'ABSENT', 'ABSENT'), /occurs 0 times/); }); test('applyEdit throws when the verbatim occurs more than once (ambiguous anchor)', () => { const dup = FILE + 'BLOCK line one\nBLOCK line two\n'; assert.throws(() => applyEdit(dup, 'BLOCK line one\nBLOCK line two', 'BLOCK line one'), /occurs 2 times/); }); test('applyEdit refuses a remainder that is not deletion-only', () => { assert.throws( () => applyEdit(FILE, 'BLOCK line one\nBLOCK line two', 'BLOCK line one\nBLOCK line THREE'), /not deletion-only/, ); }); test('applyEdit refuses a remainder that introduces a novel word form (V2b)', () => { // 'Automatically add' -> 'Add' passes a character subsequence but recapitalises. assert.throws( () => applyEdit('x\nAutomatically add samples\ny', 'Automatically add samples', 'Add samples'), /novel word form/, ); }); test('two edits in the same file compose, and the second is unaffected by the first shifting lines', () => { const src = ['head', 'AAA one', 'AAA two', 'mid', 'BBB one', 'BBB two', 'tail'].join('\n'); let out = applyEdit(src, 'AAA one\nAAA two', 'AAA one'); out = applyEdit(out, 'BBB one\nBBB two', 'BBB one'); assert.equal(out, ['head', 'AAA one', 'mid', 'BBB one', 'tail'].join('\n')); }); test('applyEdit is idempotent-safe: re-running on an applied file throws rather than corrupting', () => { const once = applyEdit(FILE, 'BLOCK line one\nBLOCK line two', 'BLOCK line one'); assert.throws(() => applyEdit(once, 'BLOCK line one\nBLOCK line two', 'BLOCK line one'), /occurs 0 times/); }); test('reduceSharePointOnly drops the SharePoint alternative and KEEPS Automatically', () => { const verbatim = [ '| **Storage** | Dataverse / SharePoint | Lagre feedback data |', '| **Model improvement** | AI Builder Feedback Loop | Automatically add reviewed samples to training set |', ].join('\n'); const out = reduceSharePointOnly(verbatim); assert.match(out, /\| Dataverse \|/); assert.doesNotMatch(out, /SharePoint/); assert.match(out, /Automatically add reviewed samples/, 'line 566 asserts automaticity — it must survive'); }); test('reduceSharePointOnly throws if the surgery is a no-op (guards against silent drift)', () => { assert.throws(() => reduceSharePointOnly('nothing to reduce'), /no-op/); }); test('RATIFIED carries exactly the four operator-ratified edits, and not the three held back', () => { assert.deepEqual(RATIFIED.map((r) => r.idx).sort((a, b) => a - b), [14, 17, 19, 33]); for (const held of [26, 27, 36]) { assert.equal(RATIFIED.some((r) => r.idx === held), false, `idx ${held} was NOT ratified`); } }); test('amendedRemainder returns the attested string untouched when there is no amendment', () => { const row = { idx: 17, proposed_remainder: 'kept', file_text_verbatim: 'kept\ndropped' }; assert.equal(amendedRemainder(row, { idx: 17, amend: null }), 'kept'); });