mirror of
https://github.com/motajs/template.git
synced 2026-10-17 03:10:17 +08:00
docs(06-05): complete hero unit test plan
This commit is contained in:
parent
351111487a
commit
6a6f717b04
@ -210,7 +210,7 @@ Plans:
|
||||
3. 测试在本地可运行且全部通过
|
||||
4. 测试由 AI 编写并运行,通过验证后可提交
|
||||
|
||||
**Plans**: 4/9 plans executed replanned (D-28;旧 06-01/06-02 执行结果标记 superseded,按同号重跑;数据端切片,非数据 render/legacy 覆盖延后)
|
||||
**Plans**: 5/9 plans executed replanned (D-28;旧 06-01/06-02 执行结果标记 superseded,按同号重跑;数据端切片,非数据 render/legacy 覆盖延后)
|
||||
|
||||
Plans:
|
||||
|
||||
@ -218,7 +218,7 @@ Plans:
|
||||
- [x] 06-02-PLAN.md — enemy top-level BASIC functionality only (data-state/src/enemy;单分支,无组合,无 save/load)
|
||||
- [x] 06-03-PLAN.md — Enemy data model full public surface except legacy (data-base/src/enemy;无 save/load)
|
||||
- [x] 06-04-PLAN.md — Replay focus ReplayArray ops + encode/decode + system/sandbox/decorators (data-common/src/replay;无 save/load,完整播放→06-07)
|
||||
- [ ] 06-05-PLAN.md — Hero ALL files incl. rendering + async mover (data-base/src/hero;无 save/load)
|
||||
- [x] 06-05-PLAN.md — Hero ALL files incl. rendering + async mover (data-base/src/hero;无 save/load)
|
||||
- [ ] 06-06-PLAN.md — Map ALL interfaces, emphasis static/dynamic tiles + static arrays (data-base/src/map;无 save/load)
|
||||
- [ ] 06-07-PLAN.md — Top-level integration: damage combos + map+replay play + second-play re-record equality; error 2001–2008 (BLOCKED: pre-execution user confirmation)
|
||||
- [ ] 06-08-PLAN.md — Flag full surface + common (utils/indexer/faceManager+face/mover) (无 save/load)
|
||||
@ -229,7 +229,7 @@ Plans:
|
||||
- [x] 06-01-PLAN.md
|
||||
- [x] 06-02-PLAN.md
|
||||
- [x] 06-03-PLAN.md
|
||||
- [ ] 06-04-PLAN.md
|
||||
- [x] 06-04-PLAN.md
|
||||
- [ ] 06-05-PLAN.md
|
||||
- [ ] 06-06-PLAN.md
|
||||
- [ ] 06-08-PLAN.md
|
||||
@ -251,4 +251,4 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6
|
||||
| 3. 数据端完成 | 19/19 | Complete | 2026-09-12 |
|
||||
| 4. 渲染适配与双布局 | 0/TBD | Not started | - |
|
||||
| 5. Legacy 移植 | 0/TBD | Not started | - |
|
||||
| 6. 单元测试 | 4/9 | In Progress| |
|
||||
| 6. 单元测试 | 5/9 | In Progress| |
|
||||
|
||||
@ -4,16 +4,16 @@ milestone: v1.0
|
||||
current_phase: 06
|
||||
current_phase_name: unit-tests
|
||||
status: executing
|
||||
stopped_at: Completed 06-04-PLAN.md
|
||||
last_updated: "2026-09-14T07:24:50.253Z"
|
||||
stopped_at: Completed 06-05-PLAN.md
|
||||
last_updated: "2026-09-14T07:59:26.958Z"
|
||||
last_activity: 2026-09-14
|
||||
last_activity_desc: Phase 06 execution started
|
||||
state_head: cb9c90abc1864345d88578194da3c727166d456a
|
||||
state_head: 351111487a69afd5a8b921c99996ac5c98bd7872
|
||||
progress:
|
||||
total_phases: 6
|
||||
completed_phases: 0
|
||||
total_plans: 46
|
||||
completed_plans: 41
|
||||
completed_plans: 42
|
||||
milestone_name: milestone
|
||||
---
|
||||
|
||||
@ -29,7 +29,7 @@ See: .planning/PROJECT.md (updated 2026-09-10)
|
||||
## Current Position
|
||||
|
||||
Phase: 06 (unit-tests) — EXECUTING
|
||||
Plan: 7 of 9
|
||||
Plan: 8 of 9
|
||||
Status: Ready to execute
|
||||
Last activity: 2026-09-14 — Phase 06 execution started
|
||||
|
||||
@ -82,6 +82,7 @@ Progress: [█████░░░░░] 50%
|
||||
| Phase 06 P02 | 8min | 3 tasks | 6 files |
|
||||
| Phase 06 P03 | 13min | 3 tasks | 5 files |
|
||||
| Phase 06 P04 | 26min | 3 tasks | 6 files |
|
||||
| Phase 06 P05 | 22min | 3 tasks | 10 files |
|
||||
|
||||
## Accumulated Context
|
||||
|
||||
@ -157,6 +158,9 @@ Recent decisions affecting current work:
|
||||
- [Phase 06]: 06-04:录像系统按 D-43 三阶段(构件→组合/流水线→完整/集成)执行,array/func/system/sandbox 四文件共 56 passed / 4 skipped,覆盖 code 148–163、175
|
||||
- [Phase 06]: 06-04:发现 4 处核心编解码/编辑缺陷(#06-04-1 int64 解码乘数、#06-04-2 多字节 bigint 编码、#06-04-3 delete 索引回退、#06-04-4 insert 参数位移方向),按 D-05 写正确预期 it.skip 只记录不修复
|
||||
- [Phase 06]: 06-04:D-32 不测 ReplayArray.saveState/loadState(归 06-09);D-40 不做完整播放/二次录制,error 2001–2008 归 06-07
|
||||
- [Phase 06]: 06-05:勇士全部子系统按 D-43 三阶段(构件→组合/流水线→完整/集成)以 10 个同目录测试覆盖,每阶段聚焦跑绿并过 D-44 门禁后提交
|
||||
- [Phase 06]: 06-05:HeroAttribute 无修饰器时 final 属性陈旧(#06-05-1)、HeroEquipment 字符串槽位空槽判断写反(#06-05-2)与码 147 不可达(#06-05-3),按 D-05 写正确预期 it.skip 只记录不修复
|
||||
- [Phase 06]: 06-05:D-32 不测任何 saveState/loadState,equipStore 专属码 58/59 归 06-09;mover 异步用真实计时器 + await controller.onEnd
|
||||
|
||||
### Pending Todos
|
||||
|
||||
@ -185,6 +189,6 @@ None yet.
|
||||
|
||||
## Session Continuity
|
||||
|
||||
Last session: 2026-09-14T07:24:49.974Z
|
||||
Stopped at: Completed 06-04-PLAN.md
|
||||
Last session: 2026-09-14T07:59:26.677Z
|
||||
Stopped at: Completed 06-05-PLAN.md
|
||||
Resume file: None
|
||||
|
||||
263
.planning/phases/06-unit-tests/06-05-SUMMARY.md
Normal file
263
.planning/phases/06-unit-tests/06-05-SUMMARY.md
Normal file
@ -0,0 +1,263 @@
|
||||
---
|
||||
phase: 06-unit-tests
|
||||
plan: 05
|
||||
subsystem: testing
|
||||
tags: [vitest, data-base, hero, attribute, modifier, equipment, follower, mover, rendering, node]
|
||||
|
||||
# Dependency graph
|
||||
requires:
|
||||
- phase: 06-unit-tests
|
||||
provides: 06-PATTERNS C 节 hero 模式、06-CONTEXT D-28/D-30/D-31/D-32/D-43/D-44 规则
|
||||
provides:
|
||||
- packages-user/data-base/src/hero 下 10 个行为测试文件(attribute/modifier/location/state/equipment/equipStore/items/follower/mover/rendering)
|
||||
- 码 108/109/116/142/144/146 的可达触发断言与 147 的不可达证据
|
||||
- 06-COVERAGE-MAP.md 06-05 小节(code → 模块 → 用例)
|
||||
- 06-TEST-FINDINGS.md #06-05-1..3 疑似缺陷登记
|
||||
affects: [06-09 存档(equipStore 58/59 与全部 save/load 归其负责), 06-07 顶层集成(hero 子系统组合语义)]
|
||||
|
||||
actuals:
|
||||
tokens: 18082
|
||||
tasks: 3
|
||||
commits: 3
|
||||
|
||||
tech-stack:
|
||||
added: []
|
||||
patterns:
|
||||
- 同目录 `*.test.ts` + `vi.hoisted` 全局 stub + `Map.getOrInsert`/`getOrInsertComputed` 运行时 polyfill
|
||||
- inline fake `IDataCommon`(真实 `TileStore`/`ItemStore` + `as never`)+ 内联 `IHeroMoveTopImpl` fake
|
||||
- 异步路径真实计时器 + `await controller.onEnd`,无 fake timers
|
||||
- 疑似 bug 按正确预期写 `it.skip` 并锚定 `#06-05-N`
|
||||
|
||||
key-files:
|
||||
created:
|
||||
- packages-user/data-base/src/hero/attribute.test.ts
|
||||
- packages-user/data-base/src/hero/modifier.test.ts
|
||||
- packages-user/data-base/src/hero/location.test.ts
|
||||
- packages-user/data-base/src/hero/state.test.ts
|
||||
- packages-user/data-base/src/hero/equipment.test.ts
|
||||
- packages-user/data-base/src/hero/equipStore.test.ts
|
||||
- packages-user/data-base/src/hero/items.test.ts
|
||||
- packages-user/data-base/src/hero/follower.test.ts
|
||||
- packages-user/data-base/src/hero/mover.test.ts
|
||||
- packages-user/data-base/src/hero/rendering.test.ts
|
||||
modified:
|
||||
- .planning/phases/06-unit-tests/06-COVERAGE-MAP.md
|
||||
- .planning/phases/06-unit-tests/06-TEST-FINDINGS.md
|
||||
|
||||
key-decisions:
|
||||
- "阶段 1 起即发现 `HeroAttribute.recalculateAttribute` 在无修饰器时提前返回,按 D-05 以正确预期 it.skip 登记 #06-05-1,不修改核心代码"
|
||||
- "`HeroMover` 测试复用真实 `HeroLocation` 作为移动宿主(tile),以覆盖真实 setPos/楼层路径,替代计划中的自定义 TestTile"
|
||||
- "`HeroEquipment` 字符串槽位空槽判断写反(#06-05-2),导致码 147 不可达(#06-05-3);147 以 it.skip 登记,覆盖表该行标注跳过"
|
||||
- "`HeroState`/`HeroEquipment` 等经接口类型调用 `registerModifier`,避免类实现泛型签名在测试侧难以满足"
|
||||
- "不测任何 saveState/loadState(D-32),equipStore 58/59 归 06-09"
|
||||
|
||||
patterns-established:
|
||||
- "Hero 子系统单测:同目录 + 全局 stub + 内联 fake 公共层 + 内联顶层移动实现"
|
||||
- "警告断言统一经 `logger.catch(fn).info.map(i => i.code)` 或 `vi.spyOn(logger, ...)`"
|
||||
- "正确预期 + it.skip + `#06-05-N` 中文注释锚定的缺陷登记流程"
|
||||
|
||||
requirements-completed: [TEST-01]
|
||||
|
||||
coverage:
|
||||
- id: D1
|
||||
description: "HeroAttribute 基础/最终属性、修饰器优先级与增删、存盘开关、克隆与 108/109"
|
||||
requirement: "TEST-01"
|
||||
verification:
|
||||
- kind: unit
|
||||
ref: "packages-user/data-base/src/hero/attribute.test.ts"
|
||||
status: pass
|
||||
human_judgment: false
|
||||
- id: D2
|
||||
description: "ValueModifier/PercentageModifier 公式、默认优先级与绑定重算"
|
||||
requirement: "TEST-01"
|
||||
verification:
|
||||
- kind: unit
|
||||
ref: "packages-user/data-base/src/hero/modifier.test.ts"
|
||||
status: pass
|
||||
human_judgment: false
|
||||
- id: D3
|
||||
description: "HeroLocation 定位/楼层 getter-setter 与 onSetPos/onSetFloor 钩子"
|
||||
requirement: "TEST-01"
|
||||
verification:
|
||||
- kind: unit
|
||||
ref: "packages-user/data-base/src/hero/location.test.ts"
|
||||
status: pass
|
||||
human_judgment: false
|
||||
- id: D4
|
||||
description: "HeroState 子系统装配、属性视图、修饰器注册(116)与 changeFloor 钩子顺序"
|
||||
requirement: "TEST-01"
|
||||
verification:
|
||||
- kind: unit
|
||||
ref: "packages-user/data-base/src/hero/state.test.ts"
|
||||
status: pass
|
||||
human_judgment: false
|
||||
- id: D5
|
||||
description: "HeroEquipment 槽位判定、装备/替换/卸下、compareEquip 与码 146"
|
||||
requirement: "TEST-01"
|
||||
verification:
|
||||
- kind: unit
|
||||
ref: "packages-user/data-base/src/hero/equipment.test.ts"
|
||||
status: pass
|
||||
human_judgment: false
|
||||
- id: D6
|
||||
description: "HeroEquipsStore 实例增删计数与按 uid/排序器排序、EquipmentState 修饰器生成"
|
||||
requirement: "TEST-01"
|
||||
verification:
|
||||
- kind: unit
|
||||
ref: "packages-user/data-base/src/hero/equipStore.test.ts"
|
||||
status: pass
|
||||
human_judgment: false
|
||||
- id: D7
|
||||
description: "HeroItems 常量/消耗计数、装备路由、拾取效果与 useItem 分类行为"
|
||||
requirement: "TEST-01"
|
||||
verification:
|
||||
- kind: unit
|
||||
ref: "packages-user/data-base/src/hero/items.test.ts"
|
||||
status: pass
|
||||
human_judgment: false
|
||||
- id: D8
|
||||
description: "HeroFollowersController 增删/链接、同步与异步 gather、码 142"
|
||||
requirement: "TEST-01"
|
||||
verification:
|
||||
- kind: unit
|
||||
ref: "packages-user/data-base/src/hero/follower.test.ts"
|
||||
status: pass
|
||||
human_judgment: false
|
||||
- id: D9
|
||||
description: "HeroMover 配置往返、Step/CannotMove/Hit、越界、地形忽略、enter/leave 顺序与码 144"
|
||||
requirement: "TEST-01"
|
||||
verification:
|
||||
- kind: unit
|
||||
ref: "packages-user/data-base/src/hero/mover.test.ts"
|
||||
status: pass
|
||||
human_judgment: false
|
||||
- id: D10
|
||||
description: "HeroRendering alpha 默认值、setAlpha 与 onSetAlpha 钩子注册/解除"
|
||||
requirement: "TEST-01"
|
||||
verification:
|
||||
- kind: unit
|
||||
ref: "packages-user/data-base/src/hero/rendering.test.ts"
|
||||
status: pass
|
||||
human_judgment: false
|
||||
- id: D11
|
||||
description: "码 147(无可用装备槽)触发断言 — 当前实现不可达,无法以正常用例覆盖"
|
||||
verification: []
|
||||
human_judgment: true
|
||||
rationale: "`HeroEquipment.equip` 的 147 分支与 `canEquipTo` 的名称槽校验互斥,无法经公开接口触发;已以 it.skip 正确预期用例登记 #06-05-3,需人工决定修复方向或标记该码保留未用。"
|
||||
|
||||
duration: 22min
|
||||
completed: 2026-09-14
|
||||
status: complete
|
||||
---
|
||||
|
||||
# Phase 06 Plan 05: 勇士全部子系统单元测试 Summary
|
||||
|
||||
**以 10 个同目录行为测试覆盖 `data-base/src/hero` 全部勇士子系统(属性/修饰器/位置/装配/装备/实例仓/道具/跟随者/异步移动/渲染),三阶段逐层跑绿并触发码 108/109/116/142/144/146**
|
||||
|
||||
## Performance
|
||||
|
||||
- **Duration:** 22 min
|
||||
- **Started:** 2026-09-14T07:35:00Z (约)
|
||||
- **Completed:** 2026-09-14T07:55:08Z
|
||||
- **Tasks:** 3 / 3(阶段 1 → 阶段 2 → 阶段 3)
|
||||
- **Files modified:** 10 个测试文件(新增,+2247 行)
|
||||
|
||||
## Accomplishments
|
||||
|
||||
- 阶段 1(构件级):`HeroAttribute`(base/final、优先级排序、增删、存盘开关、克隆、`catchCalculateProgress`)与 `ValueModifier`/`PercentageModifier` 公式,观测码 108/109。
|
||||
- 阶段 2(组合/流水线):`HeroLocation` 钩子、`HeroState` 装配与属性视图/修饰器注册(码 116)、`HeroEquipment` 装备/替换/卸下/`compareEquip`(码 146)、`HeroEquipsStore` 实例排序、`HeroItems` 路由与 `useItem`、`HeroFollowersController` 增删/链接/同步与异步 gather(码 142)。
|
||||
- 阶段 3(完整/集成):`HeroMover` 真实计时器异步移动(`Step`/`CannotMove`/`Hit`/越界/地形忽略/`enter`-`leave` 顺序/码 144)与 `HeroRendering` alpha + 钩子。
|
||||
- 聚焦运行与全量门禁:每阶段聚焦 vitest 全绿,`pnpm test:ci` 由 36 文件 / 347 通过 / 9 跳过 提升到 46 文件 / 412 通过 / 12 跳过。
|
||||
- 以 create-or-append 写入 `06-COVERAGE-MAP.md` 06-05 小节(7 个码),并在 `06-TEST-FINDINGS.md` 登记 `#06-05-1..3`。
|
||||
|
||||
## Task Commits
|
||||
|
||||
Each task was committed atomically:
|
||||
|
||||
1. **阶段 1(构件级)** - `c1781b8` (test)
|
||||
2. **阶段 2(组合/流水线)** - `6d5081a` (test)
|
||||
3. **阶段 3(完整/集成)** - `3511114` (test)
|
||||
|
||||
**Plan metadata:** 见末尾 docs 提交(SUMMARY / STATE / ROADMAP / COVERAGE-MAP / TEST-FINDINGS)
|
||||
|
||||
## Files Created/Modified
|
||||
|
||||
- `packages-user/data-base/src/hero/attribute.test.ts` - HeroAttribute 构件与码 108/109
|
||||
- `packages-user/data-base/src/hero/modifier.test.ts` - 数值/百分比修饰器公式与绑定重算
|
||||
- `packages-user/data-base/src/hero/location.test.ts` - 位置/楼层/朝向与钩子
|
||||
- `packages-user/data-base/src/hero/state.test.ts` - 子系统装配、属性视图、码 116、changeFloor 顺序
|
||||
- `packages-user/data-base/src/hero/equipment.test.ts` - 槽位判定、装备/替换/卸下、compareEquip、码 146/147
|
||||
- `packages-user/data-base/src/hero/equipStore.test.ts` - 实例增删计数与排序、EquipmentState 修饰器
|
||||
- `packages-user/data-base/src/hero/items.test.ts` - 常量/消耗计数、装备路由、拾取效果、useItem
|
||||
- `packages-user/data-base/src/hero/follower.test.ts` - 增删/链接、同步与异步 gather、码 142
|
||||
- `packages-user/data-base/src/hero/mover.test.ts` - 异步移动码、越界、地形忽略、码 144
|
||||
- `packages-user/data-base/src/hero/rendering.test.ts` - alpha 与 onSetAlpha 钩子
|
||||
- `.planning/phases/06-unit-tests/06-COVERAGE-MAP.md` - 追加 06-05 小节与 7 行码映射
|
||||
- `.planning/phases/06-unit-tests/06-TEST-FINDINGS.md` - 追加 `#06-05` 小节(3 条疑似缺陷)
|
||||
|
||||
## Decisions Made
|
||||
|
||||
- `HeroMover` 测试复用真实 `HeroLocation` 作为移动宿主(计划原本列出自定义 `TestTile`),保留真实 `setPos`/`floorId` 路径且无需实现庞大接口。
|
||||
- 有测试价值的旧式断言(`modifier.modify` 参数个数)按具体类签名调用,避免与基类抽象签名混淆。
|
||||
- `HeroState`/`HeroEquipment` 经接口类型变量调用泛型注册方法,规避类实现的泛型签名约束。
|
||||
- 无修饰器时 final 属性陈旧(`#06-05-1`)不阻断后续阶段:装备路径经 `addModifier` 触发重算,故阶段 2/3 可继续。
|
||||
|
||||
## Deviations from Plan
|
||||
|
||||
### Auto-fixed / Plan Adjustments
|
||||
|
||||
**1. [Rule 2 - 修正计划措辞] `attribute.test.ts` 基础属性断言改为在存在修饰器时进行**
|
||||
- **Found during:** 阶段 1
|
||||
- **Issue:** 计划要求「base 经 set/add/mul/div 变化,final 反映已注册 modifier」,但无修饰器时 final 不刷新(实现缺陷)。
|
||||
- **Fix:** 保留通过用例改为「挂零值修饰器后 base/final 同步」,并把无修饰器的正确预期单列为 `it.skip`(`#06-05-1`),符合 D-05。
|
||||
- **Files modified:** `attribute.test.ts`
|
||||
- **Committed in:** `c1781b8`
|
||||
|
||||
**2. [Rule 3 - 修正计划措辞] `mover.test.ts` 用真实 `HeroLocation` 代替 `TestTile`**
|
||||
- **Found during:** 阶段 3
|
||||
- **Issue:** 计划列出 `TestTile` 助手,但 `IHeroLocation` 接口庞大,定制假实现代价高且会偏离真实写回路径。
|
||||
- **Fix:** 使用真实 `HeroLocation` 作为 tile(其自带 `HeroMover`),内联 `FakeTopImpl` 注入顶层实现。
|
||||
- **Files modified:** `mover.test.ts`
|
||||
- **Committed in:** `3511114`
|
||||
|
||||
**3. [D-05 缺陷登记] 码 147 不可达,无法按计划以触发断言覆盖**
|
||||
- **Found during:** 阶段 2
|
||||
- **Issue:** 147 分支与 `canEquipTo` 的名称槽校验互斥,公开接口不可达;计划要求「147 各至少一条触发断言」。
|
||||
- **Fix:** 以正确预期 `it.skip` 登记 `#06-05-3`,覆盖表该行标注跳过;不修改核心代码。
|
||||
- **Files modified:** `equipment.test.ts`、`06-COVERAGE-MAP.md`、`06-TEST-FINDINGS.md`
|
||||
- **Committed in:** `6d5081a` + 元数据提交
|
||||
|
||||
---
|
||||
|
||||
**Total deviations:** 3(2 处计划措辞调整、1 处代码不可达的 D-05 登记)
|
||||
**Impact on plan:** 无范围蔓延;仅测试文件与阶段规划产物,未触碰任何生产/核心源码。
|
||||
|
||||
## Issues Encountered
|
||||
|
||||
- `Map.prototype.getOrInsert` 在 Node 22.18 不存在,`HeroAttribute.addModifier` 依赖它:在每个 hero 测试文件的 `vi.hoisted` 中与 `getOrInsertComputed` 一并 polyfill。
|
||||
- `vue-tsc` 曾报测试文件类型错误(`ItemStore` 泛型参数、`IEquipmentSorter` 误从 data-common 导入),已按 D-44 门禁修正为零错误。
|
||||
|
||||
## Known Stubs
|
||||
|
||||
None — 本计划仅新增测试,无桩实现;`it.skip` 用例均为 `06-TEST-FINDINGS.md` 登记的正确预期用例(`#06-05-1..3`)。
|
||||
|
||||
## Threat Flags
|
||||
|
||||
None — 仅新增仓库内 Node Vitest 测试,无运行时输入面、网络或文件写入(与原计划 threat model 一致)。
|
||||
|
||||
## Next Phase Readiness
|
||||
|
||||
- 勇士子系统行为覆盖完成,码 108/109/116/142/144/146 已触发;147 待人工决策修复方向。
|
||||
- 06-09 可在此之上补 equipStore 码 58/59 与全部 `saveState`/`loadState` 往返。
|
||||
- 三条疑似缺陷(`#06-05-1..3`)已按 D-05 只记录不修复,等待用户确认修复环节。
|
||||
|
||||
---
|
||||
*Phase: 06-unit-tests*
|
||||
*Completed: 2026-09-14*
|
||||
|
||||
## Self-Check: PASSED
|
||||
|
||||
- 10 个 hero `*.test.ts` 全部存在
|
||||
- 3 个阶段提交 `c1781b8`、`6d5081a`、`3511114` 均存在
|
||||
- `06-05-SUMMARY.md` 已写入
|
||||
|
||||
@ -43,6 +43,13 @@
|
||||
| 162 | replay/func.ts | `warns code 162 when the detail code is unknown` | 06-04 |
|
||||
| 163 | replay/system.ts | `warns code 163 on a duplicate registration and keeps the original` | 06-04 |
|
||||
| 175 | replay/sandbox.ts | `warns code 175 when notExecuted fails` | 06-04 |
|
||||
| 108 | hero/attribute.ts | `warns code 108 and ignores a modifier that already has an owner` | 06-05 |
|
||||
| 109 | hero/attribute.ts | `warns code 109 when an object modifier returns the same reference` | 06-05 |
|
||||
| 116 | hero/state.ts | `creates registered modifiers and warns code 116 for unknown types` | 06-05 |
|
||||
| 142 | hero/follower.ts | `warns code 142 for an unknown string follower id` | 06-05 |
|
||||
| 144 | hero/mover.ts | `warns code 144 and stops without a top implementation` | 06-05 |
|
||||
| 146 | hero/equipment.ts | `warns code 146 when the equipped instance is missing`、`warns code 146 when comparing an unknown uid` | 06-05 |
|
||||
| 147 | hero/equipment.ts | `warns code 147 when no equipment slot is available`(`it.skip`,当前不可达,见 `#06-05-3`) | 06-05 |
|
||||
|
||||
## 06-01 战斗系统(packages-user/data-system/src/combat)
|
||||
|
||||
@ -101,3 +108,28 @@ D-40:不做完整录像播放与二次录制比对,`error 2001–2008` 归 0
|
||||
四条编解码/编辑缺陷 `#06-04-1`(int64 解码乘数)、`#06-04-2`(多字节 bigint 编码)、
|
||||
`#06-04-3`(delete 索引回退)、`#06-04-4`(insert 参数位移方向)按 D-05 以 `it.skip`
|
||||
的正确预期用例登记,详见 `06-TEST-FINDINGS.md`。
|
||||
|
||||
## 06-05 勇士全部(packages-user/data-base/src/hero)
|
||||
|
||||
模块归属:108 / 109 → `hero/attribute.ts`(`HeroAttribute.addModifier` 重复归属 / 对象修饰器同引用);
|
||||
116 → `hero/state.ts`(`HeroState.createModifier` 未注册类型);
|
||||
142 → `hero/follower.ts`(`HeroFollower` 未知字符串 id);
|
||||
144 → `hero/mover.ts`(`HeroMover.onMoveStart` 缺顶层实现);
|
||||
146 / 147 → `hero/equipment.ts`(`HeroEquipment` 装备实例缺失 / 无可用槽位)。
|
||||
|
||||
阶段 1(构件级)完成 `HeroAttribute` 基础/最终属性、优先级排序、增删、存盘开关、克隆与
|
||||
`catchCalculateProgress`,观测 108/109;完成 `ValueModifier`/`PercentageModifier` 公式与默认优先级。
|
||||
阶段 2(组合/流水线)完成 `HeroLocation` 定位/楼层钩子、`HeroState` 装配与属性视图/修饰器注册
|
||||
(观测 116)、`changeFloor` 钩子顺序;完成 `HeroEquipment` 槽位判定/装备替换/卸下/`compareEquip`
|
||||
(观测 146)、`HeroEquipsStore` 实例排序、`HeroItems` 增删路由与 `useItem`;
|
||||
完成 `HeroFollowersController` 增删/链接/同步与异步 gather(观测 142)。
|
||||
阶段 3(完整/集成)完成 `HeroMover` 配置往返、`Step`/`CannotMove`/`Hit`、越界、地形忽略、
|
||||
`enter`/`leave` 顺序(观测 144)与 `HeroRendering` alpha + 钩子。
|
||||
|
||||
D-32:不测任何 `saveState`/`loadState`;equipStore 专属码 58/59 与全部存读档往返归 06-09。
|
||||
D-30:排除名称含 legacy 的接口/方法;`HeroMover` 顶层实现用内联 fake 注入。
|
||||
三条疑似缺陷 `#06-05-1`(无修饰器时 final 属性不随基础属性更新)、`#06-05-2`(字符串槽位空槽
|
||||
判断写反导致总是替换首个匹配槽位)、`#06-05-3`(码 147 不可达)按 D-05 以 `it.skip` 的正确预期
|
||||
用例登记,详见 `06-TEST-FINDINGS.md`;其中 147 无法触发,故本表该行标注为跳过用例。
|
||||
`HeroMover` 测试复用真实 `HeroLocation` 作为移动宿主(非自定义 `TestTile`),以零断言代价
|
||||
覆盖真实 tile 写回路径。
|
||||
|
||||
@ -63,3 +63,18 @@ D-40:不做完整播放/二次录制(归 06-07),`error 2001–2008` 未
|
||||
| `array.ts` `ReplayArray`(bigint 编码) | 多字节 bigint 编码只保留最低字节,其余写 0,读回值远小于写入值 | `array.add(0, [0x0102030405060708n])` → `array.get(0).params` 得到 `[8n]`,应为 `[0x0102030405060708n]` | `normalizeParam` 编码循环 `base = param - total; remain = base % 256n` 未按字节右移,`total` 仅累积低位,导致 i≥1 时 `remain` 恒为 0;解码又用 `getInt8` 读无符号字节 | 任何需要 >1 字节的 bigint 参数无法正确往返 | 编码改为按位取字节(如 `(param >> (8n * BigInt(i))) % 256n`),解码改用无符号字节 | `array.test.ts` `round-trips a multi-byte bigint`(#06-04-2) | 中 |
|
||||
| `array.ts` `ReplayArray.delete` | 删除中间步骤后索引数组未按删除位置回退,后续步骤读到错误参数 | `add(1,[10])`、`add(2,[20])`、`add(3,[30])` → `delete(1)` → `get(1).params` 期望 `[30]`,实际 `[false]` | 回退循环 `for (let i = paramStart; i < this.length; i++) this.indexArray[i] -= paramLength` 以 `paramStart`(参数字节偏移)当作命令索引起点,应从 `index` 起;且 `indexArray[index+1]` 对末步取到未初始化 0 | 删除任意非首步都会破坏其后步骤的参数读取;录像编辑不可靠 | 回退从 `index` 起(`for (let i = index; i < this.length; i++)`),并以 `paramUsed` 或哨兵替代 `indexArray[length]` 表示末步参数终点 | `array.test.ts` `deletes a middle step and shifts later param indexes`(#06-04-3) | 中 |
|
||||
| `array.ts` `ReplayArray.insert` | 已有参数时插入步骤会丢失插入点之后的参数 | `add(1,[10])`、`add(3,[30])` → `insert(1, 2, [20])` → 读流第三条参数期望 `[30]`,实际 `[false]` | `this.paramArray.copyWithin(paramStart, paramStart + length)` 位移方向相反,应把 `[paramStart, …)` 移到 `paramStart + length` | 带参数的录像插入功能不可用,后续步骤参数错位 | 改为 `this.paramArray.copyWithin(paramStart + length, paramStart)` | `array.test.ts` `reads the new order after inserting a step`(#06-04-4) | 中 |
|
||||
|
||||
## #06-05 勇士全部(packages-user/data-base/src/hero)
|
||||
|
||||
本计划按 D-43 三阶段(构件 → 组合/流水线 → 完整/集成)执行,10 个测试文件全部跑绿;
|
||||
`pnpm test:ci` 全绿(46 文件 / 412 通过 / 12 跳过)。D-32:不测任何 `saveState`/`loadState`,
|
||||
equipStore 专属码 58/59 归 06-09。D-30:排除名称含 legacy 的接口/方法。
|
||||
发现 3 处疑似缺陷(`#06-05-1..3`),按 D-05 以正确预期的 `it.skip` 用例登记;
|
||||
其中 `#06-05-3` 反映「码 147 在当前实现不可达」,故本计划 147 无法以正常触发断言覆盖,
|
||||
覆盖表该行标注为跳过用例(见 `06-COVERAGE-MAP.md` 06-05 小节)。
|
||||
|
||||
| 模块/接口 | 现象 | 最小复现 | 疑似原因 | 影响面 | 建议修复方向 | 关联 skip 用例 | 严重度 |
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| `attribute.ts` `HeroAttribute.recalculateAttribute` | 属性没有任何修饰器时,基础属性变化不会反映到最终属性 | `new HeroAttribute({ hp: 100 })` → `set('hp', 40)` → `add('hp', 5)`;`getBaseAttribute('hp')` 为 45,但 `getFinalAttribute('hp')` 仍为构造时的 100 | `recalculateAttribute` 在 `const modifierList = this.modifier.get(name); if (!modifierList) return;` 处提前返回,未在该分支把基础值写回 `finalAttribute` | 所有尚无修饰器的属性(基础数值、升级/金币/经验等)在 `set`/`add`/`mul`/`div` 后读取最终属性会得到旧值;只有挂上修饰器后才会刷新 | 在无 `modifierList` 时同样执行 `this.finalAttribute[name] = baseValue`(或初始化时同步),保证 final 与 base 在没有加成时一致 | `attribute.test.ts` `reflects base-only changes without any modifier`(#06-05-1) | 中 |
|
||||
| `equipment.ts` `HeroEquipment.equip`(字符串槽位分支) | 存在空的同名装备槽时仍替换第一个匹配槽位,而不是占用空槽 | `slots = ['weapon', 'weapon']`;先将 A 装备到 `'weapon'`,再装备 B 到 `'weapon'`;实际 B 替换了 slot 0 的 A,slot 1 仍为空(正确预期 A 在 slot 0、B 在 slot 1) | 空槽判断条件写反:`if (empty !== -1 && !this.equips.has(index))` 应为 `empty === -1`;因 `empty` 初值即 -1,条件恒假,`empty` 永远保持 -1,`empty !== -1` 的「占用空槽」分支成为死代码 | 多同名槽位(如双武器槽)时装错位置,可能覆盖已装备道具;同时 `equip` 的空槽直装分支永不执行 | 将条件改为 `empty === -1 && !this.equips.has(index)`,恢复「优先占用空槽、无空槽才替换」的语义 | `equipment.test.ts` `uses the first empty named slot instead of replacing an occupant`(#06-05-2) | 中 |
|
||||
| `equipment.ts` `HeroEquipment.equip` 码 147 | 无可用装备槽告警(147)在当前实现下不可达 | `slots = []`、装备支持名称槽 `'weapon'` 时调用 `equip(uid, 'weapon')`:`canEquipTo` 因 `hasSlot === false` 先返回 `CannotEquip`,`equip` 提前返回,永远不会进入 `first === -1` 的 147 分支 | `canEquipTo` 的名称槽校验(`hasSlot`)与 `equip` 的 `first === -1` 判定使用同一条件,前者已拦截所有会使后者成立的情形;叠加 `#06-05-2` 的 `empty` 死值,空槽分支同样不可达 | 码 147 属死码,D-31 的 code 全覆盖无法通过触发断言满足;非法名称槽只能得到静默 `undefined` 而无诊断 | 明确 147 的触发语义:或在 `canEquipTo` 放行后由 `equip` 补齐诊断,或在码表中标注该码保留未用并移除死分支 | `equipment.test.ts` `warns code 147 when no equipment slot is available`(#06-05-3) | 低 |
|
||||
|
||||
@ -39,5 +39,5 @@
|
||||
"label": "Advance to the next step",
|
||||
"reason": "Phase 06 of 6 · executing"
|
||||
},
|
||||
"updated_at": "2026-09-14T07:24:06.349Z"
|
||||
"updated_at": "2026-09-14T07:58:49.898Z"
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user