mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-25 11:55:47 -06:00
test(cli): remove private test seams (#122046)
This commit is contained in:
committed by
GitHub
parent
2c8ed54ddb
commit
241e1accde
+16
-18
@@ -128,32 +128,33 @@ describe("emitCliBanner", () => {
|
||||
expect(written).toContain("( o.o )");
|
||||
});
|
||||
|
||||
it("keeps lobster day out of plain terminals and pinned tagline modes", async () => {
|
||||
const { emitCliBanner, testing } = await importFreshBannerModule();
|
||||
it.each([
|
||||
{ label: "plain terminals", mode: "random" as const, richTty: false },
|
||||
{ label: "pinned tagline modes", mode: "off" as const, richTty: true },
|
||||
])("keeps lobster day out of $label", async ({ mode, richTty }) => {
|
||||
const { emitCliBanner } = await importFreshBannerModule();
|
||||
setStdoutIsTty(true);
|
||||
const writeSpy = vi.spyOn(process.stdout, "write").mockImplementation(() => true);
|
||||
const base = {
|
||||
|
||||
emitCliBanner("2026.3.7", {
|
||||
argv: ["node", "openclaw"],
|
||||
commit: "abc1234",
|
||||
env: { LANG: "en_US.UTF-8" },
|
||||
isTty: true,
|
||||
mode,
|
||||
now: () => new Date(2026, 1, 26),
|
||||
platform: "darwin" as const,
|
||||
};
|
||||
|
||||
emitCliBanner("2026.3.7", { ...base, mode: "random", richTty: false });
|
||||
testing.resetBannerEmittedForTests();
|
||||
emitCliBanner("2026.3.7", { ...base, mode: "off", richTty: true });
|
||||
platform: "darwin",
|
||||
richTty,
|
||||
});
|
||||
|
||||
const written = writeSpy.mock.calls.map(([chunk]) => String(chunk)).join("");
|
||||
expect(written).not.toContain("( o.o )");
|
||||
});
|
||||
|
||||
it("can reset banner emission state for same-module tests", async () => {
|
||||
const { emitCliBanner, hasEmittedCliBanner, testing } = await importFreshBannerModule();
|
||||
it("emits only once per module instance", async () => {
|
||||
const { emitCliBanner, hasEmittedCliBanner } = await importFreshBannerModule();
|
||||
setStdoutIsTty(true);
|
||||
const writeSpy = vi.spyOn(process.stdout, "write").mockImplementation(() => true);
|
||||
|
||||
const options = {
|
||||
argv: ["node", "openclaw"],
|
||||
commit: "abc1234",
|
||||
@@ -165,12 +166,9 @@ describe("emitCliBanner", () => {
|
||||
};
|
||||
|
||||
emitCliBanner("2026.3.7", options);
|
||||
expect(hasEmittedCliBanner()).toBe(true);
|
||||
|
||||
testing.resetBannerEmittedForTests();
|
||||
expect(hasEmittedCliBanner()).toBe(false);
|
||||
|
||||
emitCliBanner("2026.3.7", options);
|
||||
expect(writeSpy).toHaveBeenCalledTimes(2);
|
||||
|
||||
expect(hasEmittedCliBanner()).toBe(true);
|
||||
expect(writeSpy).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -134,9 +134,3 @@ export function emitCliBanner(version: string, options: BannerOptions = {}) {
|
||||
export function hasEmittedCliBanner(): boolean {
|
||||
return bannerEmitted;
|
||||
}
|
||||
|
||||
export const testing = {
|
||||
resetBannerEmittedForTests(): void {
|
||||
bannerEmitted = false;
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
// Update CLI test-helper tests cover helper fixtures used by update command tests.
|
||||
import path from "node:path";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { isOwningNpmCommand } from "./update-cli.test-helpers.js";
|
||||
|
||||
describe("isOwningNpmCommand", () => {
|
||||
it("accepts absolute npm binaries under the owning prefix", () => {
|
||||
const prefix = path.join(path.sep, "opt", "homebrew");
|
||||
|
||||
expect(isOwningNpmCommand(path.join(prefix, "bin", "npm"), prefix)).toBe(true);
|
||||
expect(isOwningNpmCommand(path.join(prefix, "npm.cmd"), prefix)).toBe(true);
|
||||
});
|
||||
|
||||
it("rejects plain npm and paths outside the owning prefix", () => {
|
||||
const prefix = path.join(path.sep, "opt", "homebrew");
|
||||
|
||||
expect(isOwningNpmCommand("npm", prefix)).toBe(false);
|
||||
expect(isOwningNpmCommand(path.join(path.sep, "usr", "local", "bin", "npm"), prefix)).toBe(
|
||||
false,
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -1,19 +0,0 @@
|
||||
// Update CLI test helpers provide shared fixtures and path helpers for update tests.
|
||||
import path from "node:path";
|
||||
|
||||
function isPathInsideRoot(candidate: string, root: string): boolean {
|
||||
const relative = path.relative(path.resolve(root), path.resolve(candidate));
|
||||
return relative === "" || (!relative.startsWith("..") && !path.isAbsolute(relative));
|
||||
}
|
||||
|
||||
export function isOwningNpmCommand(value: unknown, owningPrefix: string): boolean {
|
||||
if (typeof value !== "string" || !path.isAbsolute(value)) {
|
||||
return false;
|
||||
}
|
||||
const normalized = path.normalize(value);
|
||||
return (
|
||||
normalized !== path.normalize("npm") &&
|
||||
isPathInsideRoot(normalized, owningPrefix) &&
|
||||
/npm(?:\.cmd)?$/i.test(normalized)
|
||||
);
|
||||
}
|
||||
@@ -27,7 +27,6 @@ import { CLAWHUB_INSTALL_ERROR_CODE } from "../plugins/clawhub-error-codes.js";
|
||||
import { captureEnv, withEnvAsync } from "../test-utils/env.js";
|
||||
import { VERSION } from "../version.js";
|
||||
import { createCliRuntimeCapture, getMockCallOutput } from "./test-runtime-capture.js";
|
||||
import { isOwningNpmCommand } from "./update-cli.test-helpers.js";
|
||||
|
||||
const confirm = vi.fn();
|
||||
const select = vi.fn();
|
||||
@@ -5365,6 +5364,9 @@ describe("update-cli", () => {
|
||||
const pkgRoot = path.join(brewRoot, "openclaw");
|
||||
const brewNpm = path.join(brewPrefix, "bin", "npm");
|
||||
const win32PrefixNpm = path.join(brewPrefix, "npm.cmd");
|
||||
const owningNpmCommands = new Set([brewNpm, win32PrefixNpm].map(path.normalize));
|
||||
const isOwningNpmCommand = (value: unknown) =>
|
||||
typeof value === "string" && owningNpmCommands.has(path.normalize(value));
|
||||
const pathNpmRoot = createCaseDir("nvm-root");
|
||||
mockPackageInstallStatus(pkgRoot);
|
||||
pathExists.mockResolvedValue(false);
|
||||
@@ -5376,7 +5378,7 @@ describe("update-cli", () => {
|
||||
if (argv[0] === "npm" && argv[1] === "root" && argv[2] === "-g") {
|
||||
return commandResult({ stdout: `${pathNpmRoot}\n` });
|
||||
}
|
||||
if (isOwningNpmCommand(argv[0], brewPrefix) && argv[1] === "root" && argv[2] === "-g") {
|
||||
if (isOwningNpmCommand(argv[0]) && argv[1] === "root" && argv[2] === "-g") {
|
||||
return commandResult({ stdout: `${brewRoot}\n` });
|
||||
}
|
||||
return commandResult();
|
||||
@@ -5395,7 +5397,7 @@ describe("update-cli", () => {
|
||||
.mock.calls.find(
|
||||
([argv]) =>
|
||||
Array.isArray(argv) &&
|
||||
isOwningNpmCommand(argv[0], brewPrefix) &&
|
||||
isOwningNpmCommand(argv[0]) &&
|
||||
argv[1] === "i" &&
|
||||
argv[2] === "-g" &&
|
||||
argv.includes("openclaw@9999.0.0"),
|
||||
|
||||
@@ -25,19 +25,12 @@ import {
|
||||
resolveControlUiLinks,
|
||||
resolveLocalControlUiProbeLinks,
|
||||
summarizeExistingConfig,
|
||||
testing,
|
||||
validateGatewayPasswordInput,
|
||||
waitForGatewayReachable,
|
||||
} from "./onboard-helpers.js";
|
||||
|
||||
const tempDirs = useAutoCleanupTempDirTracker(afterEach);
|
||||
|
||||
describe("onboard error summaries", () => {
|
||||
it("keeps the bounded first line UTF-16 well-formed", () => {
|
||||
expect(testing.summarizeError(`${"x".repeat(118)}🚀tail\nignored`)).toBe(`${"x".repeat(118)}…`);
|
||||
});
|
||||
});
|
||||
|
||||
describe("printWizardHeader", () => {
|
||||
const withColumns = async (columns: number | undefined, run: () => Promise<void>) => {
|
||||
const previous = Object.getOwnPropertyDescriptor(process.stdout, "columns");
|
||||
@@ -699,6 +692,14 @@ describe("probeGatewayReachable", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("bounds thrown probe errors without splitting UTF-16", async () => {
|
||||
const detail = `${"x".repeat(118)}…`;
|
||||
const params = { url: "ws://127.0.0.1:18789" };
|
||||
mocks.probeGateway.mockRejectedValue(new Error(`${"x".repeat(118)}🚀tail\nignored`));
|
||||
expect(await probeGatewayReachable(params)).toEqual({ ok: false, detail });
|
||||
expect(await probeGatewayConfiguredModel(params)).toEqual({ kind: "unreachable", detail });
|
||||
});
|
||||
|
||||
it("forwards a configured TLS fingerprint to the gateway probe", async () => {
|
||||
mocks.probeGateway.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
|
||||
@@ -537,7 +537,5 @@ function summarizeError(err: unknown): string {
|
||||
return line.length > 120 ? `${truncateUtf16Safe(line, 119)}…` : line;
|
||||
}
|
||||
|
||||
export const testing = { summarizeError };
|
||||
|
||||
/** Default workspace path shown by onboarding prompts. */
|
||||
export const DEFAULT_WORKSPACE = DEFAULT_AGENT_WORKSPACE_DIR;
|
||||
|
||||
Reference in New Issue
Block a user