63 lines
2.5 KiB
TypeScript
63 lines
2.5 KiB
TypeScript
import { expect, test } from "bun:test";
|
|
|
|
const updaterUrl = new URL("../../lib/version-update.ts", import.meta.url).href;
|
|
const entryUrl = new URL("../../index.ts", import.meta.url).href;
|
|
const mainUrl = new URL("../../command/main.ts", import.meta.url).href;
|
|
const errorUrl = new URL("../../lib/error.ts", import.meta.url).href;
|
|
|
|
test.each([
|
|
["success", "return true", "+ Updated to 2.7.0"],
|
|
["command error", "return true", "+ Updated to 2.7.0"],
|
|
["failure", "throw new Error('offline')", "+ New version available: 2.7.0"],
|
|
[
|
|
"timeout",
|
|
"return await installVersion(version, () => ({ exited: new Promise(() => {}), kill: () => {} }), 1)",
|
|
"+ New version available: 2.7.0",
|
|
],
|
|
])(
|
|
"CLI waits for a %s update and preserves its exit status",
|
|
async (_name, outcome, message) => {
|
|
const script = `
|
|
import { mock } from "bun:test";
|
|
const { createVersionObserver, installVersion } = await import(${JSON.stringify(updaterUrl)});
|
|
const observe = createVersionObserver({ currentVersion: "2.6.1", runner: async (version) => {
|
|
if (${JSON.stringify(_name)} !== "timeout") await new Promise(resolve => setTimeout(resolve, 80));
|
|
${outcome};
|
|
}});
|
|
mock.module("citty", () => ({ createMain: () => async () => {
|
|
observe("2.7.0");
|
|
observe("2.8.0");
|
|
if (${JSON.stringify(_name)} === "command error") throw new Error("command failed");
|
|
process.exitCode = 7;
|
|
}}));
|
|
mock.module(${JSON.stringify(mainUrl)}, () => ({ main: {}, initializeCompletion: async () => {} }));
|
|
mock.module(${JSON.stringify(errorUrl)}, () => ({ formatUnknownError: String, wrapCommandErrors: () => {} }));
|
|
await import(${JSON.stringify(entryUrl)});
|
|
`;
|
|
const started = Date.now();
|
|
const child = Bun.spawn([process.execPath, "-e", script, "login"], {
|
|
stdin: "ignore",
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
});
|
|
const timer = setTimeout(() => child.kill(), 5_000);
|
|
try {
|
|
const [code, stdout, stderr] = await Promise.all([
|
|
child.exited,
|
|
new Response(child.stdout).text(),
|
|
new Response(child.stderr).text(),
|
|
]);
|
|
expect(code).toBe(_name === "command error" ? 1 : 7);
|
|
expect(Date.now() - started).toBeGreaterThanOrEqual(
|
|
_name === "timeout" ? 900 : 70,
|
|
);
|
|
expect(stdout).toBe("");
|
|
expect(stderr).toBe(
|
|
`${_name === "command error" ? "Error: command failed\n" : ""}\x1b[90m${message}\x1b[0m\n`,
|
|
);
|
|
} finally {
|
|
clearTimeout(timer);
|
|
}
|
|
},
|
|
);
|