File size: 1,587 Bytes
fc93158 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | import { describe, expect, it } from "vitest";
import type { UpdateRunResult } from "../../infra/update-runner.js";
import { inferUpdateFailureHints } from "./progress.js";
function makeResult(
stepName: string,
stderrTail: string,
mode: UpdateRunResult["mode"] = "npm",
): UpdateRunResult {
return {
status: "error",
mode,
reason: stepName,
steps: [
{
name: stepName,
command: "npm i -g openclaw@latest",
cwd: "/tmp",
durationMs: 1,
exitCode: 1,
stderrTail,
},
],
durationMs: 1,
};
}
describe("inferUpdateFailureHints", () => {
it("returns EACCES hint for global update permission failures", () => {
const result = makeResult(
"global update",
"npm ERR! code EACCES\nnpm ERR! Error: EACCES: permission denied",
);
const hints = inferUpdateFailureHints(result);
expect(hints.join("\n")).toContain("EACCES");
expect(hints.join("\n")).toContain("npm config set prefix ~/.local");
});
it("returns native optional dependency hint for node-gyp failures", () => {
const result = makeResult("global update", "node-pre-gyp ERR!\nnode-gyp rebuild failed");
const hints = inferUpdateFailureHints(result);
expect(hints.join("\n")).toContain("--omit=optional");
});
it("does not return npm hints for non-npm install modes", () => {
const result = makeResult(
"global update",
"npm ERR! code EACCES\nnpm ERR! Error: EACCES: permission denied",
"pnpm",
);
expect(inferUpdateFailureHints(result)).toEqual([]);
});
});
|