test: dedupe and optimize test suites

This commit is contained in:
Peter Steinberger
2026-02-19 15:18:50 +00:00
parent b0e55283d5
commit a1cb700a05
80 changed files with 2627 additions and 2962 deletions

View File

@@ -85,19 +85,30 @@ vi.mock("../commands/gateway-status.js", () => ({
gatewayStatusCommand: (opts: unknown) => gatewayStatusCommand(opts),
}));
const { registerGatewayCli } = await import("./gateway-cli.js");
function createGatewayProgram() {
const program = new Command();
program.exitOverride();
registerGatewayCli(program);
return program;
}
async function runGatewayCommand(args: string[]) {
const program = createGatewayProgram();
await program.parseAsync(args, { from: "user" });
}
async function expectGatewayExit(args: string[]) {
await expect(runGatewayCommand(args)).rejects.toThrow("__exit__:1");
}
describe("gateway-cli coverage", () => {
it("registers call/health commands and routes to callGateway", async () => {
resetRuntimeCapture();
callGateway.mockClear();
const { registerGatewayCli } = await import("./gateway-cli.js");
const program = new Command();
program.exitOverride();
registerGatewayCli(program);
await program.parseAsync(["gateway", "call", "health", "--params", '{"x":1}', "--json"], {
from: "user",
});
await runGatewayCommand(["gateway", "call", "health", "--params", '{"x":1}', "--json"]);
expect(callGateway).toHaveBeenCalledTimes(1);
expect(runtimeLogs.join("\n")).toContain('"ok": true');
@@ -107,48 +118,30 @@ describe("gateway-cli coverage", () => {
resetRuntimeCapture();
gatewayStatusCommand.mockClear();
const { registerGatewayCli } = await import("./gateway-cli.js");
const program = new Command();
program.exitOverride();
registerGatewayCli(program);
await program.parseAsync(["gateway", "probe", "--json"], { from: "user" });
await runGatewayCommand(["gateway", "probe", "--json"]);
expect(gatewayStatusCommand).toHaveBeenCalledTimes(1);
}, 60_000);
it("registers gateway discover and prints JSON", async () => {
resetRuntimeCapture();
discoverGatewayBeacons.mockReset();
discoverGatewayBeacons.mockResolvedValueOnce([
{
instanceName: "Studio (OpenClaw)",
displayName: "Studio",
domain: "local.",
host: "studio.local",
lanHost: "studio.local",
tailnetDns: "studio.tailnet.ts.net",
gatewayPort: 18789,
sshPort: 22,
},
]);
const { registerGatewayCli } = await import("./gateway-cli.js");
const program = new Command();
program.exitOverride();
registerGatewayCli(program);
await program.parseAsync(["gateway", "discover", "--json"], {
from: "user",
});
expect(discoverGatewayBeacons).toHaveBeenCalledTimes(1);
expect(runtimeLogs.join("\n")).toContain('"beacons"');
expect(runtimeLogs.join("\n")).toContain('"wsUrl"');
expect(runtimeLogs.join("\n")).toContain("ws://");
});
it("registers gateway discover and prints human output with details on new lines", async () => {
it.each([
{
label: "json output",
args: ["gateway", "discover", "--json"],
expectedOutput: ['"beacons"', '"wsUrl"', "ws://"],
},
{
label: "human output",
args: ["gateway", "discover", "--timeout", "1"],
expectedOutput: [
"Gateway Discovery",
"Found 1 gateway(s)",
"- Studio openclaw.internal.",
" tailnet: studio.tailnet.ts.net",
" host: studio.openclaw.internal",
" ws: ws://studio.openclaw.internal:18789",
],
},
])("registers gateway discover and prints $label", async ({ args, expectedOutput }) => {
resetRuntimeCapture();
discoverGatewayBeacons.mockReset();
discoverGatewayBeacons.mockResolvedValueOnce([
@@ -164,38 +157,19 @@ describe("gateway-cli coverage", () => {
},
]);
const { registerGatewayCli } = await import("./gateway-cli.js");
const program = new Command();
program.exitOverride();
registerGatewayCli(program);
await program.parseAsync(["gateway", "discover", "--timeout", "1"], {
from: "user",
});
await runGatewayCommand(args);
expect(discoverGatewayBeacons).toHaveBeenCalledTimes(1);
const out = runtimeLogs.join("\n");
expect(out).toContain("Gateway Discovery");
expect(out).toContain("Found 1 gateway(s)");
expect(out).toContain("- Studio openclaw.internal.");
expect(out).toContain(" tailnet: studio.tailnet.ts.net");
expect(out).toContain(" host: studio.openclaw.internal");
expect(out).toContain(" ws: ws://studio.openclaw.internal:18789");
for (const text of expectedOutput) {
expect(out).toContain(text);
}
});
it("validates gateway discover timeout", async () => {
resetRuntimeCapture();
discoverGatewayBeacons.mockReset();
const { registerGatewayCli } = await import("./gateway-cli.js");
const program = new Command();
program.exitOverride();
registerGatewayCli(program);
await expect(
program.parseAsync(["gateway", "discover", "--timeout", "0"], {
from: "user",
}),
).rejects.toThrow("__exit__:1");
await expectGatewayExit(["gateway", "discover", "--timeout", "0"]);
expect(runtimeErrors.join("\n")).toContain("gateway discover failed:");
expect(discoverGatewayBeacons).not.toHaveBeenCalled();
@@ -204,15 +178,7 @@ describe("gateway-cli coverage", () => {
it("fails gateway call on invalid params JSON", async () => {
resetRuntimeCapture();
callGateway.mockClear();
const { registerGatewayCli } = await import("./gateway-cli.js");
const program = new Command();
program.exitOverride();
registerGatewayCli(program);
await expect(
program.parseAsync(["gateway", "call", "status", "--params", "not-json"], { from: "user" }),
).rejects.toThrow("__exit__:1");
await expectGatewayExit(["gateway", "call", "status", "--params", "not-json"]);
expect(callGateway).not.toHaveBeenCalled();
expect(runtimeErrors.join("\n")).toContain("Gateway call failed:");
@@ -221,47 +187,35 @@ describe("gateway-cli coverage", () => {
it("validates gateway ports and handles force/start errors", async () => {
resetRuntimeCapture();
const { registerGatewayCli } = await import("./gateway-cli.js");
// Invalid port
const programInvalidPort = new Command();
programInvalidPort.exitOverride();
registerGatewayCli(programInvalidPort);
await expect(
programInvalidPort.parseAsync(["gateway", "--port", "0", "--token", "test-token"], {
from: "user",
}),
).rejects.toThrow("__exit__:1");
await expectGatewayExit(["gateway", "--port", "0", "--token", "test-token"]);
// Force free failure
forceFreePortAndWait.mockImplementationOnce(async () => {
throw new Error("boom");
});
const programForceFail = new Command();
programForceFail.exitOverride();
registerGatewayCli(programForceFail);
await expect(
programForceFail.parseAsync(
["gateway", "--port", "18789", "--token", "test-token", "--force", "--allow-unconfigured"],
{ from: "user" },
),
).rejects.toThrow("__exit__:1");
await expectGatewayExit([
"gateway",
"--port",
"18789",
"--token",
"test-token",
"--force",
"--allow-unconfigured",
]);
// Start failure (generic)
startGatewayServer.mockRejectedValueOnce(new Error("nope"));
const programStartFail = new Command();
programStartFail.exitOverride();
registerGatewayCli(programStartFail);
const beforeSigterm = new Set(process.listeners("SIGTERM"));
const beforeSigint = new Set(process.listeners("SIGINT"));
await expect(
programStartFail.parseAsync(
["gateway", "--port", "18789", "--token", "test-token", "--allow-unconfigured"],
{
from: "user",
},
),
).rejects.toThrow("__exit__:1");
await expectGatewayExit([
"gateway",
"--port",
"18789",
"--token",
"test-token",
"--allow-unconfigured",
]);
for (const listener of process.listeners("SIGTERM")) {
if (!beforeSigterm.has(listener)) {
process.removeListener("SIGTERM", listener);
@@ -282,17 +236,7 @@ describe("gateway-cli coverage", () => {
startGatewayServer.mockRejectedValueOnce(
new GatewayLockError("another gateway instance is already listening"),
);
const { registerGatewayCli } = await import("./gateway-cli.js");
const program = new Command();
program.exitOverride();
registerGatewayCli(program);
await expect(
program.parseAsync(["gateway", "--token", "test-token", "--allow-unconfigured"], {
from: "user",
}),
).rejects.toThrow("__exit__:1");
await expectGatewayExit(["gateway", "--token", "test-token", "--allow-unconfigured"]);
expect(startGatewayServer).toHaveBeenCalled();
expect(runtimeErrors.join("\n")).toContain("Gateway failed to start:");
@@ -304,17 +248,8 @@ describe("gateway-cli coverage", () => {
resetRuntimeCapture();
startGatewayServer.mockClear();
const { registerGatewayCli } = await import("./gateway-cli.js");
const program = new Command();
program.exitOverride();
registerGatewayCli(program);
startGatewayServer.mockRejectedValueOnce(new Error("nope"));
await expect(
program.parseAsync(["gateway", "--token", "test-token", "--allow-unconfigured"], {
from: "user",
}),
).rejects.toThrow("__exit__:1");
await expectGatewayExit(["gateway", "--token", "test-token", "--allow-unconfigured"]);
expect(startGatewayServer).toHaveBeenCalledWith(19001, expect.anything());
});