From 0d41abdaf6415fdaa2aebd7de1923b2e13cb8955 Mon Sep 17 00:00:00 2001 From: unanmed <1319491857@qq.com> Date: Mon, 5 Oct 2026 15:20:06 +0800 Subject: [PATCH] docs(08-05): record map alignment summary and plan progress - add 08-05-SUMMARY.md (status complete; D-10 production fixes + test alignments + gate evidence) - mark 08-05-PLAN.md done and bump Phase 8 progress to 4/11 --- .planning/ROADMAP.md | 4 +- .../08-test-refactor-alignment/08-05-PLAN.md | 6 ++ .../08-05-SUMMARY.md | 98 +++++++++++++++++++ 3 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 .planning/phases/08-test-refactor-alignment/08-05-SUMMARY.md diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 8d4cc42..8cde271 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -458,7 +458,7 @@ Plans: - [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` 读档禁录修复) -- [ ] 08-05-PLAN.md — data-base map 对齐(`addLayer(alias)`、`MapState(state)`;陈旧码 62/63/64/84/130/125 裁决) +- [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 守卫码) - [ ] 08-07-PLAN.md — data-system path 对齐(`useMapState` 删除、`useFaceHandler` 注入) - [ ] 08-08-PLAN.md — data-state src 对齐(`createCoreState` 删除→`CoreState({loadStarter,coreURL})`;`coreEventLayer` A1/A2) @@ -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. 测试重构与接口对齐 | 3/11 | In Progress | - | +| 8. 测试重构与接口对齐 | 4/11 | In Progress | - | diff --git a/.planning/phases/08-test-refactor-alignment/08-05-PLAN.md b/.planning/phases/08-test-refactor-alignment/08-05-PLAN.md index 87263d9..6fa3b91 100644 --- a/.planning/phases/08-test-refactor-alignment/08-05-PLAN.md +++ b/.planning/phases/08-test-refactor-alignment/08-05-PLAN.md @@ -98,6 +98,12 @@ Output: 11 个既有文件的对齐改动;零生产改动、零新增依赖。 - **Q2**:`addLayer(alias)` 中 `'event'` 之外的层别名取值约定(是否沿用测试原意),以及事件层 `setEventLayer` 的断言是否逐字保留。 - **Q3**:`DynamicTileMover` 测试是否需在夹具中预注册 Dir8 handler 以避免 192;若需,属测试夹具变更(非生产)。 + + **裁决日期:** 2026-10-04(用户「可以执行」) + - **Q1 = A:** 陈旧校验码 62/63/64/84/130/125 以**源码为准**——当前无 emit 点者,相应断言按 shipped 改写/忽略(失效错误码忽略),**不补测、不新增生产修复**。 + - **Q2:** 别名(`addLayer(alias)`)**仅为名字**,与是否事件层无关;事件层须显式 `setEventLayer(layer)`。测试别名取值沿用原意,`setEventLayer` 断言逐字保留。 + - **Q3:** 无需夹具改动——`DYNAMIC_MOVER_FACE = FaceGroup.Dir8`(`data-base/src/shared.ts:4`),夹具已注册 `FaceGroup.Dir8`,不会触发码 192。 + RESEARCH §8.6、§9.2、OQ6;PATTERNS `P8`。D-05 禁止新增接口;D-10 默认零生产改动。60/61 仍为 `fromRaw` 的 shipped 校验码。 diff --git a/.planning/phases/08-test-refactor-alignment/08-05-SUMMARY.md b/.planning/phases/08-test-refactor-alignment/08-05-SUMMARY.md new file mode 100644 index 0000000..c90805e --- /dev/null +++ b/.planning/phases/08-test-refactor-alignment/08-05-SUMMARY.md @@ -0,0 +1,98 @@ +--- +phase: 08-test-refactor-alignment +plan: 05 +subsystem: data-base/map +tags: [test-alignment, map, d10-production-fix] +status: complete +requires: + - 08-01 +provides: + - "data-base/map 子系统 11 个测试文件对齐 shipped 接口,聚焦 108/108 通过" +affects: + - packages-user/data-base/src/map +tech-stack: + added: [] + patterns: + - "MapLayer.getMapData 子区域按请求宽高返回、越界补零" + - "LayerEventView.reset 恢复参考基准并置纯" + - "MapLayer.resize/resize2 同步 indexer 宽度并重索引点事件" +key-files: + created: + - .planning/phases/08-test-refactor-alignment/08-05-SUMMARY.md + modified: + - packages-user/data-base/src/map/mapLayer.ts + - packages-user/data-base/src/map/eventView.ts + - packages-user/data-base/src/map/__test__/gameMap.test.ts + - packages-user/data-base/src/map/__test__/mapState.test.ts + - packages-user/data-base/src/map/__test__/mapLayer.test.ts + - packages-user/data-base/src/map/__test__/mapLifecycle.test.ts + - packages-user/data-base/src/map/__test__/eventPath.test.ts + - packages-user/data-base/src/map/__test__/dynamicTile.test.ts + - packages-user/data-base/src/map/__test__/tile.test.ts + - packages-user/data-base/src/map/__test__/staticTile.test.ts + - packages-user/data-base/src/map/__test__/saveLoad.test.ts + - packages-user/data-base/src/map/__test__/mover.test.ts +decisions: + - "Q1=A:陈旧码 62/63/64/84/130/125 按 shipped 改写/忽略,不补测、不改生产" + - "Q2:addLayer(alias) 别名仅为名字,事件层须显式 setEventLayer" + - "D-10 生产修复(经用户确认):getMapData 子区域、toStatic 默认事件、reset 纯度、resize2 清点事件、cropPointEvents 重索引、indexer 宽度同步" +completed: 2026-10-05 +--- + +# 08-05 — data-base/map 测试对齐 Summary + +**一句话:** 将 `packages-user/data-base` 的 `map` 子系统 11 个测试文件对齐 shipped 接口/形状,并按用户确认的 D-10 例外修复了 5 处 `mapLayer.ts`/`eventView.ts` 生产回归,聚焦 **108/108 通过、eslint 0**。 + +## Task 0 裁决 + +- **Q1 = A**:62/63/64/84/130/125 当前源码无 emit 点,按 shipped 改写/忽略,不补测、不新增生产修复。 +- **Q2**:`addLayer(alias)` 别名仅为名字,与事件层无关;事件层须显式 `setEventLayer(layer)`。 +- **Q3**:无需夹具改动(`DYNAMIC_MOVER_FACE = FaceGroup.Dir8`,夹具已注册)。 + +## 生产改动(D-10 经用户确认;仅 `mapLayer.ts` + `eventView.ts`) + +| 文件 | 位置 | 修复 | +|------|------|------| +| `map/mapLayer.ts` | `getMapData(x,y,width,height)` | 结束下标 `lineStart + nw`(原用绝对 `nr`);结果缓冲改回 `width * height`(原裁剪为 `nw*nh`),越界行补零。修复子区域取值与码 81 语义 | +| `map/mapLayer.ts` | `toStatic(tile, keepEvent)` | `keepEvent === false` 时对复用的静态图块执行 `loadState({})`(`restoreDefaultEvents()` 无覆盖),回退默认事件并保持实例同一性;`keepEvent === true` 仍 `syncTileEvent` | +| `map/mapLayer.ts` | `cropPointEvents(oldWidth,width,height)` | 按旧宽解码旧索引、按新宽 `y*width+x` 重建;超出新范围者丢弃 | +| `map/mapLayer.ts` | `resize(width,height)` | 变更后 `this.indexer.setWidth(width)`,并以 `beforeWidth` 调 `cropPointEvents` | +| `map/mapLayer.ts` | `resize2(width,height)` | 尺寸不变提前 return 分支补 `this.pointEvents.clear()`;变更分支补 `this.indexer.setWidth(width)` | +| `map/mapLayer.ts` | `indexer` 字段 | 类型收敛为 `ILocationIndexer`(构造处一次 `as`),以在层内同步共享索引器步长;不改 `types.ts` | +| `map/eventView.ts` | `reset()` | 回填参考基准后置 `this.dirtyEntries = 0`,使 `dirty()` 恢复为 `false` | + +> `types.ts` 未改动;生产改动严格限于 `mapLayer.ts`、`eventView.ts`(`git status` 佐证)。 + +## 测试对齐改动(10 个文件) + +- **通用**:删夹具 `DirectionMapper` 注入与 `@motajs/common` 导入;`new MapState(tileStore, state)` → `new MapState(state)`;`map.addLayer()` → `map.addLayer('')`、删 `setLayerAlias` 并把别名并入 `addLayer`,事件层仍 `setEventLayer`;删 `addHook({...}).load()` 的 `.load()`。 +- **计划外按 shipped 一并对齐**:`IGameMap.getLayerByAlias`/`getLayerAlias`(亦随 `bbdea04` 删除)→ 改用 `IGameMap.layerList` + `IMapLayer.alias`(`gameMap.test.ts` 用 `GameMap.aliasLayerMap`);`GameMap` 构造去掉 `tileStore` 形参;`layer.setDynamicDirection(tile,d)`(已删,原为薄包装)→ `tile.setFaceDirection(d)`。 +- **陈旧码处置台账(Q1=A)**: + + | 码 | 处置 | + |----|------| + | 62/63/64 | `mapState.test.ts` 的 `it.each` 仅保留 shipped 的 60/61;`eventPath.test.ts` malformed 块改写为「非对象事件位容器 / 非字符串事件 id 被宽松接受」两用例(不新增 `it`) | + | 84 | `gameMap.test.ts` 重写为「别名随加层绑定、可由 `aliasLayerMap` 取回」,删 84 断言 | + | 130 | `mapLayer.test.ts` 重写为「重复删除非本层图块不告警」,断言 `.not.toContain(130)` | + | 125 | map 测试无该断言,无操作 | + +- **用户裁决的测试对齐**:`transferToDynamic(keepEvent=false)` 动态图块保留默认事件(`mapLayer.test.ts` 断言改为 `Map{10:'base-event'}`);`setMapList` 不去重(`mapState.test.ts` 断言改为原样 `['A','B','A','C']`)。 +- **本轮新暴露用例的测试对齐**:`mapLifecycle.test.ts` 在直接 `transferToDynamic(1,0)` 前补 `layer.getTile(1,0)`(与 `StaticTile.toDynamic` 及 `mapLayer.test.ts` 既有用法一致,先物化静态图块),使 keepEvent=true 往返保留默认事件;**未改生产**。 +- 未新增 `it.skip`;每个 `it` 保留一行中文注释;未删用例、未弱化其它断言。 + +## 门禁证据 + +- **聚焦运行**:`pnpm exec vitest run packages-user/data-base/src/map/__test__` → **Test Files 11 passed(11);Tests 108 passed(108)**(0 failed)。 +- **eslint**:`pnpm exec eslint --fix` + `pnpm exec eslint`(`mapLayer.ts`、`eventView.ts`、`map/__test__`)→ **0 报错**。 +- **零其它生产改动**:`git status` 下 `map/**` 仅 `eventView.ts`、`mapLayer.ts` 两个生产文件 + 10 个 `__test__/*.ts`;`types.ts` 已回退。 +- **skip 计数**:未新增 skip;仓库唯一 skip 仍为 `hero/equipment.test.ts` 码 147。 + +## 备注(供知悉) + +- `transferToDynamic` 在直接调用且该格静态图块尚未物化时,因实现先 `setBlock(0)` 再 `getTile`,动态图块会以空事件被同步(默认事件被覆盖);经用户 Q3 风格确认「不改该生产方法」,本次以测试补 `getTile` 前置物化对齐。如需改为「无论是否物化均保留默认事件」,可另行授权最小生产修复。 + +## Deviations from Plan + +- **D-10 生产修复(经用户确认)**:`getMapData`/`toStatic`/`cropPointEvents`/`resize`/`resize2`/eventView `reset`——超出「零生产改动」默认,属用户逐条授权的例外。 +- **计划外一并对齐(Rule 1/F)**:`getLayerByAlias`/`getLayerAlias` 删除、`GameMap` 构造签名、`setDynamicDirection` 删除——均随同一轮重构发生,按「对齐 shipped」处理。 +- **新暴露用例**:`mapLifecycle` 的 `transferToDynamic(1,0)` 断言原被前排失败遮蔽;按「不改 transferToDynamic 生产」以测试前置物化对齐。