test.build/core/converters/graph.link.converter.test.ts
test.build/core/converters/graph.link.converter.test.ts is a file in Codebase Testing. 86 lines of code and 0 definitions.
import type { Evidence, EvidenceNode } from "@banes-lab/web/types/evidence.types.ts";
import { describe, expect, it } from "vitest";
import { evidenceEdges, linkEdges, routeEdges } from "@banes-lab/build-scripts/core/converters/graph.link.converter.ts";
import type { Discovery } from "@banes-lab/build-scripts/types/site.types.ts";
import type { ReferenceTarget } from "@banes-lab/web/types/reference.types.ts";
import { createLinker } from "@banes-lab/build-scripts/core/resolvers/link.resolver.ts";
import { sectionPlans } from "@banes-lab/build-scripts/core/converters/section.converter.ts";
import { unresolvedEvidence } from "@banes-lab/build-scripts/configuration/strings/graph.strings.ts";
const SITE = "https://example.test";
const LOOP = "chapter:/method#loop";
const GATE = "chapter:/method/build#gate";
const METHOD = {
content: {
kind: "tabbed",
tabs: [
{ id: "start", label: "Start", sections: [{ id: "loop", title: "The loop" }] },
{
id: "build",
label: "Build",
sections: [{ id: "gate", intro: "See [the loop](/method#loop).", title: "The gate" }],
},
],
},
description: "The method.",
id: "method",
label: "Method",
markdown: "",
page: "method",
path: "/method",
tab: null,
title: "Method",
};
const DISCOVERY: Discovery = {
author: "Ada",
consent: "Yes.",
name: "Site",
pages: [METHOD],
routes: [METHOD, { ...METHOD, label: "Build", path: "/method/build", tab: "build" }],
site: SITE,
summary: "A site.",
};
const plans = sectionPlans(DISCOVERY, () => null);
const linker = createLinker(
plans.map((plan) => plan.identity),
SITE,
(href) => href,
);
describe("linkEdges", () => {
it("draws a links-to edge from each section to every section its prose links", () => {
const edges = linkEdges({ linker, plans });
expect(edges.map((edge) => [edge.from, edge.to])).toStrictEqual([[GATE, LOOP]]);
});
});
const TERM = "lexicon:term";
const FOUND: EvidenceNode = { kind: "file", name: "found.ts" };
const LOST: EvidenceNode = { kind: "file", name: "lost.ts" };
const webOf = function webOf(nodes: readonly EvidenceNode[]): Parameters<typeof evidenceEdges>[0] {
const entry: Evidence = { nodes, subject: { kind: "record", ref: TERM } };
return {
evidence: { evidenceFor: (target: ReferenceTarget) => (target.ref === TERM ? [entry] : []) },
evidenceConstants: { EVIDENCE: [entry] },
};
};
const targetOf = function targetOf(node: EvidenceNode): string | null {
return node === FOUND ? "anatomy:found" : null;
};
describe("evidenceEdges", () => {
it("draws an evidence edge from each subject to every node the resolver finds", () => {
const edges = evidenceEdges(webOf([FOUND]), targetOf, [TERM, "lexicon:other"]);
expect(edges.map((edge) => [edge.from, edge.to])).toStrictEqual([[TERM, "anatomy:found"]]);
});
it("fails on a declared node the resolver no longer finds, so an evidence edge is never lost silently", () => {
expect(() => evidenceEdges(webOf([FOUND, LOST]), targetOf, [TERM])).toThrow(unresolvedEvidence(TERM, LOST));
});
});
describe("routeEdges", () => {
it("draws a builds-on edge for each prerequisite a stop names and reports one that names no stop", () => {
const stops = [
{ block: "b", code: "aa", id: "s1", label: "One", path: "/p#one", position: 1, requires: [] },
{ block: "b", code: "aa", id: "s2", label: "Two", path: "/p#two", position: 2, requires: ["s1", "gone"] },
];
const { edges, unresolved } = routeEdges(stops);
expect(edges.map((edge) => [edge.from, edge.to])).toStrictEqual([["chapter:/p#two", "chapter:/p#one"]]);
expect(unresolved.map((entry) => entry.label)).toStrictEqual(["gone"]);
});
});