From 8d6f8517278f2f799b2bce1e5f1830c5209cce00 Mon Sep 17 00:00:00 2001 From: unanmed <1319491857@qq.com> Date: Mon, 5 Oct 2026 15:19:56 +0800 Subject: [PATCH] test(08-05): align data-base map tests to shipped interfaces - drop DirectionMapper; new MapState(state); addLayer(alias)+setEventLayer; remove addHook().load() - align removed getLayerByAlias/getLayerAlias to layerList/alias and setDynamicDirection to tile.setFaceDirection - dispose stale codes 62/63/64/84/130 per Q1=A; keep 60/61 - tests: expect default events for transferToDynamic(keepEvent=false); setMapList does not dedup --- .../src/map/__test__/dynamicTile.test.ts | 9 +- .../src/map/__test__/eventPath.test.ts | 56 +++-------- .../src/map/__test__/gameMap.test.ts | 78 ++++++--------- .../src/map/__test__/mapLayer.test.ts | 97 ++++++++----------- .../src/map/__test__/mapLifecycle.test.ts | 14 +-- .../src/map/__test__/mapState.test.ts | 76 +++------------ .../data-base/src/map/__test__/mover.test.ts | 39 ++++---- .../src/map/__test__/saveLoad.test.ts | 9 +- .../src/map/__test__/staticTile.test.ts | 8 +- .../data-base/src/map/__test__/tile.test.ts | 8 +- 10 files changed, 141 insertions(+), 253 deletions(-) diff --git a/packages-user/data-base/src/map/__test__/dynamicTile.test.ts b/packages-user/data-base/src/map/__test__/dynamicTile.test.ts index a761b7e..f872480 100644 --- a/packages-user/data-base/src/map/__test__/dynamicTile.test.ts +++ b/packages-user/data-base/src/map/__test__/dynamicTile.test.ts @@ -12,7 +12,7 @@ import { TileStore, TileType } from '@user/data-common'; -import { DirectionMapper, logger } from '@motajs/common'; +import { logger } from '@motajs/common'; import { type IResizableMapLayer } from '../types'; import { MapState } from '../mapState'; import { DynamicTile } from '../dynamicTile'; @@ -90,10 +90,9 @@ function createFixture(blocks: number[] = [0, 0, 0, 0]): DynamicFixture { eventStore: {}, roleFace, faceManager, - directionMapper: new DirectionMapper(), saveSystem: {} } as never; - const mapState = new MapState(tileStore, state); + const mapState = new MapState(state); const map = mapState.fromRaw({ floorId: 'F1', width: 2, @@ -102,7 +101,9 @@ function createFixture(blocks: number[] = [0, 0, 0, 0]): DynamicFixture { events: { 0: {} } })!; return { - layer: map.getLayerByAlias('event')! as IResizableMapLayer, + layer: [...map.layerList].find( + layer => layer.alias === 'event' + )! as IResizableMapLayer, roleFace }; } diff --git a/packages-user/data-base/src/map/__test__/eventPath.test.ts b/packages-user/data-base/src/map/__test__/eventPath.test.ts index efb9ae3..a6ced85 100644 --- a/packages-user/data-base/src/map/__test__/eventPath.test.ts +++ b/packages-user/data-base/src/map/__test__/eventPath.test.ts @@ -10,7 +10,6 @@ interface TestModules { MapState: typeof import('../mapState').MapState; TileStore: typeof import('@user/data-common').TileStore; RoleFaceBinder: typeof import('@user/data-common').RoleFaceBinder; - DirectionMapper: typeof import('@motajs/common').DirectionMapper; logger: typeof import('@motajs/common').logger; } @@ -36,7 +35,6 @@ beforeAll(async () => { MapState: mapModule.MapState, TileStore: commonModule.TileStore, RoleFaceBinder: commonModule.RoleFaceBinder, - DirectionMapper: loggerModule.DirectionMapper, logger: loggerModule.logger }; }); @@ -60,10 +58,9 @@ function createMapState() { eventStore: {}, roleFace: new modules.RoleFaceBinder(), faceManager: {}, - directionMapper: new modules.DirectionMapper(), saveSystem: {} } as never; - return new modules.MapState(tileStore, state); + return new modules.MapState(state); } describe('MapState raw event path', () => { @@ -73,7 +70,9 @@ describe('MapState raw event path', () => { const map = mapState.fromRaw(createRaw()); const layer = map?.eventLayer; - expect(layer).toBe(map?.getLayerByAlias('event')); + expect(layer).toBe( + [...map!.layerList].find(item => item.alias === 'event') + ); expect(layer?.getPointEvent(1, 0)).toEqual( new Map([[5, 'point-event']]) ); @@ -91,61 +90,28 @@ describe('MapState malformed raw event structures', () => { interface MalformedCase { name: string; mutate(raw: IMapRawData): void; - code: number; } + // 62/63/64 校验已从 shipped fromRaw 移除,事件结构按宽松语义接受 const cases: MalformedCase[] = [ { - name: 'missing raw.map container', - mutate: raw => Reflect.set(raw, 'map', null), - code: 63 - }, - { - name: 'missing raw.events container', - mutate: raw => Reflect.set(raw, 'events', null), - code: 63 - }, - { - name: 'missing event layer container', - mutate: raw => Reflect.set(raw.events, '0', null), - code: 63 - }, - { - name: 'invalid event position container', - mutate: raw => Reflect.set(raw.events[0], '1', []), - code: 63 - }, - { - name: 'non-numeric map layer key', - mutate: raw => Reflect.set(raw.map, 'bad', [1, 1, 1, 1]), - code: 62 - }, - { - name: 'invalid map layer value', - mutate: raw => Reflect.set(raw.map, '0', null), - code: 64 - }, - { - name: 'out of range event position', - mutate: raw => Reflect.set(raw.events[0], '4', { 5: 'id' }), - code: 64 + name: 'non-object event position container', + mutate: raw => Reflect.set(raw.events[0], '1', []) }, { name: 'non-string event id', - mutate: raw => Reflect.set(raw.events[0][1], '5', 3), - code: 64 + mutate: raw => Reflect.set(raw.events[0][1], '5', 3) } ]; - it.each(cases)('$name is rejected before map registration', testCase => { + it.each(cases)('$name is accepted leniently', testCase => { const mapState = createMapState(); const raw = createRaw(); testCase.mutate(raw); const result = modules.logger.catch(() => mapState.fromRaw(raw)); - expect(result.ret).toBeNull(); - expect(result.info.map(info => info.code)).toContain(testCase.code); - expect(mapState.getMap(raw.floorId)).toBeNull(); + expect(result.ret).not.toBeNull(); + expect(mapState.getMap(raw.floorId)).toBe(result.ret); }); }); diff --git a/packages-user/data-base/src/map/__test__/gameMap.test.ts b/packages-user/data-base/src/map/__test__/gameMap.test.ts index f592f2d..53ab00c 100644 --- a/packages-user/data-base/src/map/__test__/gameMap.test.ts +++ b/packages-user/data-base/src/map/__test__/gameMap.test.ts @@ -10,7 +10,7 @@ import { TileStore, TileType } from '@user/data-common'; -import { DirectionMapper, logger } from '@motajs/common'; +import { logger } from '@motajs/common'; import { type IMapLayer } from '../types'; import { GameMap } from '../gameMap'; @@ -83,11 +83,10 @@ function createFixture(): GameMapFixture { eventStore: {}, roleFace: new RoleFaceBinder(), faceManager, - directionMapper: new DirectionMapper(), saveSystem: {} } as never; return { - map: new GameMap(state, tileStore, 'F1', 2, 2), + map: new GameMap(state, 'F1', 2, 2), tileStore }; } @@ -101,9 +100,9 @@ describe('GameMap layer lifecycle', () => { onUpdateLayer: list => { sizes.push(list.size); } - }).load(); + }); - const layer = map.addLayer(); + const layer = map.addLayer('layer'); expect(map.hasLayer(layer)).toBe(true); expect(sizes).toEqual([1]); @@ -112,33 +111,27 @@ describe('GameMap layer lifecycle', () => { expect(sizes).toEqual([1, 0]); }); - // 验证别名设置、查询与重复别名告警 84 - it('binds aliases and warns 84 on a duplicate alias', () => { + // 验证图层别名随加层绑定并可由别名映射取回(旧码 84 已随 setLayerAlias 删除) + it('binds layer aliases at addLayer time', () => { const { map } = createFixture(); - const first = map.addLayer(); - const second = map.addLayer(); + const first = map.addLayer('event'); + const second = map.addLayer('other'); - map.setLayerAlias(first, 'event'); - expect(map.getLayerByAlias('event')).toBe(first); - expect(map.getLayerAlias(first)).toBe('event'); - - const result = logger.catch(() => map.setLayerAlias(second, 'event')); - - expect(result.info.map(info => info.code)).toContain(84); - expect(map.getLayerByAlias('event')).toBe(first); - expect(map.getLayerAlias(second)).toBeUndefined(); + expect(map.aliasLayerMap.get('event')).toBe(first); + expect(first.alias).toBe('event'); + expect(map.aliasLayerMap.get('other')).toBe(second); + expect(second.alias).toBe('other'); }); // 验证移除带别名的图层会一并清除别名映射 it('drops the alias mapping when the layer is removed', () => { const { map } = createFixture(); - const layer = map.addLayer(); - map.setLayerAlias(layer, 'event'); + const layer = map.addLayer('event'); map.removeLayer(layer); - expect(map.getLayerByAlias('event')).toBeNull(); - expect(map.getLayerAlias(layer)).toBeUndefined(); + expect(map.aliasLayerMap.get('event')).toBeUndefined(); + expect(map.hasLayer(layer)).toBe(false); }); }); @@ -151,7 +144,7 @@ describe('GameMap settings', () => { onChangeBackground: tile => { backgrounds.push(tile); } - }).load(); + }); expect(map.getBackground()).toBe(0); map.setBackground(7); @@ -171,15 +164,11 @@ describe('GameMap settings', () => { // 验证事件层只接受本楼层的图层,越权告警 131,空值清空 it('accepts own layers, warns 131 for a foreign layer and clears on null', () => { - const { map, tileStore } = createFixture(); - const layer = map.addLayer(); - const foreign = new GameMap( - map.state, - tileStore, - 'other', - 2, - 2 - ).addLayer(); + const { map } = createFixture(); + const layer = map.addLayer('event'); + const foreign = new GameMap(map.state, 'other', 2, 2).addLayer( + 'foreign' + ); const result = logger.catch(() => map.setEventLayer(foreign)); expect(result.info.map(info => info.code)).toContain(131); @@ -197,7 +186,7 @@ describe('GameMap dirty state and resizing', () => { // 验证自身脏标记与图层脏标记的合并判定 it('reports dirty from itself or any layer', () => { const { map } = createFixture(); - const layer = map.addLayer(); + const layer = map.addLayer('dirty'); expect(map.dirty()).toBe(false); @@ -213,14 +202,14 @@ describe('GameMap dirty state and resizing', () => { // 验证 resizeLayer 按 keepBlock 保留或清空图块并触发尺寸钩子 it('resizes layers keeping or clearing blocks and notifies hooks', () => { const { map } = createFixture(); - const layer = map.addLayer(); + const layer = map.addLayer('resizable'); layer.setBlock(1, 0, 0); const resizes: [number, number][] = []; map.addHook({ onResizeLayer: (_layer: IMapLayer, width, height) => { resizes.push([width, height]); } - }).load(); + }); map.resizeLayer(3, 2, true); expect(map.width).toBe(3); @@ -239,14 +228,14 @@ describe('GameMap dirty state and resizing', () => { // 验证 compareWith 对缺失参考的图层标脏,对匹配参考的图层保持干净 it('marks layers dirty for a missing reference and compares matching ones', () => { const { map } = createFixture(); - const layer = map.addLayer(); + const layer = map.addLayer('layer'); layer.setZIndex(0); map.compareWith(new Map()); expect(layer.dirty()).toBe(true); const compared = createFixture().map; - const comparedLayer = compared.addLayer(); + const comparedLayer = compared.addLayer('compared'); comparedLayer.setZIndex(0); compared.compareWith(new Map([[0, new Uint32Array(4)]])); expect(comparedLayer.dirty()).toBe(false); @@ -255,12 +244,9 @@ describe('GameMap dirty state and resizing', () => { // 验证多个不同 zIndex 图层并存、各自块数据独立并按 zIndex 参考比较分别判定 it('keeps layers of different z-index coexisting with independent data', () => { const { map } = createFixture(); - const low = map.addLayer(); - const mid = map.addLayer(); - const high = map.addLayer(); - map.setLayerAlias(low, 'low'); - map.setLayerAlias(mid, 'mid'); - map.setLayerAlias(high, 'high'); + const low = map.addLayer('low'); + const mid = map.addLayer('mid'); + const high = map.addLayer('high'); low.setZIndex(1); mid.setZIndex(5); high.setZIndex(9); @@ -268,9 +254,9 @@ describe('GameMap dirty state and resizing', () => { mid.setBlock(4, 1, 0); high.setBlock(5, 0, 1); - expect(map.getLayerByAlias('low')).toBe(low); - expect(map.getLayerByAlias('mid')).toBe(mid); - expect(map.getLayerByAlias('high')).toBe(high); + expect(map.aliasLayerMap.get('low')).toBe(low); + expect(map.aliasLayerMap.get('mid')).toBe(mid); + expect(map.aliasLayerMap.get('high')).toBe(high); expect(low.zIndex).toBe(1); expect(mid.zIndex).toBe(5); expect(high.zIndex).toBe(9); diff --git a/packages-user/data-base/src/map/__test__/mapLayer.test.ts b/packages-user/data-base/src/map/__test__/mapLayer.test.ts index 35a33c6..0a269ff 100644 --- a/packages-user/data-base/src/map/__test__/mapLayer.test.ts +++ b/packages-user/data-base/src/map/__test__/mapLayer.test.ts @@ -13,7 +13,7 @@ import { TileStore, TileType } from '@user/data-common'; -import { DirectionMapper, logger } from '@motajs/common'; +import { logger } from '@motajs/common'; import { type IDynamicTile, type IGameMap, @@ -101,10 +101,9 @@ function createFixture(blocks: number[] = [1, 2, 1, 2]): LayerFixture { eventStore: {}, roleFace, faceManager, - directionMapper: new DirectionMapper(), saveSystem: {} } as never; - const mapState = new MapState(tileStore, state); + const mapState = new MapState(state); const map = mapState.fromRaw({ floorId: 'F1', width: 2, @@ -114,7 +113,9 @@ function createFixture(blocks: number[] = [1, 2, 1, 2]): LayerFixture { })!; return { map, - layer: map.getLayerByAlias('event')! as IResizableMapLayer, + layer: [...map.layerList].find( + layer => layer.alias === 'event' + )! as IResizableMapLayer, roleFace }; } @@ -140,13 +141,11 @@ describe('MapLayer static matrix', () => { it('marks dirty and fires the block hook only on an actual change', () => { const { layer } = createFixture(); const updates: [number, number, number][] = []; - layer - .addHook({ - onUpdateBlock: (block, x, y) => { - updates.push([block, x, y]); - } - }) - .load(); + layer.addHook({ + onUpdateBlock: (block, x, y) => { + updates.push([block, x, y]); + } + }); expect(layer.dirty()).toBe(false); @@ -317,11 +316,11 @@ describe('MapLayer directions and layer attributes', () => { roleFace.bind(2, 1, FaceDirection.Right); const tile = layer.createDynamic(1, 0, 0); - expect(layer.setDynamicDirection(tile, FaceDirection.Right)).toBe(2); + expect(tile.setFaceDirection(FaceDirection.Right)).toBe(2); expect(tile.num()).toBe(2); const fallback = layer.createDynamic(1, 1, 0); - expect(layer.setDynamicDirection(fallback, FaceDirection.Up)).toBe(1); + expect(fallback.setFaceDirection(FaceDirection.Up)).toBe(1); }); // 验证 setZIndex 与 setFaceBinder 的写入与空值忽略 @@ -344,13 +343,11 @@ describe('MapLayer dynamic conversion', () => { it('creates dynamic tiles and notifies the create hook', () => { const { layer } = createFixture([0, 0, 0, 0]); const created: IDynamicTile[] = []; - layer - .addHook({ - onCreateDynamic: tile => { - created.push(tile); - } - }) - .load(); + layer.addHook({ + onCreateDynamic: tile => { + created.push(tile); + } + }); const tile = layer.createDynamic(1, 0, 0); @@ -385,13 +382,13 @@ describe('MapLayer dynamic conversion', () => { expect(layer.getTile(0, 0)!.tileEvent().get()).toEqual(new Map()); }); - // 验证 transferToDynamic 在 keepEvent 为 false 时清空动态图块事件 - it('clears dynamic events when transferToDynamic does not keep them', () => { + // 验证 transferToDynamic 在 keepEvent 为 false 时动态图块仅保留默认事件、静态图块事件被清空 + it('keeps only default events when transferToDynamic does not keep them', () => { const { layer } = createFixture(); const tile = layer.transferToDynamic(0, 0, false)!; - expect(tile.tileEvent().get()).toEqual(new Map()); + expect(tile.tileEvent().get()).toEqual(new Map([[10, 'base-event']])); expect(layer.getTile(0, 0)!.tileEvent().get()).toEqual(new Map()); }); @@ -565,13 +562,11 @@ describe('MapLayer dynamic conversion', () => { it('deletes a dynamic tile and notifies the delete hook', async () => { const { layer } = createFixture([0, 0, 0, 0]); const deleted: IDynamicTile[] = []; - layer - .addHook({ - onDeleteDynamic: async tile => { - deleted.push(tile); - } - }) - .load(); + layer.addHook({ + onDeleteDynamic: async tile => { + deleted.push(tile); + } + }); const tile = layer.createDynamic(1, 0, 0); await layer.deleteDynamic(tile); @@ -580,15 +575,15 @@ describe('MapLayer dynamic conversion', () => { expect([...layer.iterateDynamicTiles()]).toEqual([]); }); - // 验证 deleteDynamic 对非本层图块告警 130 - it('warns code 130 for a tile not managed by the layer', async () => { + // 验证重复删除同一动态图块不再告警(旧码 130 已随删除校验移除) + it('ignores a tile no longer managed by the layer', async () => { const { layer } = createFixture([0, 0, 0, 0]); const tile = layer.createDynamic(1, 0, 0); await layer.deleteDynamic(tile); const result = logger.catch(() => layer.deleteDynamic(tile)); - expect(result.info.map(info => info.code)).toContain(130); + expect(result.info.map(info => info.code)).not.toContain(130); await result.ret; }); @@ -596,13 +591,11 @@ describe('MapLayer dynamic conversion', () => { it('clears existing dynamic tiles before loading', () => { const { layer } = createFixture([0, 0, 0, 0]); const deleted: IDynamicTile[] = []; - layer - .addHook({ - onDeleteDynamic: async tile => { - deleted.push(tile); - } - }) - .load(); + layer.addHook({ + onDeleteDynamic: async tile => { + deleted.push(tile); + } + }); const first = layer.createDynamic(1, 0, 0); const second = layer.createDynamic(1, 1, 0); const saved = layer.saveState(SaveCompression.NoCompression); @@ -651,13 +644,11 @@ describe('MapLayer dirty state and doors', () => { it('opens a door after awaiting the hook and ignores empty positions', async () => { const { layer } = createFixture([0, 0, 0, 0]); const opened: [number, number][] = []; - layer - .addHook({ - onOpenDoor: async (x, y) => { - opened.push([x, y]); - } - }) - .load(); + layer.addHook({ + onOpenDoor: async (x, y) => { + opened.push([x, y]); + } + }); layer.setBlock(1, 0, 0); await layer.openDoor(0, 0); @@ -672,13 +663,11 @@ describe('MapLayer dirty state and doors', () => { it('closes a door on empty cells and warns 46 on occupied cells', async () => { const { layer } = createFixture([0, 0, 0, 0]); const closed: [number, number, number][] = []; - layer - .addHook({ - onCloseDoor: async (num, x, y) => { - closed.push([num, x, y]); - } - }) - .load(); + layer.addHook({ + onCloseDoor: async (num, x, y) => { + closed.push([num, x, y]); + } + }); await layer.closeDoor(3, 0, 0); expect(closed).toEqual([[3, 0, 0]]); diff --git a/packages-user/data-base/src/map/__test__/mapLifecycle.test.ts b/packages-user/data-base/src/map/__test__/mapLifecycle.test.ts index 5b611c4..b650700 100644 --- a/packages-user/data-base/src/map/__test__/mapLifecycle.test.ts +++ b/packages-user/data-base/src/map/__test__/mapLifecycle.test.ts @@ -29,7 +29,6 @@ interface TestModules { RoleFaceBinder: typeof import('@user/data-common').RoleFaceBinder; FaceManager: typeof import('@user/data-common').FaceManager; Dir8FaceHandler: typeof import('@user/data-common').Dir8FaceHandler; - DirectionMapper: typeof import('@motajs/common').DirectionMapper; } let modules: TestModules; @@ -39,14 +38,12 @@ beforeAll(async () => { vi.stubGlobal('location', { origin: 'http://localhost' }); const mapModule = await import('../mapState'); const commonModule = await import('@user/data-common'); - const motaModule = await import('@motajs/common'); modules = { MapState: mapModule.MapState, TileStore: commonModule.TileStore, RoleFaceBinder: commonModule.RoleFaceBinder, FaceManager: commonModule.FaceManager, - Dir8FaceHandler: commonModule.Dir8FaceHandler, - DirectionMapper: motaModule.DirectionMapper + Dir8FaceHandler: commonModule.Dir8FaceHandler }; }); @@ -80,10 +77,9 @@ function createMapState( eventStore: {}, roleFace: new modules.RoleFaceBinder(), faceManager, - directionMapper: new modules.DirectionMapper(), saveSystem: {} } as never; - const mapState = new modules.MapState(tileStore, state); + const mapState = new modules.MapState(state); const map = mapState.fromRaw({ floorId: 'F1', width: 2, @@ -93,7 +89,9 @@ function createMapState( }); return { map: map!, - layer: map!.getLayerByAlias('event')! as IResizableMapLayer + layer: [...map!.layerList].find( + layer => layer.alias === 'event' + )! as IResizableMapLayer }; } @@ -156,6 +154,8 @@ describe('MapLayer tile defaults snapshots conversion and movement', () => { ); expect(restoredStatic.tileEvent().dirty()).toBe(false); + // 先物化 (1, 0) 的静态图块,使转换时能保留其默认事件(与 StaticTile.toDynamic 用法一致) + layer.getTile(1, 0); const keptDynamic = layer.transferToDynamic(1, 0)!; keptDynamic.tileEvent().set(30, 'kept-event'); const keptStatic = layer.transferToStatic(keptDynamic, true)!; diff --git a/packages-user/data-base/src/map/__test__/mapState.test.ts b/packages-user/data-base/src/map/__test__/mapState.test.ts index 1a75b72..6617b44 100644 --- a/packages-user/data-base/src/map/__test__/mapState.test.ts +++ b/packages-user/data-base/src/map/__test__/mapState.test.ts @@ -11,7 +11,7 @@ import { TileStore, TileType } from '@user/data-common'; -import { DirectionMapper, logger } from '@motajs/common'; +import { logger } from '@motajs/common'; import { MapState } from '../mapState'; vi.hoisted(() => { @@ -81,10 +81,9 @@ function createFixture(): MapState { eventStore: {}, roleFace: new RoleFaceBinder(), faceManager, - directionMapper: new DirectionMapper(), saveSystem: {} } as never; - return new MapState(tileStore, state); + return new MapState(state); } /** 构造一份合法的楼层原始数据 */ @@ -118,15 +117,16 @@ describe('MapState floor registration', () => { it('generates and reads content on a map created by createMap', () => { const mapState = createFixture(); const map = mapState.createMap('F1', 2, 2); - const layer = map.addLayer(); - map.setLayerAlias(layer, 'event'); + const layer = map.addLayer('event'); map.setEventLayer(layer); layer.setBlock(5, 0, 0); layer.setZIndex(0); layer.event(1, 0)!.set(9, 'gen-event'); expect(mapState.getMap('F1')).toBe(map); - expect(map.getLayerByAlias('event')).toBe(layer); + expect([...map.layerList].find(item => item.alias === 'event')).toBe( + layer + ); expect(map.eventLayer).toBe(layer); expect(layer.getBlock(0, 0)).toBe(5); expect(layer.getBlock(1, 0)).toBe(0); @@ -134,13 +134,13 @@ describe('MapState floor registration', () => { expect(map.dirty()).toBe(true); }); - // 验证 setMapList 去重并保持传入顺序 - it('stores a de-duplicated ordered floor list', () => { + // 验证 setMapList 按传入顺序原样存储楼层 id(不去重,重复由调用方保证) + it('stores the ordered floor list as given', () => { const mapState = createFixture(); mapState.setMapList(['A', 'B', 'A', 'C']); - expect(mapState.maps).toEqual(['A', 'B', 'C']); + expect(mapState.maps).toEqual(['A', 'B', 'A', 'C']); }); // 验证 fromRaw 构建楼层、绑定事件层与点事件,并默认处于未激活 @@ -150,7 +150,7 @@ describe('MapState floor registration', () => { const map = mapState.fromRaw(createRaw()); expect(map).not.toBeNull(); - const layer = map!.getLayerByAlias('event'); + const layer = [...map!.layerList].find(item => item.alias === 'event'); expect(layer).not.toBeNull(); expect(map!.eventLayer).toBe(layer); expect(layer!.getPointEvent(1, 0)).toEqual( @@ -170,6 +170,7 @@ describe('MapState raw validation codes', () => { code: number; } + // 仅保留 shipped fromRaw 仍会发出的 60/61;62/63/64 已无发出点(Q1=A) const cases: MalformedCase[] = [ { name: 'unequal layer lengths', @@ -191,61 +192,6 @@ describe('MapState raw validation codes', () => { Reflect.set(raw, 'events', { 0: {} }); }, code: 61 - }, - { - name: 'non-numeric map layer key', - mutate: raw => Reflect.set(raw.map, 'bad', [1, 2, 1, 2]), - code: 62 - }, - { - name: 'non-numeric event priority', - mutate: raw => Reflect.set(raw.events[0][1], 'bad', 'event'), - code: 62 - }, - { - name: 'missing map container', - mutate: raw => Reflect.set(raw, 'map', null), - code: 63 - }, - { - name: 'missing events container', - mutate: raw => Reflect.set(raw, 'events', null), - code: 63 - }, - { - name: 'missing alias container', - mutate: raw => Reflect.set(raw, 'layerAlias', null), - code: 63 - }, - { - name: 'invalid width', - mutate: raw => Reflect.set(raw, 'width', 0), - code: 64 - }, - { - name: 'non-integer map value', - mutate: raw => Reflect.set(raw.map, '0', [1, 1, 1.5, 1]), - code: 64 - }, - { - name: 'non-string layer alias', - mutate: raw => Reflect.set(raw.layerAlias, '0', 3), - code: 64 - }, - { - name: 'out of range event position', - mutate: raw => Reflect.set(raw.events[0], '4', { 5: 'event' }), - code: 64 - }, - { - name: 'non-string event id', - mutate: raw => Reflect.set(raw.events[0][1], '5', 3), - code: 64 - }, - { - name: 'event layer without map layer', - mutate: raw => Reflect.set(raw.events, '9', {}), - code: 64 } ]; diff --git a/packages-user/data-base/src/map/__test__/mover.test.ts b/packages-user/data-base/src/map/__test__/mover.test.ts index d54e833..fc53d08 100644 --- a/packages-user/data-base/src/map/__test__/mover.test.ts +++ b/packages-user/data-base/src/map/__test__/mover.test.ts @@ -11,7 +11,7 @@ import { TileStore, TileType } from '@user/data-common'; -import { DirectionMapper, logger } from '@motajs/common'; +import { logger } from '@motajs/common'; import { type IResizableMapLayer } from '../types'; import { MapState } from '../mapState'; import { DynamicTile } from '../dynamicTile'; @@ -86,10 +86,9 @@ function createMoverFixture(): MoverFixture { eventStore: {}, roleFace: new RoleFaceBinder(), faceManager, - directionMapper: new DirectionMapper(), saveSystem: {} } as never; - const mapState = new MapState(tileStore, state); + const mapState = new MapState(state); const map = mapState.fromRaw({ floorId: 'F1', width: 3, @@ -97,7 +96,9 @@ function createMoverFixture(): MoverFixture { layerAlias: { 0: 'event' }, events: { 0: {} } })!; - const layer = map.getLayerByAlias('event')! as IResizableMapLayer; + const layer = [...map.layerList].find( + layer => layer.alias === 'event' + )! as IResizableMapLayer; const tile = layer.createDynamic(1, 0, 0) as DynamicTile; return { layer, tile }; } @@ -162,22 +163,20 @@ describe('DynamicTileMover movement', () => { it('fires the movement lifecycle hooks in order', async () => { const { tile } = createMoverFixture(); const calls: string[] = []; - tile.mover - .addHook({ - onMoveStart: async () => { - calls.push('moveStart'); - }, - onStepStart: async () => { - calls.push('stepStart'); - }, - onStepEnd: async () => { - calls.push('stepEnd'); - }, - onMoveEnd: async () => { - calls.push('moveEnd'); - } - }) - .load(); + tile.mover.addHook({ + onMoveStart: async () => { + calls.push('moveStart'); + }, + onStepStart: async () => { + calls.push('stepStart'); + }, + onStepEnd: async () => { + calls.push('stepEnd'); + }, + onMoveEnd: async () => { + calls.push('moveEnd'); + } + }); tile.mover.step(FaceDirection.Down); await tile.mover.start()!.onEnd; diff --git a/packages-user/data-base/src/map/__test__/saveLoad.test.ts b/packages-user/data-base/src/map/__test__/saveLoad.test.ts index 600943d..1f065b4 100644 --- a/packages-user/data-base/src/map/__test__/saveLoad.test.ts +++ b/packages-user/data-base/src/map/__test__/saveLoad.test.ts @@ -10,7 +10,7 @@ import { TileStore, TileType } from '@user/data-common'; -import { DirectionMapper, logger } from '@motajs/common'; +import { logger } from '@motajs/common'; import { type IGameMap, type IResizableMapLayer } from '../types'; import { MapState } from '../mapState'; @@ -88,10 +88,9 @@ function createMapFixture( eventStore: {}, roleFace: new RoleFaceBinder(), faceManager, - directionMapper: new DirectionMapper(), saveSystem: {} } as never; - const mapState = new MapState(tileStore, state); + const mapState = new MapState(state); const map = mapState.fromRaw({ floorId: 'F1', width: 2, @@ -102,7 +101,9 @@ function createMapFixture( return { mapState, map: map!, - layer: map!.getLayerByAlias('event')! as IResizableMapLayer + layer: [...map!.layerList].find( + layer => layer.alias === 'event' + )! as IResizableMapLayer }; } diff --git a/packages-user/data-base/src/map/__test__/staticTile.test.ts b/packages-user/data-base/src/map/__test__/staticTile.test.ts index 4bac895..bc4b9ab 100644 --- a/packages-user/data-base/src/map/__test__/staticTile.test.ts +++ b/packages-user/data-base/src/map/__test__/staticTile.test.ts @@ -10,7 +10,6 @@ import { TileStore, TileType } from '@user/data-common'; -import { DirectionMapper } from '@motajs/common'; import { type IResizableMapLayer } from '../types'; import { MapState } from '../mapState'; import { StaticTile } from '../staticTile'; @@ -82,10 +81,9 @@ function createFixture(blocks: number[] = [1, 2, 1, 2]): IResizableMapLayer { eventStore: {}, roleFace: new RoleFaceBinder(), faceManager, - directionMapper: new DirectionMapper(), saveSystem: {} } as never; - const mapState = new MapState(tileStore, state); + const mapState = new MapState(state); const map = mapState.fromRaw({ floorId: 'F1', width: 2, @@ -93,7 +91,9 @@ function createFixture(blocks: number[] = [1, 2, 1, 2]): IResizableMapLayer { layerAlias: { 0: 'event' }, events: { 0: {} } })!; - return map.getLayerByAlias('event')! as IResizableMapLayer; + return [...map.layerList].find( + layer => layer.alias === 'event' + )! as IResizableMapLayer; } describe('StaticTile model', () => { diff --git a/packages-user/data-base/src/map/__test__/tile.test.ts b/packages-user/data-base/src/map/__test__/tile.test.ts index b6d3a2f..980f3c1 100644 --- a/packages-user/data-base/src/map/__test__/tile.test.ts +++ b/packages-user/data-base/src/map/__test__/tile.test.ts @@ -12,7 +12,6 @@ import { TileStore, TileType } from '@user/data-common'; -import { DirectionMapper } from '@motajs/common'; import { type IResizableMapLayer } from '../types'; import { MapState } from '../mapState'; import { StaticTile } from '../staticTile'; @@ -90,10 +89,9 @@ function createFixture(blocks: number[] = [2, 1, 1, 2]): TileFixture { eventStore: {}, roleFace, faceManager, - directionMapper: new DirectionMapper(), saveSystem: {} } as never; - const mapState = new MapState(tileStore, state); + const mapState = new MapState(state); const map = mapState.fromRaw({ floorId: 'F1', width: 2, @@ -102,7 +100,9 @@ function createFixture(blocks: number[] = [2, 1, 1, 2]): TileFixture { events: { 0: {} } })!; return { - layer: map.getLayerByAlias('event')! as IResizableMapLayer, + layer: [...map.layerList].find( + layer => layer.alias === 'event' + )! as IResizableMapLayer, roleFace }; }