Follow-up to the merged #166/#169. Addresses the second review pass (comment 1227): - footnoteWarnings plumbing: extract a single `footnoteWarningsField(markdown)` helper (footnote-analyze) and use it at all three call sites (create_page, update_page, import_page_markdown) so the field is attached identically. - New unit test footnote-warnings-import.test.mjs pins the contract that was uncovered: the field is present on problems / omitted on clean input, and the IMPORT path analyzes the BODY after the docmost:meta / docmost:comments blocks (a footnote-like token inside those JSON blocks must NOT warn; a real body marker must). Tested via the same pure composition the importer uses (footnoteWarningsField(parseDocmostMarkdown(full).body)) — no collab socket needed; a regression that analyzed fullMarkdown or skipped the body split would now go red. - footnote.marked.ts: correct the stale module header — it claimed "only definitions that have a matching reference are emitted", which was never true (orphan defs are emitted; the editor sync plugin reconciles). Now describes first-wins + reuse + sync reconciliation. - derive-id golden test: rename the describe from "(cross-package drift guard)" to "(deterministic-scheme pin)" — there is no second package to drift against. editor-ext 129, MCP 304 (+3), client+server tsc clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
64 lines
2.6 KiB
JavaScript
64 lines
2.6 KiB
JavaScript
import { test } from "node:test";
|
|
import assert from "node:assert/strict";
|
|
|
|
import {
|
|
analyzeFootnotes,
|
|
footnoteWarningsField,
|
|
} from "../../build/lib/footnote-analyze.js";
|
|
import {
|
|
serializeDocmostMarkdown,
|
|
parseDocmostMarkdown,
|
|
} from "../../build/lib/markdown-document.js";
|
|
|
|
// Pins the footnoteWarnings PLUMBING contract (#169 review): the field is
|
|
// present only on problems and omitted on clean input, AND `import_page_markdown`
|
|
// analyzes the BODY (after the docmost:meta / docmost:comments blocks) — so a
|
|
// footnote-like token inside those JSON blocks never warns, while a real marker
|
|
// in the body does. importPageMarkdown does exactly
|
|
// `footnoteWarningsField(parseDocmostMarkdown(full).body)` over a collab socket
|
|
// this harness does not stand up, so we test the same pure composition directly.
|
|
|
|
test("footnoteWarningsField is present on problems and omitted on clean input", () => {
|
|
const problem = footnoteWarningsField("See[^missing].\n\n[^a]: defined");
|
|
assert.ok(Array.isArray(problem.footnoteWarnings));
|
|
assert.match(problem.footnoteWarnings.join("\n"), /no matching definition/);
|
|
|
|
const clean = footnoteWarningsField("A[^a] and reuse[^a].\n\n[^a]: fine");
|
|
assert.deepEqual(clean, {}); // no key at all on clean input
|
|
});
|
|
|
|
test("import analyzes the BODY only — tokens inside meta/comments never warn", () => {
|
|
// meta + comments JSON carry `[^metaonly]` / `[^commentonly]`-looking text; the
|
|
// BODY has a genuinely dangling `[^bodyref]`.
|
|
const full = serializeDocmostMarkdown(
|
|
{ pageId: "p1", note: "front-matter mentions [^metaonly] in text" },
|
|
"Body with a dangling[^bodyref] marker.",
|
|
[{ id: "c1", content: "a comment that says [^commentonly]" }],
|
|
);
|
|
|
|
const { body } = parseDocmostMarkdown(full);
|
|
// Sanity: the meta/comments markers are NOT in the parsed body.
|
|
assert.ok(!body.includes("[^metaonly]"));
|
|
assert.ok(!body.includes("[^commentonly]"));
|
|
|
|
const field = footnoteWarningsField(body);
|
|
const joined = (field.footnoteWarnings ?? []).join("\n");
|
|
// ONLY the body's dangling reference is flagged.
|
|
assert.match(joined, /\[\^bodyref\]/);
|
|
assert.ok(!joined.includes("metaonly"));
|
|
assert.ok(!joined.includes("commentonly"));
|
|
|
|
// Cross-check against analyzeFootnotes directly (same composition the importer uses).
|
|
assert.deepEqual(analyzeFootnotes(body).danglingReferences, ["bodyref"]);
|
|
});
|
|
|
|
test("import on a clean body yields no footnoteWarnings field", () => {
|
|
const full = serializeDocmostMarkdown(
|
|
{ pageId: "p1" },
|
|
"Clean body[^a] reusing[^a].\n\n[^a]: ok",
|
|
[],
|
|
);
|
|
const { body } = parseDocmostMarkdown(full);
|
|
assert.deepEqual(footnoteWarningsField(body), {});
|
|
});
|