// Re-anchoring a quote in text that changed. // // Run with: pnpm test:scripts import assert from "node:assert/strict"; import test from "node:test"; import { locateQuote, normalise, quoteAnchor, sentenceAround } from "./anchor.mjs"; const P1 = "She said the vote was rigged in 2020. Nobody checked the claim at the time."; const P2 = "Two years later she said the vote was rigged again, on a different show."; const TEXT = `${P1}\n\n${P2}`; test("an exact quote is found, and the context picks between two copies", () => { const second = TEXT.indexOf("the vote was rigged", P1.length); const a = quoteAnchor(TEXT, second, second + "the vote was rigged".length); assert.equal(a.quote, "the vote was rigged"); const r = locateQuote(TEXT, a); assert.deepEqual([r.found, r.start, r.how], [true, second, "exact"]); const first = locateQuote(TEXT, quoteAnchor(TEXT, TEXT.indexOf("the vote"), TEXT.indexOf("the vote") + 19)); assert.equal(first.start, TEXT.indexOf("the vote")); }); test("a paragraph edited ABOVE the quote does not move the note off it", () => { const start = TEXT.indexOf("on a different show"); const a = quoteAnchor(TEXT, start, start + "on a different show".length); const edited = `A new opening paragraph the agent added.\n\n${P1.replace("Nobody checked", "No outlet checked")}\n\n${P2}`; const r = locateQuote(edited, a); assert.equal(r.found, true); assert.equal(edited.slice(r.start, r.end), "on a different show"); }); test("whitespace, typographic quotes and case still match (normalised)", () => { const a = { quote: "it's the\nclaim", prefix: "", suffix: "" }; const t = "And then: It’s the claim, again."; const r = locateQuote(t, a); assert.equal(r.found, true); assert.equal(r.how, "normalised"); assert.equal(t.slice(r.start, r.end), "It’s the claim"); }); test("a rewritten quote is found by its surviving context; a vanished one is orphaned", () => { const start = TEXT.indexOf("Nobody checked the claim"); const a = quoteAnchor(TEXT, start, start + "Nobody checked the claim".length); const rewritten = TEXT.replace("Nobody checked the claim", "No outlet verified it"); const r = locateQuote(rewritten, a); assert.equal(r.found, true); assert.equal(r.how, "context"); assert.equal(rewritten.slice(r.start, r.end), "No outlet verified it"); const gone = locateQuote("A completely different article.", a); assert.deepEqual(gone, { found: false }); assert.deepEqual(locateQuote("", a), { found: false }); }); test("normalise maps back to the original offsets", () => { const n = normalise(" a \n\n b—c "); assert.equal(n.text, "a b-c"); assert.deepEqual(n.map.slice(0, 5), [2, 3, 7, 8, 9]); }); test("sentenceAround gives the sentence holding the quote", () => { const s = TEXT.indexOf("Nobody checked"); assert.equal(sentenceAround(TEXT, s, s + 6), "Nobody checked the claim at the time."); const f = TEXT.indexOf("Two years"); assert.equal(sentenceAround(TEXT, f, f + 3), P2); });