mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-07 18:26:17 +00:00
59 lines
2.0 KiB
TypeScript
59 lines
2.0 KiB
TypeScript
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
|
|
/**
|
|
* Pins the security-relevant contract of the `--yes` install path: the detected
|
|
* manager binary is spawned via execFileSync with `shell: false` and the exact
|
|
* argv from installInvocation — no shell, so a version can never be re-parsed
|
|
* as shell syntax. installInvocation's argv correctness is covered separately
|
|
* in installerDetection.test.ts; this locks how it's executed.
|
|
*/
|
|
describe("runDetectedInstall", () => {
|
|
afterEach(() => {
|
|
vi.doUnmock("node:child_process");
|
|
vi.resetModules();
|
|
});
|
|
|
|
it("spawns the manager binary with shell:false and inherited stdio", async () => {
|
|
const execSpy = vi.fn();
|
|
vi.resetModules();
|
|
vi.doMock("node:child_process", () => ({ execFileSync: execSpy }));
|
|
|
|
const { runDetectedInstall } = await import("./upgrade.js");
|
|
runDetectedInstall(
|
|
{ bin: "bun", args: ["add", "-g", "hyperframes@1.2.3"] },
|
|
"bun add -g hyperframes@1.2.3",
|
|
"1.2.3",
|
|
);
|
|
|
|
expect(execSpy).toHaveBeenCalledTimes(1);
|
|
expect(execSpy).toHaveBeenCalledWith("bun", ["add", "-g", "hyperframes@1.2.3"], {
|
|
stdio: "inherit",
|
|
shell: false,
|
|
});
|
|
});
|
|
|
|
it("sets a non-zero exit code when the install fails, without throwing", async () => {
|
|
const execSpy = vi.fn(() => {
|
|
throw new Error("install boom");
|
|
});
|
|
vi.resetModules();
|
|
vi.doMock("node:child_process", () => ({ execFileSync: execSpy }));
|
|
|
|
const { runDetectedInstall } = await import("./upgrade.js");
|
|
try {
|
|
expect(() =>
|
|
runDetectedInstall(
|
|
{ bin: "npm", args: ["install", "-g", "hyperframes@1.2.3"] },
|
|
"npm install -g hyperframes@1.2.3",
|
|
"1.2.3",
|
|
),
|
|
).not.toThrow();
|
|
const { consumeCommandResult } = await import("../utils/commandResult.js");
|
|
expect(consumeCommandResult().exitCode).toBe(1);
|
|
} finally {
|
|
const { consumeCommandResult } = await import("../utils/commandResult.js");
|
|
consumeCommandResult();
|
|
}
|
|
});
|
|
});
|