mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 10:20:42 +00:00
100 lines
2.9 KiB
TypeScript
100 lines
2.9 KiB
TypeScript
import { describe, expect, it, vi } from "vitest";
|
|
import { createCliDebugTiming, formatCliDebugTimingCommand } from "./debug-timing.js";
|
|
|
|
function parseJsonTimingLine(line: string) {
|
|
return JSON.parse(line) as {
|
|
command: string;
|
|
phase: string;
|
|
elapsedMs: number;
|
|
deltaMs: number;
|
|
durationMs?: number;
|
|
detail?: string;
|
|
error?: boolean;
|
|
};
|
|
}
|
|
|
|
describe("cli debug timing", () => {
|
|
it("does not emit timing lines unless OPENCLAW_DEBUG_TIMING enables a mode", () => {
|
|
const writer = vi.fn();
|
|
const timing = createCliDebugTiming({
|
|
command: "models list",
|
|
env: {},
|
|
writer,
|
|
});
|
|
|
|
timing.mark("start");
|
|
timing.time("sync", () => 1);
|
|
|
|
expect(timing.enabled).toBe(false);
|
|
expect(writer).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("emits readable timing lines with OPENCLAW_DEBUG_TIMING=1", () => {
|
|
const writer = vi.fn();
|
|
const timing = createCliDebugTiming({
|
|
command: "models list",
|
|
env: { OPENCLAW_DEBUG_TIMING: "1" },
|
|
writer,
|
|
});
|
|
|
|
timing.mark("start", { detail: "ready" });
|
|
expect(timing.time("sync", () => 1)).toBe(1);
|
|
|
|
expect(writer.mock.calls.map(([line]) => String(line))).toEqual([
|
|
'OpenClaw CLI debug timing: "models list"',
|
|
expect.stringMatching(/\s+\d+ms\s+\+\d+ms "start" detail="ready"/),
|
|
expect.stringMatching(/\s+\d+ms\s+\+\d+ms "sync" duration=\d+ms/),
|
|
]);
|
|
});
|
|
|
|
it("emits parseable timing JSON lines with OPENCLAW_DEBUG_TIMING=json", async () => {
|
|
const writer = vi.fn();
|
|
const timing = createCliDebugTiming({
|
|
command: "models list",
|
|
env: { OPENCLAW_DEBUG_TIMING: "json" },
|
|
writer,
|
|
});
|
|
|
|
timing.mark("start", { detail: "ready" });
|
|
expect(timing.time("sync", () => 1)).toBe(1);
|
|
await expect(timing.timeAsync("async", async () => "ok")).resolves.toBe("ok");
|
|
await expect(
|
|
timing.timeAsync("reject", async () => {
|
|
throw new Error("nope");
|
|
}),
|
|
).rejects.toThrow("nope");
|
|
|
|
const payloads = writer.mock.calls.map(([line]) => parseJsonTimingLine(String(line)));
|
|
expect(payloads).toEqual([
|
|
expect.objectContaining({
|
|
command: "models list",
|
|
phase: "start",
|
|
detail: "ready",
|
|
elapsedMs: expect.any(Number),
|
|
deltaMs: expect.any(Number),
|
|
}),
|
|
expect.objectContaining({
|
|
command: "models list",
|
|
phase: "sync",
|
|
durationMs: expect.any(Number),
|
|
}),
|
|
expect.objectContaining({
|
|
command: "models list",
|
|
phase: "async",
|
|
durationMs: expect.any(Number),
|
|
}),
|
|
expect.objectContaining({
|
|
command: "models list",
|
|
phase: "reject",
|
|
durationMs: expect.any(Number),
|
|
error: true,
|
|
}),
|
|
]);
|
|
});
|
|
|
|
it("formats empty command paths as root", () => {
|
|
expect(formatCliDebugTimingCommand([])).toBe("root");
|
|
expect(formatCliDebugTimingCommand(["models", "list"])).toBe("models list");
|
|
});
|
|
});
|