/** * 网络库基础功能测试 */ import 'reflect-metadata'; import { NetworkManager } from '../src/NetworkManager'; import { NetworkIdentity } from '../src/NetworkIdentity'; import { NetworkBehaviour } from '../src/NetworkBehaviour'; import { SyncVar } from '../src/decorators/SyncVar'; import { ClientRpc } from '../src/decorators/ClientRpc'; import { Command } from '../src/decorators/Command'; import { NetworkRegistry } from '../src/Core/NetworkRegistry'; import { SyncVarManager } from '../src/Core/SyncVarManager'; import { RpcManager } from '../src/Core/RpcManager'; // 测试用的玩家组件 class TestPlayerComponent extends NetworkBehaviour { @SyncVar({ onChanged: 'onHealthChanged' }) public health: number = 100; @SyncVar() public playerName: string = 'Player'; public lastHealthChangeValue: number = 0; @ClientRpc() public showDamageEffect(damage: number, position: { x: number; y: number }): void { console.log(`显示伤害特效: ${damage} at (${position.x}, ${position.y})`); } @Command() public movePlayer(direction: { x: number; y: number }): void { console.log(`移动玩家: (${direction.x}, ${direction.y})`); } private onHealthChanged(oldValue: number, newValue: number): void { this.lastHealthChangeValue = newValue; console.log(`生命值变化: ${oldValue} -> ${newValue}`); } } // 模拟实体类 class MockEntity { private components: any[] = []; public name: string = 'TestEntity'; public addComponent(component: any): void { this.components.push(component); component.entity = this; } public getComponent(componentType: any): any { return this.components.find(c => c instanceof componentType); } public getComponents(): any[] { return this.components; } } describe('网络库基础功能测试', () => { let networkManager: NetworkManager; let entity: MockEntity; let networkIdentity: NetworkIdentity; let playerComponent: TestPlayerComponent; beforeEach(() => { // 重置单例 (NetworkManager as any)._instance = null; NetworkRegistry.instance.reset(); SyncVarManager.instance.clearPendingChanges(); RpcManager.instance.clearPendingCalls(); // 创建网络管理器 networkManager = new NetworkManager(); // 创建测试实体 entity = new MockEntity(); networkIdentity = new NetworkIdentity(); playerComponent = new TestPlayerComponent(); entity.addComponent(networkIdentity); entity.addComponent(playerComponent); // 手动调用组件初始化以注册网络行为 playerComponent.start(); }); afterEach(() => { networkManager?.destroy(); }); describe('网络身份管理', () => { test('网络对象注册和查找', () => { const networkId = networkManager.registerNetworkObject(entity); expect(networkId).toBeGreaterThan(0); expect(networkIdentity.networkId).toBe(networkId); const foundIdentity = NetworkRegistry.instance.find(networkId); expect(foundIdentity).toBe(networkIdentity); }); test('网络权威设置', () => { networkManager.registerNetworkObject(entity); expect(networkIdentity.hasAuthority).toBe(false); expect(playerComponent.hasAuthority).toBe(false); networkIdentity.setAuthority(true, 1); expect(networkIdentity.hasAuthority).toBe(true); expect(networkIdentity.ownerId).toBe(1); expect(playerComponent.hasAuthority).toBe(true); }); test('本地玩家设置', () => { networkManager.registerNetworkObject(entity); expect(networkIdentity.isLocalPlayer).toBe(false); expect(playerComponent.isLocalPlayer).toBe(false); NetworkRegistry.instance.setLocalPlayer(networkIdentity); expect(networkIdentity.isLocalPlayer).toBe(true); expect(networkIdentity.hasAuthority).toBe(true); expect(playerComponent.isLocalPlayer).toBe(true); }); }); describe('SyncVar 同步变量', () => { test('SyncVar 属性同步', () => { networkManager.registerNetworkObject(entity); networkIdentity.setAuthority(true, 1); // 修改同步变量 playerComponent.health = 80; playerComponent.playerName = 'TestPlayer'; // 检查待同步消息 const messages = SyncVarManager.instance.getPendingMessages(); expect(messages.length).toBeGreaterThanOrEqual(2); // 验证消息内容 const healthMessage = messages.find((m: any) => m.propertyName === 'health'); expect(healthMessage).toBeDefined(); expect(healthMessage?.value).toBe(80); const nameMessage = messages.find((m: any) => m.propertyName === 'playerName'); expect(nameMessage).toBeDefined(); expect(nameMessage?.value).toBe('TestPlayer'); }); test('SyncVar 变化回调', () => { networkManager.registerNetworkObject(entity); networkIdentity.setAuthority(true, 1); expect(playerComponent.lastHealthChangeValue).toBe(0); playerComponent.health = 75; expect(playerComponent.lastHealthChangeValue).toBe(75); }); test('权威验证', () => { networkManager.registerNetworkObject(entity); // 没有权威时不应该能修改 expect(networkIdentity.hasAuthority).toBe(false); const originalHealth = playerComponent.health; playerComponent.health = 50; // 检查是否有待同步消息(没有权威应该没有) const messages = SyncVarManager.instance.getPendingMessages(); expect(messages.length).toBe(0); }); }); describe('RPC 远程过程调用', () => { test('RPC 方法注册', () => { networkManager.registerNetworkObject(entity); const stats = RpcManager.instance.getStats(); expect(stats.registeredComponents).toBeGreaterThan(0); }); test('RPC 消息生成', () => { networkManager.registerNetworkObject(entity); // 模拟服务端调用ClientRpc if (NetworkManager.isServer) { playerComponent.showDamageEffect(25, { x: 100, y: 200 }); const rpcMessages = RpcManager.instance.getPendingRpcMessages(); const damageMessage = rpcMessages.find((m: any) => m.methodName === 'showDamageEffect'); expect(damageMessage).toBeDefined(); expect(damageMessage?.isClientRpc).toBe(true); } }); }); describe('网络管理器状态', () => { test('网络端类型判断', () => { // 默认应该是客户端 expect(NetworkManager.isClient).toBe(true); expect(NetworkManager.isServer).toBe(false); expect(NetworkManager.isConnected).toBe(false); }); test('连接状态管理', () => { expect(networkManager.getConnectionState()).toBe('disconnected'); }); test('网络统计信息', () => { const stats = networkManager.getStats(); expect(stats).toHaveProperty('connectionCount'); expect(stats).toHaveProperty('messagesSent'); expect(stats).toHaveProperty('messagesReceived'); expect(stats.connectionCount).toBe(0); }); }); describe('网络注册表管理', () => { test('多个网络对象管理', () => { // 创建多个实体 const entity2 = new MockEntity(); const networkIdentity2 = new NetworkIdentity(); entity2.addComponent(networkIdentity2); const playerComponent2 = new TestPlayerComponent(); entity2.addComponent(playerComponent2); playerComponent2.start(); const networkId1 = networkManager.registerNetworkObject(entity); const networkId2 = networkManager.registerNetworkObject(entity2); expect(networkId1).not.toBe(networkId2); expect(NetworkRegistry.instance.getAllNetworkObjects().length).toBe(2); }); test('网络对象注销', () => { const networkId = networkManager.registerNetworkObject(entity); expect(NetworkRegistry.instance.exists(networkId)).toBe(true); NetworkRegistry.instance.unregister(networkId); expect(NetworkRegistry.instance.exists(networkId)).toBe(false); expect(NetworkRegistry.instance.find(networkId)).toBeNull(); }); test('按所有者查找对象', () => { const networkId = networkManager.registerNetworkObject(entity); networkIdentity.setAuthority(true, 123); const ownedObjects = NetworkRegistry.instance.getObjectsByOwner(123); expect(ownedObjects.length).toBe(1); expect(ownedObjects[0]).toBe(networkIdentity); }); }); });