# dsh-message-forward 测试 针对 `lib/client.js` 的回归测试,全部基于**真实 DSH DOM 契约**(从 `app.asar` 里的 `ui-chat` 源码提取的类名与 `data-*` 属性)在 jsdom 中复现。 ```bash node tests/run.mjs # 默认:任何 SKIP 都算失败 node tests/run.mjs --allow-skip # 逃生阀:显式允许带着依赖缺口放行 ``` ## 一次性准备 ```bash cd tests && npm i --no-save jsdom react@18 react-dom@18 ``` 依赖按套件分三档(插件本身不依赖它们,所以没有写进 `package.json`): | 依赖 | 谁要 | 说明 | |---|---|---| | 无 | `test-conformance.mjs`、`test-css-tokens.mjs`、`test-forward-wrap.mjs` | 纯静态检查(读源码 / CSS) | | `jsdom` | `test-extract.mjs`、`test-batch.mjs`、`test-decorator.mjs` | 造真实 DOM 跑提取 / 装饰器 | | `jsdom` + `react` / `react-dom` | `test-primitives.mjs`、`test-entry.mjs` | **`test-entry.mjs` 是唯一真正调 `apply()` 的端到端覆盖**,`test-primitives.mjs` 用 `react-dom/server` 渲染原语;插件运行时从 DSH 的浏览器模块表里取 react,测试环境得自己装 | > **一条命令装完。** `npm i --no-save X` 会把其它同样是 `--no-save` 装进来的包清掉 > (表现为输出里的 `removed N packages`),分两次装会让先前那次的依赖消失,测试随即以 > `Cannot find module .../jsdom/package.json` 失败。 ### SKIP 语义(缺依赖时怎么办) - 缺依赖的套件**一致**走 SKIP 路径:打印 `SKIP (缺什么)` + 安装命令,并以 **0** 退出 (探测集中在 `tests/_deps.mjs` 的 `loadJsdom` / `loadReact`,五个套件共用,见 `tests/_deps.mjs`)。 - `run.mjs` **默认把 SKIP 判为失败**(打印 `FAIL(skip)`,整轮 exit 非 0),并说明缺的是什么、怎么装、 哪些覆盖被跳过了。这正是为了堵住「装了 jsdom 没装 react → 全绿 exit 0,被跳过的恰好是唯一跑 `apply()` 与真实渲染的两套」这个空洞。 - 只有显式传 `--allow-skip` 才允许带着 SKIP 放行(exit 0),并且仍然打印醒目告警。 ## 套件 | 文件 | 覆盖内容 | |---|---| | `test-conformance.mjs` | **插件规范符合性**(`cordis-plugin-development` 技能):清单字段与 exports 子路径、`icon`、`locale/*.json`(及显式导出)、宿主半边的导出形态、客户端只 require 基线运行时、没有 `require("@deepseek-ai/…")`、`Mf*` 原语自洽、词表 zh/en 同键且源码里没有漏网的硬编码中文、`t()` 回落与插值、槽位注册契约、版本兼容性声明矩阵(`dshReleases`) | | `test-extract.mjs` | 单条转发:`assistantTurnNodes` 行级回溯、只取 `assistant-step` 正文、排除用户消息与「已思考 N 秒」、`turn-error` 回退、分组嵌套穿透 | | `test-batch.mjs` | 多选:`collectUnits` / `unitIdForNode` / `mergeUnits` 的单元识别、按时间顺序合并、未选中项排除;块间不再插 `---` 分隔线、`speakers` 按实际出现过的角色去重(`user,model` / 仅模型 / 仅用户)并随 payload 传给弹窗 | | `test-forward-wrap.mjs` | **转发引文的成对边界**:词表里的开 / 闭标签(zh / en 逐字相同、不再有 `source=` / `role=`、`modal.roleBatchSource` 不得复活);成对包裹(含空 / `null` 正文);**反伪造**(正文里的 `