Luigit
repositories / pi-ext

pi-ext

bugabingas pi extensions

owned by admin

extensions/git-safe/__tests__/debug.test.ts

Raw
import { readdirSync, readFileSync } from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { afterEach, describe, expect, it, vi } from "vitest";
import {
	createPiSession,
	type PiSession,
} from "../../../test/fixture/create-pi-session.ts";

const extensionPath = fileURLToPath(new URL("../index.ts", import.meta.url));
let session: PiSession | undefined;

afterEach(async () => {
	await session?.dispose();
	session = undefined;
});

function readRecords(directory: string) {
	return readdirSync(directory).flatMap((file) =>
		readFileSync(path.join(directory, file), "utf8")
			.trim()
			.split("\n")
			.filter(Boolean)
			.map((line) => JSON.parse(line) as { event: string; extension: string }),
	);
}

describe("git-safe debug interface", () => {
	it("writes its lifecycle records in the isolated sandbox", async () => {
		session = await createPiSession({
			env: { PI_GIT_SAFE_DEBUG: "1" },
			extensionPaths: [extensionPath],
		});
		const runner = session.session.extensionRunner;
		await runner.emit({
			type: "session_start",
			reason: "startup",
		});
		await runner.emitToolResult({
			type: "tool_result",
			toolName: "read",
			toolCallId: "missing-read",
			input: { path: path.join(session.cwd, "missing") },
			content: [],
			isError: true,
		} as never);
		await runner.emit({
			type: "session_shutdown",
			reason: "quit",
		});

		if (!session.env["XDG_STATE_HOME"])
			throw new Error("missing sandbox state home");
		const directory = path.join(
			session.env["XDG_STATE_HOME"],
			"pi-ext",
			"debug",
			"git-safe",
		);
		// Debug records flush asynchronously; poll until they appear.
		await vi.waitFor(
			() => {
				const records = readRecords(directory);
				expect(records).toContainEqual(
					expect.objectContaining({
						event: "session.start",
						extension: "git-safe",
					}),
				);
				expect(records).toContainEqual(
					expect.objectContaining({
						event: "session.shutdown",
						extension: "git-safe",
					}),
				);
				expect(records).toContainEqual(
					expect.objectContaining({
						event: "read.spotlight.error",
						type: "readpath",
					}),
				);
			},
			{ timeout: 5_000 },
		);
	});
});