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
This commit is contained in:
unanmed 2026-10-05 15:19:56 +08:00
parent a76137f2a0
commit 8d6f851727
10 changed files with 141 additions and 253 deletions

View File

@ -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
};
}

View File

@ -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);
});
});

View File

@ -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);

View File

@ -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]]);

View File

@ -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)!;

View File

@ -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
}
];

View File

@ -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;

View File

@ -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
};
}

View File

@ -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', () => {

View File

@ -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
};
}