refactor: 统一 expect 断言体系,引入共享 ValueMatcher/ContentRules/KeyValueExpect 模型
- 引入共享 ValueMatcher(equals/contains/regex/exists/empty/gt/gte/lt/lte) - 引入共享 ContentRules 数组(direct/json/css/xpath 提取器) - 引入共享 KeyValueExpect(动态键值断言,字面量等价 equals) - maxDurationMs → durationMs: ValueMatcher(所有 checker) - match → regex(固定无 flags) - Ping max* → packetLossPercent/avgLatencyMs/maxLatencyMs(ValueMatcher) - LLM finishReason/rawFinishReason → ValueMatcher - DB 新增 result: ContentRules - TCP banner → ContentRules 数组 - 删除旧模块:operator.ts、validate-operator.ts、duration.ts、body.ts、text.ts、output.ts - 更新全部 checker schema/validate/expect/execute - 更新 probe-config.schema.json、probes.example.yaml - 更新 README.md、DEVELOPMENT.md(含 expect 字段选择规范) - 同步 10 个 delta specs 到主 specs,归档 change
This commit is contained in:
@@ -487,7 +487,7 @@ describe("HttpChecker", () => {
|
||||
expect(result.durationMs!).toBeGreaterThanOrEqual(0);
|
||||
});
|
||||
|
||||
test("expect.maxDurationMs 使用完整耗时", async () => {
|
||||
test("expect.durationMs 使用完整耗时", async () => {
|
||||
const slowServer = Bun.serve({
|
||||
async fetch() {
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
@@ -498,7 +498,7 @@ describe("HttpChecker", () => {
|
||||
try {
|
||||
const result = await checker.execute(
|
||||
makeTarget({
|
||||
expect: { body: [{ contains: "x" }], maxDurationMs: 10 },
|
||||
expect: { body: [{ contains: "x" }], durationMs: { lte: 10 } },
|
||||
url: `http://localhost:${slowServer.port}/`,
|
||||
}),
|
||||
makeCtx(),
|
||||
@@ -521,7 +521,7 @@ describe("HttpChecker", () => {
|
||||
test("body 失败优先于 duration 检查", async () => {
|
||||
const result = await checker.execute(
|
||||
makeTarget({
|
||||
expect: { body: [{ contains: "nonexistent" }], maxDurationMs: 999999 },
|
||||
expect: { body: [{ contains: "nonexistent" }], durationMs: { lte: 999999 } },
|
||||
url: `${baseUrl}/ok`,
|
||||
}),
|
||||
makeCtx(),
|
||||
@@ -689,7 +689,7 @@ describe("HttpChecker", () => {
|
||||
name: "test",
|
||||
type: "http",
|
||||
});
|
||||
expect(errors).toContain("缺少支持的规则类型");
|
||||
expect(errors).toContain("match 是未知字段");
|
||||
});
|
||||
|
||||
test("非法 regex 启动校验失败", () => {
|
||||
@@ -722,19 +722,19 @@ describe("HttpChecker", () => {
|
||||
expect(errors).toContain("json.path");
|
||||
});
|
||||
|
||||
test("非法 operator match 启动校验失败", () => {
|
||||
test("旧 match matcher 启动校验失败", () => {
|
||||
const errors = validateHttpTarget({
|
||||
expect: { headers: { "x-test": { match: "[invalid" } } },
|
||||
http: { url: "https://example.com" },
|
||||
name: "test",
|
||||
type: "http",
|
||||
});
|
||||
expect(errors).toContain("match 正则不合法");
|
||||
expect(errors).toContain("match 是未知 matcher");
|
||||
});
|
||||
|
||||
test("ReDoS operator match 启动校验失败", () => {
|
||||
test("ReDoS regex matcher 启动校验失败", () => {
|
||||
const errors = validateHttpTarget({
|
||||
expect: { headers: { "x-test": { match: "(\\d+)*x" } } },
|
||||
expect: { headers: { "x-test": { regex: "(\\d+)*x" } } },
|
||||
http: { url: "https://example.com" },
|
||||
name: "test",
|
||||
type: "http",
|
||||
@@ -769,17 +769,17 @@ describe("HttpChecker", () => {
|
||||
name: "test",
|
||||
type: "http",
|
||||
});
|
||||
expect(errors).toContain("必须包含至少一个合法 operator");
|
||||
expect(errors).toContain("必须包含至少一个合法 matcher");
|
||||
});
|
||||
|
||||
test("body rule 多个支持字段启动失败", () => {
|
||||
const errors = validateHttpTarget({
|
||||
expect: { body: [{ contains: "ok", regex: "ok" }] },
|
||||
expect: { body: [{ contains: "ok", json: { path: "$.status" } }] },
|
||||
http: { url: "https://example.com" },
|
||||
name: "test",
|
||||
type: "http",
|
||||
});
|
||||
expect(errors).toContain("只能配置一种规则类型");
|
||||
expect(errors).toContain("直接 matcher 不能与 extractor 混用");
|
||||
});
|
||||
|
||||
test("body rule 缺少支持字段启动失败", () => {
|
||||
@@ -789,7 +789,7 @@ describe("HttpChecker", () => {
|
||||
name: "test",
|
||||
type: "http",
|
||||
});
|
||||
expect(errors).toContain("缺少支持的规则类型");
|
||||
expect(errors).toContain("foo 是未知字段");
|
||||
});
|
||||
|
||||
test("css selector 为空启动失败", () => {
|
||||
|
||||
Reference in New Issue
Block a user