repositories / pi-ext
pi-ext
bugabingas pi extensions
owned by admin
extensions/runtime/__tests__/contract.test.ts
Rawimport { 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"]),
);
});
});