Luigit
repositories / pi-ext

pi-ext

bugabingas pi extensions

owned by admin

extensions/runtime/__tests__/contract.test.ts

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

let session: PiSession | undefined;

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

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

describe("runtime contract", () => {
	it("loads through the owned fixture", async () => {
		const extensionPath = runtimePath();
		session = await createPiSession({ extensionPaths: [extensionPath] });

		expect(session.errors).toEqual([]);
		expect(session.extensions).toHaveLength(1);
		expect(session.extensions[0]!.path).toBe(extensionPath);
	});

	it("writes its opt-in lifecycle trace inside the sandbox", async () => {
		session = await createPiSession({
			extensionPaths: [runtimePath()],
			env: { PI_RUNTIME_DEBUG: "1" },
		});
		const runner = session.session.extensionRunner;
		await runner.emit({ type: "session_start", reason: "startup" });
		await runner.emit({ type: "session_shutdown", reason: "quit" });

		const stateHome = session.env["XDG_STATE_HOME"];
		if (!stateHome) throw new Error("missing sandbox state home");
		const directory = path.join(stateHome, "pi-ext", "debug", "runtime");
		const [file] = readdirSync(directory);
		if (!file) throw new Error("missing debug trace file");
		const events = readFileSync(path.join(directory, file), "utf8")
			.trim()
			.split("\n")
			.map((line) => JSON.parse(line).event);
		expect(events).toEqual(
			expect.arrayContaining(["session.start", "session.shutdown"]),
		);
	});
});