test/provenance.test.js
Rama main · réplica de lectura del repositorio original.
import { test } from "node:test";
import assert from "node:assert/strict";
import {
slideSourceUse,
mapDeckSources,
buildReferencesSlide,
insertReferencesSlide,
} from "../src/ai/provenance.js";
import { validateDeck } from "../src/validate.js";
/**
* The slide before the thank-you slide.
*
* The writer is never asked for cites and grounding matches claims against
* the whole notes blob, so nothing knows which source each slide drew on.
* The mapping here is deterministic and best-effort: a slide "uses" every
* page that grounds at least one of its numeric claims.
*/
const PAGES = [
{ url: "https://solar.example/cells", title: "Perovskite cell efficiencies", words: 900, text: "Certified cells reach 26.1% efficiency. Degradation halves output in 9 years." },
{ url: "https://grid.example/storage", title: "Grid storage costs", words: 500, text: "Battery packs fell to 139 USD per kWh in 2023. Auctions cleared 180 GW." },
];
const deckWith = (slides) => ({ title: "T", slides });
test("a slide maps to the page that grounds its figures", () => {
const slide = { type: "bullets", headline: "Cells hit 26.1%", bullets: ["Certified cells reach 26.1% efficiency.", "Second point here.", "Third point here.", "Fourth point here."] };
assert.deepEqual(slideSourceUse(slide, PAGES), [0]);
});
test("a claim-free slide maps nowhere, dividers never map", () => {
const plain = { type: "bullets", headline: "Why this matters", bullets: ["First reason to care.", "Second reason to care.", "Third reason to care.", "Fourth reason to care."] };
assert.deepEqual(slideSourceUse(plain, PAGES), []);
const figured = { type: "bullets", headline: "Cells hit 26.1%", bullets: ["Certified cells reach 26.1% efficiency.", "Second point here.", "Third point here.", "Fourth point here."] };
const deck = deckWith([
{ type: "title", headline: "T" },
{ type: "section", headline: "S", section: 0 },
plain,
figured,
]);
assert.deepEqual(mapDeckSources(deck, PAGES).map((m) => m.slide), [3]);
});
test("the built slide names each source with its slide numbers", () => {
const deck = deckWith([
{ type: "title", headline: "T" },
{ type: "bullets", headline: "Cells hit 26.1%", bullets: ["Certified cells reach 26.1% efficiency.", "Second point here.", "Third point here.", "Fourth point here."] },
{ type: "bullets", headline: "Packs at 139 USD per kWh", bullets: ["Battery packs fell to 139 USD per kWh in 2023.", "Second point here.", "Third point here.", "Fourth point here."] },
{ type: "closing", headline: "Thanks" },
]);
const slide = buildReferencesSlide(deck, PAGES);
assert.ok(slide);
assert.equal(slide.type, "references");
assert.equal(slide.items.length, 2);
assert.ok(slide.items[0].includes("slide 2"), slide.items[0]);
assert.ok(slide.items[1].includes("slide 3"), slide.items[1]);
for (const item of slide.items) assert.ok(item.length <= 220, item);
});
test("no mappable slide means no references slide", () => {
const deck = deckWith([{ type: "title", headline: "T" }]);
assert.equal(buildReferencesSlide(deck, PAGES), null);
assert.equal(buildReferencesSlide(deck, []), null);
});
test("insertion lands before closing and never duplicates", () => {
const deck = deckWith([
{ type: "title", headline: "T" },
{ type: "bullets", headline: "Cells hit 26.1%", bullets: ["Certified cells reach 26.1% efficiency.", "Second point here.", "Third point here.", "Fourth point here."] },
{ type: "closing", headline: "Thanks" },
]);
const slide = buildReferencesSlide(
deck,
[{ url: "https://a.example/x", title: "A source", words: 10, text: "Cells reach 26.1% efficiency." }],
);
assert.ok(slide);
const first = insertReferencesSlide(deck, slide);
assert.equal(first.inserted, true);
assert.equal(first.deck.slides[first.index].type, "references");
assert.equal(first.deck.slides[first.index + 1].type, "closing");
const second = insertReferencesSlide(first.deck, slide);
assert.equal(second.inserted, false);
});
test("the inserted slide validates", async () => {
const deck = deckWith([
{ type: "title", headline: "T" },
{ type: "bullets", headline: "Cells hit 26.1%", bullets: ["Certified cells reach 26.1% efficiency.", "Second point here.", "Third point here.", "Fourth point here."] },
{ type: "closing", headline: "Thanks" },
]);
const slide = buildReferencesSlide(deck, PAGES);
const { deck: next } = insertReferencesSlide(deck, slide);
const v = await validateDeck(next);
assert.equal(v.ok, true, JSON.stringify(v.errors));
});
test("a bare year mentioned once does not link a page", () => {
const slide = { type: "bullets", headline: "2023 review after 9 trials", bullets: ["First point here.", "Second point here.", "Third point here.", "Fourth point here."] };
const pages = [
{ url: "https://a.example/x", title: "Passing mention", words: 10, text: "Published in 2023. Nothing else of note." },
{ url: "https://b.example/y", title: "Both figures", words: 10, text: "Published in 2023, revised after 9 trials." },
];
assert.deepEqual(slideSourceUse(slide, pages), [1]);
});
test("a bare number that only appears as a substring never links", () => {
const slide = { type: "bullets", headline: "25 years of warranty", bullets: ["First point here.", "Second point here.", "Third point here.", "Fourth point here."] };
const pages = [
{ url: "https://a.example/x", title: "Year soup", words: 10, text: "In 2025 and 125 trials nothing was found." },
];
assert.deepEqual(slideSourceUse(slide, pages), [], "25 must not match 2025 or 125");
});
test("tagged pages only link slides of their own part", () => {
const slide = { type: "bullets", section: 0, headline: "Cells hit 26.1%", bullets: ["Certified cells reach 26.1% efficiency.", "Second point here.", "Third point here.", "Fourth point here."] };
const pages = [
{ url: "https://a.example/x", title: "Same part", words: 10, subtopic: 0, text: "Certified cells reach 26.1% efficiency. Confirmed twice." },
{ url: "https://b.example/y", title: "Other part", words: 10, subtopic: 2, text: "Certified cells reach 26.1% efficiency. Confirmed twice." },
{ url: "https://c.example/z", title: "Untagged legacy", words: 10, text: "Certified cells reach 26.1% efficiency. Confirmed twice." },
];
assert.deepEqual(slideSourceUse(slide, pages, 0), [0, 2]);
assert.deepEqual(slideSourceUse(slide, pages, null), [0, 1, 2], "without a section every page is tested");
});