From ccc5fc4f1f5a0a8319c5dac093579cd5915758d7 Mon Sep 17 00:00:00 2001 From: unanmed <1319491857@qq.com> Date: Mon, 14 Sep 2026 18:22:57 +0800 Subject: [PATCH] docs(06): cover ReplaySystem in 06-09 replay save/load round trips (D-42) --- .planning/phases/06-unit-tests/06-09-PLAN.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/.planning/phases/06-unit-tests/06-09-PLAN.md b/.planning/phases/06-unit-tests/06-09-PLAN.md index 272670d..a6d2e27 100644 --- a/.planning/phases/06-unit-tests/06-09-PLAN.md +++ b/.planning/phases/06-unit-tests/06-09-PLAN.md @@ -23,7 +23,7 @@ must_haves: truths: - "TEST-01 由数据端行为单测满足,门禁为固定非 watch 命令 `pnpm test:ci` 全绿(D-08)。" - "存读档集中:本计划是唯一测试 `saveState`/`loadState` 的计划;其它计划一律不测(D-32 / D-42)。" - - "接口全覆盖:所有覆盖系统内含 `saveState`/`loadState` 的类(Enemy/special、EnemyManager、HeroAttribute/modifier、HeroLocation、HeroState、HeroEquipment、EquipmentState/HeroEquipsStore、HeroItems、HeroFollower、HeroRendering、MapState、GameMap、MapLayer、StaticTile、DynamicTile、ReplayArray、FlagSystem)的这两个方法至少一条正常用例;`CoreState` 的公开 `saveState`/`loadState` 亦经顶层入口覆盖(D-45);名称含 legacy 的接口/方法排除(D-30 / D-42)。" + - "接口全覆盖:所有覆盖系统内含 `saveState`/`loadState` 的类(Enemy/special、EnemyManager、HeroAttribute/modifier、HeroLocation、HeroState、HeroEquipment、EquipmentState/HeroEquipsStore、HeroItems、HeroFollower、HeroRendering、MapState、GameMap、MapLayer、StaticTile、DynamicTile、ReplayArray、ReplaySystem、FlagSystem)的这两个方法至少一条正常用例(`ReplaySystem.saveState()`/`loadState(state)` 承载其已注册指令/route/录像状态,须有同实例往返正常用例);`CoreState` 的公开 `saveState`/`loadState` 亦经顶层入口覆盖(D-45);名称含 legacy 的接口/方法排除(D-30 / D-42)。" - "code 全覆盖:本计划可达的码 55(MapStore load 缺 reference)、58(equipment store load 找不到 maxUid)、59(equipment load 找不到 item raw data)、112(重复 saveable id)、113(bindSaveableExecuter 目标未添加)、119(loadState 缺 prefab)、120(loadState 缺 special)、122(MapStore load 楼层缺失)、124(MapLayer load 引用缺失)、177(CoreState.loadState 存档缺 saveable key)、178(CoreState.loadState 存档含未加载的 key)各至少一条触发断言(D-31 / D-42 / D-45)。" - "往返形式为**同实例恢复**:对可存档对象 `saveState` → 继续修改状态 → `loadState` → 关键字段回到存档点(D-12)。" - "压缩档全覆盖:`NoCompression`/`LowCompression`/`HighCompression` 三档(按各 `saveState`/`loadState` 签名适用者)(D-11 / D-42)。" @@ -44,7 +44,7 @@ must_haves: - path: packages-user/data-base/src/map/saveLoad.test.ts provides: 地图各层/tile 存读档覆盖(55/122/124) - path: packages-user/data-common/src/replay/saveLoad.test.ts - provides: ReplayArray 存读档覆盖 + provides: ReplayArray 与 ReplaySystem 存读档覆盖 - path: packages-user/data-base/src/flag/saveLoad.test.ts provides: FlagSystem 存读档覆盖 - path: packages-user/data-state/test/saveablesRoundTrip.test.ts @@ -97,6 +97,7 @@ Output: 6 个 `*.test.ts` 与 `06-SAVE-EXCLUSIONS.md`。 @packages-user/data-base/src/map/mapState.ts @packages-user/data-base/src/map/mapLayer.ts @packages-user/data-common/src/replay/array.ts +@packages-user/data-common/src/replay/system.ts @@ -198,7 +199,7 @@ Output: 6 个 `*.test.ts` 与 `06-SAVE-EXCLUSIONS.md`。 - 阶段 2(组合/流水线):map + replay + flag 各类同实例往返(码 55/122/124) + 阶段 2(组合/流水线):map + replay + flag 各类同实例往返(replay 含 ReplaySystem/ReplayArray;码 55/122/124) packages-user/data-base/src/map/saveLoad.test.ts, packages-user/data-common/src/replay/saveLoad.test.ts, packages-user/data-base/src/flag/saveLoad.test.ts packages-user/data-base/src/map/mapState.ts @@ -207,6 +208,7 @@ Output: 6 个 `*.test.ts` 与 `06-SAVE-EXCLUSIONS.md`。 packages-user/data-base/src/map/staticTile.ts packages-user/data-base/src/map/dynamicTile.ts packages-user/data-common/src/replay/array.ts + packages-user/data-common/src/replay/system.ts packages-user/data-base/src/flag/system.ts packages-user/data-base/src/map/mapLifecycle.test.ts .planning/phases/06-unit-tests/06-PATTERNS.md(D/E/F 节) @@ -219,17 +221,19 @@ Output: 6 个 `*.test.ts` 与 `06-SAVE-EXCLUSIONS.md`。 - StaticTile/DynamicTile:关键 num 与覆盖事件恢复。 - 只断言关键字段(D-13)。 - `replay/saveLoad.test.ts`:`ReplayArray.saveState`/`loadState` 同实例往返:命令与参数(含 boolean/整数/bigint/string/数组)读回一致;不比较内部容量/元数据。 + `replay/saveLoad.test.ts`:覆盖 `ReplaySystem` 与 `ReplayArray` 两者的同实例往返(不新增码): + - `ReplaySystem.saveState()`/`loadState(state)`(D-42:其实现 `ISaveableContent`,见 `data-common/src/replay/system.ts`)同实例往返:先 `registerCommand` 注册指令并 `record` 若干录像步 → `saveState()` → 继续 `record` 新步/改动 `replaying`、`sandbox` 等 → `loadState(snapshot)` → **显式关键字段断言**——录像步数(`length`)、`commandWidth`、`getCommandArray()`/`getParamArray()` 关键命令与参数(含 boolean/整数/bigint/string/数组)读回一致;并断言已注册指令经 `getCommand(code)` 仍可取回、`route` 状态回到存档点。不比较内部容量/元数据(D-13)。 + - `ReplayArray.saveState`/`loadState` 同实例往返:命令与参数(含 boolean/整数/bigint/string/数组)读回一致;不比较内部容量/元数据。 `flag/saveLoad.test.ts`:`FlagSystem.saveState()`(无压缩参数)/`loadState` 同实例往返:已知字段值 + `occupied` 恢复;`saveState` 返回分离克隆。 pnpm exec vitest run packages-user/data-base/src/map/saveLoad.test.ts packages-user/data-common/src/replay/saveLoad.test.ts packages-user/data-base/src/flag/saveLoad.test.ts - 运行失败,或 55/122/124 中任一码未被观测,或某类缺少同实例往返断言 + 运行失败,或 55/122/124 中任一码未被观测,或某类缺少同实例往返断言,或 `ReplaySystem`/`ReplayArray` 任一缺少同实例往返关键字段断言 - 三个文件零非跳过失败。 - - map/replay/flag 各类同实例往返;断言码 55/122/124。 + - map/replay/flag 各类同实例往返(replay 含 `ReplaySystem` 与 `ReplayArray` 两者);断言码 55/122/124。 - 只用关键字段显式断言,无整体深度相等。 - 每个 `it` 前有单行中文注释。 - D-44 门禁通过:改动文件 `eslint --fix` 后 `eslint <改动文件>` 0 错误;本计划改动的测试文件在 `pnpm exec vue-tsc --noEmit` 输出中按文件路径过滤 0 类型错误;`pnpm test:ci` 全绿。 @@ -319,7 +323,7 @@ Inline helper symbols: - `enemy/saveLoad.test.ts`: `createEnemy`、`SAVE_COMPRESSIONS` - `hero/saveLoad.test.ts`: `createState`、`createHeroState`、`SAVE_COMPRESSIONS` - `map/saveLoad.test.ts`: `createMapState`、`SAVE_COMPRESSIONS` -- `replay/saveLoad.test.ts`: `createArray`、`createRoute` +- `replay/saveLoad.test.ts`: `createArray`、`createRoute`、`createSystem` - `flag/saveLoad.test.ts`: `createFlags` - `saveablesRoundTrip.test.ts`: `SAVEABLE_IDS`、`COMPRESSIONS`、`mutateKeyField`