Luigit
repositories / dotfiles

dotfiles

bugabingas dorkfiles

owned by admin

pi/agent/skills/mermaid/scripts/validate-pi.test.mjs

Raw
import assert from "node:assert/strict";
import { spawnSync } from "node:child_process";
import { mkdtempSync, readdirSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { fileURLToPath } from "node:url";
import { describe, test } from "node:test";

const script = fileURLToPath(new URL("./validate-pi.mjs", import.meta.url));
const installedPackage = process.env.PI_CONTEXT_PACKAGE_JSON_PATH;
const examples = {
	A: 'flowchart TD\n A["Agent"] --> B["Review"]',
	B: 'sequenceDiagram\n participant H as You\n participant A as Agent\n H->>A: Task\n A-->>H: Patch',
	C: 'flowchart LR\n A["Prepare environment"] --> B["Run agent assignment"] --> C["Collect test evidence"] --> D["Review proposed changes"] --> E["Integrate accepted revision"]',
	D: 'gantt\n title Agent work\n dateFormat YYYY-MM-DD\n section Work\n Review :2026-01-01, 1d',
	E: 'flowchart TD\n A[Start --> B',
};

function invoke(source = examples.A, args = ["--width", "48"], options = {}) {
	const result = spawnSync(process.execPath, [script, ...args], {
		input: source,
		encoding: "utf8",
		timeout: 10_000,
		...options,
	});
	assert.ifError(result.error);
	assert.equal(result.signal, null);
	return result;
}

function withoutPi() {
	const env = { ...process.env };
	delete env.PI_CONTEXT_PACKAGE_JSON_PATH;
	return env;
}

test("help requires neither Pi nor source", () => {
	const result = invoke("", ["--help"], { env: withoutPi() });
	assert.equal(result.status, 0);
	assert.match(result.stdout, /--width/);
});

test("requires explicit positive integer width; rejects file arguments", () => {
	for (const args of [[], ["--width", "0"], ["--width", "-1"], ["--width", "1.5"], ["--width", "abc"], ["--width", "9007199254740992"], ["--width", "48", "diagram.mmd"]]) {
		const result = invoke("", args, { env: withoutPi() });
		assert.equal(result.status, 2);
		assert.match(result.stderr, /Usage:/);
	}
});

test("missing Pi context fails explicitly without fallback", () => {
	const result = invoke(examples.A, undefined, { env: withoutPi() });
	assert.equal(result.status, 2);
	assert.match(result.stderr, /PI_CONTEXT_PACKAGE_JSON_PATH/);
});

test("relative Pi package path is rejected", () => {
	const result = invoke(examples.A, undefined, { env: { ...withoutPi(), PI_CONTEXT_PACKAGE_JSON_PATH: "package.json" } });
	assert.equal(result.status, 2);
	assert.match(result.stderr, /absolute path/);
});

test("missing Pi renderer fails without installing dependencies", () => {
	const root = mkdtempSync(join(tmpdir(), "mermaid-pi-missing-"));
	try {
		const manifest = join(root, "package.json");
		writeFileSync(manifest, "{}");
		const result = invoke(examples.A, undefined, { cwd: root, env: { ...withoutPi(), PI_CONTEXT_PACKAGE_JSON_PATH: manifest } });
		assert.equal(result.status, 2);
		assert.match(result.stderr, /Cannot load Pi's installed grok-mermaid/);
		assert.deepEqual(readdirSync(root), ["package.json"]);
	} finally {
		rmSync(root, { recursive: true, force: true });
	}
});

describe("installed Pi renderer", { skip: !installedPackage && "PI_CONTEXT_PACKAGE_JSON_PATH is needed for renderer integration tests" }, () => {
	for (const name of ["A", "B"]) {
		test(`${name}: narrow diagram passes with preview`, () => {
			const result = invoke(examples[name]);
			assert.equal(result.status, 0, result.stderr);
			const report = JSON.parse(result.stdout);
			assert.equal(report.ok, true);
			assert.deepEqual(report.warnings, []);
			assert.equal(report.overflow, false);
			assert.ok(report.lines.length > 0);
		});
	}
	test("C: wide diagram fails width budget", () => {
		const result = invoke(examples.C);
		assert.equal(result.status, 1, result.stderr);
		const report = JSON.parse(result.stdout);
		assert.equal(report.ok, false);
		assert.equal(report.overflow, true);
		assert.ok(report.requiredColumns > 48);
	});
	test("D: unsupported diagram fails", () => {
		const result = invoke(examples.D);
		assert.equal(result.status, 1, result.stderr);
		assert.equal(JSON.parse(result.stdout).requiredColumns, null);
	});
	test("E: warnings fail even when the partial drawing fits", () => {
		const result = invoke(examples.E);
		assert.equal(result.status, 1, result.stderr);
		const report = JSON.parse(result.stdout);
		assert.equal(report.ok, false);
		assert.equal(report.overflow, false);
		assert.ok(report.warnings.length > 0);
	});
	test("empty stdin fails", () => {
		const result = invoke("");
		assert.equal(result.status, 1, result.stderr);
		assert.equal(JSON.parse(result.stdout).ok, false);
	});
	test("exact width fits; one column less fails", () => {
		const width = JSON.parse(invoke().stdout).requiredColumns;
		assert.equal(invoke(examples.A, ["--width", String(width)]).status, 0);
		assert.equal(invoke(examples.A, ["--width", String(width - 1)]).status, 1);
	});
	test("stdin validation from a Unicode/space cwd creates no files", () => {
		const root = mkdtempSync(join(tmpdir(), "mermaid pi #é-"));
		try {
			const result = invoke(examples.A, undefined, { cwd: root });
			assert.equal(result.status, 0, result.stderr);
			assert.deepEqual(readdirSync(root), []);
		} finally {
			rmSync(root, { recursive: true, force: true });
		}
	});
});