import { mkdtempSync, readdirSync, readFileSync, rmSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { afterEach, describe, expect, it, vi } from "vitest"; import { createTestSession, type TestSession } from "../../../test/harness"; import nuBangExtension from "../index"; describe("nu-bang pi-test-harness", () => { let t: TestSession | undefined; afterEach(() => { t?.dispose(); t = undefined; }); it("writes enabled lifecycle debug records in an isolated sandbox", async () => { const root = mkdtempSync(join(tmpdir(), "pi-ext-nu-bang-debug-")); const original = { debug: process.env.PI_NU_BANG_DEBUG, state: process.env.XDG_STATE_HOME, }; try { process.env.PI_NU_BANG_DEBUG = "1"; process.env.XDG_STATE_HOME = join(root, "state"); vi.resetModules(); const { default: extension } = await import("../index.ts"); t = await createTestSession({ cwd: root, env: { PI_NU_BANG_DEBUG: "1", XDG_STATE_HOME: join(root, "state"), }, extensionFactories: [extension], }); await t.session.extensionRunner.emit({ type: "session_start", reason: "startup", }); await t.session.extensionRunner.emit({ type: "session_shutdown", reason: "quit", }); const events = readdirSync( join(root, "state", "pi-ext", "debug", "nu-bang"), ).flatMap((file) => readFileSync( join(root, "state", "pi-ext", "debug", "nu-bang", file), "utf8", ) .trim() .split("\n") .map((line) => JSON.parse(line)), ); expect(events).toEqual( expect.arrayContaining([ expect.objectContaining({ extension: "nu-bang", event: "session.start", }), expect.objectContaining({ extension: "nu-bang", event: "session.shutdown", }), ]), ); } finally { t?.dispose(); t = undefined; if (original.debug === undefined) delete process.env.PI_NU_BANG_DEBUG; else process.env.PI_NU_BANG_DEBUG = original.debug; if (original.state === undefined) delete process.env.XDG_STATE_HOME; else process.env.XDG_STATE_HOME = original.state; rmSync(root, { recursive: true, force: true }); } }); it("loads in real Pi extension runtime", async () => { t = await createTestSession({ extensionFactories: [nuBangExtension] }); expect(t.session.extensionRunner.extensions).toHaveLength(1); }); });