# test.web/core/analyzers/diagram.analyzer.test.ts

> 77 lines of code and 0 definitions.

Tree: Codebase Testing
Language: typescript
Canonical: https://banes-lab.com/anatomy/testing#file-testing-test-web-core-analyzers-diagram-analyzer-test-ts
Source text: https://banes-lab.com/source/testing/test.web/core/analyzers/diagram.analyzer.test.ts.txt

Listed in [test.web/core/analyzers](https://banes-lab.com/api/source/testing/test.web/core/analyzers.md), before [test.web/core/analyzers/search.analyzer.test.ts](https://banes-lab.com/source/testing/test.web/core/analyzers/search.analyzer.test.ts.md).

## Contained in

- [test.web/core/analyzers](https://banes-lab.com/anatomy/testing/folder-testing-test-web-core-analyzers.md)

## Source

```typescript
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);
        }
    });
});
```
