feat(web-platform): release V0.7 地图模块
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
import { discoverMapEntries, resolveProjectMap } from './MapLoader';
|
||||
import type { ProjectFile, ProjectManifest } from '../project/types';
|
||||
|
||||
const encode = (value: string) => new TextEncoder().encode(value);
|
||||
const file = (path: string, value = ''): ProjectFile => ({
|
||||
path,
|
||||
data: encode(value),
|
||||
size: encode(value).byteLength,
|
||||
source: 'directory',
|
||||
mimeType: '',
|
||||
});
|
||||
|
||||
const descriptor = JSON.stringify({
|
||||
schemaVersion: 1,
|
||||
id: 'warehouse',
|
||||
name: '仓库',
|
||||
coordinateSystem: { units: 'm', up: 'Z', forward: '+X' },
|
||||
physics: { source: 'physics/world.xml' },
|
||||
visual: { source: 'visuals/scene.glb' },
|
||||
spawnPoints: [{ id: 'door', name: '入口', position: [1, 2, 0.3], yawDeg: 90 }],
|
||||
});
|
||||
|
||||
describe('MapLoader', () => {
|
||||
it('发现 map.json 并解析工程内资源', () => {
|
||||
const files = [
|
||||
file('maps/warehouse/map.json', descriptor),
|
||||
file('maps/warehouse/physics/world.xml', '<mujoco><worldbody/></mujoco>'),
|
||||
file('maps/warehouse/visuals/scene.glb'),
|
||||
];
|
||||
expect(discoverMapEntries(files)).toEqual([
|
||||
{
|
||||
descriptorPath: 'maps/warehouse/map.json',
|
||||
schemaVersion: 1,
|
||||
id: 'warehouse',
|
||||
name: '仓库',
|
||||
physicsPath: 'maps/warehouse/physics/world.xml',
|
||||
visualPath: 'maps/warehouse/visuals/scene.glb',
|
||||
spawnPoints: [{ id: 'door', name: '入口' }],
|
||||
},
|
||||
]);
|
||||
const manifest: ProjectManifest = {
|
||||
id: 'test',
|
||||
name: 'test',
|
||||
files,
|
||||
entries: [],
|
||||
maps: discoverMapEntries(files),
|
||||
totalBytes: files.reduce((sum, item) => sum + item.size, 0),
|
||||
};
|
||||
expect(resolveProjectMap(manifest, 'maps/warehouse/map.json')).toMatchObject({
|
||||
physicsPath: 'maps/warehouse/physics/world.xml',
|
||||
visualPath: 'maps/warehouse/visuals/scene.glb',
|
||||
});
|
||||
});
|
||||
|
||||
it('发现 schema V2 authoring 创作层', () => {
|
||||
const editable = JSON.stringify({
|
||||
...JSON.parse(descriptor),
|
||||
schemaVersion: 2,
|
||||
authoring: { source: 'authoring/map.scene.json' },
|
||||
});
|
||||
const files = [
|
||||
file('maps/warehouse/map.json', editable),
|
||||
file('maps/warehouse/physics/world.xml'),
|
||||
file('maps/warehouse/visuals/scene.glb'),
|
||||
file(
|
||||
'maps/warehouse/authoring/map.scene.json',
|
||||
JSON.stringify({
|
||||
schemaVersion: 1,
|
||||
mapId: 'warehouse',
|
||||
revision: 0,
|
||||
objects: [],
|
||||
spawnPoints: [],
|
||||
}),
|
||||
),
|
||||
];
|
||||
expect(discoverMapEntries(files)[0]).toMatchObject({
|
||||
schemaVersion: 2,
|
||||
authoringPath: 'maps/warehouse/authoring/map.scene.json',
|
||||
});
|
||||
});
|
||||
|
||||
it('拒绝没有物理产物的 authoring 地图', () => {
|
||||
const invalid = JSON.stringify({
|
||||
schemaVersion: 2,
|
||||
id: 'editable',
|
||||
name: 'editable',
|
||||
coordinateSystem: { units: 'm', up: 'Z', forward: '+X' },
|
||||
visual: { source: 'scene.glb' },
|
||||
authoring: { source: 'map.scene.json' },
|
||||
spawnPoints: [],
|
||||
});
|
||||
expect(() => discoverMapEntries([file('map.json', invalid)])).toThrow('physics.source');
|
||||
});
|
||||
|
||||
it('拒绝坐标约定错误、缺失资源和重复地图 id', () => {
|
||||
const wrongCoordinates = descriptor.replace('"Z"', '"Y"');
|
||||
expect(() => discoverMapEntries([file('map.json', wrongCoordinates)])).toThrow(
|
||||
'coordinateSystem',
|
||||
);
|
||||
expect(() => discoverMapEntries([file('map.json', descriptor)])).toThrow('资源不存在');
|
||||
const physics = file('physics/world.xml');
|
||||
const visual = file('visuals/scene.glb');
|
||||
expect(() =>
|
||||
discoverMapEntries([
|
||||
file(
|
||||
'a/map.json',
|
||||
descriptor.replaceAll('physics/', '../physics/').replaceAll('visuals/', '../visuals/'),
|
||||
),
|
||||
file(
|
||||
'b/map.json',
|
||||
descriptor.replaceAll('physics/', '../physics/').replaceAll('visuals/', '../visuals/'),
|
||||
),
|
||||
physics,
|
||||
visual,
|
||||
]),
|
||||
).toThrow('地图 id 重复');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user