refactor: 移除 success 字段,简化为 matched 单层判定模型
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-05-09
|
||||
@@ -0,0 +1,112 @@
|
||||
## Context
|
||||
|
||||
当前 expect 校验通过 `checkExpect()` 函数(`src/server/checker/fetcher.ts`)实现,仅支持 status 白名单、bodyContains 子串匹配、maxLatencyMs 延迟阈值。body 校验能力薄弱,无法处理 JSON 结构化数据和 HTML/XML 页面内容校验。
|
||||
|
||||
本次设计将 body 校验扩展为五种可组合方法,并引入操作符系统统一提取值的比较逻辑。同时新增响应头校验。
|
||||
|
||||
项目约束:Bun 1.3.13 运行时、TypeScript、SQLite 持久化、YAML 配置格式。
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
- body 校验支持五大方法:contains、regex、json、css、xpath,任意 AND 组合
|
||||
- 操作符系统:equals(默认)、contains、match、empty、exists、gte、lte、gt、lt
|
||||
- 响应头校验 headers
|
||||
- 保持 matched/success 两层判定模型不变
|
||||
- 所有新逻辑有完整单元测试
|
||||
|
||||
**Non-Goals:**
|
||||
- 不支持 json/csv/xpath 的 OR 组合(当前全 AND)
|
||||
- 不支持 JSONPath 的通配符/过滤器(`.items[*].name`、`.items[?(@.price>10)]`)
|
||||
- 不支持 CSS 伪类选择器(如 `:nth-child`)
|
||||
- 不改变前端 Dashboard UI
|
||||
- 不做告警通知
|
||||
|
||||
## Decisions
|
||||
|
||||
### D1: body 分组嵌套结构
|
||||
|
||||
选择 `expect.body.<method>` 而非平铺 `expect.bodyXxx`。
|
||||
|
||||
**理由**:五种 body 方法语义上同属一层,嵌套结构比平铺更清晰,YAML 可读性更好。代价是将 `bodyContains` 从 `ExpectConfig` 顶层迁移至 `body.contains`,属于 **BREAKING** 变更,但项目尚在早期,影响极小。
|
||||
|
||||
**替代方案**:平铺 `expect.bodyContains`、`expect.bodyRegex` 等。不选,因随着方法增多字段名会越来越长且缺乏层次。
|
||||
|
||||
### D2: 操作符采用"标量=equals,对象=显式"的二态模型
|
||||
|
||||
```yaml
|
||||
json:
|
||||
$.status: ok # 标量 → equals
|
||||
$.data.count: # 对象 → 显式操作符
|
||||
gte: 1
|
||||
```
|
||||
|
||||
**理由**:90% 的拨测场景只需要等值比较,标量语法最简洁。需要复杂比较时展开为对象,二态在同一个 map 中共存,无需额外字段指示意图。
|
||||
|
||||
**替代方案**:每个规则必须是 `{ path, operator, value }` 对象。过于冗长,不如二态模型灵活。
|
||||
|
||||
### D3: CSS 选择器通过 `attr` 切换提取维度
|
||||
|
||||
```yaml
|
||||
css:
|
||||
"div.status": OK # 默认 textContent
|
||||
"meta[name=build-hash]": # 提取属性
|
||||
attr: content
|
||||
empty: false
|
||||
```
|
||||
|
||||
**理由**:99% 的 CSS 选择器场景只需要 textContent。通过可选的 `attr` 字段覆盖属性提取场景,保持常见用法最简。
|
||||
|
||||
**替代方案**:在选择器字符串中编码(如 `meta[name=build]@content`)。不选,语法污染。
|
||||
|
||||
### D4: 依赖选型 cheerio + xpath + @xmldom/xmldom
|
||||
|
||||
| 包 | 用途 | 选型理由 |
|
||||
|----|------|---------|
|
||||
| cheerio | CSS 选择器 HTML 解析 | npm 27M+ 周下载,jQuery API 熟悉度高,依赖树由同一组织维护 |
|
||||
| xpath | XPath 1.0 引擎 | npm 600K+ 周下载,轻量,业界标准 |
|
||||
| @xmldom/xmldom | xpath 的 DOM 实现 | 2M+ 周下载,xmldom 官方维护 |
|
||||
|
||||
**替代方案**:jsdom(体积大,~200KB)、linkedom(不支持 XPath)。不选。
|
||||
|
||||
cheerio 和 xpath 使用不同的 DOM 模型,同一个 HTML body 需要各自解析。拨测场景(秒级频率,非高并发 HTML 解析)性能开销可忽略。
|
||||
|
||||
### D5: body 方法按需解析,短路 AND 执行
|
||||
|
||||
整体 checkExpect 执行顺序为 `status → headers → body → maxLatencyMs`,均为 AND 短路。body 内部执行顺序:
|
||||
|
||||
```
|
||||
body 内部:
|
||||
1. contains → 文本匹配,失败立即返回
|
||||
2. regex → 文本匹配,失败立即返回
|
||||
3. json → 仅当 json 配置存在时解析 JSON(否则跳过)
|
||||
4. css → 仅当 css 配置存在时解析 HTML(cheerio)
|
||||
5. xpath → 仅当 xpath 配置存在时解析 HTML/XML(xmldom)
|
||||
|
||||
解析失败(JSON.parse 异常、cheerio 加载失败)→ matched=false
|
||||
```
|
||||
|
||||
**理由**:避免不必要的解析开销(例如只配了 contains 时不解析 JSON/HTML)。AND 短路语义与现有 expect 规则保持一致。
|
||||
|
||||
### D6: 操作符的类型转换策略
|
||||
|
||||
| 操作符 | 提取值类型 | 转换逻辑 |
|
||||
|--------|-----------|---------|
|
||||
| equals | 保留原类型 | strict === 比较 |
|
||||
| contains | 强制 toString() | actual.toString().includes(expected) |
|
||||
| match | 强制 toString() | new RegExp(pattern).test(actual.toString()) |
|
||||
| empty | - | null、undefined、""、[]、{} → 判定为空 |
|
||||
| exists | - | undefined vs 非 undefined |
|
||||
| gte/lte/gt/lt | 强制 Number() | Number(actual) >= expected |
|
||||
|
||||
CSS/XPath 提取的值始终是 string,数字比较时自动 Number() 转换。JSON 提取的值保留原类型(number/boolean/null/string)。
|
||||
|
||||
单个提取值可配置多个操作符(如 `{gte: 10, lte: 100}`),所有操作符全部通过才算该字段通过,语义为 AND。
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- **[兼容性风险]** `bodyContains` → `body.contains` 是 BREAKING 变更 → 通过 README 和示例配置文件说明,现有用户量极小,影响可控
|
||||
- **[性能风险]** cheerio 和 xpath 各自解析 HTML → 同一 body 可能解析两次 → 拨测场景下无需缓存,单次解析耗时 <5ms,整体影响可忽略
|
||||
- **[JSONPath 功能局限]** 自实现简易路径解析不支持通配符和过滤器 → 通过文档说明限制,后续可按需增强
|
||||
- **[XPath 浏览器兼容]** xpath 使用 xmldom 而非浏览器原生 evaluate → 语义上等价,测试覆盖保证行为正确
|
||||
- **[依赖体积]** 新增 3 个包增加约 95KB → 这是 executable 构建,Bun compile 会打包进二进制,对最终产物影响有限
|
||||
@@ -0,0 +1,39 @@
|
||||
## Why
|
||||
|
||||
当前 expect 规则仅有 `status`、`bodyContains`、`maxLatencyMs` 三条,无法满足 API 网关拨测中对 JSON 返回值字段校验、HTML 页面内容校验、响应头校验等常见需求。body 校验能力单薄(仅子串匹配),需要增强为多种可组合的校验方法,覆盖主流响应格式。
|
||||
|
||||
## What Changes
|
||||
|
||||
- 新增 `headers` 规则,支持按响应头键值对校验
|
||||
- 重构 body 校验:将独立的 `bodyContains` 移至 `body` 分组下,新增五种 body 校验方法:
|
||||
- `contains`:子串匹配(从原 `bodyContains` 迁移)
|
||||
- `regex`:正则表达式全文匹配
|
||||
- `json`:JSONPath 提取值后比较
|
||||
- `css`:CSS 选择器提取 HTML 元素文本/属性后比较
|
||||
- `xpath`:XPath 提取 XML/HTML 节点后比较
|
||||
- body 五种方法可任意组合,AND 串联
|
||||
- 新增操作符系统:`equals`(默认)、`contains`、`match`(正则)、`empty`、`exists`、`gte`、`lte`、`gt`、`lt`
|
||||
- 新增依赖:`cheerio`(CSS 选择器)、`xpath` + `@xmldom/xmldom`(XPath 引擎)
|
||||
- **BREAKING**:`expect.bodyContains` 迁移至 `expect.body.contains`
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `expect-body-checkers`:body 响应校验方法集(contains/regex/json/css/xpath)及操作符系统
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `probe-config`:expect 配置 schema 变更,新增 headers/body 分组,bodyContains 迁移
|
||||
- `probe-engine`:checkExpect 函数扩展,支持新的 body 校验方法和操作符
|
||||
|
||||
## Impact
|
||||
|
||||
- 类型定义:`src/server/checker/types.ts`(ExpectConfig/BodyExpectConfig/ExpectOperator)
|
||||
- 配置加载:`src/server/checker/config-loader.ts`(解析新的 expect 结构)
|
||||
- 拨测执行:`src/server/checker/fetcher.ts`(checkExpect 扩展)
|
||||
- 数据存储:`src/server/checker/store.ts`(expect JSON 序列化兼容)
|
||||
- 前端展示:状态判定逻辑不变(matched 字段语义不变)
|
||||
- 配置文件:`probes.example.yaml`(更新示例)
|
||||
- README.md:更新配置文档
|
||||
- 依赖:`package.json` 新增 cheerio、xpath、@xmldom/xmldom
|
||||
@@ -0,0 +1,113 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: 响应体多种校验方法
|
||||
系统 SHALL 支持对 HTTP 响应体进行五种可组合的校验方法:contains(子串)、regex(正则)、json(JSONPath)、css(CSS 选择器)、xpath(XPath),配置在 `expect.body` 分组下。
|
||||
|
||||
#### Scenario: contains 子串匹配
|
||||
- **WHEN** 目标配置 `expect.body.contains: "healthy"`,且响应体包含 `"healthy"`
|
||||
- **THEN** 系统 SHALL 判定 matched 为 true
|
||||
|
||||
#### Scenario: contains 不匹配
|
||||
- **WHEN** 目标配置 `expect.body.contains: "healthy"`,且响应体不包含该文本
|
||||
- **THEN** 系统 SHALL 判定 matched 为 false
|
||||
|
||||
#### Scenario: regex 正则匹配
|
||||
- **WHEN** 目标配置 `expect.body.regex: '"status"\\s*:\\s*"ok"'`,且响应体匹配该正则
|
||||
- **THEN** 系统 SHALL 判定 matched 为 true
|
||||
|
||||
#### Scenario: regex 不匹配
|
||||
- **WHEN** 目标配置 `expect.body.regex: '"status"\\s*:\\s*"ok"'`,且响应体不匹配该正则
|
||||
- **THEN** 系统 SHALL 判定 matched 为 false
|
||||
|
||||
#### Scenario: json JSONPath 等值匹配
|
||||
- **WHEN** 目标配置 `expect.body.json: {"$.status": "ok"}`,且响应 JSON 中 `$.status` 值为 `"ok"`
|
||||
- **THEN** 系统 SHALL 判定 matched 为 true
|
||||
|
||||
#### Scenario: json JSONPath 值不匹配
|
||||
- **WHEN** 目标配置 `expect.body.json: {"$.status": "ok"}`,且响应 JSON 中 `$.status` 值为 `"error"`
|
||||
- **THEN** 系统 SHALL 判定 matched 为 false
|
||||
|
||||
#### Scenario: json 解析失败
|
||||
- **WHEN** 目标配置了 `expect.body.json` 但响应体不是合法 JSON
|
||||
- **THEN** 系统 SHALL 判定 matched 为 false
|
||||
|
||||
#### Scenario: css 选择器匹配
|
||||
- **WHEN** 目标配置 `expect.body.css: {"div#health": "OK"}`,且 HTML 中存在 `div#health` 元素文本为 `"OK"`
|
||||
- **THEN** 系统 SHALL 判定 matched 为 true
|
||||
|
||||
#### Scenario: css 选择器匹配属性值
|
||||
- **WHEN** 目标配置 css 规则带 `attr: "content"` 用于提取属性,且属性值匹配期望
|
||||
- **THEN** 系统 SHALL 判定 matched 为 true
|
||||
|
||||
#### Scenario: css 选择器无匹配元素
|
||||
- **WHEN** 目标配置了 css 选择器但 HTML 中无匹配元素
|
||||
- **THEN** 系统 SHALL 判定 matched 为 false
|
||||
|
||||
#### Scenario: xpath 表达式匹配
|
||||
- **WHEN** 目标配置 `expect.body.xpath: {"/root/status/text()": "ok"}`,且 XML 中 `/root/status` 节点文本为 `"ok"`
|
||||
- **THEN** 系统 SHALL 判定 matched 为 true
|
||||
|
||||
#### Scenario: xpath 表达式无匹配节点
|
||||
- **WHEN** 目标配置了 xpath 表达式但 XML 中无匹配节点
|
||||
- **THEN** 系统 SHALL 判定 matched 为 false
|
||||
|
||||
### Requirement: 多种 body 校验方法 AND 组合
|
||||
系统 SHALL 支持同时配置多种 body 校验方法,所有方法均通过时 matched 方为 true。
|
||||
|
||||
#### Scenario: 多种方法全部通过
|
||||
- **WHEN** 目标同时配置 `body.contains`、`body.json`、`body.regex`,且全部通过
|
||||
- **THEN** 系统 SHALL 判定 matched 为 true
|
||||
|
||||
#### Scenario: 多种方法任一失败
|
||||
- **WHEN** 目标同时配置 `body.contains` 和 `body.json`,且 `body.contains` 不通过
|
||||
- **THEN** 系统 SHALL 判定 matched 为 false,且不再检查 `body.json`
|
||||
|
||||
### Requirement: 操作符系统
|
||||
系统 SHALL 支持对 body 校验的提取值使用以下操作符进行比较:equals(默认等值)、contains(子串包含)、match(正则匹配)、empty(空值判断)、exists(存在性判断)、gte/lte/gt/lt(数值比较)。
|
||||
|
||||
#### Scenario: 标量值隐式 equals
|
||||
- **WHEN** jsonPath 配置的期望值为标量(字符串/数字/布尔/null),如 `$.status: ok`
|
||||
- **THEN** 系统 SHALL 使用 equals 操作符,对提取值做严格相等比较
|
||||
|
||||
#### Scenario: 显式 contains 操作符
|
||||
- **WHEN** 配置 `$.message: {contains: "success"}`,且提取值包含 `"success"`
|
||||
- **THEN** 系统 SHALL 判定 matched 为 true
|
||||
|
||||
#### Scenario: 显式 match 操作符
|
||||
- **WHEN** 配置 `$.version: {match: '\\d+\\.\\d+\\.\\d+'}`,且提取值匹配该正则
|
||||
- **THEN** 系统 SHALL 判定 matched 为 true
|
||||
|
||||
#### Scenario: empty 操作符判断为空
|
||||
- **WHEN** 配置 `$.items: {empty: true}`,且提取值为空数组 `[]`
|
||||
- **THEN** 系统 SHALL 判定 matched 为 true
|
||||
|
||||
#### Scenario: empty 操作符判断非空
|
||||
- **WHEN** 配置 `$.items: {empty: false}`,且提取值为 `[1, 2]`
|
||||
- **THEN** 系统 SHALL 判定 matched 为 true
|
||||
|
||||
#### Scenario: exists 操作符判断存在
|
||||
- **WHEN** 配置 `$.error: {exists: false}`,且 JSON 中不存在 `error` 字段
|
||||
- **THEN** 系统 SHALL 判定 matched 为 true
|
||||
|
||||
#### Scenario: gte 数值比较
|
||||
- **WHEN** 配置 `$.count: {gte: 10}`,且提取值为 `15`(数字)
|
||||
- **THEN** 系统 SHALL 判定 matched 为 true
|
||||
|
||||
#### Scenario: gt/lt 数值比较
|
||||
- **WHEN** 配置 `$.latency: {gt: 0, lt: 1000}`,且提取值为 `500`
|
||||
- **THEN** 系统 SHALL 对同一字段进行多操作符复合比较,全部通过则 matched 为 true
|
||||
|
||||
### Requirement: 响应头校验
|
||||
系统 SHALL 支持通过 `expect.headers` 配置对响应头进行键值对校验。
|
||||
|
||||
#### Scenario: 响应头匹配
|
||||
- **WHEN** 目标配置 `expect.headers: {"Content-Type": "application/json"}`,且响应包含该 header 且值匹配
|
||||
- **THEN** 系统 SHALL 判定 matched 为 true
|
||||
|
||||
#### Scenario: 响应头不匹配
|
||||
- **WHEN** 目标配置 `expect.headers: {"Content-Type": "application/json"}`,且响应 header 值为 `"text/html"`
|
||||
- **THEN** 系统 SHALL 判定 matched 为 false
|
||||
|
||||
#### Scenario: 响应头缺失
|
||||
- **WHEN** 目标配置了某个 header 但响应中不存在该 header
|
||||
- **THEN** 系统 SHALL 判定 matched 为 false
|
||||
@@ -0,0 +1,21 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: expect 配置增强
|
||||
系统 SHALL 支持增强的 expect 配置格式,包括 `headers` 响应头校验和 `body` 分组下的多种校验方法(contains、regex、json、css、xpath)。
|
||||
|
||||
#### Scenario: 解析增强的 expect 配置
|
||||
- **WHEN** YAML 配置文件中 target 的 expect 包含 headers、body 分组及内部方法
|
||||
- **THEN** 系统 SHALL 正确解析并存储为 ResolvedTarget 的 expect 字段
|
||||
|
||||
#### Scenario: 解析仅含 body.contains 的最简配置
|
||||
- **WHEN** YAML 中 target 配置 `expect.body.contains: "healthy"`
|
||||
- **THEN** 系统 SHALL 正确解析,功能等价于旧版 `expect.bodyContains`
|
||||
|
||||
#### Scenario: 不配置 expect
|
||||
- **WHEN** target 未配置任何 expect 规则
|
||||
- **THEN** 系统 SHALL 正常处理,expect 字段为 undefined
|
||||
|
||||
#### Scenario: 旧版 bodyContains 字段不再支持
|
||||
- **WHEN** YAML 中使用 `expect.bodyContains: "xxx"` 格式
|
||||
- **THEN** 该字段 SHALL 被忽略(系统仅识别 `expect.body.contains`)
|
||||
- **Migration**: 将配置文件中 `expect.bodyContains: "xxx"` 改为 `expect.body.contains: "xxx"`
|
||||
@@ -0,0 +1,61 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: expect 校验
|
||||
系统 SHALL 在拨测完成后根据目标的 expect 配置校验响应,校验结果记入 check result。
|
||||
|
||||
#### Scenario: 校验状态码
|
||||
- **WHEN** 目标配置了 `expect.status: [200, 201]`
|
||||
- **THEN** 系统 SHALL 检查响应状态码是否在列表中,将匹配结果记录到 matched 字段
|
||||
|
||||
#### Scenario: 校验响应头
|
||||
- **WHEN** 目标配置了 `expect.headers: {"Content-Type": "application/json"}`
|
||||
- **THEN** 系统 SHALL 检查响应头是否包含指定键值对,全部匹配时将 matched 设为 true
|
||||
|
||||
#### Scenario: 校验响应体包含
|
||||
- **WHEN** 目标配置了 `expect.body.contains: "healthy"`
|
||||
- **THEN** 系统 SHALL 检查响应体是否包含该文本,将匹配结果记录到 matched 字段
|
||||
|
||||
#### Scenario: 校验响应体正则
|
||||
- **WHEN** 目标配置了 `expect.body.regex: '"status"\\s*:\\s*"ok"'`
|
||||
- **THEN** 系统 SHALL 检查响应体是否匹配该正则,将匹配结果记录到 matched 字段
|
||||
|
||||
#### Scenario: 校验 JSON 响应
|
||||
- **WHEN** 目标配置了 `expect.body.json: {"$.status": "ok"}`
|
||||
- **THEN** 系统 SHALL 解析 JSON 并检查 JSONPath 对应值是否符合期望,将匹配结果记录到 matched 字段
|
||||
|
||||
#### Scenario: 校验 HTML 响应(CSS 选择器)
|
||||
- **WHEN** 目标配置了 `expect.body.css: {"div#health": "OK"}`
|
||||
- **THEN** 系统 SHALL 解析 HTML 并用 CSS 选择器提取元素文本进行比较,将匹配结果记录到 matched 字段
|
||||
|
||||
#### Scenario: 校验 HTML/XML 响应(XPath)
|
||||
- **WHEN** 目标配置了 `expect.body.xpath: {"/root/status/text()": "ok"}`
|
||||
- **THEN** 系统 SHALL 解析文档并用 XPath 提取节点文本进行比较,将匹配结果记录到 matched 字段
|
||||
|
||||
#### Scenario: 校验延迟阈值
|
||||
- **WHEN** 目标配置了 `expect.maxLatencyMs: 3000`
|
||||
- **THEN** 系统 SHALL 检查实际延迟是否超过阈值,将匹配结果记录到 matched 字段
|
||||
|
||||
#### Scenario: 无 expect 配置
|
||||
- **WHEN** 目标未配置任何 expect 规则
|
||||
- **THEN** 系统 SHALL 将 matched 字段设为 true
|
||||
|
||||
#### Scenario: 多条 expect 规则
|
||||
- **WHEN** 目标同时配置了 status、headers、body.contains、body.json 和 maxLatencyMs
|
||||
- **THEN** 系统 SHALL 所有规则全部通过时 matched 为 true,任一不通过则为 false
|
||||
|
||||
#### Scenario: 多种 body 方法 AND 组合
|
||||
- **WHEN** 目标在 body 分组下配置了 contains、json、css 多种方法
|
||||
- **THEN** 系统 SHALL 按 contains → regex → json → css → xpath 顺序执行,任一失败立即返回 false
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Body 校验按需解析
|
||||
系统 SHALL 仅在配置了对应 body 校验方法时才解析响应体为对应格式,避免不必要的解析开销。
|
||||
|
||||
#### Scenario: 仅配置 contains 时不解析 JSON
|
||||
- **WHEN** 目标仅配置 `expect.body.contains` 而未配置 json/css/xpath
|
||||
- **THEN** 系统 SHALL 不执行 JSON.parse 或 HTML/XML 解析
|
||||
|
||||
#### Scenario: 配置 json 时解析 JSON 失败
|
||||
- **WHEN** 目标配置了 `expect.body.json` 但响应体不是合法 JSON
|
||||
- **THEN** 系统 SHALL 判定 matched 为 false
|
||||
@@ -0,0 +1,53 @@
|
||||
## 1. 依赖安装
|
||||
|
||||
- [x] 1.1 安装 cheerio、xpath、@xmldom/xmldom 依赖
|
||||
|
||||
## 2. 类型定义
|
||||
|
||||
- [x] 2.1 在 types.ts 中定义 ExpectOperator、BodyExpectConfig 接口
|
||||
- [x] 2.2 更新 ExpectConfig 接口,新增 headers 字段,将 bodyContains 替换为 body 分组
|
||||
- [x] 2.3 新增 CssExpect 类型(ExpectValue | ExpectOperator & { attr?: string })
|
||||
- [x] 2.4 导出 ExpectValue 联合类型
|
||||
|
||||
## 3. Body 校验核心实现
|
||||
|
||||
- [x] 3.1 实现简易 JSONPath 求值函数 evaluateJsonPath(支持 $.a.b、$.a[0].b 等基本路径)
|
||||
- [x] 3.2 实现操作符比较函数 applyOperator(equals/contains/match/empty/exists/gte/lte/gt/lt)
|
||||
- [x] 3.3 实现 checkExpectValue 函数:标量 → equals,对象 → 遍历操作符
|
||||
- [x] 3.4 实现 checkBodyContains:body.includes 包装
|
||||
- [x] 3.5 实现 checkBodyRegex:new RegExp().test 包装
|
||||
- [x] 3.6 实现 checkBodyJson:JSON.parse + evaluateJsonPath + applyOperator
|
||||
- [x] 3.7 实现 checkBodyCss:cheerio.load + 选择器查询 + text/attr 提取 + applyOperator
|
||||
- [x] 3.8 实现 checkBodyXpath:xmldom 解析 + xpath 引擎 evaluate + applyOperator
|
||||
|
||||
## 4. Expect 校验重构
|
||||
|
||||
- [x] 4.1 重构 checkExpect 函数,新增 headers 检查逻辑
|
||||
- [x] 4.2 将 bodyContains 检查替换为 checkBodyExpect 调用,按需分发到五种子方法
|
||||
- [x] 4.3 实现 checkBodyExpect 主入口:按 contains → regex → json → css → xpath 顺序 AND 短路执行
|
||||
|
||||
## 5. 配置加载
|
||||
|
||||
- [x] 5.1 确认 config-loader 中 expect 透传逻辑对新结构的兼容性,更新类型引用
|
||||
|
||||
## 6. 数据存储兼容
|
||||
|
||||
- [x] 6.1 验证 store.ts 中 expect JSON 序列化对新结构的兼容性,必要时调整
|
||||
|
||||
## 7. 测试
|
||||
|
||||
- [x] 7.1 为 evaluateJsonPath 编写单元测试(嵌套对象、数组索引、不存在路径、边界情况)
|
||||
- [x] 7.2 为 applyOperator 编写单元测试(9 种操作符各至少 2 个 case)
|
||||
- [x] 7.3 为 checkBodyContains/checkBodyRegex 编写单元测试
|
||||
- [x] 7.4 为 checkBodyJson 编写单元测试(等值匹配、操作符匹配、JSON 解析失败、路径不存在)
|
||||
- [x] 7.5 为 checkBodyCss 编写单元测试(text 提取、attr 提取、无匹配元素)
|
||||
- [x] 7.6 为 checkBodyXpath 编写单元测试(节点文本、属性值、无匹配节点、XML 解析失败)
|
||||
- [x] 7.7 为 checkExpect 新增测试用例(headers 校验、body 多种方法 AND 组合、全量规则)
|
||||
- [x] 7.8 更新 config-loader 测试用例(新 expect 格式解析、向后兼容验证)
|
||||
- [x] 7.9 端到端模拟测试:构造完整 expect 配置并验证 checkExpect 整体行为
|
||||
|
||||
## 8. 文档与示例
|
||||
|
||||
- [x] 8.1 更新 probes.example.yaml,展示 headers 和 body 分组全部用法示例
|
||||
- [x] 8.2 更新 README.md 配置说明章节,补充 expect.body 和 headers 的文档
|
||||
- [x] 8.3 更新 README.md 依赖列表(如有需要)
|
||||
Reference in New Issue
Block a user