test.web/core/analyzers/diagram.analyzer.test.ts
test.web/core/analyzers/diagram.analyzer.test.ts is a file in Codebase Testing. 77 lines of code and 0 definitions.
import { describe, expect, it } from "vitest";
import { edgeEndsOf, nodeNameOf, walkAttributeOf, walkOrder } from "@banes-lab/web/core/analyzers/diagram.analyzer.ts";
import { readFileSync, readdirSync } from "node:fs";
import { absolutePath } from "@ssot/paths";
import { join } from "node:path";
const NODES = [
"diagram-7-flowchart-write-0",
"diagram-7-flowchart-plant_a_violation-1",
"diagram-7-flowchart-code-2",
"diagram-7-flowchart-orphan-3",
];
const EDGES = ["L_write_plant_a_violation_0", "L_plant_a_violation_code_0"];
const ID_OPEN = 'id="';
const ID_CLOSE = '"';
const DIAGRAM_SAMPLES = 3;
const idsIn = function idsIn(markup: string, head: string): readonly string[] {
const found: string[] = [];
for (let at = markup.indexOf(ID_OPEN + head); at !== -1; at = markup.indexOf(ID_OPEN + head, at + 1)) {
const start = at + ID_OPEN.length;
found.push(markup.slice(start, markup.indexOf(ID_CLOSE, start)));
}
return found;
};
const part = function part(className: string, id: string): Element {
const element = document.createElement("span");
element.className = className;
element.id = id;
return element;
};
describe("nodeNameOf and edgeEndsOf", () => {
it("reads a node's name between the flowchart mark and its counter", () => {
expect(nodeNameOf("diagram-7-flowchart-plant_a_violation-1")).toBe("plant_a_violation");
expect(nodeNameOf("not-a-node")).toBeNull();
});
it("splits an edge only where both halves name real nodes, even when names hold underscores", () => {
const names = new Set(["write", "plant_a_violation", "code"]);
expect(edgeEndsOf("L_write_plant_a_violation_0", names)).toStrictEqual(["write", "plant_a_violation"]);
expect(edgeEndsOf("L_write_nowhere_0", names)).toBeNull();
expect(edgeEndsOf("path-1", names)).toBeNull();
});
});
describe("walkOrder", () => {
it("walks each edge between its two nodes in declaration order and visits isolated nodes last", () => {
expect(walkOrder(NODES, EDGES).map((step) => step.id)).toStrictEqual([
"diagram-7-flowchart-write-0",
"L_write_plant_a_violation_0",
"diagram-7-flowchart-plant_a_violation-1",
"L_plant_a_violation_code_0",
"diagram-7-flowchart-code-2",
"diagram-7-flowchart-orphan-3",
]);
});
it("writes the walk of a rendered vector as its node and edge ids in walk order", () => {
const vector = document.createElement("div");
vector.append(
part("node", "diagram-7-flowchart-write-0"),
part("node", "diagram-7-flowchart-code-1"),
part("flowchart-link", "L_write_code_0"),
);
expect(walkAttributeOf(vector)).toBe("diagram-7-flowchart-write-0 L_write_code_0 diagram-7-flowchart-code-1");
});
it("walks the site's own rendered diagrams, edge ids included, without inventing an edge", () => {
const folder = absolutePath("app.diagrams");
const files = readdirSync(folder)
.filter((name) => name.endsWith(".svg"))
.slice(0, DIAGRAM_SAMPLES);
expect(files).toHaveLength(DIAGRAM_SAMPLES);
for (const file of files) {
const markup = readFileSync(join(folder, file), "utf8");
const nodes = idsIn(markup, "").filter((id) => nodeNameOf(id) !== null);
const edges = idsIn(markup, "L_");
const walked = walkOrder(nodes, edges).filter((step) => step.kind === "edge");
expect(walked.length).toBeLessThanOrEqual(edges.length);
expect(walked.length > 0 || edges.length === 0).toBe(true);
}
});
});