1
0

refactor: 移除 success 字段,简化为 matched 单层判定模型

This commit is contained in:
2026-05-11 13:12:55 +08:00
parent 548b44d28e
commit 35ba56888b
93 changed files with 3893 additions and 103 deletions

View File

@@ -58,7 +58,6 @@ describe("API 路由", () => {
store.insertCheckResult({
targetId: targets[0]!.id,
timestamp: "2025-01-01T00:00:00.000Z",
success: true,
matched: true,
durationMs: 150,
statusDetail: "200 OK",
@@ -67,7 +66,6 @@ describe("API 路由", () => {
store.insertCheckResult({
targetId: targets[0]!.id,
timestamp: "2025-01-01T00:00:30.000Z",
success: false,
matched: false,
durationMs: null,
statusDetail: null,
@@ -121,7 +119,6 @@ describe("API 路由", () => {
expect(tA.target).toBe("http://a.com");
expect(tA.group).toBe("default");
expect(tA.latestCheck).not.toBeNull();
expect(tA.latestCheck!.success).toBe(false);
expect(tA.latestCheck!.matched).toBe(false);
expect(tA.latestCheck!.failure).not.toBeNull();
expect(tA.recentSamples).toBeDefined();

View File

@@ -27,7 +27,6 @@ function makeTarget(
describe("runCommandCheck", () => {
test("exitCode=0 成功", async () => {
const result = await runCommandCheck(makeTarget({ exec: "true", args: [] }));
expect(result.success).toBe(true);
expect(result.matched).toBe(true);
expect(result.statusDetail).toBe("exitCode=0");
expect(result.failure).toBeNull();
@@ -35,7 +34,6 @@ describe("runCommandCheck", () => {
test("exitCode=1 不匹配默认 [0]", async () => {
const result = await runCommandCheck(makeTarget({ exec: "false", args: [] }));
expect(result.success).toBe(false);
expect(result.matched).toBe(false);
expect(result.statusDetail).toBe("exitCode=1");
expect(result.failure).not.toBeNull();
@@ -44,14 +42,13 @@ describe("runCommandCheck", () => {
test("exitCode=1 匹配自定义 [1]", async () => {
const result = await runCommandCheck(makeTarget({ exec: "false", args: [] }, { expect: { exitCode: [1] } }));
expect(result.success).toBe(true);
expect(result.matched).toBe(true);
expect(result.statusDetail).toBe("exitCode=1");
});
test("命令不存在返回 spawn 错误", async () => {
const result = await runCommandCheck(makeTarget({ exec: "/nonexistent/command/xyz" }));
expect(result.success).toBe(false);
expect(result.matched).toBe(false);
expect(result.failure).not.toBeNull();
expect(result.failure!.phase).toBe("exitCode");
expect(result.failure!.message).toBeTruthy();
@@ -59,21 +56,20 @@ describe("runCommandCheck", () => {
test("超时返回错误", async () => {
const result = await runCommandCheck(makeTarget({ exec: "sleep", args: ["10"] }, { timeoutMs: 100 }));
expect(result.success).toBe(false);
expect(result.matched).toBe(false);
expect(result.failure).not.toBeNull();
expect(result.failure!.message).toContain("超时");
});
test("stdout 输出捕获", async () => {
const result = await runCommandCheck(makeTarget({ exec: "echo", args: ["hello world"] }));
expect(result.success).toBe(true);
expect(result.matched).toBe(true);
});
test("stdout 匹配 expect", async () => {
const result = await runCommandCheck(
makeTarget({ exec: "echo", args: ["hello"] }, { expect: { stdout: [{ contains: "hello" }] } }),
);
expect(result.success).toBe(true);
expect(result.matched).toBe(true);
});
@@ -81,7 +77,7 @@ describe("runCommandCheck", () => {
const result = await runCommandCheck(
makeTarget({ exec: "echo", args: ["hello"] }, { expect: { stdout: [{ contains: "nonexistent" }] } }),
);
expect(result.success).toBe(false);
expect(result.matched).toBe(false);
expect(result.failure!.phase).toBe("stdout");
});
@@ -89,7 +85,6 @@ describe("runCommandCheck", () => {
const result = await runCommandCheck(
makeTarget({ exec: "bash", args: ["-c", "echo error >&2"] }, { expect: { stderr: [{ contains: "error" }] } }),
);
expect(result.success).toBe(true);
expect(result.matched).toBe(true);
});
@@ -101,7 +96,7 @@ describe("runCommandCheck", () => {
maxOutputBytes: 10,
}),
);
expect(result.success).toBe(false);
expect(result.matched).toBe(false);
expect(result.failure).not.toBeNull();
expect(result.failure!.message).toContain("超过限制");
});
@@ -114,7 +109,7 @@ describe("runCommandCheck", () => {
test("ls 命令执行成功", async () => {
const result = await runCommandCheck(makeTarget({ exec: "ls", args: ["/tmp"] }));
expect(result.success).toBe(true);
expect(result.matched).toBe(true);
expect(result.statusDetail).toBe("exitCode=0");
});
@@ -122,11 +117,11 @@ describe("runCommandCheck", () => {
const result = await runCommandCheck(
makeTarget({ exec: "echo", args: ["*"] }, { expect: { stdout: [{ contains: "*" }] } }),
);
expect(result.success).toBe(true);
expect(result.matched).toBe(true);
});
test("不提供 stdin等待输入的命令会阻塞超时", async () => {
const result = await runCommandCheck(makeTarget({ exec: "bash", args: ["-c", "read line"] }, { timeoutMs: 500 }));
expect(result.success).toBe(false);
expect(result.matched).toBe(false);
});
});

View File

@@ -69,7 +69,6 @@ describe("ProbeEngine", () => {
const results = (mockStore as unknown as { _results: Array<Record<string, unknown>> })._results;
expect(results.length).toBe(1);
expect(results[0]!.success).toBe(true);
expect(results[0]!.matched).toBe(true);
expect(results[0]!.statusDetail).toBe("exitCode=0");
});
@@ -111,8 +110,8 @@ describe("ProbeEngine", () => {
const results = (mockStore as unknown as { _results: Array<Record<string, unknown>> })._results;
expect(results.length).toBe(2);
const badResult = results.find((r) => r.success === false);
const goodResult = results.find((r) => r.success === true);
const badResult = results.find((r) => r.matched === false);
const goodResult = results.find((r) => r.matched === true);
expect(badResult).toBeDefined();
expect(goodResult).toBeDefined();
});
@@ -135,7 +134,7 @@ describe("ProbeEngine", () => {
const results = (mockStore as unknown as { _results: Array<Record<string, unknown>> })._results;
expect(results.length).toBe(5);
for (const r of results) {
expect(r.success).toBe(true);
expect(r.matched).toBe(true);
}
});
@@ -198,7 +197,7 @@ describe("ProbeEngine", () => {
const results = (mockStore as unknown as { _results: Array<Record<string, unknown>> })._results;
expect(results.length).toBe(1);
expect(results[0]!.success).toBe(true);
expect(results[0]!.matched).toBe(true);
expect(results[0]!.statusDetail).toBe("HTTP 200");
} finally {
httpServer.stop();

View File

@@ -77,7 +77,6 @@ describe("runHttpCheck 集成", () => {
test("成功请求 200", async () => {
const result = await runHttpCheck(makeTarget({ url: `${baseUrl}/ok` }));
expect(result.success).toBe(true);
expect(result.matched).toBe(true);
expect(result.statusDetail).toBe("HTTP 200");
expect(result.durationMs).not.toBeNull();
@@ -86,7 +85,6 @@ describe("runHttpCheck 集成", () => {
test("404 不匹配默认 status [200]", async () => {
const result = await runHttpCheck(makeTarget({ url: `${baseUrl}/notfound` }));
expect(result.success).toBe(false);
expect(result.matched).toBe(false);
expect(result.statusDetail).toBe("HTTP 404");
expect(result.failure).not.toBeNull();
@@ -100,7 +98,6 @@ describe("runHttpCheck 集成", () => {
expect: { status: [404] },
}),
);
expect(result.success).toBe(true);
expect(result.matched).toBe(true);
});
@@ -111,7 +108,6 @@ describe("runHttpCheck 集成", () => {
expect: { headers: { "x-custom": "test-value" } },
}),
);
expect(result.success).toBe(true);
expect(result.matched).toBe(true);
});
@@ -122,7 +118,7 @@ describe("runHttpCheck 集成", () => {
expect: { headers: { "x-custom": "wrong-value" } },
}),
);
expect(result.success).toBe(false);
expect(result.matched).toBe(false);
expect(result.failure!.phase).toBe("headers");
});
@@ -133,7 +129,6 @@ describe("runHttpCheck 集成", () => {
expect: { body: [{ contains: "hello" }] },
}),
);
expect(result.success).toBe(true);
expect(result.matched).toBe(true);
});
@@ -144,7 +139,7 @@ describe("runHttpCheck 集成", () => {
expect: { body: [{ contains: "nonexistent" }] },
}),
);
expect(result.success).toBe(false);
expect(result.matched).toBe(false);
expect(result.failure!.phase).toBe("body");
});
@@ -155,7 +150,7 @@ describe("runHttpCheck 集成", () => {
expect: { body: [{ json: { path: "$.status", equals: "ok" } }] },
}),
);
expect(result.success).toBe(true);
expect(result.matched).toBe(true);
});
test("响应体超过 maxBodyBytes", async () => {
@@ -166,7 +161,7 @@ describe("runHttpCheck 集成", () => {
expect: { body: [{ contains: "x" }] },
}),
);
expect(result.success).toBe(false);
expect(result.matched).toBe(false);
expect(result.failure).not.toBeNull();
expect(result.failure!.phase).toBe("body");
expect(result.failure!.message).toContain("超过限制");
@@ -188,7 +183,7 @@ describe("runHttpCheck 集成", () => {
timeoutMs: 100,
}),
);
expect(result.success).toBe(false);
expect(result.matched).toBe(false);
expect(result.failure).not.toBeNull();
expect(result.failure!.message).toContain("超时");
} finally {
@@ -203,7 +198,7 @@ describe("runHttpCheck 集成", () => {
expect: { status: [200], body: [{ contains: "something" }] },
}),
);
expect(result.success).toBe(false);
expect(result.matched).toBe(false);
expect(result.failure!.phase).toBe("status");
});
@@ -214,7 +209,7 @@ describe("runHttpCheck 集成", () => {
expect: { headers: { "x-missing": "value" }, body: [{ contains: "hello" }] },
}),
);
expect(result.success).toBe(false);
expect(result.matched).toBe(false);
expect(result.failure!.phase).toBe("headers");
});
@@ -225,13 +220,13 @@ describe("runHttpCheck 集成", () => {
expect: { status: [200], body: [{ contains: "not-in-body" }] },
}),
);
expect(result.success).toBe(false);
expect(result.matched).toBe(false);
expect(result.failure!.phase).toBe("body");
});
test("无 expect 时默认检查 status 200", async () => {
const result = await runHttpCheck(makeTarget({ url: `${baseUrl}/ok`, expect: undefined }));
expect(result.success).toBe(true);
expect(result.matched).toBe(true);
});
test("POST 请求携带 body", async () => {
@@ -244,7 +239,7 @@ describe("runHttpCheck 集成", () => {
expect: { status: [200], body: [{ json: { path: "$.body", equals: "present" } }] },
}),
);
expect(result.success).toBe(true);
expect(result.matched).toBe(true);
});
test("仅 contains 规则时不解析 JSON", async () => {
@@ -254,6 +249,6 @@ describe("runHttpCheck 集成", () => {
expect: { body: [{ contains: "hello world" }] },
}),
);
expect(result.success).toBe(true);
expect(result.matched).toBe(true);
});
});

View File

@@ -132,7 +132,6 @@ describe("ProbeStore", () => {
store.insertCheckResult({
targetId: t1Id,
timestamp: "2025-01-01T00:00:00.000Z",
success: true,
matched: true,
durationMs: 150.5,
statusDetail: "200 OK",
@@ -142,7 +141,6 @@ describe("ProbeStore", () => {
store.insertCheckResult({
targetId: t1Id,
timestamp: "2025-01-01T00:00:30.000Z",
success: true,
matched: true,
durationMs: 300,
statusDetail: "200 OK",
@@ -161,7 +159,6 @@ describe("ProbeStore", () => {
store.insertCheckResult({
targetId: t1Id,
timestamp: "2025-01-01T00:01:00.000Z",
success: false,
matched: false,
durationMs: null,
statusDetail: null,
@@ -173,7 +170,7 @@ describe("ProbeStore", () => {
expect(history.items[0]!.timestamp).toBe("2025-01-01T00:01:00.000Z");
const latest = store.getLatestCheck(t1Id)!;
expect(latest.success).toBe(0);
expect(latest.matched).toBe(0);
expect(latest.failure).not.toBeNull();
const parsedFailure = JSON.parse(latest.failure!) as CheckFailure;
expect(parsedFailure.kind).toBe("error");
@@ -189,7 +186,6 @@ describe("ProbeStore", () => {
store.insertCheckResult({
targetId: t1Id,
timestamp: `2025-01-01T01:${String(i).padStart(2, "0")}:00.000Z`,
success: true,
matched: true,
durationMs: 100 + i,
statusDetail: "200 OK",
@@ -250,7 +246,6 @@ describe("ProbeStore", () => {
expect(samples.length).toBeGreaterThan(0);
for (const sample of samples) {
expect(typeof sample.timestamp).toBe("string");
expect(typeof sample.success).toBe("number");
expect(typeof sample.matched).toBe("number");
}
});