import { describe, expect, test } from "bun:test"; import type { CheckerContext } from "../../../../../src/server/checker/runner/types"; import type { ResolvedCommandTarget } from "../../../../../src/server/checker/types"; import { CommandChecker } from "../../../../../src/server/checker/runner/command/runner"; const checker = new CommandChecker(); function makeCtx(timeoutMs = 5000): CheckerContext { const controller = new AbortController(); setTimeout(() => controller.abort(), timeoutMs); return { signal: controller.signal }; } function makeTarget( command: Partial, overrides?: Partial, ): ResolvedCommandTarget { return { command: { args: ["hello"], cwd: "/tmp", env: {}, exec: "echo", maxOutputBytes: 1024 * 1024, ...command, }, group: "default", intervalMs: 60000, name: "test-cmd", timeoutMs: 5000, type: "command", ...overrides, }; } describe("CommandChecker", () => { test("exitCode=0 成功", async () => { const result = await checker.execute(makeTarget({ args: [], exec: "true" }), makeCtx()); expect(result.matched).toBe(true); expect(result.statusDetail).toBe("exitCode=0"); expect(result.failure).toBeNull(); }); test("exitCode=1 不匹配默认 [0]", async () => { const result = await checker.execute(makeTarget({ args: [], exec: "false" }), makeCtx()); expect(result.matched).toBe(false); expect(result.statusDetail).toBe("exitCode=1"); expect(result.failure!.phase).toBe("exitCode"); }); test("exitCode=1 匹配自定义 [1]", async () => { const result = await checker.execute( makeTarget({ args: [], exec: "false" }, { expect: { exitCode: [1] } }), makeCtx(), ); expect(result.matched).toBe(true); expect(result.statusDetail).toBe("exitCode=1"); }); test("命令不存在返回 spawn 错误", async () => { const result = await checker.execute(makeTarget({ exec: "/nonexistent/command/xyz" }), makeCtx()); expect(result.matched).toBe(false); expect(result.failure!.phase).toBe("exitCode"); expect(result.failure!.message).toBeTruthy(); }); test("超时返回错误", async () => { const result = await checker.execute(makeTarget({ args: ["10"], exec: "sleep" }, { timeoutMs: 100 }), makeCtx(100)); expect(result.matched).toBe(false); expect(result.failure!.message).toContain("超时"); }); test("stdout 输出捕获", async () => { const result = await checker.execute(makeTarget({ args: ["hello world"], exec: "echo" }), makeCtx()); expect(result.matched).toBe(true); }); test("stdout 匹配 expect", async () => { const result = await checker.execute( makeTarget({ args: ["hello"], exec: "echo" }, { expect: { stdout: [{ contains: "hello" }] } }), makeCtx(), ); expect(result.matched).toBe(true); }); test("stdout 不匹配 expect", async () => { const result = await checker.execute( makeTarget({ args: ["hello"], exec: "echo" }, { expect: { stdout: [{ contains: "nonexistent" }] } }), makeCtx(), ); expect(result.matched).toBe(false); expect(result.failure!.phase).toBe("stdout"); }); test("stderr 匹配 expect", async () => { const result = await checker.execute( makeTarget({ args: ["-c", "echo error >&2"], exec: "bash" }, { expect: { stderr: [{ contains: "error" }] } }), makeCtx(), ); expect(result.matched).toBe(true); }); test("输出超过 maxOutputBytes", async () => { const result = await checker.execute( makeTarget({ args: ["-c", "yes | head -1000"], exec: "bash", maxOutputBytes: 10 }), makeCtx(), ); expect(result.matched).toBe(false); expect(result.failure!.message).toContain("超过限制"); }); test("durationMs 非空", async () => { const result = await checker.execute(makeTarget({ args: [], exec: "true" }), makeCtx()); expect(result.durationMs).not.toBeNull(); expect(result.durationMs!).toBeGreaterThanOrEqual(0); }); test("不使用 shell,通配符不被展开", async () => { const result = await checker.execute( makeTarget({ args: ["-e", "console.log('*')"], exec: "bun" }, { expect: { stdout: [{ contains: "*" }] } }), makeCtx(), ); expect(result.matched).toBe(true); }); test("serialize 返回命令摘要和 config JSON", () => { const target = makeTarget({ args: ["hello"], exec: "echo" }); const s = checker.serialize(target); expect(s.target).toBe("exec echo hello"); const config = JSON.parse(s.config) as { args: string[]; exec: string }; expect(config.exec).toBe("echo"); expect(config.args).toEqual(["hello"]); }); });