Luigit
repositories / dotfiles

dotfiles

bugabingas dorkfiles

owned by admin

pi/agent/skills/optional/ascii-boxes/index.test.mjs

Raw
import assert from "node:assert/strict";
import { describe, test } from "node:test";

function expect(actual) {
	return {
		toBe(expected) { assert.equal(actual, expected); },
		toContain(expected) { assert.ok(actual.includes(expected)); },
		not: { toContain(expected) { assert.ok(!actual.includes(expected)); } },
		toBeGreaterThan(expected) { assert.ok(actual > expected); },
		toBeGreaterThanOrEqual(expected) { assert.ok(actual >= expected); },
		toBeLessThan(expected) { assert.ok(actual < expected); },
		toBeLessThanOrEqual(expected) { assert.ok(actual <= expected); },
	};
}
import { createTable, drawBox, drawNested } from "./index.mjs";

describe("drawBox", () => {
	test("simple box with content", () => {
		const result = drawBox("Hello", { width: 10 });
		const lines = result.split("\n");
		expect(lines.length).toBe(3);
		expect(lines[0]).toContain("┌");
		expect(lines[0]).toContain("┐");
		expect(lines[1]).toContain("│");
		expect(lines[2]).toContain("└");
		expect(lines[2]).toContain("┘");
	});

	test("content alignment left", () => {
		const result = drawBox("Test", { width: 20, alignment: "left" });
		const lines = result.split("\n");
		const contentLine = lines[1];
		const testIndex = contentLine.indexOf("Test");
		const pipeIndex = contentLine.indexOf("│");
		expect(contentLine[pipeIndex]).toBe("│");
		expect(testIndex).toBe(pipeIndex + 2);
	});

	test("content alignment center", () => {
		const result = drawBox("Hi", { width: 20, alignment: "center" });
		const lines = result.split("\n");
		expect(lines[1][0]).toBe("│");
	});

	test("content alignment right", () => {
		const result = drawBox("X", { width: 10, alignment: "right" });
		const lines = result.split("\n");
		const contentLine = lines[1];
		const rightPipeIndex = contentLine.lastIndexOf("│");
		expect(contentLine[rightPipeIndex]).toBe("│");
	});

	test("double border style", () => {
		const result = drawBox("Test", { style: "double" });
		expect(result).toContain("╔");
		expect(result).toContain("╗");
		expect(result).toContain("╚");
		expect(result).toContain("╝");
		expect(result).toContain("║");
		expect(result).toContain("═");
		expect(result).not.toContain("┌");
		expect(result).not.toContain("│");
	});

	test("bold border style", () => {
		const result = drawBox("Test", { style: "bold" });
		expect(result).toContain("┏");
		expect(result).toContain("┓");
		expect(result).toContain("┗");
		expect(result).toContain("┛");
		expect(result).toContain("┃");
		expect(result).toContain("━");
	});

	test("padding", () => {
		const result = drawBox("X", {
			width: 10,
			paddingTop: 2,
			paddingBottom: 2,
			paddingLeft: 2,
			paddingRight: 2,
		});
		const lines = result.split("\n");
		expect(lines.length).toBe(7);
		expect(lines[0]).toContain("┌");
		expect(lines[6]).toContain("┘");
		expect(lines[1]).toContain("│");
		expect(lines[2]).toContain("│");
		expect(lines[3]).toContain("X");
		expect(lines[4]).toContain("│");
	});

	test("multi-line content", () => {
		const result = drawBox(["Line 1", "Line 2", "Line 3"], { width: 20 });
		const lines = result.split("\n");
		expect(lines.length).toBe(5);
		expect(result).toContain("Line 1");
		expect(result).toContain("Line 2");
		expect(result).toContain("Line 3");
	});

	test("wrap long text", () => {
		const result = drawBox("This is a very long sentence that needs wrapping", {
			width: 20,
		});
		const lines = result.split("\n");
		expect(lines.length).toBeGreaterThan(3);
	});

	test("array content", () => {
		const lines = ["Line 1", "Line 2", "Line 3"];
		const result = drawBox(lines, { width: 20 });
		expect(result).toContain("Line 1");
		expect(result).toContain("Line 2");
		expect(result).toContain("Line 3");
		expect(result.split("\n").length).toBe(5);
	});

	test("alignment right with padding", () => {
		const result = drawBox("X", {
			width: 10,
			alignment: "right",
			paddingLeft: 2,
			paddingRight: 2,
		});
		const lines = result.split("\n");
		const contentLine = lines[1];
		const xIdx = contentLine.indexOf("X");
		const rightPipe = contentLine.lastIndexOf("│");
		const leftPipe = contentLine.indexOf("│");
		expect(xIdx).toBeLessThan(rightPipe);
		expect(xIdx).toBeGreaterThan(leftPipe);
	});

	test("single character wide", () => {
		const result = drawBox("X", { width: 1 });
		expect(result).toContain("┌───┐");
		expect(result).toContain("│ X │");
		expect(result).toContain("└───┘");
	});

	test("zero padding", () => {
		const result = drawBox("AB", {
			width: 4,
			paddingTop: 0,
			paddingBottom: 0,
			paddingLeft: 0,
			paddingRight: 0,
		});
		const lines = result.split("\n");
		expect(lines.length).toBe(3);
		expect(lines[0]).toContain("┌────┐");
		expect(lines[1]).toContain("│AB  │");
		expect(lines[2]).toContain("└────┘");
	});

	test("long text forces wrap", () => {
		const result = drawBox("This is a very long line of text", { width: 10 });
		const lines = result.split("\n");
		expect(lines.length).toBeGreaterThan(3);
		const contentLines = lines.slice(1, -1);
		for (const cl of contentLines) {
			const firstPipe = cl.indexOf("│");
			const lastPipe = cl.lastIndexOf("│");
			const betweenPipes = cl.slice(firstPipe + 1, lastPipe);
			expect(betweenPipes.length).toBeLessThanOrEqual(12);
		}
	});
});

describe("createTable", () => {
	test("simple table", () => {
		const result = createTable(
			["Name", "Age"],
			[
				["Alice", "30"],
				["Bob", "25"],
			],
		);
		expect(result).toContain("Name");
		expect(result).toContain("Age");
		expect(result).toContain("Alice");
		expect(result).toContain("Bob");
		expect(result).toContain("┌");
		expect(result).toContain("┐");
		expect(result).toContain("└");
		expect(result).toContain("┘");
	});

	test("separator line uses tee", () => {
		const result = createTable(["H1", "H2"], [["a", "b"]]);
		const lines = result.split("\n");
		expect(lines[2]).toContain("├");
		expect(lines[2]).toContain("┤");
		expect(lines[2]).toContain("┼");
	});

	test("double style", () => {
		const result = createTable(["H"], [["d"]], { style: "double" });
		expect(result).toContain("╔");
		expect(result).toContain("╗");
		expect(result).toContain("╠");
		expect(result).toContain("╣");
		expect(result).toContain("║");
		expect(result).toContain("═");
	});

	test("padding", () => {
		const result = createTable(["Name"], [["Alice"]], { padding: 3 });
		expect(result).toContain("│   Name");
		expect(result).toContain("│   Alice");
	});

	test("empty rows", () => {
		const result = createTable(["A", "B"], [], { style: "single" });
		expect(result).toContain("A");
		expect(result).toContain("B");
		expect(result).toContain("├");
		expect(result).toContain("┤");
	});

	test("single column", () => {
		const result = createTable(["Name"], [["Alice"], ["Bob"]]);
		expect(result).toContain("Name");
		expect(result).toContain("Alice");
		expect(result).toContain("Bob");
	});
});

describe("drawNested", () => {
	test("nested boxes", () => {
		const result = drawNested("Outer", "Inner");
		expect(result).toContain("Outer");
		expect(result).toContain("Inner");
		expect((result.match(/┌/g) || []).length).toBe(2);
	});

	test("with gap", () => {
		const result = drawNested("O", "I", { gap: 2 });
		expect(result).toContain("O");
		expect(result).toContain("I");
		const innerLine = result.split("\n").findIndex((l) => l.includes("I"));
		const outerLine = result.split("\n").findIndex((l) => l.includes("O"));
		expect(Math.abs(innerLine - outerLine)).toBeGreaterThan(2);
	});

	test("zero width content", () => {
		const result = drawNested("", "", { gap: 0 });
		expect(result).toContain("┌");
		expect(result).toContain("└");
	});

	test("different styles", () => {
		const result = drawNested("O", "I", {
			styleOuter: "double",
			styleInner: "bold",
			gap: 0,
		});
		expect(result.includes("╔") || result.includes("╗")).toBe(true);
		expect(result.includes("┏") || result.includes("┓")).toBe(true);
	});

	test("gap creates space", () => {
		const r1 = drawNested("O", "I", { gap: 0 });
		const r2 = drawNested("O", "I", { gap: 2 });
		expect(r2.split("\n").length).toBeGreaterThanOrEqual(
			r1.split("\n").length + 2,
		);
	});
});

describe("border styles", () => {
	test("are consistent", () => {
		const single = drawBox("T", { style: "single" });
		const double = drawBox("T", { style: "double" });
		const bold = drawBox("T", { style: "bold" });
		expect(
			single.includes("┌") && single.includes("─") && single.includes("│"),
		).toBe(true);
		expect(
			double.includes("╔") && double.includes("═") && double.includes("║"),
		).toBe(true);
		expect(bold.includes("┏") && bold.includes("━") && bold.includes("┃")).toBe(
			true,
		);
		expect(single).not.toContain("╔");
		expect(double).not.toContain("┌");
	});
});

describe("demo - system status panel", () => {
	test("renders without errors", () => {
		const box = drawBox(" System Status ", {
			style: "bold",
			width: 30,
			alignment: "center",
			paddingTop: 1,
			paddingBottom: 1,
		});
		const table = createTable(
			["Module", "Status"],
			[
				["Agent Core", "✅"],
				["Memory", "45%"],
				["Cache", "OK"],
			],
			{ padding: 2 },
		);
		expect(box.length).toBeGreaterThan(0);
		expect(table.length).toBeGreaterThan(0);
		expect(box).toContain("┏");
		expect(box).toContain("┛");
	});
});