mirror of
https://github.com/motajs/template.git
synced 2026-10-03 17:40:19 +08:00
docs(06-06): complete map unit test plan
This commit is contained in:
parent
235eb1a5c9
commit
2b6de6df5f
@ -210,7 +210,7 @@ Plans:
|
||||
3. 测试在本地可运行且全部通过
|
||||
4. 测试由 AI 编写并运行,通过验证后可提交
|
||||
|
||||
**Plans**: 5/9 plans executed replanned (D-28;旧 06-01/06-02 执行结果标记 superseded,按同号重跑;数据端切片,非数据 render/legacy 覆盖延后)
|
||||
**Plans**: 6/9 plans executed replanned (D-28;旧 06-01/06-02 执行结果标记 superseded,按同号重跑;数据端切片,非数据 render/legacy 覆盖延后)
|
||||
|
||||
Plans:
|
||||
|
||||
@ -219,7 +219,7 @@ Plans:
|
||||
- [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)
|
||||
- [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)
|
||||
- [x] 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)
|
||||
- [ ] 06-09-PLAN.md — Save/load independent system: every saveState/loadState class + CoreState top-level (BLOCKED: pre-execution user confirmation)
|
||||
@ -230,7 +230,7 @@ Plans:
|
||||
- [x] 06-02-PLAN.md
|
||||
- [x] 06-03-PLAN.md
|
||||
- [x] 06-04-PLAN.md
|
||||
- [ ] 06-05-PLAN.md
|
||||
- [x] 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. 单元测试 | 5/9 | In Progress| |
|
||||
| 6. 单元测试 | 6/9 | In Progress| |
|
||||
|
||||
@ -4,16 +4,16 @@ milestone: v1.0
|
||||
current_phase: 06
|
||||
current_phase_name: unit-tests
|
||||
status: executing
|
||||
stopped_at: Completed 06-05-PLAN.md
|
||||
last_updated: "2026-09-14T07:59:26.958Z"
|
||||
stopped_at: Completed 06-06-PLAN.md
|
||||
last_updated: "2026-09-14T08:32:08.508Z"
|
||||
last_activity: 2026-09-14
|
||||
last_activity_desc: Phase 06 execution started
|
||||
state_head: 351111487a69afd5a8b921c99996ac5c98bd7872
|
||||
state_head: 235eb1a5c9e17c985a28cc582248664e56385762
|
||||
progress:
|
||||
total_phases: 6
|
||||
completed_phases: 0
|
||||
total_plans: 46
|
||||
completed_plans: 42
|
||||
completed_plans: 43
|
||||
milestone_name: milestone
|
||||
---
|
||||
|
||||
@ -29,7 +29,7 @@ See: .planning/PROJECT.md (updated 2026-09-10)
|
||||
## Current Position
|
||||
|
||||
Phase: 06 (unit-tests) — EXECUTING
|
||||
Plan: 8 of 9
|
||||
Plan: 9 of 9
|
||||
Status: Ready to execute
|
||||
Last activity: 2026-09-14 — Phase 06 execution started
|
||||
|
||||
@ -83,6 +83,7 @@ Progress: [█████░░░░░] 50%
|
||||
| Phase 06 P03 | 13min | 3 tasks | 5 files |
|
||||
| Phase 06 P04 | 26min | 3 tasks | 6 files |
|
||||
| Phase 06 P05 | 22min | 3 tasks | 10 files |
|
||||
| Phase 06 P06 | 24min | 3 tasks | 8 files |
|
||||
|
||||
## Accumulated Context
|
||||
|
||||
@ -161,6 +162,10 @@ Recent decisions affecting current work:
|
||||
- [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
|
||||
- [Phase 06]: 06-06:地图全部按 D-43 三阶段(构件 → 组合/流水线 → 完整/集成)以 8 个同目录测试覆盖,每阶段聚焦跑绿并过 D-44 门禁后提交
|
||||
- [Phase 06]: 06-06:transferToDynamic 越图实际发码 131(setEventLayer 专属)而 transferToStatic 发 128,按 D-05 以正确预期 it.skip 登记 #06-06-1 待用户确认;131 正常覆盖由 gameMap.setEventLayer 越权路径承担
|
||||
- [Phase 06]: 06-06:IMapState 并无 canPass/shouldHit(实现在 data-state/src/hero/predicate.ts),mapState.test 只覆盖谓词侧依赖的「活跃楼层 → 事件层」数据供给;计划中的 createLayerState 码 121 实为 MapState.createMap 重复注册告警
|
||||
- [Phase 06]: 06-06:D-32 不测任何 saveState/loadState(55/122/124 归 06-09);MapTileBase 抽象类经 StaticTile/DynamicTile 具体子类覆盖,mover protected 回调为 no-op 故经公开钩子观测生命周期
|
||||
|
||||
### Pending Todos
|
||||
|
||||
@ -189,6 +194,6 @@ None yet.
|
||||
|
||||
## Session Continuity
|
||||
|
||||
Last session: 2026-09-14T07:59:26.677Z
|
||||
Stopped at: Completed 06-05-PLAN.md
|
||||
Last session: 2026-09-14T08:32:08.256Z
|
||||
Stopped at: Completed 06-06-PLAN.md
|
||||
Resume file: None
|
||||
|
||||
181
.planning/phases/06-unit-tests/06-06-SUMMARY.md
Normal file
181
.planning/phases/06-unit-tests/06-06-SUMMARY.md
Normal file
@ -0,0 +1,181 @@
|
||||
---
|
||||
phase: 06-unit-tests
|
||||
plan: 06
|
||||
subsystem: testing
|
||||
tags: [vitest, map, data-base, gamemap, maplayer, dynamic-tile, mover]
|
||||
|
||||
requires:
|
||||
- phase: 06-unit-tests
|
||||
provides: 06-01..06-05 既有测试基建(vi.hoisted 全局 stub、logger.catch、真实计时器模式)
|
||||
provides:
|
||||
- MapState 注册/原始数据校验/激活/分区/参考基准覆盖
|
||||
- GameMap 图层生命周期/别名/背景/事件层/脏标记/resize 覆盖
|
||||
- MapLayer 矩阵/静态数组/动态转换/点位事件/脏/异步门覆盖
|
||||
- MapTileBase/StaticTile/DynamicTile/LayerEventView/DynamicTileMover 单元覆盖
|
||||
- 06-COVERAGE-MAP.md 的 06-06 小节(21 个 code)
|
||||
affects: [06-07, 06-09]
|
||||
|
||||
actuals:
|
||||
tokens: 18374
|
||||
tasks: 3
|
||||
commits: 3
|
||||
plan_head_before: 6a6f717b040d71aad7ddb3970f10ad870f60448e
|
||||
|
||||
tech-stack:
|
||||
added: []
|
||||
patterns:
|
||||
- "同目录 inline fixture + vi.hoisted 全局 stub(沿用 06-05 静态 import 形态)"
|
||||
- "抽象基类 MapTileBase 经具体子类 StaticTile/DynamicTile 覆盖"
|
||||
- "异步移动生命周期经 IObjectMover 公开钩子观测(protected 回调为 no-op)"
|
||||
- "疑似缺陷按正确预期编写并 it.skip + 中文注释锚定 #06-06-N(D-05)"
|
||||
|
||||
key-files:
|
||||
created:
|
||||
- packages-user/data-base/src/map/mapState.test.ts
|
||||
- packages-user/data-base/src/map/gameMap.test.ts
|
||||
- packages-user/data-base/src/map/mapLayer.test.ts
|
||||
- packages-user/data-base/src/map/tile.test.ts
|
||||
- packages-user/data-base/src/map/staticTile.test.ts
|
||||
- packages-user/data-base/src/map/dynamicTile.test.ts
|
||||
- packages-user/data-base/src/map/mover.test.ts
|
||||
modified:
|
||||
- packages-user/data-base/src/map/eventView.test.ts
|
||||
|
||||
key-decisions:
|
||||
- "06-06:地图全部按 D-43 三阶段(构件 → 组合/流水线 → 完整/集成)执行,每阶段聚焦跑绿并过 D-44 门禁后提交"
|
||||
- "06-06:transferToDynamic 越图实际发码 131(setEventLayer 专属)而 transferToStatic 发 128,按 D-05 以正确预期 it.skip 登记 #06-06-1 待用户确认;131 的正常覆盖由 gameMap.setEventLayer 越权路径承担"
|
||||
- "06-06:IMapState 并无 canPass/shouldHit(实现在 data-state/src/hero/predicate.ts),mapState.test 只覆盖谓词侧依赖的「活跃楼层 → 事件层」数据供给"
|
||||
- "06-06:计划中的 createLayerState 码 121 实为 MapState.createMap 重复注册告警,测试按真实接口覆盖"
|
||||
- "06-06:不测任何 saveState/loadState,55/122/124 归 06-09(D-32);MapTileBase 抽象类经具体子类覆盖"
|
||||
|
||||
patterns-established:
|
||||
- "地图测试 fixture:TileStore(1/2) + FaceManager(Dir8) + RoleFaceBinder + DirectionMapper 组装 IDataCommon,经 MapState.fromRaw 建 2x2 小地图"
|
||||
- "越界/非法参数调用经宽松签名(LooseMapDataArgs)绕过重载类型,保留单处 as 断言"
|
||||
|
||||
requirements-completed: [TEST-01]
|
||||
|
||||
coverage:
|
||||
- id: D1
|
||||
description: "阶段 1(构件级):tile/staticTile/dynamicTile/eventView 单个类单元覆盖(含码 136/143)"
|
||||
requirement: TEST-01
|
||||
verification:
|
||||
- kind: unit
|
||||
ref: "packages-user/data-base/src/map/tile.test.ts"
|
||||
status: pass
|
||||
- kind: unit
|
||||
ref: "packages-user/data-base/src/map/staticTile.test.ts"
|
||||
status: pass
|
||||
- kind: unit
|
||||
ref: "packages-user/data-base/src/map/dynamicTile.test.ts"
|
||||
status: pass
|
||||
- kind: unit
|
||||
ref: "packages-user/data-base/src/map/eventView.test.ts"
|
||||
status: pass
|
||||
human_judgment: false
|
||||
- id: D2
|
||||
description: "阶段 2(组合/流水线):MapState 注册/校验/激活/分区 + GameMap 图层 + MapLayer 矩阵/静态数组/动态转换(含码 8/9/46/60/61/62/63/64/80/81/84/121/123/127/129/130/131)"
|
||||
requirement: TEST-01
|
||||
verification:
|
||||
- kind: unit
|
||||
ref: "packages-user/data-base/src/map/mapState.test.ts"
|
||||
status: pass
|
||||
- kind: unit
|
||||
ref: "packages-user/data-base/src/map/gameMap.test.ts"
|
||||
status: pass
|
||||
- kind: unit
|
||||
ref: "packages-user/data-base/src/map/mapLayer.test.ts"
|
||||
status: pass
|
||||
human_judgment: false
|
||||
- id: D3
|
||||
description: "阶段 3(完整/集成):DynamicTileMover 异步移动生命周期(含码 126)"
|
||||
requirement: TEST-01
|
||||
verification:
|
||||
- kind: unit
|
||||
ref: "packages-user/data-base/src/map/mover.test.ts"
|
||||
status: pass
|
||||
human_judgment: false
|
||||
- id: D4
|
||||
description: "疑似缺陷 #06-06-1(transferToDynamic 越图误发 131 而非 128)经正确预期 it.skip 登记,待用户确认后修复并转回归"
|
||||
requirement: TEST-01
|
||||
verification: []
|
||||
human_judgment: true
|
||||
rationale: "这是被测实现的行为/语义判定,需用户确认属于缺陷还是有意设计;D-05 要求先记录不修复,人工签字后方可取消 skip"
|
||||
|
||||
duration: 24min
|
||||
completed: 2026-09-14
|
||||
status: complete
|
||||
---
|
||||
|
||||
# Phase 06 Plan 06: 地图系统单元测试 Summary
|
||||
|
||||
**地图系统(data-base/src/map)按 构件→组合/流水线→完整/集成 三阶段补齐 8 个行为测试文件,覆盖 21 个 warn/error 码,聚焦静态图块、动态图块转换与静态数组设置**
|
||||
|
||||
## Performance
|
||||
|
||||
- **Duration:** 24 min
|
||||
- **Started:** 2026-09-14T16:06:00+08:00
|
||||
- **Completed:** 2026-09-14T16:30:00+08:00
|
||||
- **Tasks:** 3
|
||||
- **Files modified:** 8(7 新建 + 1 扩展)
|
||||
|
||||
## Accomplishments
|
||||
|
||||
- 阶段 1:`tile`/`staticTile`/`dynamicTile`/`eventView` 构件级单元 26 通过;覆盖默认事件恢复、`shouldSave`、`toDynamic`、缺 raw 告警 143、重复优先级告警 136。
|
||||
- 阶段 2:`mapState`/`gameMap`/`mapLayer` 组合/流水线 63 通过 / 1 跳过;覆盖 raw 校验码 60/61/62/63/64、矩阵读写、`getMapData` 80/81、`putMapData` 8/9、`setMapRef` 123、动态转换 127/128/129/130、事件层 131、别名 84、楼层重复 121、异步开关门 46。
|
||||
- 阶段 3:`DynamicTileMover` 完整异步移动 6 通过;覆盖成功/连续/斜向移动、图层索引更新、非法移动码告警 126、移动生命周期钩子顺序。
|
||||
- `pnpm test:ci` 全绿:53 文件 / 505 通过 / 13 跳过(本计划新增 1 条 skip)。
|
||||
- `06-COVERAGE-MAP.md` 06-06 小节写入 21 个 code;`06-TEST-FINDINGS.md` 写入 `#06-06-1`。
|
||||
|
||||
## Task Commits
|
||||
|
||||
Each task was committed atomically:
|
||||
|
||||
1. **阶段 1(构件级)** - `4cffe90` (test)
|
||||
2. **阶段 2(组合/流水线)** - `b971e14` (test)
|
||||
3. **阶段 3(完整/集成)** - `235eb1a` (test)
|
||||
|
||||
**Plan metadata:** 本次 docs 提交(SUMMARY/STATE/ROADMAP/COVERAGE-MAP/TEST-FINDINGS)
|
||||
|
||||
## Files Created/Modified
|
||||
|
||||
- `packages-user/data-base/src/map/tile.test.ts` - MapTileBase 经静态/动态图块覆盖:num/raw/set、默认事件、逐实例事件视图、pointEvent、setFaceDirection
|
||||
- `packages-user/data-base/src/map/staticTile.test.ts` - StaticTile:num/raw/set/shouldSave/toDynamic 与越图 raw 为空
|
||||
- `packages-user/data-base/src/map/dynamicTile.test.ts` - DynamicTile:构造/设置告警 143、setPos、getCurrentFaceDirection、toStatic/toStaticIfSafe、step、delete
|
||||
- `packages-user/data-base/src/map/eventView.test.ts` - 扩展:逐优先级脏跟踪、clear 恢复、未知优先级删除、重复优先级告警 136(保留既有覆盖)
|
||||
- `packages-user/data-base/src/map/mapState.test.ts` - createMap/getMap、setMapList、fromRaw 校验码 60/61/62/63/64、激活迭代、分区、compareWith
|
||||
- `packages-user/data-base/src/map/gameMap.test.ts` - 图层增删/别名 84、背景、事件层 131、脏、resizeLayer、compareWith
|
||||
- `packages-user/data-base/src/map/mapLayer.test.ts` - 矩阵、getMapData 80/81、putMapData 8/9、setMapRef 123、动态转换、点位事件、脏、异步门 46
|
||||
- `packages-user/data-base/src/map/mover.test.ts` - DynamicTileMover 异步移动生命周期与告警 126
|
||||
|
||||
## Decisions Made
|
||||
|
||||
- 三阶段严格按 D-43 执行,每阶段聚焦跑绿并过 D-44(eslint / vue-tsc 文件级 / `pnpm test:ci`)后再提交。
|
||||
- `transferToDynamic` 越图实际发码 131(`setEventLayer` 专属码)而 `transferToStatic` 发 128,按 D-05 以正确预期 `it.skip` 登记 `#06-06-1`;131 的正常覆盖由 `gameMap.setEventLayer` 越权路径承担,保证 code 全覆盖。
|
||||
- `IMapState` 并无 `canPass`/`shouldHit`(实现在 `data-state/src/hero/predicate.ts`),`mapState.test.ts` 只覆盖谓词侧依赖的「活跃楼层 → 事件层」数据供给。
|
||||
- 计划中的 `createLayerState` 码 121 实为 `MapState.createMap` 的重复楼层注册告警(码表文案沿用旧名),测试按真实接口覆盖。
|
||||
- D-32:不测任何 `saveState`/`loadState`(55/122/124 归 06-09)。
|
||||
- `MapTileBase` 为抽象类,经 `StaticTile`/`DynamicTile` 具体子类覆盖;`DynamicTileMover` 的 protected 回调为 no-op,生命周期经 `IObjectMover` 公开钩子观测。
|
||||
|
||||
## Deviations from Plan
|
||||
|
||||
None - 无生产/核心源码改动,未触发 Rule 1-3 自动修复。两处**计划措辞与实现不符**已按真实接口覆盖并记录(见 Decisions 与 `06-COVERAGE-MAP.md` 06-06 小节),非代码缺陷、不登记为 bug。
|
||||
|
||||
## Issues Encountered
|
||||
|
||||
暂无阻断性问题;三阶段顺序执行均一次跑绿并通过 D-44 门禁。
|
||||
|
||||
## User Setup Required
|
||||
|
||||
None - no external service configuration required.
|
||||
|
||||
## Next Phase Readiness
|
||||
|
||||
- 地图系统的行为覆盖已就绪,可供 06-07(顶层集成:伤害组合 + 录像播放/二次录制)使用合成地图场景。
|
||||
- 存读档集中计划 06-09 仍需覆盖 55/122/124 与全部 `saveState`/`loadState` 往返。
|
||||
- `#06-06-1` 待用户确认:若判定为缺陷,修复后将 `mover`/`mapLayer` 的 `it.skip` 取消并转回归用例。
|
||||
|
||||
---
|
||||
*Phase: 06-unit-tests*
|
||||
*Completed: 2026-09-14*
|
||||
|
||||
## Self-Check: PASSED
|
||||
@ -50,6 +50,27 @@
|
||||
| 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 |
|
||||
| 8 | map/mapLayer.ts | `warns code 8 for incomplete data and code 9 for an out-of-range area` | 06-06 |
|
||||
| 9 | map/mapLayer.ts | `warns code 8 for incomplete data and code 9 for an out-of-range area` | 06-06 |
|
||||
| 46 | map/mapLayer.ts | `closes a door on empty cells and warns 46 on occupied cells` | 06-06 |
|
||||
| 60 | map/mapState.ts | `unequal layer lengths is rejected with code 60` | 06-06 |
|
||||
| 61 | map/mapState.ts | `area not divisible by width is rejected with code 61` | 06-06 |
|
||||
| 62 | map/mapState.ts | `non-numeric map layer key is rejected with code 62`、`non-numeric event priority is rejected with code 62` | 06-06 |
|
||||
| 63 | map/mapState.ts | `missing map container is rejected with code 63`、`missing events container is rejected with code 63`、`missing alias container is rejected with code 63` | 06-06 |
|
||||
| 64 | map/mapState.ts | `invalid width is rejected with code 64`、`non-integer map value is rejected with code 64`、`non-string layer alias is rejected with code 64`、`out of range event position is rejected with code 64`、`non-string event id is rejected with code 64`、`event layer without map layer is rejected with code 64` | 06-06 |
|
||||
| 80 | map/mapLayer.ts | `warns code 80 for an illegal argument count` | 06-06 |
|
||||
| 81 | map/mapLayer.ts | `warns code 81 for an out-of-range region` | 06-06 |
|
||||
| 84 | map/gameMap.ts | `binds aliases and warns 84 on a duplicate alias` | 06-06 |
|
||||
| 121 | map/mapState.ts | `registers floors and warns 121 when the floor already exists` | 06-06 |
|
||||
| 123 | map/mapLayer.ts | `warns code 123 on a length mismatch and replaces the reference otherwise` | 06-06 |
|
||||
| 126 | map/mover.ts | `warns code 126 for an unexpected move code and keeps the position` | 06-06 |
|
||||
| 127 | map/mapLayer.ts | `warns code 127 when transferring an empty block` | 06-06 |
|
||||
| 128 | map/mapLayer.ts | `warns code 128 when transferToStatic is out of bounds`(`transferToDynamic` 越图当前误发 131,另见 `#06-06-1` 的 `it.skip` 正确预期用例) | 06-06 |
|
||||
| 129 | map/mapLayer.ts | `warns code 129 when transferToStatic overwrites a static block` | 06-06 |
|
||||
| 130 | map/mapLayer.ts | `warns code 130 for a tile not managed by the layer` | 06-06 |
|
||||
| 131 | map/gameMap.ts | `accepts own layers, warns 131 for a foreign layer and clears on null` | 06-06 |
|
||||
| 136 | map/eventView.ts | `warns code 136 when the same priority is set twice` | 06-06 |
|
||||
| 143 | map/dynamicTile.ts | `warns code 143 when the raw tile data is missing`、`reflects num and raw and warns 143 on an unknown set` | 06-06 |
|
||||
|
||||
## 06-01 战斗系统(packages-user/data-system/src/combat)
|
||||
|
||||
@ -133,3 +154,27 @@ D-30:排除名称含 legacy 的接口/方法;`HeroMover` 顶层实现用内
|
||||
用例登记,详见 `06-TEST-FINDINGS.md`;其中 147 无法触发,故本表该行标注为跳过用例。
|
||||
`HeroMover` 测试复用真实 `HeroLocation` 作为移动宿主(非自定义 `TestTile`),以零断言代价
|
||||
覆盖真实 tile 写回路径。
|
||||
|
||||
## 06-06 地图全部(packages-user/data-base/src/map)
|
||||
|
||||
模块归属:60 / 61 / 62 / 63 / 64 / 121 → `map/mapState.ts`(`validateRaw` / `createMap`);
|
||||
84 / 131 → `map/gameMap.ts`(`setLayerAlias` / `setEventLayer`);
|
||||
8 / 9 / 46 / 80 / 81 / 123 / 127 / 128 / 129 / 130 → `map/mapLayer.ts`
|
||||
(`putMapData` / `closeDoor` / `getMapData` / `setMapRef` / 动态转换);
|
||||
126 → `map/mover.ts`(`DynamicTileMover.onStepEnd` 非法移动码);
|
||||
136 → `map/eventView.ts`(重复优先级);143 → `map/dynamicTile.ts`(缺图块原始数据)。
|
||||
|
||||
阶段 1(构件级)完成 `tile` / `staticTile` / `dynamicTile` / `eventView` 单元,观测 136/143;
|
||||
阶段 2(组合/流水线)完成 `MapState` 注册/校验/激活/分区与 `GameMap` 图层、`MapLayer` 矩阵/
|
||||
静态数组/动态转换/点位/脏/异步门,观测 8/9/46/60/61/62/63/64/80/81/84/121/123/127/129/130/131;
|
||||
阶段 3(完整/集成)完成 `DynamicTileMover` 异步移动生命周期,观测 126。
|
||||
|
||||
D-32:不测任何 `saveState`/`loadState`,其专属码 55/122/124 与存读档往返归 06-09。
|
||||
D-30:排除名称含 legacy 的接口/方法;`MapTileBase` 为抽象类,经 `StaticTile`/`DynamicTile` 具体子类覆盖。
|
||||
D-18/D-39 计划措辞与实现的两处偏差(非代码缺陷,不登记为 bug):
|
||||
其一,`IMapState` 并无 `canPass`/`shouldHit`,通行谓词实现在 `data-state/src/hero/predicate.ts`,
|
||||
故 `mapState.test.ts` 只覆盖谓词侧依赖的「活跃楼层 → 事件层」数据供给;
|
||||
其二,计划中的 `createLayerState` 码 121 实为 `MapState.createMap` 的重复注册告警(码表文案沿用旧名)。
|
||||
一条疑似缺陷 `#06-06-1`(`transferToDynamic` 越图误发 131 而非 128)按 D-05 以 `it.skip` 的
|
||||
正确预期用例登记,详见 `06-TEST-FINDINGS.md`;码 131 的触发则由 `gameMap.test.ts` 的
|
||||
`setEventLayer` 越权路径正常覆盖。
|
||||
|
||||
@ -78,3 +78,23 @@ equipStore 专属码 58/59 归 06-09。D-30:排除名称含 legacy 的接口/
|
||||
| `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) | 低 |
|
||||
|
||||
## #06-06 地图全部(packages-user/data-base/src/map)
|
||||
|
||||
本计划按 D-43 三阶段(构件 → 组合/流水线 → 完整/集成)执行,8 个测试文件全部跑绿
|
||||
(阶段 1:26 通过;阶段 2:63 通过 / 1 跳过;阶段 3:6 通过);`pnpm test:ci` 全绿
|
||||
(53 文件 / 505 通过 / 13 跳过,其中 1 条为本计划新增 skip)。
|
||||
D-32:不测任何 `saveState`/`loadState`,55/122/124 与存读档往返归 06-09。
|
||||
D-30:排除名称含 legacy 的接口/方法;两处**计划措辞与实现不符**(非代码缺陷,不登记为 bug):
|
||||
|
||||
- `IMapState` 并没有 `canPass`/`shouldHit`;通行谓词实现在 `data-state/src/hero/predicate.ts`
|
||||
(`DefaultPassPredicateImpl`,消费 `IMapState` 的活跃/普通楼层与事件层)。故 `mapState.test.ts`
|
||||
只覆盖谓词所依赖的「活跃楼层 → 事件层」数据供给,不测试并不存在的 MapState 谓词方法。
|
||||
- 计划中的「`createLayerState` 告警 121」实为 `MapState.createMap` 的重复楼层注册告警
|
||||
(码 121 的文案沿用了旧名 `MapStore.createLayerState`),测试按真实接口 `createMap` 覆盖。
|
||||
|
||||
发现 1 处疑似缺陷(`#06-06-1`),按 D-05 以正确预期的 `it.skip` 用例登记。
|
||||
|
||||
| 模块/接口 | 现象 | 最小复现 | 疑似原因 | 影响面 | 建议修复方向 | 关联 skip 用例 | 严重度 |
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| `mapLayer.ts` `MapLayer.transferToDynamic`(越图分支) | 越图转换发出的诊断码与语义不符:发的是 setEventLayer 专属码 131,且返回 null | 2x2 图层上调用 `layer.transferToDynamic(9, 9)`;`logger.catch` 捕获到码 131(`Cannot set event layer since target map layer does not belongs to current GameMap instance.`),返回 null | `if (!this.inMap(x, y))` 分支写成 `logger.warn(131, x, y)`;对照同文件 `transferToStatic`/`transferToStaticIfSafe` 的越界分支发码 128(`Cannot transfer ... out of bounds.`),此处应为 128 | 越界转换的诊断码错误,人工/回放诊断可能误判为事件层绑定问题;行为(返回 null、不产生动态图块)本身正确 | 将该分支改发 128,与 `transferToStatic` 的越界语义保持一致 | `mapLayer.test.ts` `warns code 128 for an out-of-map transferToDynamic`(#06-06-1) | 低 |
|
||||
|
||||
@ -39,5 +39,5 @@
|
||||
"label": "Advance to the next step",
|
||||
"reason": "Phase 06 of 6 · executing"
|
||||
},
|
||||
"updated_at": "2026-09-14T07:58:49.898Z"
|
||||
"updated_at": "2026-09-14T08:31:22.162Z"
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user