refactor: 移除 success 字段,简化为 matched 单层判定模型
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user