import { readdirSync, readFileSync } from "node:fs"; import path from "node:path"; import { afterEach, describe, expect, it } from "vitest"; import { createTestSession, type TestSession } from "../../../test/harness"; import usageExtension from "../index"; describe("usage pi-test-harness", () => { let t: TestSession | undefined; afterEach(() => { t?.dispose(); t = undefined; }); it("loads in real Pi extension runtime", async () => { t = await createTestSession({ extensionFactories: [usageExtension] }); expect(t.session.extensionRunner.extensions).toHaveLength(1); }); it("writes debug lifecycle records in its sandbox when enabled", async () => { const extensionPath = path.resolve(import.meta.dirname, "../index.ts"); t = await createTestSession({ env: { PI_USAGE_DEBUG: "1" }, extensions: [extensionPath], }); const extension = t.session.extensionRunner.extensions[0]; const context = t.session.extensionRunner.createCommandContext(); for (const handler of extension.handlers.get("session_start")) await handler({ type: "session_start" }, context); for (const handler of extension.handlers.get("session_shutdown")) await handler({ type: "session_shutdown" }, context); const directory = path.join( t.cwd, ".test-state", "pi-ext", "debug", "usage", ); const records = readFileSync( path.join(directory, readdirSync(directory)[0]), "utf8", ) .trim() .split("\n") .map((line) => JSON.parse(line)); expect(records.map((record) => record.event)).toEqual( expect.arrayContaining(["session.start", "session.shutdown"]), ); }); it("loads the dashboard implementation on first command use", async () => { t = await createTestSession({ extensionFactories: [usageExtension] }); const command = t.session.extensionRunner.extensions[0].commands.get("usage"); await expect(command.handler("", { hasUI: false } as never)).resolves.toBe( undefined, ); }); });