repositories / pi-ext
pi-ext
bugabingas pi extensions
owned by admin
extensions/nu-bang/__tests__/settings.test.ts
Rawimport {
chmodSync,
mkdirSync,
mkdtempSync,
rmSync,
writeFileSync,
} from "node:fs";
import { tmpdir } from "node:os";
import path from "node:path";
import { afterEach, describe, expect, it } from "vitest";
import { createTestSession, type TestSession } from "../../../test/harness";
const extensionPath = path.resolve(import.meta.dirname, "../index.ts");
type Case = {
user?: unknown;
project?: unknown;
env?: string;
untrusted?: boolean;
};
describe("nu-bang.command resolution", () => {
let t: TestSession | undefined;
let root: string | undefined;
afterEach(async () => {
await t?.session.extensionRunner.emit({
type: "session_shutdown",
reason: "quit",
});
t?.dispose();
t = undefined;
if (root) rmSync(root, { recursive: true, force: true });
root = undefined;
});
/** Start a session, run `print real-nu` as bang input, and report which executable ran it. */
async function run(input: Case) {
const dir = mkdtempSync(path.join(tmpdir(), "pi-ext-nu-bang-settings-"));
root = dir;
// Fake executables print their own name instead of running Nushell.
const fake = (name: string) => {
const file = path.join(dir, name);
writeFileSync(file, '#!/bin/sh\necho "fake:${0##*/}"\n');
chmodSync(file, 0o755);
return file;
};
const resolve = (value: unknown) =>
typeof value === "string" && value.startsWith("fake-")
? fake(value)
: value;
const write = (settingsDir: string, value: unknown) => {
mkdirSync(settingsDir, { recursive: true });
writeFileSync(
path.join(settingsDir, "settings.json"),
JSON.stringify({ "nu-bang": { command: resolve(value) } }),
);
};
if ("user" in input)
write(path.join(dir, ".test-home/.pi/agent"), input.user);
if ("project" in input) write(path.join(dir, ".pi"), input.project);
const env =
input.env === undefined
? {}
: { PI_NU_BANG_COMMAND: String(resolve(input.env)) };
t = await createTestSession({ cwd: dir, env, extensions: [extensionPath] });
if (input.untrusted) t.session.settingsManager.setProjectTrusted(false);
const before = t.events.uiCallsFor("notify").length;
await t.session.extensionRunner.emit({
type: "session_start",
reason: "startup",
});
const warnings = t.events
.uiCallsFor("notify")
.slice(before)
.filter((call) => call.args[1] === "warning")
.map((call) => call.args[0]);
const result = await t.session.extensionRunner.emitUserBash({
type: "user_bash",
command: "print real-nu",
excludeFromContext: false,
cwd: dir,
});
let output = "";
await result?.operations?.exec("print real-nu", dir, {
onData: (chunk) => {
output += chunk.toString("utf8");
},
});
return { ran: output.trim(), warnings };
}
it.each([
["default nu", {}, "real-nu"],
["user path", { user: "fake-user" }, "fake:fake-user"],
[
"env over settings",
{ user: "fake-user", env: "fake-env" },
"fake:fake-env",
],
[
"trusted project over user",
{ user: "fake-user", project: "fake-project" },
"fake:fake-project",
],
[
"untrusted project ignored",
{ user: "fake-user", project: "fake-project", untrusted: true },
"fake:fake-user",
],
] satisfies [string, Case, string][])(
"%s",
async (_name, input, expected) => {
const { ran, warnings } = await run(input);
expect(ran).toBe(expected);
expect(warnings).toEqual([]);
},
);
it.each([
["numeric user", { user: 5 }, "user settings"],
["empty project", { user: "fake-user", project: "" }, "project settings"],
[
"blank env",
{ user: "fake-user", env: " " },
"environment variable PI_NU_BANG_COMMAND",
],
] satisfies [string, Case, string][])(
"rejects %s without falling through",
async (_name, input, source) => {
const { ran, warnings } = await run(input);
expect(ran).toBe("real-nu");
expect(warnings).toEqual([
`Invalid nu-bang.command from ${source}; using nu`,
]);
},
);
});