Luigit
repositories / pi-ext

pi-ext

bugabingas pi extensions

owned by admin

extensions/good-job/__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";

function extensionPath(): string {
	return fileURLToPath(new URL("../index.ts", import.meta.url));
}

async function eventually<T>(
	read: () => T,
	accept: (value: T) => boolean,
): Promise<T> {
	const deadline = Date.now() + 3_000;
	let value = read();
	while (!accept(value) && Date.now() < deadline) {
		await new Promise((resolve) => setTimeout(resolve, 20));
		value = read();
	}
	return value;
}

describe("good-job debug harness", () => {
	let session: PiSession | undefined;
	afterEach(async () => {
		await session?.dispose();
		session = undefined;
		vi.restoreAllMocks();
	});

	it("writes its lifecycle records in the isolated sandbox", async () => {
		session = await createPiSession({
			env: { PI_GOOD_JOB_DEBUG: "1" },
			extensionPaths: [extensionPath()],
		});
		await session.session.extensionRunner.emit({
			type: "session_start",
			reason: "startup",
		});
		await session.session.extensionRunner.emit({
			type: "session_shutdown",
			reason: "quit",
		});

		const directory = path.join(
			session.env["XDG_STATE_HOME"] ?? "",
			"pi-ext",
			"debug",
			"good-job",
		);
		const readRecords = () =>
			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 },
					),
			);
		const records = await eventually(
			readRecords,
			(value) =>
				value.some((record) => record.event === "session.start") &&
				value.some((record) => record.event === "session.shutdown"),
		);
		expect(records).toContainEqual(
			expect.objectContaining({
				event: "session.start",
				extension: "good-job",
			}),
		);
		expect(records).toContainEqual(
			expect.objectContaining({
				event: "session.shutdown",
				extension: "good-job",
			}),
		);
	});
});