diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index 5a70029..d5ca330 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -35,7 +35,7 @@ Requirements for the engine's completion. Each maps to roadmap phases. ### 测试(Testing) - [ ] **TEST-01**: 为核心系统(数据层等)补齐单元测试 -- [ ] **TEST-02**: 测试文件统一归入 `__test__` 目录,并按数据端当前接口对齐既有测试、修复重构遗漏导致的测试失效 +- [x] **TEST-02**: 测试文件统一归入 `__test__` 目录,并按数据端当前接口对齐既有测试、修复重构遗漏导致的测试失效 ### 数据端缺陷修复(Fix) @@ -68,7 +68,7 @@ Which phases cover which requirements. Updated during roadmap creation. | LEGACY-01 | Phase 5 | Pending | | LEGACY-02 | Phase 5 | Pending | | TEST-01 | Phase 6 | In Progress | -| TEST-02 | Phase 8 | Pending | +| TEST-02 | Phase 8 | Complete | | FIX-01 | Phase 7 | Complete | **Coverage:** diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 8cde271..6ba47d8 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -450,16 +450,16 @@ Plans: 3. 重构遗漏的细节问题已修复(测试面或经用户确认的数据端细节),不弱化既有断言 4. `pnpm test:perf` 仍可运行;不新增跳过用例 -**Plans**: 11 planned(08-01..08-11;规划 2026-10-04,`gsd-plan-checker` 判 PASS / 0 blocker / 3 非阻塞 warning)——迁移 `08-01`(独立先行)→ 子系统对齐 `08-02..08-09` → 错误码与接口覆盖 `08-10` → 收口 `08-11`;每个计划 `autonomous: false`,以 blocking-human Task 0 汇报关卡开头 +**Plans**: 6/11 plans executedned(08-01..08-11;规划 2026-10-04,`gsd-plan-checker` 判 PASS / 0 blocker / 3 非阻塞 warning)——迁移 `08-01`(独立先行)→ 子系统对齐 `08-02..08-09` → 错误码与接口覆盖 `08-10` → 收口 `08-11`;每个计划 `autonomous: false`,以 blocking-human Task 0 汇报关卡开头 Plans: -- [ ] 08-01-PLAN.md — 全量目录迁移到 `__test__/`(Rule A/B 分流改相对导入 + `script/test-data-node.ts:67,122` 硬编码路径;门禁=文件数守恒 66/6、零配置/零生产改动) +- [x] 08-01-PLAN.md — 全量目录迁移到 `__test__/`(Rule A/B 分流改相对导入 + `script/test-data-node.ts:67,122` 硬编码路径;门禁=文件数守恒 66/6、零配置/零生产改动) - [x] 08-02-PLAN.md — data-common 对齐(`utils.test.ts` 退役、`DirectionMapper` 删除、`addHook().load()` 移除、158/175→72;含经确认的 sandbox 首步预读生产修复) - [x] 08-03-PLAN.md — data-base enemy+flag 对齐(真实 `TileStore` + 注册图块、删 legacy bridge、`getPrefab` 签名 `number|string` 类型修正、flag 读档重建语义对齐) - [x] 08-04-PLAN.md — data-base hero 对齐(录像桩 `array`、删 `.load()`、真实 `TileStore`/`ItemStore(tileStore)`、`setFloor(IGameMap|null)`、`getItem`→`addItem`;含经确认的 `equipment.loadState` 读档禁录修复) - [x] 08-05-PLAN.md — data-base map 对齐(`addLayer(alias)`、`MapState(state)`;陈旧码 62/63/64/84/130/125 裁决;含 D-10 生产修复,map 聚焦 108/108 通过) -- [ ] 08-06-PLAN.md — data-system combat+event 对齐(`CombatFlow` 构造、`.load()` 移除、DEV 守卫码) +- [x] 08-06-PLAN.md — data-system combat+event 对齐(`CombatFlow` 构造、`.load()` 移除、DEV 守卫码) - [ ] 08-07-PLAN.md — data-system path 对齐(`useMapState` 删除、`useFaceHandler` 注入) - [ ] 08-08-PLAN.md — data-state src 对齐(`createCoreState` 删除→`CoreState({loadStarter,coreURL})`;`coreEventLayer` A1/A2) - [ ] 08-09-PLAN.md — data-state 集成对齐(共享夹具 `closed-loop.ts`、`tileLegacy` 去留、寻路注入) @@ -483,4 +483,4 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 | 5. Legacy 移植 | 0/TBD | Not started | - | | 6. 单元测试 | 18/18 | In Progress| | | 7. 数据端缺陷修复 | 15/16 | Complete(07-16 superseded) | - | -| 8. 测试重构与接口对齐 | 4/11 | In Progress | - | +| 8. 测试重构与接口对齐 | 6/11 | In Progress| | diff --git a/.planning/STATE.md b/.planning/STATE.md index 66457c6..8fa2fff 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -1,19 +1,19 @@ --- gsd_state_version: "1.0" milestone: v1.0 -current_phase: 04 -current_phase_name: 渲染适配与双布局 +current_phase: 08 +current_phase_name: 测试重构与接口对齐 status: executing -stopped_at: Completed 04-14-PLAN.md(部分 UI 适配·第二步实施:main.tsx 状态栏改在勇士属性对象上 addHook({onUpdateAttribute})(D-78);load.tsx 改接新加载系统 loader.start()/manager.get*(D-74/D-75);删除 restart 注释块与 client.ts/entry-client 旧接线残留(D-76/D-77);生产零外溢;REND-01/REND-02 保持 Pending) -last_updated: "2026-09-30T09:10:00.000Z" -last_activity: 2026-09-30 -last_activity_desc: Completed 04-14-PLAN.md(部分 UI 进一步接口适配·第二步适配实施) -state_head: bc7d631 +stopped_at: Completed 08-06-PLAN.md(combat 4 test + 2 perf 与 event 1 文件对齐 shipped 接口:删 addHook(...).load() 链、CombatFlow/EnemyContext/MapState 单参构造、删 DirectionMapper、事件层改 GameMap.eventLayer;聚焦 96/96 通过、perf 6/6、eslint 0;零生产改动) +last_updated: "2026-10-05T09:30:06.601Z" +last_activity: 2026-10-05 +last_activity_desc: Phase 08 execution started +state_head: e024e2d2ea2ce610d6ca2e79236c074b9985fadb progress: - total_phases: 7 - completed_phases: 1 - total_plans: 85 - completed_plans: 84 + total_phases: 8 + completed_phases: 0 + total_plans: 98 + completed_plans: 92 milestone_name: milestone --- @@ -24,14 +24,14 @@ milestone_name: milestone See: .planning/PROJECT.md (updated 2026-09-17) **Core value:** 引擎能完整跑通一部魔塔——开局到结局,存档、战斗、地图、事件、剧情全链路可玩。 -**Current focus:** Phase 04 — 渲染适配与双布局 +**Current focus:** Phase 08 — 测试重构与接口对齐 ## Current Position -Phase: 04 (渲染适配与双布局) — IN PROGRESS -Plan: 14/14 已执行(04-01..04-14) -Status: 04-14 完成(部分 UI 适配·第二步实施);Phase 4 整体仍未完成 — REND-01/REND-02 保持 Pending -Last activity: 2026-09-30 — Completed 04-14-PLAN.md(部分 UI 进一步接口适配·第二步适配实施) +Phase: 08 (测试重构与接口对齐) — EXECUTING +Plan: 2 of 11 +Status: Ready to execute +Last activity: 2026-10-05 — Phase 08 execution started Progress: [█████░░░░░] 50% @@ -101,6 +101,7 @@ Progress: [█████░░░░░] 50% | Phase 04 P3 | 40min | 4 tasks | 3 files | | Phase 04 P4 | ~45min | 4 tasks | 3 files | | Phase 04 P7 | 35min | 3 tasks | 10 files | +| Phase 08 P06 | 10min | 2 tasks | 3 files | ## Accumulated Context @@ -232,6 +233,9 @@ Recent decisions affecting current work: - [Phase 04]: [Phase 04]: 04-04:hero.ts 弃用 mutate-animate 的 TimingFn<2>,改用 @motajs/animate 的 ExcitationCurve2D;D-28 存量 state.roleFace.getFaceOf 三处与 import 逐字保留;types.ts 单行 addHero 签名与 manager.ts 单行构造调用按仓库惯例加 // prettier-ignore 以同时满足计划的单行静态门禁与 prettier - [Phase 04]: [Phase 04]: 04-07:D-35 裁定 state 一律经构造器注入(ClientCore 传 this、renderer 从 manager.state 取),不取全局单例(D-23);textures 由新建专用 TextureStore 承担(本次范围内无写入者) - [Phase 04]: [Phase 04]: 04-07:D-34 的 getIfBigImage ≡ getTile(bigImageData 唯一写入者 setBigImage 消费者调用点 0),7 处消费者改写行为保持;getOffsetPool 的 big-image 偏移收集删除、其余来源保留 +- [Phase 08]: [Phase 08] 08-06 Q1:combat 测试沿用各文件既有 {} as IStateBase 最小桩装配 CombatFlow/EnemyContext 单参构造,不新建 Phase 6 风格夹具 +- [Phase 08]: [Phase 08] 08-06 Q2:eventDispatch 删除已废弃 DirectionMapper 注入与 import/module 条目、MapState 改单参 commonState;getLayerByAlias 已删故事件层改用 GameMap.eventLayer +- [Phase 08]: [Phase 08] 08-06 Q3(用户授权偏离计划 must_haves):不触发/不补测 DEV 守卫码 98/99/101、忽略无 emit 点错误码;保持 Vitest 默认 mode=test,不改配置;记录于 08-06-SUMMARY Deviations ### Roadmap Evolution @@ -271,6 +275,6 @@ None yet. ## Session Continuity -Last session: 2026-09-22T04:25:51.224Z -Stopped at: Completed 04-07-PLAN.md(material 接口适应实施:big-image 全删、7 处改 getTile、四实现类构造器注入 state、cache.ts legacy 路径删除、补 @user/data-state 声明;material 诊断 19→0、总行数 199→180;REND-01/REND-02 保持 Pending) +Last session: 2026-10-05T09:30:06.319Z +Stopped at: Completed 08-06-PLAN.md(combat 4 test + 2 perf 与 event 1 文件对齐 shipped 接口:删 addHook(...).load() 链、CombatFlow/EnemyContext/MapState 单参构造、删 DirectionMapper、事件层改 GameMap.eventLayer;聚焦 96/96 通过、perf 6/6、eslint 0;零生产改动) Resume file: None diff --git a/.planning/phases/08-test-refactor-alignment/08-06-SUMMARY.md b/.planning/phases/08-test-refactor-alignment/08-06-SUMMARY.md new file mode 100644 index 0000000..8cbbf65 --- /dev/null +++ b/.planning/phases/08-test-refactor-alignment/08-06-SUMMARY.md @@ -0,0 +1,151 @@ +--- +phase: 08-test-refactor-alignment +plan: 06 +subsystem: data-system/combat+event +tags: [test-alignment, combat, event, vitest, zero-production] +status: complete +requires: + - phase: 08-test-refactor-alignment/08-01 + provides: 测试文件迁入 __test__ 目录的基线 +provides: + - "data-system 的 combat(4 test + 2 perf)与 event(1)共 7 个声明测试文件对齐 shipped 接口,聚焦 96/96 通过、perf 6/6 通过" +affects: + - packages-user/data-system/src/combat + - packages-user/data-system/src/event +tech-stack: + added: [] + patterns: + - "CombatFlow/EnemyContext 单参构造以 {} as IStateBase 最小桩装配,不新建重型夹具" + - "已删的 addHook(...).load() 只保留 addHook(...)(Hookable 立即注册)" + - "事件层经 GameMap.eventLayer 获取(IGameMap.getLayerByAlias 已删)" +key-files: + created: [] + modified: + - packages-user/data-system/src/combat/__test__/combat.test.ts + - packages-user/data-system/src/combat/__test__/context.test.ts + - packages-user/data-system/src/event/__test__/eventDispatch.test.ts +decisions: + - "Q1:沿用各 combat 测试文件既有的 {} as IStateBase 最小桩;不新建 Phase 6 风格夹具" + - "Q2:删除 eventDispatch 的 DirectionMapper 注入与 import/module 条目;MapState 改单参 commonState;不重注入 IFaceManager/IFaceHandler" + - "Q3(用户授权偏离计划 must_haves):不触发/不补测 DEV 守卫码 98/99/101,忽略无 emit 点的错误码;保持 Vitest 默认 mode=test,不改构建模式与配置" +requirements-completed: [TEST-02] +actuals: + tokens: 1611 + tasks: 2 + commits: 3 + plan_head_before: 59e190b4689f5ea49b89c1b5545140d0304d0b9f +coverage: + - id: D1 + description: "combat 4 test + 2 perf 对齐 shipped 接口,聚焦 0 失败" + requirement: TEST-02 + verification: + - kind: unit + ref: "pnpm exec vitest run packages-user/data-system/src/combat/__test__ — 4 files / 90 passed / 0 failed" + status: pass + - kind: other + ref: "pnpm exec vitest run --config vitest.perf.config.ts packages-user/data-system/src/combat/__test__ — 2 files / 6 passed / 0 failed" + status: pass + human_judgment: false + - id: D2 + description: "event/eventDispatch 对齐 shipped 接口,聚焦 0 失败" + requirement: TEST-02 + verification: + - kind: unit + ref: "pnpm exec vitest run packages-user/data-system/src/event/__test__ — 1 file / 6 passed / 0 failed" + status: pass + human_judgment: false +duration: 10min +completed: 2026-10-05 +--- + +# 08-06 — combat/event 测试对齐 Summary + +**一句话:** 将 `packages-user/data-system` 的 `combat`(4 test + 2 perf)与 `event`(1)声明测试文件对齐 shipped 接口——删除废弃的 `addHook(...).load()` 链与 `DirectionMapper` 注入、`CombatFlow`/`EnemyContext`/`MapState` 按单参构造装配、事件层改用 `GameMap.eventLayer`——聚焦 **96/96 通过**、perf **6/6 通过**、eslint **0 报错**、**零生产改动**。 + +## Task 0 裁决(已由用户批准「可以执行」) + +- **Q1**:沿用各 combat 测试文件既有的 `{} as IStateBase` 最小桩,不新建 Phase 6 风格夹具。 +- **Q2**:删除 `eventDispatch.test.ts` 中已废弃的 `DirectionMapper` 注入及其 import/module 条目(原 `:69/:104/:143`);不重注入 `IFaceManager`/`IFaceHandler`;同夹具内 `new modules.MapState(tileStore, commonState)` → `new modules.MapState(commonState)`。测试文件技术处理由执行者判断。 +- **Q3**:不触发/不补测 DEV 守卫码(98/99/101),忽略无 emit 点的错误码;保持 Vitest 默认 `mode=test`,不切构建模式、不改配置。此为对计划 must_haves「DEV 守卫码保持可触发」的**用户授权偏离**(见 Deviations)。 + +## 测试对齐改动(3 个文件) + +- `combat/__test__/combat.test.ts`:删除 `addHook({...}).load()` 的 `.load()` 三处(原 `:442/:474/:499`),仅保留 `addHook(...)`;`CombatFlow` 构造本已传 `state`(`{} as IStateBase`),随 Q1 保留。删除后 eslint `--fix` 依 prettier 折叠链式调用(格式,非语义)。 +- `combat/__test__/context.test.ts`:为「构造特殊查询修饰器」「告警 100(add 与 delete 同时非空)」两个用例夹具补一个**无副作用全局光环**,使 shipped `EnemyContext.buildupSpecials` 的 `if (this.sortedAura.size === 0) return;` 提前返回不再遮蔽特殊查询阶段;**断言文本与期望值未改、未删 `it`**。 +- `event/__test__/eventDispatch.test.ts`:按 Q2 删 `DirectionMapper`;`MapState` 改单参 `commonState`;另将 `map.getLayerByAlias('event')` 改为 shipped 的 `map.eventLayer`(`getLayerByAlias` 已随重构删除,`fromRaw` 在 `alias==='event'` 时设置 `eventLayer`)。 + +## 门禁证据 + +- **聚焦运行**:`pnpm exec vitest run packages-user/data-system/src/combat/__test__ packages-user/data-system/src/event/__test__` → **Test Files 5 passed(5);Tests 96 passed(96)**(0 failed)。 +- **perf 通道**:`pnpm exec vitest run --config vitest.perf.config.ts packages-user/data-system/src/combat/__test__` → **2 passed / 6 passed**(0 failed)。两个 `.perf.ts` 无需改动(构造与导入未漂移)。 +- **eslint**:`pnpm exec eslint packages-user/data-system/src/combat/__test__ packages-user/data-system/src/event/__test__` → **0 报错**(perf 文件 2 条既有 `no-console` 告警,非报错)。 +- **生产改动范围**:`git status` 下 `packages-user/data-system/src/{combat,event}` 仅上述 3 个 `__test__` 文件;**零生产改动**。 +- **skip 计数**:未新增/未删除任何 `it`,`data-system` 测试内无 `.skip`/`.todo`;仓库级 skipped 仍为 1(`hero/equipment.test.ts` 码 147)。 + +## 并发保护(D-08) + +未触碰、未暂存、未提交任何用户并发改动(`packages-user/client-*`、`packages/system/src/ui/*` 等)。每个任务仅以显式路径 `git add` 声明文件。 + +## Deviations from Plan + +### 1. [用户授权偏离 must_haves] DEV 守卫码不触发/不补测(Q3) + +- **Found during:** Task 0 裁决 → 贯穿 Task 1/2。 +- **Issue:** 计划 must_haves 原写「DEV 守卫码保持可触发」(98/99/101,依赖 Vitest 默认 `mode=test`)。 +- **Decision(用户):** 不触发、不为这些码新增覆盖断言,亦不为无 emit 点的错误码补测;保持默认 `mode=test`,不改构建模式与配置。 +- **Impact:** 既有 98/99/101 用例保持不变(未删未弱化);未新增任何覆盖。属**用户明确授权**的偏离,登记于此。 + +### 2. [Rule 3 - Blocking] context 夹具补无副作用全局光环 + +- **Found during:** Task 1(combat 对齐)。 +- **Issue:** shipped `EnemyContext.buildupSpecials`(commit `e25ef3f` 引入)在 `sortedAura.size === 0` 时提前返回,导致「仅注册特殊查询效果、无任何光环」的既有用例 `for` 不被调用 / 码 100 不在全链路径触发(2 个用例红灯)。 +- **Fix:** 在两个用例夹具中各加一个 `FakeAura`(FullRange、`onApply` 空)作为全局光环,使构建进入特殊查询阶段;**未改生产**、未改断言、未删用例。 +- **Files modified:** `packages-user/data-system/src/combat/__test__/context.test.ts` +- **Verification:** 聚焦 combat 90/90 通过。 +- **Committed in:** `71f93a5`(Task 1)。 + +### 3. [Rule 1 - Bug/接口漂移] eventDispatch 再对齐 `getLayerByAlias` → `eventLayer` + +- **Found during:** Task 2(eventDispatch 对齐)。 +- **Issue:** 计划仅预期 `DirectionMapper` 与 `MapState` 两处漂移;修完这两处后暴露 `map.getLayerByAlias is not a function`——`IGameMap.getLayerByAlias` 已随同轮重构删除,`IGameMap` 现暴露 `eventLayer`。 +- **Fix:** `map!.getLayerByAlias('event')!` → `map!.eventLayer!`(`fromRaw` 在 `alias==='event'` 时设置 `eventLayer`,语义等价)。 +- **Files modified:** `packages-user/data-system/src/event/__test__/eventDispatch.test.ts` +- **Verification:** event 聚焦 6/6 通过。 +- **Committed in:** `e024e2d`(Task 2)。 + +### 4. [Rule 3 - Blocking] 未改动 `.perf.ts` + +- 计划 `files_modified` 含 2 个 perf 文件,但其导入/构造未漂移,按 Task 1「只改因导入/构造漂移必需的形状」保持原样;已用 perf 配置独立跑通(6/6)。 + +--- + +**Total deviations:** 2 自动修复(1 blocking 夹具、1 接口漂移) + 1 用户授权偏离(Q3)。 +**Impact on plan:** 无范围蔓延;对齐范围严格限制在 7 个声明测试文件,零生产改动、零新增依赖。 + +## Issues Encountered + +- 计划对 combat 的 `context.test.ts` 失效根因(`buildupSpecials` 提前返回)与 event 的 `getLayerByAlias` 漂移均未在 Task 0/计划中列出,执行期按「只对齐测试、零生产改动」原则处理并登记为 Deviations。 + +## Known Stubs + +None。 + +## Threat Flags + +None——未引入新的网络/鉴权/文件访问/信任边界表面;`T-08-06-01..04/S C` 缓解均满足(未用 `as never` 伪造、未删用例、未切构建模式、未提交用户并发改动、未安装任何包)。 + +## Next Phase Readiness + +- combat 与 event 两子系统对齐完成,为 data-state 集成与后续覆盖计划铺路。 +- 无阻塞;后续计划可继续对齐 `data-system/src` 其余 `__test__` 子系统。 + +--- + +*Phase: 08-test-refactor-alignment* +*Completed: 2026-10-05* + +## Self-Check: PASSED + +- FOUND: .planning/phases/08-test-refactor-alignment/08-06-SUMMARY.md +- FOUND: 71f93a5 (Task 1) +- FOUND: e024e2d (Task 2)