"use strict"; const test = require("node:test"); const assert = require("node:assert/strict"); const { generateMarkdown, derivedDocument, relationLines } = require("../static/js/cmap-export.js"); function map(slug, title, document) { return { slug, title, document }; } const root = map("root", "Root map", { schemaVersion: 2, metadata: { tags: ["architecture", "report"], summary: "Summary of the root map.", explanationPageSlug: "cmap:root-explanation" }, concepts: [ { id: "concept-a", label: "Decision", synopsis: "Choose the approach.", aspects: ["governance"], pageSlug: "decisions:approach", descriptionPageSlug: "cmap:decision", cmapSlug: "child", externalUrl: "https://example.com/decision", tags: [{ type: "person", value: "Alex Morgan" }, { type: "person", value: "Sam de Vries" }] }, { id: "concept-b", label: "Delivery" } ], items: [ { id: 1, conceptId: "concept-a", kind: "concept" }, { id: 2, kind: "phrase", label: "enables" }, { id: 3, conceptId: "concept-b", kind: "concept" } ], connectors: [ { id: 1, sourceId: 1, targetId: 2, hasArrow: false }, { id: 2, sourceId: 2, targetId: 3, hasArrow: true } ] }); const child = map("child", "Child map", { schemaVersion: 2, metadata: { tags: ["detail"], summary: "Child summary." }, concepts: [{ id: "concept-c", label: "Child concept", cmapSlug: "root" }], items: [{ id: 1, conceptId: "concept-c", kind: "concept" }], connectors: [] }); const pages = new Map([ ["cmap:root-explanation", { slug: "cmap:root-explanation", title: "Root explanation", tags: ["explanation"], markdown: "# Why\n\nBecause." }], ["decisions:approach", { slug: "decisions:approach", title: "Approach", tags: ["decision"], markdown: "# Decision\n\nUse the simple option." }], ["cmap:decision", { slug: "cmap:decision", title: "Decision explanation", tags: [], markdown: "Details." }] ]); test("exports metadata, person tags, relations and linked maps to the selected depth", async () => { const markdown = await generateMarkdown({ rootMap: root, maxDepth: 1, includeWikiPages: false, language: "nl", loadConceptMap: async (slug) => ({ root, child }[slug]), loadWikiPage: async (slug) => pages.get(slug) }); assert.match(markdown, /CMap: Root map \(niveau 0\)/); assert.match(markdown, /CMap: Child map \(niveau 1\)/); assert.match(markdown, /`architecture`, `report`/); assert.match(markdown, /Personen \(verantwoordelijkheid\/actie\):\*\* Alex Morgan, Sam de Vries/); assert.match(markdown, /Decision — \*\*enables\*\* → Delivery/); assert.match(markdown, /### CMap-uitleg/); assert.match(markdown, /Webpagina:\*\* https:\/\/example\.com\/decision/); assert.doesNotMatch(markdown, /## Gekoppelde wikipagina's/); assert.equal((markdown.match(/## CMap: Root map/g) || []).length, 1, "cycles are exported once"); }); test("depth zero exports only the selected map", async () => { const markdown = await generateMarkdown({ rootMap: root, maxDepth: 0, includeWikiPages: false, loadConceptMap: async (slug) => ({ root, child }[slug]), loadWikiPage: async (slug) => pages.get(slug) }); assert.match(markdown, /Root map/); assert.doesNotMatch(markdown, /## CMap: Child map/); }); test("optionally appends linked wiki pages and concept explanations", async () => { const markdown = await generateMarkdown({ rootMap: root, maxDepth: 0, includeWikiPages: true, language: "en", loadConceptMap: async (slug) => ({ root, child }[slug]), loadWikiPage: async (slug) => pages.get(slug) }); assert.match(markdown, /## Linked wiki pages/); assert.match(markdown, /### Approach/); assert.match(markdown, /### Decision explanation/); assert.equal((markdown.match(/Root explanation/g) || []).length, 0, "the explanation page is embedded under the CMap rather than duplicated as an appendix heading"); assert.match(markdown, /Because\./); }); test("derived views contain their root subtree and inherit useful root metadata", () => { const source = { schemaVersion: 2, concepts: [ { id: "root-concept", label: "Team", synopsis: "Team scope", aspects: ["people"], descriptionPageSlug: "cmap:team" }, { id: "child-concept", label: "Work" }, { id: "outside-concept", label: "Outside" } ], items: [ { id: 10, conceptId: "root-concept", kind: "submap" }, { id: 11, conceptId: "child-concept", kind: "concept", parentSubmapId: 10 }, { id: 12, conceptId: "outside-concept", kind: "concept" } ], connectors: [ { id: 1, sourceId: 10, targetId: 11 }, { id: 2, sourceId: 11, targetId: 12 } ] }; const result = derivedDocument(source, { derivedView: { sourceCmapSlug: "source", rootItemId: 10 } }); assert.deepEqual(result.items.map((item) => item.id), [10, 11]); assert.deepEqual(result.connectors.map((connector) => connector.id), [1]); assert.deepEqual(result.metadata.tags, ["people"]); assert.equal(result.metadata.summary, "Team scope"); assert.equal(result.metadata.explanationPageSlug, "cmap:team"); }); test("direct and phrase relations receive readable Markdown", () => { const documentValue = { items: [ { id: 1, label: "A" }, { id: 2, kind: "phrase", label: "supports" }, { id: 3, label: "B" }, { id: 4, label: "C" } ], connectors: [ { sourceId: 1, targetId: 2, hasArrow: false }, { sourceId: 2, targetId: 3, hasArrow: true }, { sourceId: 3, targetId: 4, hasArrow: true } ] }; assert.deepEqual(relationLines(documentValue), ["A — **supports** → B", "B → C"]); });