Feature/editor optimization (#251)
* refactor: 编辑器/运行时架构拆分与构建系统升级 * feat(core): 层级系统重构与UI变换矩阵修复 * refactor: 移除 ecs-components 聚合包并修复跨包组件查找问题 * fix(physics): 修复跨包组件类引用问题 * feat: 统一运行时架构与浏览器运行支持 * feat(asset): 实现浏览器运行时资产加载系统 * fix: 修复文档、CodeQL安全问题和CI类型检查错误 * fix: 修复文档、CodeQL安全问题和CI类型检查错误 * fix: 修复文档、CodeQL安全问题、CI类型检查和测试错误 * test: 补齐核心模块测试用例,修复CI构建配置 * fix: 修复测试用例中的类型错误和断言问题 * fix: 修复 turbo build:npm 任务的依赖顺序问题 * fix: 修复 CI 构建错误并优化构建性能
This commit is contained in:
@@ -629,4 +629,201 @@ describe('Scene - 场景管理系统测试', () => {
|
||||
scene2.end();
|
||||
});
|
||||
});
|
||||
|
||||
describe('扩展测试 - 补齐覆盖率', () => {
|
||||
describe('实体标签查找', () => {
|
||||
test('findEntitiesByTag 应该返回具有指定标签的实体', () => {
|
||||
const entity1 = scene.createEntity('Entity1');
|
||||
entity1.tag = 0x01;
|
||||
|
||||
const entity2 = scene.createEntity('Entity2');
|
||||
entity2.tag = 0x02;
|
||||
|
||||
const entity3 = scene.createEntity('Entity3');
|
||||
entity3.tag = 0x01;
|
||||
|
||||
const found = scene.findEntitiesByTag(0x01);
|
||||
|
||||
expect(found.length).toBe(2);
|
||||
expect(found).toContain(entity1);
|
||||
expect(found).toContain(entity3);
|
||||
});
|
||||
|
||||
test('findEntitiesByTag 应该在没有匹配时返回空数组', () => {
|
||||
scene.createEntity('Entity1');
|
||||
|
||||
const found = scene.findEntitiesByTag(0xFF);
|
||||
|
||||
expect(found).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('批量实体操作', () => {
|
||||
test('destroyEntities 应该批量销毁实体', () => {
|
||||
const entities = scene.createEntities(5, 'Entity');
|
||||
expect(scene.entities.count).toBe(5);
|
||||
|
||||
const toDestroy = entities.slice(0, 3);
|
||||
scene.destroyEntities(toDestroy);
|
||||
|
||||
expect(scene.entities.count).toBe(2);
|
||||
});
|
||||
|
||||
test('destroyEntities 应该处理空数组', () => {
|
||||
scene.createEntities(3, 'Entity');
|
||||
|
||||
expect(() => {
|
||||
scene.destroyEntities([]);
|
||||
}).not.toThrow();
|
||||
|
||||
expect(scene.entities.count).toBe(3);
|
||||
});
|
||||
});
|
||||
|
||||
describe('查询方法', () => {
|
||||
test('queryAny 应该返回具有任意一个组件的实体', () => {
|
||||
const entity1 = scene.createEntity('Entity1');
|
||||
entity1.addComponent(new PositionComponent());
|
||||
|
||||
const entity2 = scene.createEntity('Entity2');
|
||||
entity2.addComponent(new VelocityComponent());
|
||||
|
||||
const entity3 = scene.createEntity('Entity3');
|
||||
entity3.addComponent(new HealthComponent());
|
||||
|
||||
const result = scene.queryAny(PositionComponent, VelocityComponent);
|
||||
|
||||
expect(result.entities.length).toBe(2);
|
||||
});
|
||||
|
||||
test('queryNone 应该返回不包含指定组件的实体', () => {
|
||||
const entity1 = scene.createEntity('Entity1');
|
||||
entity1.addComponent(new PositionComponent());
|
||||
|
||||
const entity2 = scene.createEntity('Entity2');
|
||||
entity2.addComponent(new VelocityComponent());
|
||||
|
||||
const entity3 = scene.createEntity('Entity3');
|
||||
|
||||
const result = scene.queryNone(PositionComponent);
|
||||
|
||||
expect(result.entities.length).toBe(2);
|
||||
expect(result.entities).toContain(entity2);
|
||||
expect(result.entities).toContain(entity3);
|
||||
});
|
||||
|
||||
test('query 应该创建类型安全的查询构建器', () => {
|
||||
const builder = scene.query();
|
||||
expect(builder).toBeDefined();
|
||||
|
||||
const matcher = builder.withAll(PositionComponent).buildMatcher();
|
||||
expect(matcher).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('服务容器', () => {
|
||||
test('scene.services 应该返回服务容器', () => {
|
||||
expect(scene.services).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('系统错误处理', () => {
|
||||
test('频繁出错的系统应该被自动禁用', () => {
|
||||
const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
|
||||
class ErrorProneSystem extends EntitySystem {
|
||||
constructor() {
|
||||
super(Matcher.empty().all(PositionComponent));
|
||||
}
|
||||
|
||||
protected override process(): void {
|
||||
throw new Error('Intentional error');
|
||||
}
|
||||
}
|
||||
|
||||
const system = new ErrorProneSystem();
|
||||
scene.addEntityProcessor(system);
|
||||
|
||||
const entity = scene.createEntity('TestEntity');
|
||||
entity.addComponent(new PositionComponent(0, 0));
|
||||
|
||||
// 多次更新以触发错误阈值
|
||||
for (let i = 0; i < 15; i++) {
|
||||
scene.update();
|
||||
}
|
||||
|
||||
// 系统应该被禁用
|
||||
expect(system.enabled).toBe(false);
|
||||
|
||||
consoleSpy.mockRestore();
|
||||
});
|
||||
});
|
||||
|
||||
describe('已废弃方法', () => {
|
||||
test('getEntityByName 应该作为 findEntity 的别名工作', () => {
|
||||
const entity = scene.createEntity('TestEntity');
|
||||
|
||||
const found = scene.getEntityByName('TestEntity');
|
||||
|
||||
expect(found).toBe(entity);
|
||||
});
|
||||
|
||||
test('getEntitiesByTag 应该作为 findEntitiesByTag 的别名工作', () => {
|
||||
const entity = scene.createEntity('Entity');
|
||||
entity.tag = 0x10;
|
||||
|
||||
const found = scene.getEntitiesByTag(0x10);
|
||||
|
||||
expect(found.length).toBe(1);
|
||||
expect(found[0]).toBe(entity);
|
||||
});
|
||||
});
|
||||
|
||||
describe('系统管理扩展', () => {
|
||||
test('getSystem 应该返回指定类型的系统', () => {
|
||||
const movementSystem = new MovementSystem();
|
||||
scene.addEntityProcessor(movementSystem);
|
||||
|
||||
const found = scene.getSystem(MovementSystem);
|
||||
|
||||
expect(found).toBe(movementSystem);
|
||||
});
|
||||
|
||||
test('getSystem 应该在系统不存在时返回 null', () => {
|
||||
const found = scene.getSystem(MovementSystem);
|
||||
|
||||
expect(found).toBeNull();
|
||||
});
|
||||
|
||||
test('markSystemsOrderDirty 应该标记系统顺序为脏', () => {
|
||||
const system1 = new MovementSystem();
|
||||
const system2 = new RenderSystem();
|
||||
|
||||
scene.addEntityProcessor(system1);
|
||||
scene.addEntityProcessor(system2);
|
||||
|
||||
// 访问 systems 以清除脏标记
|
||||
const _ = scene.systems;
|
||||
|
||||
// 标记为脏
|
||||
scene.markSystemsOrderDirty();
|
||||
|
||||
// 再次访问应该重新构建缓存
|
||||
const systems = scene.systems;
|
||||
expect(systems).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('延迟缓存清理', () => {
|
||||
test('addEntity 应该支持延迟缓存清理', () => {
|
||||
scene.createEntity('Entity1');
|
||||
const entity2 = new Entity('Entity2', scene.identifierPool.checkOut());
|
||||
|
||||
// 延迟缓存清理
|
||||
scene.addEntity(entity2, true);
|
||||
|
||||
expect(scene.entities.count).toBe(2);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user