Files
esengine/packages/core/tests/Core.test.ts

491 lines
15 KiB
TypeScript
Raw Normal View History

import { Core } from '../src/Core';
import { Scene } from '../src/ECS/Scene';
import { Entity } from '../src/ECS/Entity';
import { Component } from '../src/ECS/Component';
import { GlobalManager } from '../src/Utils/GlobalManager';
import { ITimer } from '../src/Utils/Timers/ITimer';
// 测试组件
class TestComponent extends Component {
2025-07-31 15:37:40 +08:00
public value: number;
constructor(...args: unknown[]) {
super();
2025-07-31 15:37:40 +08:00
const [value = 0] = args as [number?];
this.value = value;
}
}
// 测试场景
class TestScene extends Scene {
public initializeCalled = false;
public beginCalled = false;
public endCalled = false;
public updateCallCount = 0;
public override initialize(): void {
this.initializeCalled = true;
}
public override begin(): void {
this.beginCalled = true;
}
public override end(): void {
this.endCalled = true;
}
public override update(): void {
this.updateCallCount++;
}
}
// 测试全局管理器
class TestGlobalManager extends GlobalManager {
public updateCallCount = 0;
public override _enabled = false;
public override get enabled(): boolean {
return this._enabled;
}
public override set enabled(value: boolean) {
this._enabled = value;
}
public override update(): void {
this.updateCallCount++;
}
}
describe('Core - 核心管理系统测试', () => {
let originalConsoleWarn: typeof console.warn;
beforeEach(() => {
// 清除之前的实例
(Core as any)._instance = null;
// 模拟console.warn以避免测试输出
originalConsoleWarn = console.warn;
console.warn = jest.fn();
});
afterEach(() => {
// 恢复console.warn
console.warn = originalConsoleWarn;
// 清理Core实例
(Core as any)._instance = null;
});
describe('实例创建和管理', () => {
test('应该能够创建Core实例', () => {
const core = Core.create(true);
expect(core).toBeDefined();
expect(core).toBeInstanceOf(Core);
expect(core.debug).toBe(true);
expect(Core.entitySystemsEnabled).toBe(true);
});
test('应该能够通过配置对象创建Core实例', () => {
const config = {
debug: false,
enableEntitySystems: false
};
const core = Core.create(config);
expect(core.debug).toBe(false);
expect(Core.entitySystemsEnabled).toBe(false);
});
test('重复调用create应该返回同一个实例', () => {
const core1 = Core.create(true);
const core2 = Core.create(false); // 不同参数
expect(core1).toBe(core2);
});
test('应该能够获取Core实例', () => {
const core = Core.create(true);
const instance = Core.Instance;
expect(instance).toBe(core);
});
test('在未创建实例时调用update应该显示警告', () => {
Core.update(0.016);
expect(console.warn).toHaveBeenCalledWith("Core实例未创建请先调用Core.create()");
});
});
describe('场景管理', () => {
let core: Core;
let testScene: TestScene;
beforeEach(() => {
core = Core.create(true);
testScene = new TestScene();
});
test('应该能够设置场景', () => {
Core.scene = testScene;
expect(Core.scene).toBe(testScene);
expect(testScene.beginCalled).toBe(true);
});
test('设置新场景应该触发场景切换', () => {
const firstScene = new TestScene();
const secondScene = new TestScene();
// 设置第一个场景
Core.scene = firstScene;
expect(firstScene.beginCalled).toBe(true);
// 设置第二个场景(应该在下一帧切换)
Core.scene = secondScene;
// 模拟更新循环触发场景切换
Core.update(0.016);
expect(firstScene.endCalled).toBe(true);
expect(secondScene.beginCalled).toBe(true);
expect(Core.scene).toBe(secondScene);
});
test('获取场景在未设置时应该返回null', () => {
expect(Core.scene).toBeNull();
});
});
describe('更新循环', () => {
let core: Core;
let testScene: TestScene;
let globalManager: TestGlobalManager;
beforeEach(() => {
core = Core.create(true);
testScene = new TestScene();
globalManager = new TestGlobalManager();
Core.registerGlobalManager(globalManager);
Core.scene = testScene;
});
test('应该能够执行更新循环', () => {
const deltaTime = 0.016;
Core.update(deltaTime);
expect(testScene.updateCallCount).toBe(1);
expect(globalManager.updateCallCount).toBe(1);
});
test('暂停状态下不应该执行更新', () => {
Core.paused = true;
Core.update(0.016);
expect(testScene.updateCallCount).toBe(0);
expect(globalManager.updateCallCount).toBe(0);
// 恢复状态
Core.paused = false;
});
test('禁用的全局管理器不应该被更新', () => {
globalManager.enabled = false;
Core.update(0.016);
expect(globalManager.updateCallCount).toBe(0);
});
test('多次更新应该累积调用', () => {
Core.update(0.016);
Core.update(0.016);
Core.update(0.016);
expect(testScene.updateCallCount).toBe(3);
expect(globalManager.updateCallCount).toBe(3);
});
});
describe('全局管理器管理', () => {
let core: Core;
let manager1: TestGlobalManager;
let manager2: TestGlobalManager;
beforeEach(() => {
core = Core.create(true);
manager1 = new TestGlobalManager();
manager2 = new TestGlobalManager();
});
test('应该能够注册全局管理器', () => {
Core.registerGlobalManager(manager1);
expect(manager1.enabled).toBe(true);
// 测试更新是否被调用
Core.update(0.016);
expect(manager1.updateCallCount).toBe(1);
});
test('应该能够注销全局管理器', () => {
Core.registerGlobalManager(manager1);
Core.unregisterGlobalManager(manager1);
expect(manager1.enabled).toBe(false);
// 测试更新不应该被调用
Core.update(0.016);
expect(manager1.updateCallCount).toBe(0);
});
test('应该能够获取指定类型的全局管理器', () => {
Core.registerGlobalManager(manager1);
const retrieved = Core.getGlobalManager(TestGlobalManager);
expect(retrieved).toBe(manager1);
});
test('获取不存在的管理器应该返回null', () => {
const retrieved = Core.getGlobalManager(TestGlobalManager);
expect(retrieved).toBeNull();
});
test('应该能够管理多个全局管理器', () => {
Core.registerGlobalManager(manager1);
Core.registerGlobalManager(manager2);
Core.update(0.016);
expect(manager1.updateCallCount).toBe(1);
expect(manager2.updateCallCount).toBe(1);
});
});
describe('定时器系统', () => {
let core: Core;
beforeEach(() => {
core = Core.create(true);
});
test('应该能够调度定时器', () => {
let callbackExecuted = false;
let timerInstance: ITimer | null = null;
const timer = Core.schedule(0.1, false, null, (timer) => {
callbackExecuted = true;
timerInstance = timer;
});
expect(timer).toBeDefined();
// 模拟时间推进
for (let i = 0; i < 10; i++) {
Core.update(0.016); // 约160ms总计
}
expect(callbackExecuted).toBe(true);
expect(timerInstance).toBe(timer);
});
test('应该能够调度重复定时器', () => {
let callbackCount = 0;
Core.schedule(0.05, true, null, () => {
callbackCount++;
});
// 模拟足够长的时间以触发多次回调
for (let i = 0; i < 15; i++) {
Core.update(0.016); // 约240ms总计应该触发4-5次
}
expect(callbackCount).toBeGreaterThan(1);
});
test('应该支持带上下文的定时器', () => {
const context = { value: 42 };
let receivedContext: any = null;
Core.schedule(0.05, false, context, function(this: any, timer) {
receivedContext = this;
});
// 模拟时间推进
for (let i = 0; i < 5; i++) {
Core.update(0.016);
}
expect(receivedContext).toBe(context);
});
});
describe('调试功能', () => {
test('应该能够启用调试功能', () => {
const core = Core.create(true);
const debugConfig = {
enabled: true,
websocketUrl: 'ws://localhost:8080',
autoReconnect: true,
updateInterval: 1000,
channels: {
entities: true,
systems: true,
performance: true,
components: true,
scenes: true
}
};
Core.enableDebug(debugConfig);
expect(Core.isDebugEnabled).toBe(true);
});
test('应该能够禁用调试功能', () => {
const core = Core.create(true);
const debugConfig = {
enabled: true,
websocketUrl: 'ws://localhost:8080',
autoReconnect: true,
updateInterval: 1000,
channels: {
entities: true,
systems: true,
performance: true,
components: true,
scenes: true
}
};
Core.enableDebug(debugConfig);
Core.disableDebug();
expect(Core.isDebugEnabled).toBe(false);
});
test('在未创建实例时启用调试应该显示警告', () => {
const debugConfig = {
enabled: true,
websocketUrl: 'ws://localhost:8080',
autoReconnect: true,
updateInterval: 1000,
channels: {
entities: true,
systems: true,
performance: true,
components: true,
scenes: true
}
};
Core.enableDebug(debugConfig);
expect(console.warn).toHaveBeenCalledWith("Core实例未创建请先调用Core.create()");
});
});
describe('ECS API集成', () => {
let core: Core;
let testScene: TestScene;
beforeEach(() => {
core = Core.create(true);
testScene = new TestScene();
});
test('设置支持ECS的场景应该初始化ECS API', () => {
// 模拟带有querySystem和eventSystem的场景
const ecsScene = Object.assign(testScene, {
querySystem: { query: jest.fn() },
eventSystem: { emit: jest.fn() }
});
Core.scene = ecsScene;
expect(Core.ecsAPI).toBeDefined();
});
test('设置普通场景不应该初始化ECS API', () => {
// 创建一个普通场景对象不继承Scene
const plainScene = {
initialize: () => {},
begin: () => {},
end: () => {},
update: () => {}
};
Core.scene = plainScene as any;
expect(Core.ecsAPI).toBeNull();
});
});
describe('性能监控集成', () => {
let core: Core;
beforeEach(() => {
core = Core.create(true);
});
test('调试模式下应该启用性能监控', () => {
const performanceMonitor = (core as any)._performanceMonitor;
expect(performanceMonitor).toBeDefined();
// 性能监控器应该在调试模式下被启用
expect(performanceMonitor.isEnabled).toBe(true);
});
test('更新循环应该包含性能监控', () => {
const scene = new TestScene();
Core.scene = scene;
const performanceMonitor = (core as any)._performanceMonitor;
const startMonitoringSpy = jest.spyOn(performanceMonitor, 'startMonitoring');
const endMonitoringSpy = jest.spyOn(performanceMonitor, 'endMonitoring');
Core.update(0.016);
expect(startMonitoringSpy).toHaveBeenCalled();
expect(endMonitoringSpy).toHaveBeenCalled();
});
});
describe('错误处理', () => {
test('设置null场景应该被忽略', () => {
Core.create(true);
expect(() => {
Core.scene = null;
}).not.toThrow();
expect(Core.scene).toBeNull();
});
test('应该处理场景更新中的异常', () => {
const core = Core.create(true);
const errorScene = new TestScene();
// 模拟场景更新抛出异常
errorScene.update = () => {
throw new Error('Test error');
};
Core.scene = errorScene;
// 由于Core目前不捕获场景异常我们预期它会抛出异常
// 这是一个已知的行为,可以在未来版本中改进
expect(() => {
Core.update(0.016);
}).toThrow('Test error');
});
});
});