From 7cae1991a76e941999754d797c83be439053f0e4 Mon Sep 17 00:00:00 2001 From: HexaField Date: Wed, 13 Dec 2023 16:52:26 +1100 Subject: [PATCH 01/15] configure basic test --- packages/engine/.mocharc.js | 2 +- ...em.test.ts => SceneLoadingSystem.test.tsx} | 64 ++++++------------- 2 files changed, 19 insertions(+), 47 deletions(-) rename packages/engine/src/scene/systems/{SceneLoadingSystem.test.ts => SceneLoadingSystem.test.tsx} (52%) diff --git a/packages/engine/.mocharc.js b/packages/engine/.mocharc.js index 32651d520f6..05d17ea2080 100644 --- a/packages/engine/.mocharc.js +++ b/packages/engine/.mocharc.js @@ -28,7 +28,7 @@ Ethereal Engine. All Rights Reserved. module.exports = { failZero: false, parallel: true, - spec: ['**/*.test.ts'], + spec: ['**/*.test.ts', '**/*.test.tsx'], require: [ 'tests/mocha.env', // init env here 'jsdom-global/register' diff --git a/packages/engine/src/scene/systems/SceneLoadingSystem.test.ts b/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx similarity index 52% rename from packages/engine/src/scene/systems/SceneLoadingSystem.test.ts rename to packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx index e2dbe7f0fb6..8521f41c298 100644 --- a/packages/engine/src/scene/systems/SceneLoadingSystem.test.ts +++ b/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx @@ -25,9 +25,16 @@ Ethereal Engine. All Rights Reserved. import { EntityUUID } from '@etherealengine/common/src/interfaces/EntityUUID' +import { act, render } from '@testing-library/react' +import assert from 'assert' +import React from 'react' import { destroyEngine } from '../../ecs/classes/Engine' +import { UndefinedEntity } from '../../ecs/classes/Entity' +import { SystemDefinitions } from '../../ecs/functions/SystemFunctions' import { createEngine } from '../../initializeEngine' import { SceneDataType, SceneJsonType } from '../../schemas/projects/scene.schema' +import { UUIDComponent } from '../components/UUIDComponent' +import { SceneLoadingSystem } from './SceneLoadingSystem' const sceneJSON_1 = { scene: { @@ -65,54 +72,19 @@ describe('SceneLoadingSystem', () => { createEngine() }) - // describe('updateSceneFromJSON', () => { - // it('will load root entity', async () => { - // /** Load First Test Scene */ - // const sceneState = getMutableState(SceneState) - // sceneState.sceneData.set(sceneJSON_1) + it('test reactor', async () => { + // init + const Reactor = SystemDefinitions.get(SceneLoadingSystem)!.reactor! + console.log(Reactor) - // await updateSceneFromJSON() + // render + const { rerender } = render() + console.log('rerender') + await act(() => rerender()) - // const rootEntity = UUIDComponent.entitiesByUUID['root'] - // assert(rootEntity) - // assert(hasComponent(rootEntity, EntityTreeComponent)) - // assert(EntityTreeComponent.roots[rootEntity]) - // assert.equal(getComponent(rootEntity, EntityTreeComponent).parentEntity, null) - // assert.equal(getComponent(rootEntity, NameComponent), 'Root') - // }) - - // it('will load child entity', async () => { - // const sceneState = getMutableState(SceneState) - // sceneState.sceneData.set(sceneJSON_1) - - // await updateSceneFromJSON() - - // sceneState.sceneData.set(sceneJSON_2) - // await updateSceneFromJSON() - - // const rootEntity = UUIDComponent.entitiesByUUID['root'] - // const childEntity = UUIDComponent.entitiesByUUID['child_0'] - // assert(childEntity) - // assert(hasComponent(childEntity, EntityTreeComponent)) - // assert.equal(getComponent(childEntity, EntityTreeComponent).parentEntity, rootEntity) - // assert.equal(getComponent(childEntity, NameComponent), 'Child 0') - // }) - - // it('will unload child entity', async () => { - // const sceneState = getMutableState(SceneState) - // sceneState.sceneData.set(sceneJSON_2) - - // await updateSceneFromJSON() - - // sceneState.sceneData.set(sceneJSON_1) - // await updateSceneFromJSON() - - // const rootEntity = UUIDComponent.entitiesByUUID['root'] - // const childEntity = UUIDComponent.entitiesByUUID['child_0'] - // assert(rootEntity) - // assert.equal(childEntity, undefined) - // }) - // }) + // assertions + assert.notEqual(UUIDComponent.entitiesByUUID['some UUID'], UndefinedEntity) + }) afterEach(() => { return destroyEngine() From 796c08faf806cd0af7037196d351829e8454dc29 Mon Sep 17 00:00:00 2001 From: HexaField Date: Wed, 13 Dec 2023 17:08:03 +1100 Subject: [PATCH 02/15] basic example works --- .../scene/systems/SceneLoadingSystem.test.tsx | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx b/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx index 8521f41c298..6813e5c80a7 100644 --- a/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx +++ b/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx @@ -25,14 +25,16 @@ Ethereal Engine. All Rights Reserved. import { EntityUUID } from '@etherealengine/common/src/interfaces/EntityUUID' +import { getMutableState } from '@etherealengine/hyperflux' import { act, render } from '@testing-library/react' import assert from 'assert' import React from 'react' import { destroyEngine } from '../../ecs/classes/Engine' -import { UndefinedEntity } from '../../ecs/classes/Entity' +import { SceneState } from '../../ecs/classes/Scene' import { SystemDefinitions } from '../../ecs/functions/SystemFunctions' import { createEngine } from '../../initializeEngine' -import { SceneDataType, SceneJsonType } from '../../schemas/projects/scene.schema' +import { PhysicsState } from '../../physics/state/PhysicsState' +import { SceneDataType, SceneID, SceneJsonType } from '../../schemas/projects/scene.schema' import { UUIDComponent } from '../components/UUIDComponent' import { SceneLoadingSystem } from './SceneLoadingSystem' @@ -73,17 +75,24 @@ describe('SceneLoadingSystem', () => { }) it('test reactor', async () => { + getMutableState(PhysicsState).physicsWorld.set({} as any) + // init const Reactor = SystemDefinitions.get(SceneLoadingSystem)!.reactor! - console.log(Reactor) + + const tag = // render - const { rerender } = render() - console.log('rerender') - await act(() => rerender()) + const { rerender } = render(tag) + + // load scene + SceneState.loadScene('scene 1' as SceneID, sceneJSON_1) + + // force re-render + await act(() => rerender(tag)) // assertions - assert.notEqual(UUIDComponent.entitiesByUUID['some UUID'], UndefinedEntity) + assert.notEqual(UUIDComponent.entitiesByUUID['root'], undefined) }) afterEach(() => { From fa6e681a57afab1a2e7294c18b283d623e32254c Mon Sep 17 00:00:00 2001 From: HexaField Date: Wed, 13 Dec 2023 17:13:38 +1100 Subject: [PATCH 03/15] unmoutn after assetsions --- .../engine/src/scene/systems/SceneLoadingSystem.test.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx b/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx index 6813e5c80a7..835e8e7def2 100644 --- a/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx +++ b/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx @@ -79,11 +79,10 @@ describe('SceneLoadingSystem', () => { // init const Reactor = SystemDefinitions.get(SceneLoadingSystem)!.reactor! - const tag = // render - const { rerender } = render(tag) + const { rerender, unmount } = render(tag) // load scene SceneState.loadScene('scene 1' as SceneID, sceneJSON_1) @@ -93,6 +92,9 @@ describe('SceneLoadingSystem', () => { // assertions assert.notEqual(UUIDComponent.entitiesByUUID['root'], undefined) + + // unmount to cleanup + unmount() }) afterEach(() => { From 90ad063e0979001ce6abdb656e0a45a8d29dac7e Mon Sep 17 00:00:00 2001 From: sybiote Date: Wed, 13 Dec 2023 15:30:59 +0530 Subject: [PATCH 04/15] load entites test --- .../scene/systems/SceneLoadingSystem.test.tsx | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx b/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx index 835e8e7def2..5e73bdaf069 100644 --- a/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx +++ b/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx @@ -62,6 +62,31 @@ const sceneJSON_2 = { name: 'Child 0', components: [], parent: 'root' + }, + child_1: { + name: 'Child 0', + components: [], + parent: 'child_0' + }, + child_2: { + name: 'Child 0', + components: [], + parent: 'child_1' + }, + child_3: { + name: 'Child 0', + components: [], + parent: 'child_2' + }, + child_4: { + name: 'Child 0', + components: [], + parent: 'child_3' + }, + child_5: { + name: 'Child 0', + components: [], + parent: 'child_4' } }, root: 'root' as EntityUUID, @@ -85,14 +110,18 @@ describe('SceneLoadingSystem', () => { const { rerender, unmount } = render(tag) // load scene - SceneState.loadScene('scene 1' as SceneID, sceneJSON_1) + SceneState.loadScene('scene 2' as SceneID, sceneJSON_2) // force re-render await act(() => rerender(tag)) // assertions + console.log(UUIDComponent.entitiesByUUID) assert.notEqual(UUIDComponent.entitiesByUUID['root'], undefined) + // check all entites are loaded correctly + // check if data in the manual json matches scene data + // unmount to cleanup unmount() }) From 56befb3dad86fa9209af9797d00d30be52a14ad2 Mon Sep 17 00:00:00 2001 From: sybiote Date: Wed, 13 Dec 2023 15:36:24 +0530 Subject: [PATCH 05/15] entity loader tests --- .../scene/systems/SceneLoadingSystem.test.tsx | 128 ++++++++++++++---- 1 file changed, 104 insertions(+), 24 deletions(-) diff --git a/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx b/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx index 5e73bdaf069..98d55fafc81 100644 --- a/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx +++ b/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx @@ -31,6 +31,8 @@ import assert from 'assert' import React from 'react' import { destroyEngine } from '../../ecs/classes/Engine' import { SceneState } from '../../ecs/classes/Scene' +import { getComponent, hasComponent } from '../../ecs/functions/ComponentFunctions' +import { EntityTreeComponent } from '../../ecs/functions/EntityTree' import { SystemDefinitions } from '../../ecs/functions/SystemFunctions' import { createEngine } from '../../initializeEngine' import { PhysicsState } from '../../physics/state/PhysicsState' @@ -38,20 +40,11 @@ import { SceneDataType, SceneID, SceneJsonType } from '../../schemas/projects/sc import { UUIDComponent } from '../components/UUIDComponent' import { SceneLoadingSystem } from './SceneLoadingSystem' -const sceneJSON_1 = { - scene: { - entities: { - root: { - name: 'Root', - components: [] - } - }, - root: 'root' as EntityUUID, - version: 0 - } as SceneJsonType -} as SceneDataType - -const sceneJSON_2 = { +const testScene = { + name: '', + thumbnailUrl: '', + project: '', + scenePath: 'test' as SceneID, scene: { entities: { root: { @@ -64,42 +57,49 @@ const sceneJSON_2 = { parent: 'root' }, child_1: { - name: 'Child 0', + name: 'Child 1', components: [], parent: 'child_0' }, child_2: { - name: 'Child 0', + name: 'Child 2', components: [], parent: 'child_1' }, child_3: { - name: 'Child 0', + name: 'Child 3', components: [], parent: 'child_2' }, child_4: { - name: 'Child 0', + name: 'Child 4', components: [], parent: 'child_3' }, child_5: { - name: 'Child 0', + name: 'Child 5', components: [], parent: 'child_4' + }, + child_2_1: { + name: 'Child 2 _ 1', + components: [], + parent: 'child_2' } }, root: 'root' as EntityUUID, version: 0 } as SceneJsonType } as SceneDataType +const testID = 'test' as SceneID describe('SceneLoadingSystem', () => { beforeEach(() => { createEngine() }) - it('test reactor', async () => { + it('will load entities', async () => { + getMutableState(SceneState).activeScene.set(testID) getMutableState(PhysicsState).physicsWorld.set({} as any) // init @@ -110,14 +110,73 @@ describe('SceneLoadingSystem', () => { const { rerender, unmount } = render(tag) // load scene - SceneState.loadScene('scene 2' as SceneID, sceneJSON_2) + SceneState.loadScene('test' as SceneID, testScene) + // force re-render + await act(() => rerender(tag)) + + // assertions + const rootEntity = SceneState.getRootEntity(testID) + assert(rootEntity) + assert.equal(hasComponent(rootEntity, EntityTreeComponent), true) + assert.equal(getComponent(rootEntity, EntityTreeComponent).parentEntity, null) + + const child1Entity = UUIDComponent.entitiesByUUID['child_1'] + assert(child1Entity) + assert.equal(hasComponent(child1Entity, EntityTreeComponent), true) + assert.equal(getComponent(child1Entity, EntityTreeComponent).parentEntity, rootEntity) + + const child2Entity = UUIDComponent.entitiesByUUID['child_2'] + assert(child2Entity) + assert.equal(hasComponent(child2Entity, EntityTreeComponent), true) + assert.equal(getComponent(child2Entity, EntityTreeComponent).parentEntity, child1Entity) + + const child3Entity = UUIDComponent.entitiesByUUID['child_3'] + assert(child3Entity) + assert.equal(hasComponent(child3Entity, EntityTreeComponent), true) + assert.equal(getComponent(child3Entity, EntityTreeComponent).parentEntity, child2Entity) + + const child4Entity = UUIDComponent.entitiesByUUID['child_4'] + assert(child4Entity) + assert.equal(hasComponent(child4Entity, EntityTreeComponent), true) + assert.equal(getComponent(child4Entity, EntityTreeComponent).parentEntity, child3Entity) + + const child5Entity = UUIDComponent.entitiesByUUID['child_5'] + assert(child5Entity) + assert.equal(hasComponent(child5Entity, EntityTreeComponent), true) + assert.equal(getComponent(child5Entity, EntityTreeComponent).parentEntity, child4Entity) + + const child2_1Entity = UUIDComponent.entitiesByUUID['child_2_1'] + assert(child2_1Entity) + assert.equal(hasComponent(child2_1Entity, EntityTreeComponent), true) + assert.equal(getComponent(child2_1Entity, EntityTreeComponent).parentEntity, child2Entity) + // check all entites are loaded correctly + // check if data in the manual json matches scene data + // unmount to cleanup + unmount() + }) + + it('will load entities data', async () => { + getMutableState(SceneState).activeScene.set(testID) + getMutableState(PhysicsState).physicsWorld.set({} as any) + + // init + const Reactor = SystemDefinitions.get(SceneLoadingSystem)!.reactor! + const tag = + + // render + const { rerender, unmount } = render(tag) + + // load scene + SceneState.loadScene('test' as SceneID, testScene) // force re-render await act(() => rerender(tag)) // assertions - console.log(UUIDComponent.entitiesByUUID) - assert.notEqual(UUIDComponent.entitiesByUUID['root'], undefined) + const rootEntity = SceneState.getRootEntity(testID) + assert(rootEntity) + assert.equal(hasComponent(rootEntity, EntityTreeComponent), true) + assert.equal(getComponent(rootEntity, EntityTreeComponent).parentEntity, null) // check all entites are loaded correctly // check if data in the manual json matches scene data @@ -125,7 +184,28 @@ describe('SceneLoadingSystem', () => { // unmount to cleanup unmount() }) - + it('will not load dynamic entity', async () => { + // set to location mode + // load scene + // create dynamic entity + // load dynamic entity + // check for failure to load + }) + it('will load dynamic entity', async () => { + // set to studio mode + // load scene + // create dynamic entity + // load dynamic entity + // check for success to load + }) + it('will load sub-scene', async () => { + // load scene with model component + // check for success of model component + // check for model component children + }) + it('test reactor', async () => { + // init + }) afterEach(() => { return destroyEngine() }) From 8fadca6ddb724030d19ea40b017012a6ae908750 Mon Sep 17 00:00:00 2001 From: sybiote Date: Wed, 13 Dec 2023 17:06:14 +0530 Subject: [PATCH 06/15] data check test --- .../scene/systems/SceneLoadingSystem.test.tsx | 152 ++++++++++++++---- 1 file changed, 125 insertions(+), 27 deletions(-) diff --git a/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx b/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx index 98d55fafc81..83a5c1343a8 100644 --- a/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx +++ b/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx @@ -29,7 +29,8 @@ import { getMutableState } from '@etherealengine/hyperflux' import { act, render } from '@testing-library/react' import assert from 'assert' import React from 'react' -import { destroyEngine } from '../../ecs/classes/Engine' +import { EventDispatcher } from '../../common/classes/EventDispatcher' +import { Engine, destroyEngine } from '../../ecs/classes/Engine' import { SceneState } from '../../ecs/classes/Scene' import { getComponent, hasComponent } from '../../ecs/functions/ComponentFunctions' import { EntityTreeComponent } from '../../ecs/functions/EntityTree' @@ -37,6 +38,7 @@ import { SystemDefinitions } from '../../ecs/functions/SystemFunctions' import { createEngine } from '../../initializeEngine' import { PhysicsState } from '../../physics/state/PhysicsState' import { SceneDataType, SceneID, SceneJsonType } from '../../schemas/projects/scene.schema' +import { FogSettingsComponent } from '../components/FogSettingsComponent' import { UUIDComponent } from '../components/UUIDComponent' import { SceneLoadingSystem } from './SceneLoadingSystem' @@ -83,7 +85,20 @@ const testScene = { }, child_2_1: { name: 'Child 2 _ 1', - components: [], + components: [ + { + name: 'fog', + props: { + type: 'linear', + color: '#FFFFFF', + density: 0.005, + near: 1, + far: 1000, + timeScale: 1, + height: 0.05 + } + } + ], parent: 'child_2' } }, @@ -96,6 +111,19 @@ const testID = 'test' as SceneID describe('SceneLoadingSystem', () => { beforeEach(() => { createEngine() + const eventDispatcher = new EventDispatcher() + ;(Engine.instance.api as any) = { + service: () => { + return { + on: (serviceName, cb) => { + eventDispatcher.addEventListener(serviceName, cb) + }, + off: (serviceName, cb) => { + eventDispatcher.removeEventListener(serviceName, cb) + } + } + } + } }) it('will load entities', async () => { @@ -106,49 +134,115 @@ describe('SceneLoadingSystem', () => { const Reactor = SystemDefinitions.get(SceneLoadingSystem)!.reactor! const tag = + SceneState.loadScene(testID, testScene) + // render const { rerender, unmount } = render(tag) // load scene - SceneState.loadScene('test' as SceneID, testScene) // force re-render await act(() => rerender(tag)) // assertions const rootEntity = SceneState.getRootEntity(testID) - assert(rootEntity) - assert.equal(hasComponent(rootEntity, EntityTreeComponent), true) - assert.equal(getComponent(rootEntity, EntityTreeComponent).parentEntity, null) + assert(rootEntity, 'root entity not found') + assert.equal(hasComponent(rootEntity, EntityTreeComponent), true, 'root entity does not have EntityTreeComponent') + assert.equal( + getComponent(rootEntity, EntityTreeComponent).parentEntity, + null, + 'root entity does not have parentEntity' + ) + + const child0Entity = UUIDComponent.entitiesByUUID['child_0'] + assert(child0Entity, 'child_0 entity not found') + assert.equal( + hasComponent(child0Entity, EntityTreeComponent), + true, + 'child_0 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child0Entity, EntityTreeComponent).parentEntity, + rootEntity, + 'child_0 entity does not have parentEntity as root entity' + ) const child1Entity = UUIDComponent.entitiesByUUID['child_1'] - assert(child1Entity) - assert.equal(hasComponent(child1Entity, EntityTreeComponent), true) - assert.equal(getComponent(child1Entity, EntityTreeComponent).parentEntity, rootEntity) + assert(child1Entity, 'child_1 entity not found') + assert.equal( + hasComponent(child1Entity, EntityTreeComponent), + true, + 'child_1 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child1Entity, EntityTreeComponent).parentEntity, + child0Entity, + 'child_1 entity does not have parentEntity as child_0 entity' + ) const child2Entity = UUIDComponent.entitiesByUUID['child_2'] - assert(child2Entity) - assert.equal(hasComponent(child2Entity, EntityTreeComponent), true) - assert.equal(getComponent(child2Entity, EntityTreeComponent).parentEntity, child1Entity) + assert(child2Entity, 'child_2 entity not found') + assert.equal( + hasComponent(child2Entity, EntityTreeComponent), + true, + 'child_2 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child2Entity, EntityTreeComponent).parentEntity, + child1Entity, + 'child_2 entity does not have parentEntity as child_1 entity' + ) const child3Entity = UUIDComponent.entitiesByUUID['child_3'] - assert(child3Entity) - assert.equal(hasComponent(child3Entity, EntityTreeComponent), true) - assert.equal(getComponent(child3Entity, EntityTreeComponent).parentEntity, child2Entity) + assert(child3Entity, 'child_3 entity not found') + assert.equal( + hasComponent(child3Entity, EntityTreeComponent), + true, + 'child_3 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child3Entity, EntityTreeComponent).parentEntity, + child2Entity, + 'child_3 entity does not have parentEntity as child_2 entity' + ) const child4Entity = UUIDComponent.entitiesByUUID['child_4'] - assert(child4Entity) - assert.equal(hasComponent(child4Entity, EntityTreeComponent), true) - assert.equal(getComponent(child4Entity, EntityTreeComponent).parentEntity, child3Entity) + assert(child4Entity, 'child_4 entity not found') + assert.equal( + hasComponent(child4Entity, EntityTreeComponent), + true, + 'child_4 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child4Entity, EntityTreeComponent).parentEntity, + child3Entity, + 'child_4 entity does not have parentEntity as child_3 entity' + ) const child5Entity = UUIDComponent.entitiesByUUID['child_5'] - assert(child5Entity) - assert.equal(hasComponent(child5Entity, EntityTreeComponent), true) - assert.equal(getComponent(child5Entity, EntityTreeComponent).parentEntity, child4Entity) + assert(child5Entity, 'child_5 entity not found') + assert.equal( + hasComponent(child5Entity, EntityTreeComponent), + true, + 'child_5 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child5Entity, EntityTreeComponent).parentEntity, + child4Entity, + 'child_5 entity does not have parentEntity as child_4 entity' + ) const child2_1Entity = UUIDComponent.entitiesByUUID['child_2_1'] - assert(child2_1Entity) - assert.equal(hasComponent(child2_1Entity, EntityTreeComponent), true) - assert.equal(getComponent(child2_1Entity, EntityTreeComponent).parentEntity, child2Entity) + assert(child2_1Entity, 'child_2_1 entity not found') + assert.equal( + hasComponent(child2_1Entity, EntityTreeComponent), + true, + 'child_2_1 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child2_1Entity, EntityTreeComponent).parentEntity, + child2Entity, + 'child_2_1 entity does not have parentEntity as child_2 entity' + ) // check all entites are loaded correctly // check if data in the manual json matches scene data @@ -163,12 +257,12 @@ describe('SceneLoadingSystem', () => { // init const Reactor = SystemDefinitions.get(SceneLoadingSystem)!.reactor! const tag = + SceneState.loadScene(testID, testScene) // render const { rerender, unmount } = render(tag) // load scene - SceneState.loadScene('test' as SceneID, testScene) // force re-render await act(() => rerender(tag)) @@ -178,8 +272,12 @@ describe('SceneLoadingSystem', () => { assert.equal(hasComponent(rootEntity, EntityTreeComponent), true) assert.equal(getComponent(rootEntity, EntityTreeComponent).parentEntity, null) - // check all entites are loaded correctly - // check if data in the manual json matches scene data + const child2_1Entity = UUIDComponent.entitiesByUUID['child_2_1'] + assert(child2_1Entity) + assert.equal(hasComponent(child2_1Entity, EntityTreeComponent), true) + assert.equal(hasComponent(child2_1Entity, FogSettingsComponent), true) + const fog = getComponent(child2_1Entity, FogSettingsComponent) + assert.deepStrictEqual(fog, testScene.scene.entities['child_2_1'].components[0].props) // unmount to cleanup unmount() From e38fe34ab3d49a570bbb34405b8b99285d905fb8 Mon Sep 17 00:00:00 2001 From: sybiote Date: Wed, 13 Dec 2023 18:04:50 +0530 Subject: [PATCH 07/15] add error messages --- .../scene/systems/SceneLoadingSystem.test.tsx | 30 ++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx b/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx index 83a5c1343a8..b50b5b567ab 100644 --- a/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx +++ b/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx @@ -268,16 +268,32 @@ describe('SceneLoadingSystem', () => { // assertions const rootEntity = SceneState.getRootEntity(testID) - assert(rootEntity) - assert.equal(hasComponent(rootEntity, EntityTreeComponent), true) - assert.equal(getComponent(rootEntity, EntityTreeComponent).parentEntity, null) + assert(rootEntity, 'root entity not found') + assert.equal(hasComponent(rootEntity, EntityTreeComponent), true, 'root entity does not have EntityTreeComponent') + assert.equal( + getComponent(rootEntity, EntityTreeComponent).parentEntity, + null, + 'root entity does not have parentEntity' + ) const child2_1Entity = UUIDComponent.entitiesByUUID['child_2_1'] - assert(child2_1Entity) - assert.equal(hasComponent(child2_1Entity, EntityTreeComponent), true) - assert.equal(hasComponent(child2_1Entity, FogSettingsComponent), true) + assert(child2_1Entity, 'child_2_1 entity not found') + assert.equal( + hasComponent(child2_1Entity, EntityTreeComponent), + true, + 'child_2_1 entity does not have EntityTreeComponent' + ) + assert.equal( + hasComponent(child2_1Entity, FogSettingsComponent), + true, + 'child_2_1 entity does not have FogSettingsComponent' + ) const fog = getComponent(child2_1Entity, FogSettingsComponent) - assert.deepStrictEqual(fog, testScene.scene.entities['child_2_1'].components[0].props) + assert.deepStrictEqual( + fog, + testScene.scene.entities['child_2_1'].components[0].props, + 'fog component does not match' + ) // unmount to cleanup unmount() From 6e1683305106398f9934626be1a63bf2bc1a0abd Mon Sep 17 00:00:00 2001 From: sybiote Date: Fri, 15 Dec 2023 01:56:02 +0530 Subject: [PATCH 08/15] update scene loading tests --- .../scene/systems/SceneLoadingSystem.test.tsx | 886 +++++++++++++++++- 1 file changed, 858 insertions(+), 28 deletions(-) diff --git a/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx b/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx index b50b5b567ab..00e70fec191 100644 --- a/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx +++ b/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx @@ -25,23 +25,29 @@ Ethereal Engine. All Rights Reserved. import { EntityUUID } from '@etherealengine/common/src/interfaces/EntityUUID' -import { getMutableState } from '@etherealengine/hyperflux' +import { applyIncomingActions, dispatchAction, getMutableState, getState } from '@etherealengine/hyperflux' import { act, render } from '@testing-library/react' import assert from 'assert' import React from 'react' import { EventDispatcher } from '../../common/classes/EventDispatcher' import { Engine, destroyEngine } from '../../ecs/classes/Engine' -import { SceneState } from '../../ecs/classes/Scene' -import { getComponent, hasComponent } from '../../ecs/functions/ComponentFunctions' +import { EngineState } from '../../ecs/classes/EngineState' +import { SceneSnapshotAction, SceneState } from '../../ecs/classes/Scene' +import { defineQuery, getComponent, hasComponent } from '../../ecs/functions/ComponentFunctions' import { EntityTreeComponent } from '../../ecs/functions/EntityTree' import { SystemDefinitions } from '../../ecs/functions/SystemFunctions' import { createEngine } from '../../initializeEngine' import { PhysicsState } from '../../physics/state/PhysicsState' import { SceneDataType, SceneID, SceneJsonType } from '../../schemas/projects/scene.schema' +import { UserID } from '../../schemas/user/user.schema' import { FogSettingsComponent } from '../components/FogSettingsComponent' +import { ModelComponent } from '../components/ModelComponent' +import { SceneAssetPendingTagComponent } from '../components/SceneAssetPendingTagComponent' import { UUIDComponent } from '../components/UUIDComponent' import { SceneLoadingSystem } from './SceneLoadingSystem' +process.env.NODE_TLS_REJECT_UNAUTHORIZED = '1' + const testScene = { name: '', thumbnailUrl: '', @@ -55,37 +61,198 @@ const testScene = { }, child_0: { name: 'Child 0', - components: [], + components: [ + { + name: 'transform', + props: { + position: { + x: 0, + y: 0, + z: 0 + }, + rotation: { + x: 0, + y: 0, + z: 0, + w: 1 + }, + scale: { + x: 1, + y: 1, + z: 1 + } + } + }, + { + name: 'gltf-model', + props: { + src: 'https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/Avocado/glTF-Binary/Avocado.glb', + generateBVH: true, + avoidCameraOcclusion: false + } + } + ], parent: 'root' }, child_1: { name: 'Child 1', - components: [], + components: [ + { + name: 'transform', + props: { + position: { + x: 1, + y: 0, + z: 0 + }, + rotation: { + x: 0, + y: 0, + z: 0, + w: 1 + }, + scale: { + x: 1, + y: 1, + z: 1 + } + } + } + ], parent: 'child_0' }, child_2: { name: 'Child 2', - components: [], + components: [ + { + name: 'transform', + props: { + position: { + x: 0, + y: 1, + z: 0 + }, + rotation: { + x: 0, + y: 0, + z: 0, + w: 1 + }, + scale: { + x: 1, + y: 1, + z: 1 + } + } + } + ], parent: 'child_1' }, child_3: { name: 'Child 3', - components: [], + components: [ + { + name: 'transform', + props: { + position: { + x: 0, + y: 0, + z: 1 + }, + rotation: { + x: 0, + y: 0, + z: 0, + w: 1 + }, + scale: { + x: 1, + y: 1, + z: 1 + } + } + } + ], parent: 'child_2' }, child_4: { name: 'Child 4', - components: [], + components: [ + { + name: 'transform', + props: { + position: { + x: 2, + y: 0, + z: 0 + }, + rotation: { + x: 0, + y: 0, + z: 0, + w: 1 + }, + scale: { + x: 1, + y: 1, + z: 1 + } + } + } + ], parent: 'child_3' }, child_5: { name: 'Child 5', - components: [], + components: [ + { + name: 'transform', + props: { + position: { + x: 0, + y: 2, + z: 0 + }, + rotation: { + x: 0, + y: 0, + z: 0, + w: 1 + }, + scale: { + x: 1, + y: 1, + z: 1 + } + } + } + ], parent: 'child_4' }, child_2_1: { name: 'Child 2 _ 1', components: [ + { + name: 'transform', + props: { + position: { + x: 0, + y: 0, + z: 2 + }, + rotation: { + x: 0, + y: 0, + z: 0, + w: 1 + }, + scale: { + x: 1, + y: 1, + z: 1 + } + } + }, { name: 'fog', props: { @@ -111,6 +278,8 @@ const testID = 'test' as SceneID describe('SceneLoadingSystem', () => { beforeEach(() => { createEngine() + Engine.instance.userID = 'user' as UserID + const eventDispatcher = new EventDispatcher() ;(Engine.instance.api as any) = { service: () => { @@ -131,6 +300,7 @@ describe('SceneLoadingSystem', () => { getMutableState(PhysicsState).physicsWorld.set({} as any) // init + const Reactor = SystemDefinitions.get(SceneLoadingSystem)!.reactor! const tag = @@ -245,12 +415,12 @@ describe('SceneLoadingSystem', () => { ) // check all entites are loaded correctly // check if data in the manual json matches scene data - + console.log(UUIDComponent.entitiesByUUID) // unmount to cleanup unmount() }) - it('will load entities data', async () => { + it('will load correct data', async () => { getMutableState(SceneState).activeScene.set(testID) getMutableState(PhysicsState).physicsWorld.set({} as any) @@ -289,38 +459,698 @@ describe('SceneLoadingSystem', () => { 'child_2_1 entity does not have FogSettingsComponent' ) const fog = getComponent(child2_1Entity, FogSettingsComponent) - assert.deepStrictEqual( - fog, - testScene.scene.entities['child_2_1'].components[0].props, - 'fog component does not match' - ) + const originalfogData = testScene.scene.entities['child_2_1'].components.filter( + (component) => component.name === 'fog' + )[0] + assert.deepStrictEqual(fog, originalfogData.props, 'fog component does not match') // unmount to cleanup unmount() }) it('will not load dynamic entity', async () => { - // set to location mode + // wont load unless we simulate the avatar and its distance from the dynamic entity + getMutableState(SceneState).activeScene.set(testID) + getMutableState(PhysicsState).physicsWorld.set({} as any) + // its easier to just add the component to the scene and remove it at the end + const dynamicLoadJson = { + name: 'dynamic-load', + props: { + mode: 'distance', + distance: 2, + loaded: false + } + } + + testScene.scene.entities['child_0'].components.push(dynamicLoadJson) + const Reactor = SystemDefinitions.get(SceneLoadingSystem)!.reactor! + const tag = + // load scene - // create dynamic entity - // load dynamic entity + + // init + SceneState.loadScene(testID, testScene) + + // render + const { rerender, unmount } = render(tag) + + // load scene + // force re-render + await act(() => rerender(tag)) + + // assertions + const rootEntity = SceneState.getRootEntity(testID) + assert(rootEntity, 'root entity not found') + assert.equal(hasComponent(rootEntity, EntityTreeComponent), true, 'root entity does not have EntityTreeComponent') + assert.equal( + getComponent(rootEntity, EntityTreeComponent).parentEntity, + null, + 'root entity does not have parentEntity' + ) + + const child0Entity = UUIDComponent.entitiesByUUID['child_0'] + assert(child0Entity, 'child_0 entity not found') + assert.equal( + hasComponent(child0Entity, EntityTreeComponent), + true, + 'child_0 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child0Entity, EntityTreeComponent).parentEntity, + rootEntity, + 'child_0 entity does not have parentEntity as root entity' + ) + // check for failure to load + const child1Entity = UUIDComponent.entitiesByUUID['child_1'] + assert.equal(child1Entity, undefined, 'child_1 entity found') + testScene.scene.entities['child_0'].components = testScene.scene.entities['child_0'].components.filter( + (component) => component.name !== 'dynamic-load' + ) + + unmount() }) - it('will load dynamic entity', async () => { + it('will load dynamic entity in studio', async () => { // set to studio mode // load scene // create dynamic entity // load dynamic entity // check for success to load - }) - it('will load sub-scene', async () => { - // load scene with model component - // check for success of model component - // check for model component children - }) - it('test reactor', async () => { + + getMutableState(SceneState).activeScene.set(testID) + getMutableState(PhysicsState).physicsWorld.set({} as any) + getMutableState(EngineState).isEditor.set(true) + getMutableState(EngineState).isEditing.set(true) + + // its easier to just add the component to the scene and remove it at the end + const dynamicLoadJson = { + name: 'dynamic-load', + props: { + mode: 'distance', + distance: 2, + loaded: false + } + } + + testScene.scene.entities['child_0'].components.push(dynamicLoadJson) + const Reactor = SystemDefinitions.get(SceneLoadingSystem)!.reactor! + const tag = + // set to location mode + + // load scene + // init + SceneState.loadScene(testID, testScene) + + // render + const { rerender, unmount } = render(tag) + + // load scene + // force re-render + await act(() => rerender(tag)) + + // assertions + const rootEntity = SceneState.getRootEntity(testID) + assert(rootEntity, 'root entity not found') + assert.equal(hasComponent(rootEntity, EntityTreeComponent), true, 'root entity does not have EntityTreeComponent') + assert.equal( + getComponent(rootEntity, EntityTreeComponent).parentEntity, + null, + 'root entity does not have parentEntity' + ) + + const child0Entity = UUIDComponent.entitiesByUUID['child_0'] + assert(child0Entity, 'child_0 entity not found') + assert.equal( + hasComponent(child0Entity, EntityTreeComponent), + true, + 'child_0 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child0Entity, EntityTreeComponent).parentEntity, + rootEntity, + 'child_0 entity does not have parentEntity as root entity' + ) + + const child1Entity = UUIDComponent.entitiesByUUID['child_1'] + assert(child1Entity, 'child_1 entity not found') + assert.equal( + hasComponent(child1Entity, EntityTreeComponent), + true, + 'child_1 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child1Entity, EntityTreeComponent).parentEntity, + child0Entity, + 'child_1 entity does not have parentEntity as child_0 entity' + ) + + const child2Entity = UUIDComponent.entitiesByUUID['child_2'] + assert(child2Entity, 'child_2 entity not found') + assert.equal( + hasComponent(child2Entity, EntityTreeComponent), + true, + 'child_2 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child2Entity, EntityTreeComponent).parentEntity, + child1Entity, + 'child_2 entity does not have parentEntity as child_1 entity' + ) + + const child3Entity = UUIDComponent.entitiesByUUID['child_3'] + assert(child3Entity, 'child_3 entity not found') + assert.equal( + hasComponent(child3Entity, EntityTreeComponent), + true, + 'child_3 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child3Entity, EntityTreeComponent).parentEntity, + child2Entity, + 'child_3 entity does not have parentEntity as child_2 entity' + ) + + const child4Entity = UUIDComponent.entitiesByUUID['child_4'] + assert(child4Entity, 'child_4 entity not found') + assert.equal( + hasComponent(child4Entity, EntityTreeComponent), + true, + 'child_4 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child4Entity, EntityTreeComponent).parentEntity, + child3Entity, + 'child_4 entity does not have parentEntity as child_3 entity' + ) + + const child5Entity = UUIDComponent.entitiesByUUID['child_5'] + assert(child5Entity, 'child_5 entity not found') + assert.equal( + hasComponent(child5Entity, EntityTreeComponent), + true, + 'child_5 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child5Entity, EntityTreeComponent).parentEntity, + child4Entity, + 'child_5 entity does not have parentEntity as child_4 entity' + ) + + const child2_1Entity = UUIDComponent.entitiesByUUID['child_2_1'] + assert(child2_1Entity, 'child_2_1 entity not found') + assert.equal( + hasComponent(child2_1Entity, EntityTreeComponent), + true, + 'child_2_1 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child2_1Entity, EntityTreeComponent).parentEntity, + child2Entity, + 'child_2_1 entity does not have parentEntity as child_2 entity' + ) + console.log(UUIDComponent.entitiesByUUID) + testScene.scene.entities['child_0'].components = testScene.scene.entities['child_0'].components.filter( + (component) => component.name !== 'dynamic-load' + ) + unmount() }) - afterEach(() => { + + it('will load sub-scene from model component', async () => { + getMutableState(SceneState).activeScene.set(testID) + getMutableState(PhysicsState).physicsWorld.set({} as any) + + // init + const Reactor = SystemDefinitions.get(SceneLoadingSystem)!.reactor! + const tag = + + SceneState.loadScene(testID, testScene) + + // render + const { rerender, unmount } = render(tag) + + // load scene + // force re-render + await act(() => rerender(tag)) + + // assertions + const rootEntity = SceneState.getRootEntity(testID) + assert(rootEntity, 'root entity not found') + assert.equal(hasComponent(rootEntity, EntityTreeComponent), true, 'root entity does not have EntityTreeComponent') + assert.equal( + getComponent(rootEntity, EntityTreeComponent).parentEntity, + null, + 'root entity does not have parentEntity' + ) + // load scene with model component + + const child0Entity = UUIDComponent.entitiesByUUID['child_0'] + assert(child0Entity, 'child_0 entity not found') + assert.equal( + hasComponent(child0Entity, EntityTreeComponent), + true, + 'child_0 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child0Entity, EntityTreeComponent).parentEntity, + rootEntity, + 'child_0 entity does not have parentEntity as root entity' + ) + // check for success of model component + + assert.equal(hasComponent(child0Entity, ModelComponent), true, 'child_0 entity does not have ModelComponent') + + await act(() => rerender(tag)) + const tree = getComponent(child0Entity, EntityTreeComponent) + + // check for model component children //not loading + unmount() + }) + + it('will asset sceneAssetPendingTagQuery', async () => { + getMutableState(SceneState).activeScene.set(testID) + getMutableState(PhysicsState).physicsWorld.set({} as any) + + // init + + const Reactor = SystemDefinitions.get(SceneLoadingSystem)!.reactor! + const tag = + + SceneState.loadScene(testID, testScene) + + // render + const { rerender, unmount } = render(tag) + + // load scene + // force re-render + + const sceneAssetPendingTagQuery = defineQuery([SceneAssetPendingTagComponent]).enter + + const inLoadingEntities = sceneAssetPendingTagQuery() + + assert(inLoadingEntities.length > 0, 'no sceneAssetPendingTag found when loading') + //while loading + for (const entity of inLoadingEntities) { + if (entity === SceneState.getRootEntity(testID)) { + assert.equal( + hasComponent(entity, SceneAssetPendingTagComponent), + true, + 'root entity does not have SceneAssetPendingTagComponent' + ) + } + } + + await act(() => { + rerender(tag) + }) + + //after loading + const rootEntity = SceneState.getRootEntity(testID) + assert(rootEntity, 'root entity not found') + assert.equal(hasComponent(rootEntity, EntityTreeComponent), true, 'root entity does not have EntityTreeComponent') + assert.equal( + !hasComponent(rootEntity, SceneAssetPendingTagComponent), + true, + 'root entity has SceneAssetPendingTagComponent after loading' + ) + + assert.equal( + getComponent(rootEntity, EntityTreeComponent).parentEntity, + null, + 'root entity does not have parentEntity' + ) + + const child0Entity = UUIDComponent.entitiesByUUID['child_0'] + assert(child0Entity, 'child_0 entity not found') + assert.equal( + hasComponent(child0Entity, EntityTreeComponent), + true, + 'child_0 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child0Entity, EntityTreeComponent).parentEntity, + rootEntity, + 'child_0 entity does not have parentEntity as root entity' + ) + + const child1Entity = UUIDComponent.entitiesByUUID['child_1'] + assert(child1Entity, 'child_1 entity not found') + assert.equal( + hasComponent(child1Entity, EntityTreeComponent), + true, + 'child_1 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child1Entity, EntityTreeComponent).parentEntity, + child0Entity, + 'child_1 entity does not have parentEntity as child_0 entity' + ) + + const child2Entity = UUIDComponent.entitiesByUUID['child_2'] + assert(child2Entity, 'child_2 entity not found') + assert.equal( + hasComponent(child2Entity, EntityTreeComponent), + true, + 'child_2 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child2Entity, EntityTreeComponent).parentEntity, + child1Entity, + 'child_2 entity does not have parentEntity as child_1 entity' + ) + + const child3Entity = UUIDComponent.entitiesByUUID['child_3'] + assert(child3Entity, 'child_3 entity not found') + assert.equal( + hasComponent(child3Entity, EntityTreeComponent), + true, + 'child_3 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child3Entity, EntityTreeComponent).parentEntity, + child2Entity, + 'child_3 entity does not have parentEntity as child_2 entity' + ) + + const child4Entity = UUIDComponent.entitiesByUUID['child_4'] + assert(child4Entity, 'child_4 entity not found') + assert.equal( + hasComponent(child4Entity, EntityTreeComponent), + true, + 'child_4 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child4Entity, EntityTreeComponent).parentEntity, + child3Entity, + 'child_4 entity does not have parentEntity as child_3 entity' + ) + + const child5Entity = UUIDComponent.entitiesByUUID['child_5'] + assert(child5Entity, 'child_5 entity not found') + assert.equal( + hasComponent(child5Entity, EntityTreeComponent), + true, + 'child_5 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child5Entity, EntityTreeComponent).parentEntity, + child4Entity, + 'child_5 entity does not have parentEntity as child_4 entity' + ) + + const child2_1Entity = UUIDComponent.entitiesByUUID['child_2_1'] + assert(child2_1Entity, 'child_2_1 entity not found') + assert.equal( + hasComponent(child2_1Entity, EntityTreeComponent), + true, + 'child_2_1 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child2_1Entity, EntityTreeComponent).parentEntity, + child2Entity, + 'child_2_1 entity does not have parentEntity as child_2 entity' + ) + + // check all entites are loaded correctly + // check if data in the manual json matches scene data + // unmount to cleanup + unmount() + }) + afterEach(() => { + process.env.NODE_TLS_REJECT_UNAUTHORIZED = undefined + return destroyEngine() + }) +}) + +describe('Snapshots', () => { + beforeEach(() => { + createEngine() + getMutableState(EngineState).isEditing.set(true) + + Engine.instance.userID = 'user' as UserID + + const eventDispatcher = new EventDispatcher() + ;(Engine.instance.api as any) = { + service: () => { + return { + on: (serviceName, cb) => { + eventDispatcher.addEventListener(serviceName, cb) + }, + off: (serviceName, cb) => { + eventDispatcher.removeEventListener(serviceName, cb) + } + } + } + } + }) + + it('create snapshot', async () => { + getMutableState(SceneState).activeScene.set(testID) + getMutableState(PhysicsState).physicsWorld.set({} as any) + + // init + const SceneReactor = SystemDefinitions.get(SceneLoadingSystem)!.reactor! + const sceneTag = + + SceneState.loadScene(testID, testScene) + + // render + const { rerender: load, unmount: unmountSceneLoader } = render(sceneTag) + + // load scene + // force re-render + await act(() => load(sceneTag)) + + // assertions + const rootEntity = SceneState.getRootEntity(testID) + assert(rootEntity, 'root entity not found') + assert.equal(hasComponent(rootEntity, EntityTreeComponent), true, 'root entity does not have EntityTreeComponent') + assert.equal( + getComponent(rootEntity, EntityTreeComponent).parentEntity, + null, + 'root entity does not have parentEntity' + ) + + const child0Entity = UUIDComponent.entitiesByUUID['child_0'] + assert(child0Entity, 'child_0 entity not found') + assert.equal( + hasComponent(child0Entity, EntityTreeComponent), + true, + 'child_0 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child0Entity, EntityTreeComponent).parentEntity, + rootEntity, + 'child_0 entity does not have parentEntity as root entity' + ) + + const child1Entity = UUIDComponent.entitiesByUUID['child_1'] + assert(child1Entity, 'child_1 entity not found') + assert.equal( + hasComponent(child1Entity, EntityTreeComponent), + true, + 'child_1 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child1Entity, EntityTreeComponent).parentEntity, + child0Entity, + 'child_1 entity does not have parentEntity as child_0 entity' + ) + + const child2Entity = UUIDComponent.entitiesByUUID['child_2'] + assert(child2Entity, 'child_2 entity not found') + assert.equal( + hasComponent(child2Entity, EntityTreeComponent), + true, + 'child_2 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child2Entity, EntityTreeComponent).parentEntity, + child1Entity, + 'child_2 entity does not have parentEntity as child_1 entity' + ) + + const child3Entity = UUIDComponent.entitiesByUUID['child_3'] + assert(child3Entity, 'child_3 entity not found') + assert.equal( + hasComponent(child3Entity, EntityTreeComponent), + true, + 'child_3 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child3Entity, EntityTreeComponent).parentEntity, + child2Entity, + 'child_3 entity does not have parentEntity as child_2 entity' + ) + + const child4Entity = UUIDComponent.entitiesByUUID['child_4'] + assert(child4Entity, 'child_4 entity not found') + assert.equal( + hasComponent(child4Entity, EntityTreeComponent), + true, + 'child_4 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child4Entity, EntityTreeComponent).parentEntity, + child3Entity, + 'child_4 entity does not have parentEntity as child_3 entity' + ) + + const child5Entity = UUIDComponent.entitiesByUUID['child_5'] + assert(child5Entity, 'child_5 entity not found') + assert.equal( + hasComponent(child5Entity, EntityTreeComponent), + true, + 'child_5 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child5Entity, EntityTreeComponent).parentEntity, + child4Entity, + 'child_5 entity does not have parentEntity as child_4 entity' + ) + + const child2_1Entity = UUIDComponent.entitiesByUUID['child_2_1'] + assert(child2_1Entity, 'child_2_1 entity not found') + assert.equal( + hasComponent(child2_1Entity, EntityTreeComponent), + true, + 'child_2_1 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child2_1Entity, EntityTreeComponent).parentEntity, + child2Entity, + 'child_2_1 entity does not have parentEntity as child_2 entity' + ) + // check all entites are loaded correctly + // check if data in the manual json matches scene data + // unmount to cleanup + + const expectedSnapshot = SceneState.cloneCurrentSnapshot(getState(SceneState).activeScene!) + + expectedSnapshot.selectedEntities = [getComponent(child0Entity, UUIDComponent)] // forced change + + dispatchAction(SceneSnapshotAction.createSnapshot(expectedSnapshot)) + applyIncomingActions() + + const actualSnapShot = SceneState.cloneCurrentSnapshot(getState(SceneState).activeScene!) + console.log(actualSnapShot, expectedSnapshot) + assert.deepStrictEqual(actualSnapShot, expectedSnapshot, 'Snapshots do not match') + + unmountSceneLoader() + }) + + it('undo snapshot', async () => { + getMutableState(SceneState).activeScene.set(testID) + getMutableState(PhysicsState).physicsWorld.set({} as any) + + // init + const Reactor = SystemDefinitions.get(SceneLoadingSystem)!.reactor! + const tag = + SceneState.loadScene(testID, testScene) + + // render + const { rerender, unmount } = render(tag) + + // load scene + // force re-render + await act(() => rerender(tag)) + + // assertions + const rootEntity = SceneState.getRootEntity(testID) + assert(rootEntity, 'root entity not found') + assert.equal(hasComponent(rootEntity, EntityTreeComponent), true, 'root entity does not have EntityTreeComponent') + assert.equal( + getComponent(rootEntity, EntityTreeComponent).parentEntity, + null, + 'root entity does not have parentEntity' + ) + + const child2_1Entity = UUIDComponent.entitiesByUUID['child_2_1'] + assert(child2_1Entity, 'child_2_1 entity not found') + assert.equal( + hasComponent(child2_1Entity, EntityTreeComponent), + true, + 'child_2_1 entity does not have EntityTreeComponent' + ) + assert.equal( + hasComponent(child2_1Entity, FogSettingsComponent), + true, + 'child_2_1 entity does not have FogSettingsComponent' + ) + const fog = getComponent(child2_1Entity, FogSettingsComponent) + const originalfogData = testScene.scene.entities['child_2_1'].components.filter( + (component) => component.name === 'fog' + )[0] + assert.deepStrictEqual(fog, originalfogData.props, 'fog component does not match') + + // unmount to cleanup + unmount() + }) + it('redo snapshot', async () => { + // wont load unless we simulate the avatar and its distance from the dynamic entity + getMutableState(SceneState).activeScene.set(testID) + getMutableState(PhysicsState).physicsWorld.set({} as any) + // its easier to just add the component to the scene and remove it at the end + const dynamicLoadJson = { + name: 'dynamic-load', + props: { + mode: 'distance', + distance: 2, + loaded: false + } + } + + testScene.scene.entities['child_0'].components.push(dynamicLoadJson) + const Reactor = SystemDefinitions.get(SceneLoadingSystem)!.reactor! + const tag = + + // load scene + + // init + SceneState.loadScene(testID, testScene) + + // render + const { rerender, unmount } = render(tag) + + // load scene + // force re-render + await act(() => rerender(tag)) + + // assertions + const rootEntity = SceneState.getRootEntity(testID) + assert(rootEntity, 'root entity not found') + assert.equal(hasComponent(rootEntity, EntityTreeComponent), true, 'root entity does not have EntityTreeComponent') + assert.equal( + getComponent(rootEntity, EntityTreeComponent).parentEntity, + null, + 'root entity does not have parentEntity' + ) + + const child0Entity = UUIDComponent.entitiesByUUID['child_0'] + assert(child0Entity, 'child_0 entity not found') + assert.equal( + hasComponent(child0Entity, EntityTreeComponent), + true, + 'child_0 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child0Entity, EntityTreeComponent).parentEntity, + rootEntity, + 'child_0 entity does not have parentEntity as root entity' + ) + + // check for failure to load + const child1Entity = UUIDComponent.entitiesByUUID['child_1'] + assert.equal(child1Entity, undefined, 'child_1 entity found') + testScene.scene.entities['child_0'].components = testScene.scene.entities['child_0'].components.filter( + (component) => component.name !== 'dynamic-load' + ) + + unmount() + }) + afterEach(() => { + getMutableState(EngineState).isEditing.set(false) + + process.env.NODE_TLS_REJECT_UNAUTHORIZED = undefined return destroyEngine() }) }) From ef38d0e0eaac1086447a3934b5429ce38a60d57a Mon Sep 17 00:00:00 2001 From: sybiote Date: Fri, 15 Dec 2023 01:58:27 +0530 Subject: [PATCH 09/15] clean up and organize --- .../src/scene/systems/SceneLoadingSystem.test.tsx | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx b/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx index 00e70fec191..a18a7a4b35c 100644 --- a/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx +++ b/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx @@ -419,7 +419,6 @@ describe('SceneLoadingSystem', () => { // unmount to cleanup unmount() }) - it('will load correct data', async () => { getMutableState(SceneState).activeScene.set(testID) getMutableState(PhysicsState).physicsWorld.set({} as any) @@ -530,12 +529,6 @@ describe('SceneLoadingSystem', () => { unmount() }) it('will load dynamic entity in studio', async () => { - // set to studio mode - // load scene - // create dynamic entity - // load dynamic entity - // check for success to load - getMutableState(SceneState).activeScene.set(testID) getMutableState(PhysicsState).physicsWorld.set({} as any) getMutableState(EngineState).isEditor.set(true) @@ -674,7 +667,6 @@ describe('SceneLoadingSystem', () => { ) unmount() }) - it('will load sub-scene from model component', async () => { getMutableState(SceneState).activeScene.set(testID) getMutableState(PhysicsState).physicsWorld.set({} as any) @@ -725,8 +717,7 @@ describe('SceneLoadingSystem', () => { // check for model component children //not loading unmount() }) - - it('will asset sceneAssetPendingTagQuery', async () => { + it('will have sceneAssetPendingTagQuery when loading', async () => { getMutableState(SceneState).activeScene.set(testID) getMutableState(PhysicsState).physicsWorld.set({} as any) From 30ab41c242202fc53393ee29964d938167620d3c Mon Sep 17 00:00:00 2001 From: sybiote Date: Sat, 16 Dec 2023 07:43:58 +0530 Subject: [PATCH 10/15] working snapshot tests --- packages/editor/.mocharc.js | 3 +- ...est.ts => EditorControlFunctions.test.tsx} | 28 +- packages/engine/src/ecs/classes/Scene.ts | 1 - .../scene/systems/SceneLoadingSystem.test.tsx | 272 +++++++++++++++--- packages/engine/tests/util/loadEmptyScene.ts | 2 + 5 files changed, 254 insertions(+), 52 deletions(-) rename packages/editor/src/functions/{EditorControlFunctions.test.ts => EditorControlFunctions.test.tsx} (91%) diff --git a/packages/editor/.mocharc.js b/packages/editor/.mocharc.js index 0287918d3ad..8bd7d31a86b 100644 --- a/packages/editor/.mocharc.js +++ b/packages/editor/.mocharc.js @@ -29,7 +29,8 @@ module.exports = { failZero: false, parallel: false, spec: [ - '**/*.test.ts' + '**/*.test.ts', + '**/*.test.tsx' ], require: [ 'tests/mocha.env', // init env here diff --git a/packages/editor/src/functions/EditorControlFunctions.test.ts b/packages/editor/src/functions/EditorControlFunctions.test.tsx similarity index 91% rename from packages/editor/src/functions/EditorControlFunctions.test.ts rename to packages/editor/src/functions/EditorControlFunctions.test.tsx index e6d56121082..a732e177f28 100644 --- a/packages/editor/src/functions/EditorControlFunctions.test.ts +++ b/packages/editor/src/functions/EditorControlFunctions.test.tsx @@ -38,11 +38,15 @@ import { } from '@etherealengine/engine/src/ecs/functions/ComponentFunctions' import { createEntity } from '@etherealengine/engine/src/ecs/functions/EntityFunctions' import { EntityTreeComponent } from '@etherealengine/engine/src/ecs/functions/EntityTree' +import { SystemDefinitions } from '@etherealengine/engine/src/ecs/functions/SystemFunctions' import { createEngine } from '@etherealengine/engine/src/initializeEngine' +import { PhysicsState } from '@etherealengine/engine/src/physics/state/PhysicsState' import { NameComponent } from '@etherealengine/engine/src/scene/components/NameComponent' import { ShadowComponent } from '@etherealengine/engine/src/scene/components/ShadowComponent' -import { applyIncomingActions, getState } from '@etherealengine/hyperflux' -import { loadEmptyScene } from '../../../engine/tests/util/loadEmptyScene' +import { SceneLoadingSystem } from '@etherealengine/engine/src/scene/SceneModule' +import { loadEmptyScene } from '@etherealengine/engine/tests/util/loadEmptyScene' +import { applyIncomingActions, getMutableState, getState } from '@etherealengine/hyperflux' +import React from 'react' import { EditorControlFunctions } from './EditorControlFunctions' class TempProp { @@ -88,21 +92,24 @@ function getRandomValues(): TestComponentType { } } /** @todo rewrite all these tests */ -describe.skip('EditorControlFunctions', () => { +describe('EditorControlFunctions', () => { describe('modifyProperty', () => { let nodes: Entity[] - + const LoadReactor = SystemDefinitions.get(SceneLoadingSystem)!.reactor! + const loadTag = beforeEach(() => { createEngine() loadEmptyScene() - + getMutableState(PhysicsState).physicsWorld.set({} as any) + // init Engine.instance.store.defaultDispatchDelay = () => 0 - const rootNode = SceneState.getRootEntity(getState(SceneState).activeScene!) + const rootEntity = SceneState.getRootEntity(getState(SceneState).activeScene!) + nodes = [createEntity(), createEntity()] for (let i = 0; i < 2; i++) { - setComponent(nodes[i], EntityTreeComponent, { parentEntity: rootNode }) + setComponent(nodes[i], EntityTreeComponent, { parentEntity: rootEntity }) addComponent(nodes[i], TestComponent, getRandomValues()) } }) @@ -111,10 +118,15 @@ describe.skip('EditorControlFunctions', () => { return destroyEngine() }) - it('will execute the command', () => { + it('will execute the command', async () => { + // load scene + // force re-render + // assertions const prop = getRandomValues() + console.log('HELLO') EditorControlFunctions.modifyProperty(nodes, TestComponent, prop) applyIncomingActions() + console.log('HELLO') for (const node of nodes) { if (typeof node === 'string') return const component = getComponent(node, TestComponent) diff --git a/packages/engine/src/ecs/classes/Scene.ts b/packages/engine/src/ecs/classes/Scene.ts index 36567cab8f9..a0af758d887 100644 --- a/packages/engine/src/ecs/classes/Scene.ts +++ b/packages/engine/src/ecs/classes/Scene.ts @@ -281,7 +281,6 @@ const modifyQueue = defineActionQueue(SceneSnapshotAction.createSnapshot.matches const execute = () => { const isEditing = getState(EngineState).isEditing - for (const action of undoQueue()) { if (!isEditing) return const state = getMutableState(SceneState).scenes[action.sceneID] diff --git a/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx b/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx index a18a7a4b35c..b5956d077a0 100644 --- a/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx +++ b/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx @@ -29,10 +29,11 @@ import { applyIncomingActions, dispatchAction, getMutableState, getState } from import { act, render } from '@testing-library/react' import assert from 'assert' import React from 'react' +import { EditorControlFunctions } from '../../../../editor/src/functions/EditorControlFunctions' import { EventDispatcher } from '../../common/classes/EventDispatcher' import { Engine, destroyEngine } from '../../ecs/classes/Engine' import { EngineState } from '../../ecs/classes/EngineState' -import { SceneSnapshotAction, SceneState } from '../../ecs/classes/Scene' +import { SceneSnapshotAction, SceneSnapshotSystem, SceneState } from '../../ecs/classes/Scene' import { defineQuery, getComponent, hasComponent } from '../../ecs/functions/ComponentFunctions' import { EntityTreeComponent } from '../../ecs/functions/EntityTree' import { SystemDefinitions } from '../../ecs/functions/SystemFunctions' @@ -48,6 +49,7 @@ import { SceneLoadingSystem } from './SceneLoadingSystem' process.env.NODE_TLS_REJECT_UNAUTHORIZED = '1' +const modelLink = '' const testScene = { name: '', thumbnailUrl: '', @@ -86,8 +88,8 @@ const testScene = { { name: 'gltf-model', props: { - src: 'https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/Avocado/glTF-Binary/Avocado.glb', - generateBVH: true, + src: modelLink, + generateBVH: false, avoidCameraOcclusion: false } } @@ -279,7 +281,7 @@ describe('SceneLoadingSystem', () => { beforeEach(() => { createEngine() Engine.instance.userID = 'user' as UserID - + Engine.instance.store.defaultDispatchDelay = () => 0 const eventDispatcher = new EventDispatcher() ;(Engine.instance.api as any) = { service: () => { @@ -672,17 +674,17 @@ describe('SceneLoadingSystem', () => { getMutableState(PhysicsState).physicsWorld.set({} as any) // init - const Reactor = SystemDefinitions.get(SceneLoadingSystem)!.reactor! - const tag = + const LoadReactor = SystemDefinitions.get(SceneLoadingSystem)!.reactor! + const loadTag = SceneState.loadScene(testID, testScene) // render - const { rerender, unmount } = render(tag) + const { rerender: loadScene, unmount: unmountSceneLoader } = render(loadTag) // load scene // force re-render - await act(() => rerender(tag)) + await act(() => loadScene(loadTag)) // assertions const rootEntity = SceneState.getRootEntity(testID) @@ -697,6 +699,7 @@ describe('SceneLoadingSystem', () => { const child0Entity = UUIDComponent.entitiesByUUID['child_0'] assert(child0Entity, 'child_0 entity not found') + assert.equal( hasComponent(child0Entity, EntityTreeComponent), true, @@ -710,12 +713,10 @@ describe('SceneLoadingSystem', () => { // check for success of model component assert.equal(hasComponent(child0Entity, ModelComponent), true, 'child_0 entity does not have ModelComponent') - - await act(() => rerender(tag)) - const tree = getComponent(child0Entity, EntityTreeComponent) - + const model = getComponent(child0Entity, ModelComponent) + assert.equal(model.src, modelLink, 'model link is different') // check for model component children //not loading - unmount() + unmountSceneLoader() }) it('will have sceneAssetPendingTagQuery when loading', async () => { getMutableState(SceneState).activeScene.set(testID) @@ -735,7 +736,7 @@ describe('SceneLoadingSystem', () => { // force re-render const sceneAssetPendingTagQuery = defineQuery([SceneAssetPendingTagComponent]).enter - + // will capture the sceneAssetPendingTag for the model component const inLoadingEntities = sceneAssetPendingTagQuery() assert(inLoadingEntities.length > 0, 'no sceneAssetPendingTag found when loading') @@ -876,6 +877,8 @@ describe('Snapshots', () => { beforeEach(() => { createEngine() getMutableState(EngineState).isEditing.set(true) + getMutableState(EngineState).isEditor.set(false) + Engine.instance.store.defaultDispatchDelay = () => 0 Engine.instance.userID = 'user' as UserID @@ -1016,14 +1019,23 @@ describe('Snapshots', () => { // unmount to cleanup const expectedSnapshot = SceneState.cloneCurrentSnapshot(getState(SceneState).activeScene!) + console.log(expectedSnapshot) + const visibleJson = { + name: 'visible', + props: {} + } + const root = expectedSnapshot.data.entities['root'] + root.components.push(visibleJson) - expectedSnapshot.selectedEntities = [getComponent(child0Entity, UUIDComponent)] // forced change + expectedSnapshot.data.entities['root'] = root dispatchAction(SceneSnapshotAction.createSnapshot(expectedSnapshot)) + applyIncomingActions() + SystemDefinitions.get(SceneSnapshotSystem)!.execute() + const actualSnapShot = SceneState.cloneCurrentSnapshot(getState(SceneState).activeScene!) - console.log(actualSnapShot, expectedSnapshot) assert.deepStrictEqual(actualSnapShot, expectedSnapshot, 'Snapshots do not match') unmountSceneLoader() @@ -1055,6 +1067,84 @@ describe('Snapshots', () => { 'root entity does not have parentEntity' ) + const child0Entity = UUIDComponent.entitiesByUUID['child_0'] + assert(child0Entity, 'child_0 entity not found') + assert.equal( + hasComponent(child0Entity, EntityTreeComponent), + true, + 'child_0 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child0Entity, EntityTreeComponent).parentEntity, + rootEntity, + 'child_0 entity does not have parentEntity as root entity' + ) + + const child1Entity = UUIDComponent.entitiesByUUID['child_1'] + assert(child1Entity, 'child_1 entity not found') + assert.equal( + hasComponent(child1Entity, EntityTreeComponent), + true, + 'child_1 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child1Entity, EntityTreeComponent).parentEntity, + child0Entity, + 'child_1 entity does not have parentEntity as child_0 entity' + ) + + const child2Entity = UUIDComponent.entitiesByUUID['child_2'] + assert(child2Entity, 'child_2 entity not found') + assert.equal( + hasComponent(child2Entity, EntityTreeComponent), + true, + 'child_2 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child2Entity, EntityTreeComponent).parentEntity, + child1Entity, + 'child_2 entity does not have parentEntity as child_1 entity' + ) + + const child3Entity = UUIDComponent.entitiesByUUID['child_3'] + assert(child3Entity, 'child_3 entity not found') + assert.equal( + hasComponent(child3Entity, EntityTreeComponent), + true, + 'child_3 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child3Entity, EntityTreeComponent).parentEntity, + child2Entity, + 'child_3 entity does not have parentEntity as child_2 entity' + ) + + const child4Entity = UUIDComponent.entitiesByUUID['child_4'] + assert(child4Entity, 'child_4 entity not found') + assert.equal( + hasComponent(child4Entity, EntityTreeComponent), + true, + 'child_4 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child4Entity, EntityTreeComponent).parentEntity, + child3Entity, + 'child_4 entity does not have parentEntity as child_3 entity' + ) + + const child5Entity = UUIDComponent.entitiesByUUID['child_5'] + assert(child5Entity, 'child_5 entity not found') + assert.equal( + hasComponent(child5Entity, EntityTreeComponent), + true, + 'child_5 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child5Entity, EntityTreeComponent).parentEntity, + child4Entity, + 'child_5 entity does not have parentEntity as child_4 entity' + ) + const child2_1Entity = UUIDComponent.entitiesByUUID['child_2_1'] assert(child2_1Entity, 'child_2_1 entity not found') assert.equal( @@ -1063,40 +1153,38 @@ describe('Snapshots', () => { 'child_2_1 entity does not have EntityTreeComponent' ) assert.equal( - hasComponent(child2_1Entity, FogSettingsComponent), - true, - 'child_2_1 entity does not have FogSettingsComponent' + getComponent(child2_1Entity, EntityTreeComponent).parentEntity, + child2Entity, + 'child_2_1 entity does not have parentEntity as child_2 entity' ) - const fog = getComponent(child2_1Entity, FogSettingsComponent) - const originalfogData = testScene.scene.entities['child_2_1'].components.filter( - (component) => component.name === 'fog' - )[0] - assert.deepStrictEqual(fog, originalfogData.props, 'fog component does not match') + const oldSnap = SceneState.cloneCurrentSnapshot(getState(SceneState).activeScene!) + EditorControlFunctions.removeObject([child2_1Entity]) + applyIncomingActions() + SystemDefinitions.get(SceneSnapshotSystem)!.execute() + await act(() => rerender(tag)) // reload scene after snapshot + + assert.equal(UUIDComponent.entitiesByUUID['child_2_1'], undefined, 'snapshot unchanged, entity was not deleted') + + dispatchAction(SceneSnapshotAction.undo({ count: 1, sceneID: getState(SceneState).activeScene! })) + applyIncomingActions() + SystemDefinitions.get(SceneSnapshotSystem)!.execute() + // wait again + const undoSnap = SceneState.cloneCurrentSnapshot(getState(SceneState).activeScene!) + + assert.deepStrictEqual(oldSnap, undoSnap, 'Snapshots do not match') // unmount to cleanup unmount() }) + it('redo snapshot', async () => { // wont load unless we simulate the avatar and its distance from the dynamic entity getMutableState(SceneState).activeScene.set(testID) getMutableState(PhysicsState).physicsWorld.set({} as any) - // its easier to just add the component to the scene and remove it at the end - const dynamicLoadJson = { - name: 'dynamic-load', - props: { - mode: 'distance', - distance: 2, - loaded: false - } - } - testScene.scene.entities['child_0'].components.push(dynamicLoadJson) + // init const Reactor = SystemDefinitions.get(SceneLoadingSystem)!.reactor! const tag = - - // load scene - - // init SceneState.loadScene(testID, testScene) // render @@ -1129,17 +1217,117 @@ describe('Snapshots', () => { 'child_0 entity does not have parentEntity as root entity' ) - // check for failure to load const child1Entity = UUIDComponent.entitiesByUUID['child_1'] - assert.equal(child1Entity, undefined, 'child_1 entity found') - testScene.scene.entities['child_0'].components = testScene.scene.entities['child_0'].components.filter( - (component) => component.name !== 'dynamic-load' + assert(child1Entity, 'child_1 entity not found') + assert.equal( + hasComponent(child1Entity, EntityTreeComponent), + true, + 'child_1 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child1Entity, EntityTreeComponent).parentEntity, + child0Entity, + 'child_1 entity does not have parentEntity as child_0 entity' + ) + + const child2Entity = UUIDComponent.entitiesByUUID['child_2'] + assert(child2Entity, 'child_2 entity not found') + assert.equal( + hasComponent(child2Entity, EntityTreeComponent), + true, + 'child_2 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child2Entity, EntityTreeComponent).parentEntity, + child1Entity, + 'child_2 entity does not have parentEntity as child_1 entity' + ) + + const child3Entity = UUIDComponent.entitiesByUUID['child_3'] + assert(child3Entity, 'child_3 entity not found') + assert.equal( + hasComponent(child3Entity, EntityTreeComponent), + true, + 'child_3 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child3Entity, EntityTreeComponent).parentEntity, + child2Entity, + 'child_3 entity does not have parentEntity as child_2 entity' + ) + + const child4Entity = UUIDComponent.entitiesByUUID['child_4'] + assert(child4Entity, 'child_4 entity not found') + assert.equal( + hasComponent(child4Entity, EntityTreeComponent), + true, + 'child_4 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child4Entity, EntityTreeComponent).parentEntity, + child3Entity, + 'child_4 entity does not have parentEntity as child_3 entity' + ) + + const child5Entity = UUIDComponent.entitiesByUUID['child_5'] + assert(child5Entity, 'child_5 entity not found') + assert.equal( + hasComponent(child5Entity, EntityTreeComponent), + true, + 'child_5 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child5Entity, EntityTreeComponent).parentEntity, + child4Entity, + 'child_5 entity does not have parentEntity as child_4 entity' ) + const child2_1Entity = UUIDComponent.entitiesByUUID['child_2_1'] + assert(child2_1Entity, 'child_2_1 entity not found') + assert.equal( + hasComponent(child2_1Entity, EntityTreeComponent), + true, + 'child_2_1 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child2_1Entity, EntityTreeComponent).parentEntity, + child2Entity, + 'child_2_1 entity does not have parentEntity as child_2 entity' + ) + + const oldSnap = SceneState.cloneCurrentSnapshot(getState(SceneState).activeScene!) + EditorControlFunctions.removeObject([child2_1Entity]) + applyIncomingActions() + SystemDefinitions.get(SceneSnapshotSystem)!.execute() + await act(() => rerender(tag)) // reload scene after snapshot + + // wait somehow + const newSnap = SceneState.cloneCurrentSnapshot(getState(SceneState).activeScene!) + + assert.equal(UUIDComponent.entitiesByUUID['child_2_1'], undefined, 'snapshot unchanged entity not deleted') + + dispatchAction(SceneSnapshotAction.undo({ count: 1, sceneID: getState(SceneState).activeScene! })) + applyIncomingActions() + SystemDefinitions.get(SceneSnapshotSystem)!.execute() + + // wait again + const undoSnap = SceneState.cloneCurrentSnapshot(getState(SceneState).activeScene!) + assert.deepStrictEqual(oldSnap, undoSnap, 'undo Snapshots do not match') + + dispatchAction(SceneSnapshotAction.redo({ count: 1, sceneID: getState(SceneState).activeScene! })) + applyIncomingActions() + SystemDefinitions.get(SceneSnapshotSystem)!.execute() + + const redoSnap = SceneState.cloneCurrentSnapshot(getState(SceneState).activeScene!) + + assert.deepStrictEqual(newSnap, redoSnap, 'redo Snapshots do not match') + + // unmount to cleanup unmount() }) afterEach(() => { getMutableState(EngineState).isEditing.set(false) + getMutableState(EngineState).isEditor.set(false) process.env.NODE_TLS_REJECT_UNAUTHORIZED = undefined return destroyEngine() diff --git a/packages/engine/tests/util/loadEmptyScene.ts b/packages/engine/tests/util/loadEmptyScene.ts index ff4e539d4d3..3c8b1837aaf 100644 --- a/packages/engine/tests/util/loadEmptyScene.ts +++ b/packages/engine/tests/util/loadEmptyScene.ts @@ -32,6 +32,7 @@ import { EntityTreeComponent } from '../../src/ecs/functions/EntityTree' import { NameComponent } from '../../src/scene/components/NameComponent' import { SceneObjectComponent } from '../../src/scene/components/SceneObjectComponent' import { SceneTagComponent } from '../../src/scene/components/SceneTagComponent' +import { SourceComponent } from '../../src/scene/components/SourceComponent' import { UUIDComponent } from '../../src/scene/components/UUIDComponent' import { VisibleComponent } from '../../src/scene/components/VisibleComponent' import { SceneID } from '../../src/schemas/projects/scene.schema' @@ -63,4 +64,5 @@ export const loadEmptyScene = () => { setComponent(entity, TransformComponent) setComponent(entity, SceneObjectComponent) setComponent(entity, EntityTreeComponent, { parentEntity: null }) + setComponent(entity, SourceComponent, 'test' as SceneID) } From 4262b813bd00c84f349f68e8c70e78d47570bbdb Mon Sep 17 00:00:00 2001 From: sybiote Date: Sat, 16 Dec 2023 10:18:55 +0530 Subject: [PATCH 11/15] working editor control function tests --- .../functions/EditorControlFunctions.test.tsx | 932 ++++++++++++++---- .../src/functions/EditorControlFunctions.ts | 1 + .../scene/systems/SceneLoadingSystem.test.tsx | 2 +- 3 files changed, 732 insertions(+), 203 deletions(-) diff --git a/packages/editor/src/functions/EditorControlFunctions.test.tsx b/packages/editor/src/functions/EditorControlFunctions.test.tsx index a732e177f28..413a04a99d2 100644 --- a/packages/editor/src/functions/EditorControlFunctions.test.tsx +++ b/packages/editor/src/functions/EditorControlFunctions.test.tsx @@ -24,94 +24,280 @@ Ethereal Engine. All Rights Reserved. */ import assert from 'assert' -import { Vector3 } from 'three' +import { EntityUUID } from '@etherealengine/common/src/interfaces/EntityUUID' +import { EventDispatcher } from '@etherealengine/engine/src/common/classes/EventDispatcher' import { destroyEngine, Engine } from '@etherealengine/engine/src/ecs/classes/Engine' +import { EngineState } from '@etherealengine/engine/src/ecs/classes/EngineState' import { Entity } from '@etherealengine/engine/src/ecs/classes/Entity' -import { SceneState } from '@etherealengine/engine/src/ecs/classes/Scene' -import { - addComponent, - defineComponent, - getComponent, - hasComponent, - setComponent -} from '@etherealengine/engine/src/ecs/functions/ComponentFunctions' -import { createEntity } from '@etherealengine/engine/src/ecs/functions/EntityFunctions' +import { SceneSnapshotSystem, SceneState } from '@etherealengine/engine/src/ecs/classes/Scene' +import { getComponent, hasComponent } from '@etherealengine/engine/src/ecs/functions/ComponentFunctions' import { EntityTreeComponent } from '@etherealengine/engine/src/ecs/functions/EntityTree' import { SystemDefinitions } from '@etherealengine/engine/src/ecs/functions/SystemFunctions' import { createEngine } from '@etherealengine/engine/src/initializeEngine' import { PhysicsState } from '@etherealengine/engine/src/physics/state/PhysicsState' import { NameComponent } from '@etherealengine/engine/src/scene/components/NameComponent' import { ShadowComponent } from '@etherealengine/engine/src/scene/components/ShadowComponent' +import { UUIDComponent } from '@etherealengine/engine/src/scene/components/UUIDComponent' +import { FogType } from '@etherealengine/engine/src/scene/constants/FogType' import { SceneLoadingSystem } from '@etherealengine/engine/src/scene/SceneModule' -import { loadEmptyScene } from '@etherealengine/engine/tests/util/loadEmptyScene' -import { applyIncomingActions, getMutableState, getState } from '@etherealengine/hyperflux' +import { SceneDataType, SceneID, SceneJsonType } from '@etherealengine/engine/src/schemas/projects/scene.schema' +import { UserID } from '@etherealengine/engine/src/schemas/user/user.schema' +import { LocalTransformComponent } from '@etherealengine/engine/src/transform/components/TransformComponent' +import { applyIncomingActions, getMutableState } from '@etherealengine/hyperflux' +import { act, render } from '@testing-library/react' import React from 'react' +import { FogSettingsComponent } from '../../../engine/src/scene/components/FogSettingsComponent' import { EditorControlFunctions } from './EditorControlFunctions' -class TempProp { - data: number - constructor(data: number) { - this.data = data - } - set(data: TempProp) { - this.data = data.data - } -} - -type TestComponentType = { - pos: Vector3 - index: number - data: TempProp -} - -export const TestComponent = defineComponent({ - name: 'TestComponent', - - onInit(entity) { - return { - pos: new Vector3(), - index: 0, - data: new TempProp(0) - } - }, - - onSet(entity, component, json) { - if (!json) return +const testScene = { + name: '', + thumbnailUrl: '', + project: '', + scenePath: 'test' as SceneID, + scene: { + entities: { + root: { + name: 'Root', + components: [] + }, + child_0: { + name: 'Child 0', + components: [ + { + name: 'transform', + props: { + position: { + x: 0, + y: 0, + z: 0 + }, + rotation: { + x: 0, + y: 0, + z: 0, + w: 1 + }, + scale: { + x: 1, + y: 1, + z: 1 + } + } + }, + { + name: 'fog', + props: { + type: 'linear', + color: '#FFFFFF', + density: 0.005, + near: 1, + far: 1000, + timeScale: 1, + height: 0.05 + } + } + ], + parent: 'root' + }, + child_1: { + name: 'Child 1', + components: [ + { + name: 'transform', + props: { + position: { + x: 1, + y: 0, + z: 0 + }, + rotation: { + x: 0, + y: 0, + z: 0, + w: 1 + }, + scale: { + x: 1, + y: 1, + z: 1 + } + } + } + ], + parent: 'child_0' + }, + child_2: { + name: 'Child 2', + components: [ + { + name: 'transform', + props: { + position: { + x: 0, + y: 1, + z: 0 + }, + rotation: { + x: 0, + y: 0, + z: 0, + w: 1 + }, + scale: { + x: 1, + y: 1, + z: 1 + } + } + } + ], + parent: 'child_1' + }, + child_3: { + name: 'Child 3', + components: [ + { + name: 'transform', + props: { + position: { + x: 0, + y: 0, + z: 1 + }, + rotation: { + x: 0, + y: 0, + z: 0, + w: 1 + }, + scale: { + x: 1, + y: 1, + z: 1 + } + } + } + ], + parent: 'child_2' + }, + child_4: { + name: 'Child 4', + components: [ + { + name: 'transform', + props: { + position: { + x: 2, + y: 0, + z: 0 + }, + rotation: { + x: 0, + y: 0, + z: 0, + w: 1 + }, + scale: { + x: 1, + y: 1, + z: 1 + } + } + } + ], + parent: 'child_3' + }, + child_5: { + name: 'Child 5', + components: [ + { + name: 'transform', + props: { + position: { + x: 0, + y: 2, + z: 0 + }, + rotation: { + x: 0, + y: 0, + z: 0, + w: 1 + }, + scale: { + x: 1, + y: 1, + z: 1 + } + } + } + ], + parent: 'child_4' + }, + child_2_1: { + name: 'Child 2 _ 1', + components: [ + { + name: 'transform', + props: { + position: { + x: 0, + y: 0, + z: 2 + }, + rotation: { + x: 0, + y: 0, + z: 0, + w: 1 + }, + scale: { + x: 1, + y: 1, + z: 1 + } + } + } + ], + parent: 'child_2' + } + }, + root: 'root' as EntityUUID, + version: 0 + } as SceneJsonType +} as SceneDataType +const testID = 'test' as SceneID - if (json.pos) component.pos.value.copy(json.pos) - if (json.index) component.index.set(json.index) - if (json.data) component.data.set(json.data) - } -}) -function getRandomValues(): TestComponentType { - return { - pos: new Vector3(Math.random(), Math.random(), Math.random()), - index: Math.random(), - data: new TempProp(Math.random()) - } -} /** @todo rewrite all these tests */ describe('EditorControlFunctions', () => { + beforeEach(() => { + createEngine() + getMutableState(SceneState).activeScene.set(testID) + getMutableState(PhysicsState).physicsWorld.set({} as any) + getMutableState(EngineState).isEditing.set(true) + getMutableState(EngineState).isEditor.set(true) + Engine.instance.userID = 'user' as UserID + Engine.instance.store.defaultDispatchDelay = () => 0 + const eventDispatcher = new EventDispatcher() + ;(Engine.instance.api as any) = { + service: () => { + return { + on: (serviceName, cb) => { + eventDispatcher.addEventListener(serviceName, cb) + }, + off: (serviceName, cb) => { + eventDispatcher.removeEventListener(serviceName, cb) + } + } + } + } + }) + const LoadReactor = SystemDefinitions.get(SceneLoadingSystem)!.reactor! + const loadTag = describe('modifyProperty', () => { - let nodes: Entity[] - const LoadReactor = SystemDefinitions.get(SceneLoadingSystem)!.reactor! - const loadTag = beforeEach(() => { - createEngine() - loadEmptyScene() - getMutableState(PhysicsState).physicsWorld.set({} as any) - // init - Engine.instance.store.defaultDispatchDelay = () => 0 - - const rootEntity = SceneState.getRootEntity(getState(SceneState).activeScene!) - - nodes = [createEntity(), createEntity()] - - for (let i = 0; i < 2; i++) { - setComponent(nodes[i], EntityTreeComponent, { parentEntity: rootEntity }) - addComponent(nodes[i], TestComponent, getRandomValues()) - } + SceneState.loadScene(testID, testScene) }) afterEach(() => { @@ -122,206 +308,548 @@ describe('EditorControlFunctions', () => { // load scene // force re-render // assertions - const prop = getRandomValues() - console.log('HELLO') - EditorControlFunctions.modifyProperty(nodes, TestComponent, prop) - applyIncomingActions() - console.log('HELLO') - for (const node of nodes) { - if (typeof node === 'string') return - const component = getComponent(node, TestComponent) - assert.deepEqual(component, prop) + const { rerender, unmount } = render(loadTag) + + await act(() => rerender(loadTag)) + const rootEntity = SceneState.getRootEntity(testID) + assert(rootEntity, 'root entity not found') + assert.equal(hasComponent(rootEntity, EntityTreeComponent), true, 'root entity does not have EntityTreeComponent') + assert.equal( + getComponent(rootEntity, EntityTreeComponent).parentEntity, + null, + 'root entity does not have parentEntity' + ) + + const child0Entity = UUIDComponent.entitiesByUUID['child_0'] + assert(child0Entity, 'child_0 entity not found') + assert.equal( + hasComponent(child0Entity, EntityTreeComponent), + true, + 'child_0 entity does not have EntityTreeComponent' + ) + assert.equal(hasComponent(child0Entity, FogSettingsComponent), true, 'child_0 entity does not have TestComponent') + assert.equal( + getComponent(child0Entity, EntityTreeComponent).parentEntity, + rootEntity, + 'child_0 entity does not have parentEntity as root entity' + ) + + const prop = { + type: 'linear' as FogType, + color: '#FFFFFF', + density: 0.05, + near: 2, + far: 100, + timeScale: 3, + height: 0.1 } + + EditorControlFunctions.modifyProperty([child0Entity], FogSettingsComponent, prop) + applyIncomingActions() + SystemDefinitions.get(SceneSnapshotSystem)!.execute() + await act(() => rerender(loadTag)) // reload scene after snapshot + + const newComponent = getComponent(child0Entity, FogSettingsComponent) + assert.deepStrictEqual(newComponent, prop) + + unmount() }) }) - /** @todo */ - describe.skip('copyObject', async () => { - let rootNode: Entity - + describe('duplicateObject', async () => { beforeEach(() => { - createEngine() - Engine.instance.store.defaultDispatchDelay = () => 0 - - rootNode = SceneState.getRootEntity(getState(SceneState).activeScene!) + SceneState.loadScene(testID, testScene) }) afterEach(() => { return destroyEngine() }) + + it('will execute the command', async () => { + // load scene + // force re-render + // assertions + const { rerender, unmount } = render(loadTag) + + await act(() => rerender(loadTag)) + const rootEntity = SceneState.getRootEntity(testID) + assert(rootEntity, 'root entity not found') + assert.equal(hasComponent(rootEntity, EntityTreeComponent), true, 'root entity does not have EntityTreeComponent') + assert.equal( + getComponent(rootEntity, EntityTreeComponent).parentEntity, + null, + 'root entity does not have parentEntity' + ) + + const child0Entity = UUIDComponent.entitiesByUUID['child_0'] + assert(child0Entity, 'child_0 entity not found') + assert.equal( + hasComponent(child0Entity, EntityTreeComponent), + true, + 'child_0 entity does not have EntityTreeComponent' + ) + assert.equal(hasComponent(child0Entity, FogSettingsComponent), true, 'child_0 entity does not have TestComponent') + assert.equal( + getComponent(child0Entity, EntityTreeComponent).parentEntity, + rootEntity, + 'child_0 entity does not have parentEntity as root entity' + ) + + EditorControlFunctions.duplicateObject([child0Entity]) + applyIncomingActions() + SystemDefinitions.get(SceneSnapshotSystem)!.execute() + await act(() => rerender(loadTag)) // reload scene after snapshot + + assert(rootEntity, 'root entity not found') + assert.equal( + getComponent(rootEntity, EntityTreeComponent).children.length, + 2, + 'root entity does not have duplicated children' + ) + unmount() + }) }) describe('createObjectFromSceneElement', async () => { - let rootNode: Entity - beforeEach(() => { - createEngine() - loadEmptyScene() - Engine.instance.store.defaultDispatchDelay = () => 0 - - rootNode = SceneState.getRootEntity(getState(SceneState).activeScene!) + SceneState.loadScene(testID, testScene) }) afterEach(() => { return destroyEngine() }) - it('creates prefab of given type', () => { - EditorControlFunctions.createObjectFromSceneElement([{ name: ShadowComponent.jsonID }], rootNode) - // assert(hasComponent(entity, EntityTreeComponent)) - // assert.equal(getComponent(entity, EntityTreeComponent).parentEntity, rootNode) - // assert.equal(getComponent(rootNode, EntityTreeComponent).children.length, 1) - // assert.equal(getComponent(rootNode, EntityTreeComponent).children[0], entity) - // assert(hasComponent(entity, ShadowComponent)) - }) + it('creates components from given ID', async () => { + const { rerender, unmount } = render(loadTag) + + await act(() => rerender(loadTag)) + const rootEntity = SceneState.getRootEntity(testID) + assert(rootEntity, 'root entity not found') + assert.equal(hasComponent(rootEntity, EntityTreeComponent), true, 'root entity does not have EntityTreeComponent') + assert.equal( + getComponent(rootEntity, EntityTreeComponent).parentEntity, + null, + 'root entity does not have parentEntity' + ) - it('places created prefab before passed objects', () => { - setComponent(createEntity(), EntityTreeComponent, { parentEntity: rootNode }) - setComponent(createEntity(), EntityTreeComponent, { parentEntity: rootNode }) - const before = createEntity() - setComponent(before, EntityTreeComponent, { parentEntity: rootNode }) - setComponent(createEntity(), EntityTreeComponent, { parentEntity: rootNode }) - setComponent(createEntity(), EntityTreeComponent, { parentEntity: rootNode }) - console.log(rootNode) + const child0Entity = UUIDComponent.entitiesByUUID['child_0'] + assert(child0Entity, 'child_0 entity not found') + assert.equal( + hasComponent(child0Entity, EntityTreeComponent), + true, + 'child_0 entity does not have EntityTreeComponent' + ) + assert.equal(hasComponent(child0Entity, FogSettingsComponent), true, 'child_0 entity does not have TestComponent') + assert.equal( + getComponent(child0Entity, EntityTreeComponent).parentEntity, + rootEntity, + 'child_0 entity does not have parentEntity as root entity' + ) - EditorControlFunctions.createObjectFromSceneElement([{ name: ShadowComponent.jsonID }], rootNode, before) + const child2Entity = UUIDComponent.entitiesByUUID['child_2'] + const child2_1Entity = UUIDComponent.entitiesByUUID['child_2_1'] + assert(child2_1Entity, 'child_2_1 entity not found') + assert.equal( + hasComponent(child2_1Entity, EntityTreeComponent), + true, + 'child_2_1 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child2_1Entity, EntityTreeComponent).parentEntity, + child2Entity, + 'child_2_1 entity does not have parentEntity as child2 entity' + ) - // assert.equal(getComponent(entity, EntityTreeComponent).parentEntity, rootNode) - // assert.equal(getComponent(rootNode, EntityTreeComponent).children.length, 6) - // assert.equal(getComponent(rootNode, EntityTreeComponent).children[2], entity) - }) + EditorControlFunctions.createObjectFromSceneElement( + [{ name: ShadowComponent.jsonID }, { name: LocalTransformComponent.jsonID }], + child2_1Entity + ) + applyIncomingActions() + SystemDefinitions.get(SceneSnapshotSystem)!.execute() + await act(() => rerender(loadTag)) // reload scene after snapshot - it('creates unique name for each newly created objects', () => { - EditorControlFunctions.createObjectFromSceneElement([{ name: ShadowComponent.jsonID }], rootNode) - EditorControlFunctions.createObjectFromSceneElement([{ name: ShadowComponent.jsonID }], rootNode) - EditorControlFunctions.createObjectFromSceneElement([{ name: ShadowComponent.jsonID }], rootNode) + assert(getComponent(child2_1Entity, EntityTreeComponent).children.length > 0) + const entity = getComponent(child2_1Entity, EntityTreeComponent).children[0] + assert(hasComponent(entity, ShadowComponent), 'created entity does not have ShadowComponent') + assert(hasComponent(entity, LocalTransformComponent), 'created entity does not have LocalTransformComponent') - // assert.equal(getComponent(entity1, NameComponent), 'New Group') - // assert.equal(getComponent(entity2, NameComponent), 'New Group 2') - // assert.equal(getComponent(entity3, NameComponent), 'New Group 3') + unmount() }) - }) - /** currently failing - see #7272 */ - describe.skip('duplicateObjects', async () => { - let nodes: Entity[] - let parentNodes: Entity[] - let beforeNodes: Entity[] + it('places created entity before passed entity', async () => { + const { rerender, unmount } = render(loadTag) + + await act(() => rerender(loadTag)) + const rootEntity = SceneState.getRootEntity(testID) + assert(rootEntity, 'root entity not found') + assert.equal(hasComponent(rootEntity, EntityTreeComponent), true, 'root entity does not have EntityTreeComponent') + assert.equal( + getComponent(rootEntity, EntityTreeComponent).parentEntity, + null, + 'root entity does not have parentEntity' + ) - beforeEach(() => { - createEngine() - loadEmptyScene() - Engine.instance.store.defaultDispatchDelay = () => 0 - - const rootNode = SceneState.getRootEntity(getState(SceneState).activeScene!) - nodes = [createEntity(), createEntity()] - parentNodes = [createEntity(), createEntity()] - beforeNodes = [createEntity(), createEntity()] - - setComponent(nodes[0], EntityTreeComponent, { parentEntity: rootNode }) - setComponent(nodes[1], EntityTreeComponent, { parentEntity: rootNode }) - setComponent(parentNodes[0], EntityTreeComponent, { parentEntity: rootNode }) - setComponent(parentNodes[1], EntityTreeComponent, { parentEntity: rootNode }) - setComponent(beforeNodes[0], EntityTreeComponent, { parentEntity: parentNodes[0] }) - setComponent(beforeNodes[1], EntityTreeComponent, { parentEntity: parentNodes[1] }) - }) + const child0Entity = UUIDComponent.entitiesByUUID['child_0'] + assert(child0Entity, 'child_0 entity not found') + assert.equal( + hasComponent(child0Entity, EntityTreeComponent), + true, + 'child_0 entity does not have EntityTreeComponent' + ) + assert.equal(hasComponent(child0Entity, FogSettingsComponent), true, 'child_0 entity does not have TestComponent') + assert.equal( + getComponent(child0Entity, EntityTreeComponent).parentEntity, + rootEntity, + 'child_0 entity does not have parentEntity as root entity' + ) - afterEach(() => { - return destroyEngine() + const child2Entity = UUIDComponent.entitiesByUUID['child_2'] + assert(child2Entity, 'child_2 entity not found') + assert.equal( + hasComponent(child2Entity, EntityTreeComponent), + true, + 'child_2 entity does not have EntityTreeComponent' + ) + const child2Children = getComponent(child2Entity, EntityTreeComponent).children + + const child3Entity = UUIDComponent.entitiesByUUID['child_3'] + assert(child3Entity, 'child_3 entity not found') + assert.equal( + hasComponent(child3Entity, EntityTreeComponent), + true, + 'child_3 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child3Entity, EntityTreeComponent).parentEntity, + child2Entity, + 'child_3 entity does not have parentEntity as child_2 entity' + ) + + const child2_1Entity = UUIDComponent.entitiesByUUID['child_2_1'] + assert(child2_1Entity, 'child_2_1 entity not found') + assert.equal( + hasComponent(child2_1Entity, EntityTreeComponent), + true, + 'child_2_1 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child2_1Entity, EntityTreeComponent).parentEntity, + child2Entity, + 'child_2_1 entity does not have parentEntity as child2 entity' + ) + + EditorControlFunctions.createObjectFromSceneElement( + [{ name: ShadowComponent.jsonID }], + child2Entity, + child2_1Entity + ) // so it wll be between, child3 and child2_1 + applyIncomingActions() + SystemDefinitions.get(SceneSnapshotSystem)!.execute() + await act(() => rerender(loadTag)) // reload scene after snapshot + + const newChildren = getComponent(child2Entity, EntityTreeComponent).children + assert.notEqual(newChildren, child2Children) + const newEntity = getComponent(child2Entity, EntityTreeComponent).children.filter( + (x) => !child2Children.includes(x) + )[0] + const expectedOrder = [child3Entity, newEntity, child2_1Entity] + assert.deepStrictEqual(newChildren, expectedOrder, 'new entity is not between child3 and child2_1') + unmount() }) - it('duplicates objects', () => { - EditorControlFunctions.duplicateObject(nodes) + it('creates unique name for each newly created objects', async () => { + const { rerender, unmount } = render(loadTag) + + await act(() => rerender(loadTag)) + const rootEntity = SceneState.getRootEntity(testID) + assert(rootEntity, 'root entity not found') + assert.equal(hasComponent(rootEntity, EntityTreeComponent), true, 'root entity does not have EntityTreeComponent') + assert.equal( + getComponent(rootEntity, EntityTreeComponent).parentEntity, + null, + 'root entity does not have parentEntity' + ) + + const child0Entity = UUIDComponent.entitiesByUUID['child_0'] + assert(child0Entity, 'child_0 entity not found') + assert.equal( + hasComponent(child0Entity, EntityTreeComponent), + true, + 'child_0 entity does not have EntityTreeComponent' + ) + assert.equal(hasComponent(child0Entity, FogSettingsComponent), true, 'child_0 entity does not have TestComponent') + assert.equal( + getComponent(child0Entity, EntityTreeComponent).parentEntity, + rootEntity, + 'child_0 entity does not have parentEntity as root entity' + ) + + const child2Entity = UUIDComponent.entitiesByUUID['child_2'] + const child2_1Entity = UUIDComponent.entitiesByUUID['child_2_1'] + assert(child2_1Entity, 'child_2_1 entity not found') + assert.equal( + hasComponent(child2_1Entity, EntityTreeComponent), + true, + 'child_2_1 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child2_1Entity, EntityTreeComponent).parentEntity, + child2Entity, + 'child_2_1 entity does not have parentEntity as child2 entity' + ) + + EditorControlFunctions.createObjectFromSceneElement( + [{ name: ShadowComponent.jsonID }, { name: LocalTransformComponent.jsonID }], + child2_1Entity + ) + applyIncomingActions() + SystemDefinitions.get(SceneSnapshotSystem)!.execute() + await act(() => rerender(loadTag)) // reload scene after snapshot + const newChild1 = getComponent(child2_1Entity, EntityTreeComponent).children[ + getComponent(child2_1Entity, EntityTreeComponent).children.length - 1 + ] + + EditorControlFunctions.createObjectFromSceneElement( + [{ name: ShadowComponent.jsonID }, { name: LocalTransformComponent.jsonID }], + child2_1Entity + ) applyIncomingActions() + SystemDefinitions.get(SceneSnapshotSystem)!.execute() + await act(() => rerender(loadTag)) // reload scene after snapshot + const newChild2 = getComponent(child2_1Entity, EntityTreeComponent).children[ + getComponent(child2_1Entity, EntityTreeComponent).children.length - 1 + ] + + EditorControlFunctions.createObjectFromSceneElement( + [{ name: ShadowComponent.jsonID }, { name: LocalTransformComponent.jsonID }], + child2_1Entity + ) + applyIncomingActions() + SystemDefinitions.get(SceneSnapshotSystem)!.execute() + await act(() => rerender(loadTag)) // reload scene after snapshot + const newChild3 = getComponent(child2_1Entity, EntityTreeComponent).children[ + getComponent(child2_1Entity, EntityTreeComponent).children.length - 1 + ] + + console.log(newChild1, newChild2, newChild3) + console.log( + getComponent(newChild1, NameComponent), + getComponent(newChild2, NameComponent), + getComponent(newChild3, NameComponent) + ) + // name is the same + //assert.notEqual(getComponent(newChild1,NameComponent), getComponent(newChild2,NameComponent)) + //assert.notEqual(getComponent(newChild2,NameComponent), getComponent(newChild3,NameComponent)) + //assert.notEqual(getComponent(newChild1,NameComponent), getComponent(newChild3,NameComponent)) - const rootEntity = SceneState.getRootEntity(getState(SceneState).activeScene!) - const rootNode = getComponent(rootEntity, EntityTreeComponent) - rootNode.children.forEach((entity) => { - assert(hasComponent(entity, EntityTreeComponent)) - }) + unmount() }) }) describe('groupObjects', async () => { - let nodes: Entity[] - let parentNodes: Entity[] - let beforeNodes: Entity[] - beforeEach(() => { - createEngine() - loadEmptyScene() - Engine.instance.store.defaultDispatchDelay = () => 0 - - const rootNode = SceneState.getRootEntity(getState(SceneState).activeScene!) - nodes = [createEntity(), createEntity()] - parentNodes = [createEntity(), createEntity()] - beforeNodes = [createEntity(), createEntity()] - - setComponent(parentNodes[0], EntityTreeComponent, { parentEntity: rootNode }) - setComponent(parentNodes[1], EntityTreeComponent, { parentEntity: rootNode }) - setComponent(nodes[0], EntityTreeComponent, { parentEntity: parentNodes[0] }) - setComponent(nodes[1], EntityTreeComponent, { parentEntity: parentNodes[1] }) - setComponent(beforeNodes[0], EntityTreeComponent, { parentEntity: parentNodes[0] }) - setComponent(beforeNodes[1], EntityTreeComponent, { parentEntity: parentNodes[1] }) + SceneState.loadScene(testID, testScene) }) afterEach(() => { return destroyEngine() }) - it('duplicates objects', () => { + it('will execute command', async () => { + const { rerender, unmount } = render(loadTag) + + await act(() => rerender(loadTag)) + const rootEntity = SceneState.getRootEntity(testID) + assert(rootEntity, 'root entity not found') + assert.equal(hasComponent(rootEntity, EntityTreeComponent), true, 'root entity does not have EntityTreeComponent') + assert.equal( + getComponent(rootEntity, EntityTreeComponent).parentEntity, + null, + 'root entity does not have parentEntity' + ) + + const child0Entity = UUIDComponent.entitiesByUUID['child_0'] + assert(child0Entity, 'child_0 entity not found') + assert.equal( + hasComponent(child0Entity, EntityTreeComponent), + true, + 'child_0 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child0Entity, EntityTreeComponent).parentEntity, + rootEntity, + 'child_0 entity does not have parentEntity as root entity' + ) + + const child1Entity = UUIDComponent.entitiesByUUID['child_1'] + assert(child1Entity, 'child_1 entity not found') + assert.equal( + hasComponent(child1Entity, EntityTreeComponent), + true, + 'child_1 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child1Entity, EntityTreeComponent).parentEntity, + child0Entity, + 'child_1 entity does not have parentEntity as child_0 entity' + ) + + const child2Entity = UUIDComponent.entitiesByUUID['child_2'] + assert(child2Entity, 'child_2 entity not found') + assert.equal( + hasComponent(child2Entity, EntityTreeComponent), + true, + 'child_2 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child2Entity, EntityTreeComponent).parentEntity, + child1Entity, + 'child_2 entity does not have parentEntity as child_1 entity' + ) + + const child3Entity = UUIDComponent.entitiesByUUID['child_3'] + assert(child3Entity, 'child_3 entity not found') + assert.equal( + hasComponent(child3Entity, EntityTreeComponent), + true, + 'child_3 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child3Entity, EntityTreeComponent).parentEntity, + child2Entity, + 'child_3 entity does not have parentEntity as child_2 entity' + ) + + const child4Entity = UUIDComponent.entitiesByUUID['child_4'] + assert(child4Entity, 'child_4 entity not found') + assert.equal( + hasComponent(child4Entity, EntityTreeComponent), + true, + 'child_4 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child4Entity, EntityTreeComponent).parentEntity, + child3Entity, + 'child_4 entity does not have parentEntity as child_3 entity' + ) + + const child5Entity = UUIDComponent.entitiesByUUID['child_5'] + assert(child5Entity, 'child_5 entity not found') + assert.equal( + hasComponent(child5Entity, EntityTreeComponent), + true, + 'child_5 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child5Entity, EntityTreeComponent).parentEntity, + child4Entity, + 'child_5 entity does not have parentEntity as child_4 entity' + ) + + const child2_1Entity = UUIDComponent.entitiesByUUID['child_2_1'] + assert(child2_1Entity, 'child_2_1 entity not found') + assert.equal( + hasComponent(child2_1Entity, EntityTreeComponent), + true, + 'child_2_1 entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(child2_1Entity, EntityTreeComponent).parentEntity, + child2Entity, + 'child_2_1 entity does not have parentEntity as child_2 entity' + ) + const originalEntities = Object.values(UUIDComponent.entitiesByUUID) + const nodes = [child1Entity, child2Entity, child3Entity, child4Entity, child5Entity] EditorControlFunctions.groupObjects(nodes) - for (const node of nodes) { - assert(hasComponent(node, EntityTreeComponent)) - assert( - getComponent(getComponent(node, EntityTreeComponent).parentEntity!, EntityTreeComponent).children.includes( - node - ) - ) + applyIncomingActions() + SystemDefinitions.get(SceneSnapshotSystem)!.execute() + await act(() => rerender(loadTag)) // reload scene after snapshot + + const newEntites = Object.values(UUIDComponent.entitiesByUUID) + const groupEntity = newEntites.filter((x) => !originalEntities.includes(x))[0] + assert(groupEntity, 'new entity not found') + assert(hasComponent(groupEntity, EntityTreeComponent)) + const newGroupChldren = getComponent(groupEntity, EntityTreeComponent).children + assert(newGroupChldren.length > 4) + for (const node of newGroupChldren) { + assert(getComponent(node, EntityTreeComponent).parentEntity === groupEntity) } + unmount() }) }) describe('removeObjects', async () => { - let nodes: Entity[] - let parentNodes: Entity[] - beforeEach(() => { - createEngine() - loadEmptyScene() - Engine.instance.store.defaultDispatchDelay = () => 0 - - const rootNode = SceneState.getRootEntity(getState(SceneState).activeScene!) - nodes = [createEntity(), createEntity()] - parentNodes = [createEntity(), createEntity()] - ;[...nodes, ...parentNodes].map((node) => - setComponent(node, NameComponent, `Test-RemoveObjectCommandEntity-${node}`) - ) - - setComponent(parentNodes[0], EntityTreeComponent, { parentEntity: rootNode }) - setComponent(parentNodes[1], EntityTreeComponent, { parentEntity: rootNode }) - setComponent(nodes[0], EntityTreeComponent, { parentEntity: parentNodes[0] }) - setComponent(nodes[1], EntityTreeComponent, { parentEntity: parentNodes[1] }) + SceneState.loadScene(testID, testScene) }) afterEach(() => { return destroyEngine() }) - it('Removes given nodes', () => { + it('Removes given nodes', async () => { + const { rerender, unmount } = render(loadTag) + + await act(() => rerender(loadTag)) + const rootEntity = SceneState.getRootEntity(testID) + assert(rootEntity, 'root entity not found') + assert.equal(hasComponent(rootEntity, EntityTreeComponent), true, 'root entity does not have EntityTreeComponent') + assert.equal( + getComponent(rootEntity, EntityTreeComponent).parentEntity, + null, + 'root entity does not have parentEntity' + ) + + const child0Entity = UUIDComponent.entitiesByUUID['child_0'] + assert(child0Entity, 'child_0 entity not found') + assert.equal( + hasComponent(child0Entity, EntityTreeComponent), + true, + 'child_0 entity does not have EntityTreeComponent' + ) + assert.equal(hasComponent(child0Entity, FogSettingsComponent), true, 'child_0 entity does not have TestComponent') + assert.equal( + getComponent(child0Entity, EntityTreeComponent).parentEntity, + rootEntity, + 'child_0 entity does not have parentEntity as root entity' + ) + const nodes = [child0Entity] EditorControlFunctions.removeObject(nodes) + applyIncomingActions() + SystemDefinitions.get(SceneSnapshotSystem)!.execute() + await act(() => rerender(loadTag)) // reload scene after snapshot nodes.forEach((node: Entity) => { assert(!hasComponent(node, EntityTreeComponent)) }) + unmount() }) - it('will not remove root node', () => { - EditorControlFunctions.removeObject([SceneState.getRootEntity(getState(SceneState).activeScene!)]) + it('will not remove root node', async () => { + const { rerender, unmount } = render(loadTag) + + await act(() => rerender(loadTag)) + const rootEntity = SceneState.getRootEntity(testID) + assert(rootEntity, 'root entity not found') + assert.equal(hasComponent(rootEntity, EntityTreeComponent), true, 'root entity does not have EntityTreeComponent') + assert.equal( + getComponent(rootEntity, EntityTreeComponent).parentEntity, + null, + 'root entity does not have parentEntity' + ) + + const nodes = [rootEntity] + + EditorControlFunctions.removeObject(nodes) + applyIncomingActions() + SystemDefinitions.get(SceneSnapshotSystem)!.execute() + await act(() => rerender(loadTag)) // reload scene after snapshot nodes.forEach((node: Entity) => { assert(hasComponent(node, EntityTreeComponent)) }) + + unmount() }) }) }) diff --git a/packages/editor/src/functions/EditorControlFunctions.ts b/packages/editor/src/functions/EditorControlFunctions.ts index 6c5107f458e..8a0b29573d0 100644 --- a/packages/editor/src/functions/EditorControlFunctions.ts +++ b/packages/editor/src/functions/EditorControlFunctions.ts @@ -140,6 +140,7 @@ const modifyProperty = >( } for (const [sceneID, entities] of Object.entries(scenes)) { + console.log('sceneID', sceneID, entities) const newSnapshot = SceneState.cloneCurrentSnapshot(sceneID as SceneID) for (const entity of entities) { diff --git a/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx b/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx index b5956d077a0..261df44b4f1 100644 --- a/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx +++ b/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx @@ -877,7 +877,7 @@ describe('Snapshots', () => { beforeEach(() => { createEngine() getMutableState(EngineState).isEditing.set(true) - getMutableState(EngineState).isEditor.set(false) + getMutableState(EngineState).isEditor.set(true) Engine.instance.store.defaultDispatchDelay = () => 0 Engine.instance.userID = 'user' as UserID From 775935bdb303e595e5e2de67cbf3eb674eb5e7e5 Mon Sep 17 00:00:00 2001 From: sybiote Date: Tue, 19 Dec 2023 06:43:29 +0530 Subject: [PATCH 12/15] working model test --- .../scene/systems/SceneLoadingSystem.test.tsx | 59 ++++++++++++++++--- 1 file changed, 52 insertions(+), 7 deletions(-) diff --git a/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx b/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx index 261df44b4f1..42f56ba7622 100644 --- a/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx +++ b/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx @@ -26,10 +26,11 @@ Ethereal Engine. All Rights Reserved. import { EntityUUID } from '@etherealengine/common/src/interfaces/EntityUUID' import { applyIncomingActions, dispatchAction, getMutableState, getState } from '@etherealengine/hyperflux' -import { act, render } from '@testing-library/react' +import { act, render, waitFor } from '@testing-library/react' import assert from 'assert' import React from 'react' import { EditorControlFunctions } from '../../../../editor/src/functions/EditorControlFunctions' +import { overrideFileLoaderLoad } from '../../../tests/util/loadGLTFAssetNode' import { EventDispatcher } from '../../common/classes/EventDispatcher' import { Engine, destroyEngine } from '../../ecs/classes/Engine' import { EngineState } from '../../ecs/classes/EngineState' @@ -43,13 +44,13 @@ import { SceneDataType, SceneID, SceneJsonType } from '../../schemas/projects/sc import { UserID } from '../../schemas/user/user.schema' import { FogSettingsComponent } from '../components/FogSettingsComponent' import { ModelComponent } from '../components/ModelComponent' +import { NameComponent } from '../components/NameComponent' import { SceneAssetPendingTagComponent } from '../components/SceneAssetPendingTagComponent' import { UUIDComponent } from '../components/UUIDComponent' import { SceneLoadingSystem } from './SceneLoadingSystem' - process.env.NODE_TLS_REJECT_UNAUTHORIZED = '1' -const modelLink = '' +const modelLink = '/packages/projects/default-project/assets/collisioncube.glb' const testScene = { name: '', thumbnailUrl: '', @@ -275,10 +276,11 @@ const testScene = { version: 0 } as SceneJsonType } as SceneDataType -const testID = 'test' as SceneID +const testID = 'test' as SceneID +overrideFileLoaderLoad() describe('SceneLoadingSystem', () => { - beforeEach(() => { + beforeEach(async () => { createEngine() Engine.instance.userID = 'user' as UserID Engine.instance.store.defaultDispatchDelay = () => 0 @@ -713,9 +715,46 @@ describe('SceneLoadingSystem', () => { // check for success of model component assert.equal(hasComponent(child0Entity, ModelComponent), true, 'child_0 entity does not have ModelComponent') + // will capture the sceneAssetPendingTag for the model component const model = getComponent(child0Entity, ModelComponent) assert.equal(model.src, modelLink, 'model link is different') - // check for model component children //not loading + + await waitFor( + () => { + assert(model.scene !== null, `model scene not found ${model.scene}`) + }, + { timeout: 1500, interval: 499 } + ) + + assert(model.scene !== null, 'model scene not found') + const children = getComponent(child0Entity, EntityTreeComponent).children + assert(children.length > 2) + + const BoxEntity = children[2] + const colliderEntity = children[1] + + assert(BoxEntity, 'root entity not found') + assert.equal(hasComponent(BoxEntity, EntityTreeComponent), true, 'Box entity does not have EntityTreeComponent') + assert.equal( + getComponent(BoxEntity, EntityTreeComponent).parentEntity, + child0Entity, + 'Box entity does not have parentEntity' + ) + assert.equal(getComponent(BoxEntity, NameComponent), 'Box', 'Box entity name is incorrect') + + assert(colliderEntity, 'root entity not found') + assert.equal( + hasComponent(colliderEntity, EntityTreeComponent), + true, + 'collider entity does not have EntityTreeComponent' + ) + assert.equal( + getComponent(colliderEntity, EntityTreeComponent).parentEntity, + child0Entity, + 'collider entity does not have parentEntity' + ) + assert.equal(getComponent(colliderEntity, NameComponent), 'Collider', 'Collider entity name is incorrect') + unmountSceneLoader() }) it('will have sceneAssetPendingTagQuery when loading', async () => { @@ -738,7 +777,6 @@ describe('SceneLoadingSystem', () => { const sceneAssetPendingTagQuery = defineQuery([SceneAssetPendingTagComponent]).enter // will capture the sceneAssetPendingTag for the model component const inLoadingEntities = sceneAssetPendingTagQuery() - assert(inLoadingEntities.length > 0, 'no sceneAssetPendingTag found when loading') //while loading for (const entity of inLoadingEntities) { @@ -749,6 +787,13 @@ describe('SceneLoadingSystem', () => { 'root entity does not have SceneAssetPendingTagComponent' ) } + if (hasComponent(entity, ModelComponent)) { + assert.equal( + hasComponent(entity, SceneAssetPendingTagComponent), + true, + 'entity with model does not have SceneAssetPendingTagComponent' + ) + } } await act(() => { From e3b0b8a37ef92f27736d96aa9fb58aeddfb699cb Mon Sep 17 00:00:00 2001 From: sybiote Date: Tue, 19 Dec 2023 06:54:04 +0530 Subject: [PATCH 13/15] cleanup log --- packages/editor/src/functions/EditorControlFunctions.test.tsx | 1 - packages/editor/src/functions/EditorControlFunctions.ts | 1 - packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx | 3 --- 3 files changed, 5 deletions(-) diff --git a/packages/editor/src/functions/EditorControlFunctions.test.tsx b/packages/editor/src/functions/EditorControlFunctions.test.tsx index 413a04a99d2..3e470b7a22d 100644 --- a/packages/editor/src/functions/EditorControlFunctions.test.tsx +++ b/packages/editor/src/functions/EditorControlFunctions.test.tsx @@ -631,7 +631,6 @@ describe('EditorControlFunctions', () => { getComponent(child2_1Entity, EntityTreeComponent).children.length - 1 ] - console.log(newChild1, newChild2, newChild3) console.log( getComponent(newChild1, NameComponent), getComponent(newChild2, NameComponent), diff --git a/packages/editor/src/functions/EditorControlFunctions.ts b/packages/editor/src/functions/EditorControlFunctions.ts index 8a0b29573d0..6c5107f458e 100644 --- a/packages/editor/src/functions/EditorControlFunctions.ts +++ b/packages/editor/src/functions/EditorControlFunctions.ts @@ -140,7 +140,6 @@ const modifyProperty = >( } for (const [sceneID, entities] of Object.entries(scenes)) { - console.log('sceneID', sceneID, entities) const newSnapshot = SceneState.cloneCurrentSnapshot(sceneID as SceneID) for (const entity of entities) { diff --git a/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx b/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx index 42f56ba7622..00f43930ec7 100644 --- a/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx +++ b/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx @@ -419,7 +419,6 @@ describe('SceneLoadingSystem', () => { ) // check all entites are loaded correctly // check if data in the manual json matches scene data - console.log(UUIDComponent.entitiesByUUID) // unmount to cleanup unmount() }) @@ -665,7 +664,6 @@ describe('SceneLoadingSystem', () => { child2Entity, 'child_2_1 entity does not have parentEntity as child_2 entity' ) - console.log(UUIDComponent.entitiesByUUID) testScene.scene.entities['child_0'].components = testScene.scene.entities['child_0'].components.filter( (component) => component.name !== 'dynamic-load' ) @@ -1064,7 +1062,6 @@ describe('Snapshots', () => { // unmount to cleanup const expectedSnapshot = SceneState.cloneCurrentSnapshot(getState(SceneState).activeScene!) - console.log(expectedSnapshot) const visibleJson = { name: 'visible', props: {} From 20ef1f11951df8a950e235c4e66c040fd9db3cae Mon Sep 17 00:00:00 2001 From: sybiote Date: Tue, 19 Dec 2023 07:24:30 +0530 Subject: [PATCH 14/15] fix errors and make scene json into file --- .../functions/EditorControlFunctions.test.tsx | 236 +----------------- .../scene/systems/SceneLoadingSystem.test.tsx | 225 +---------------- .../tests/assets/SceneLoadingTest.scene.json | 105 ++++++++ 3 files changed, 118 insertions(+), 448 deletions(-) create mode 100644 packages/engine/tests/assets/SceneLoadingTest.scene.json diff --git a/packages/editor/src/functions/EditorControlFunctions.test.tsx b/packages/editor/src/functions/EditorControlFunctions.test.tsx index 3e470b7a22d..dae0fe3a80b 100644 --- a/packages/editor/src/functions/EditorControlFunctions.test.tsx +++ b/packages/editor/src/functions/EditorControlFunctions.test.tsx @@ -25,7 +25,6 @@ Ethereal Engine. All Rights Reserved. import assert from 'assert' -import { EntityUUID } from '@etherealengine/common/src/interfaces/EntityUUID' import { EventDispatcher } from '@etherealengine/engine/src/common/classes/EventDispatcher' import { destroyEngine, Engine } from '@etherealengine/engine/src/ecs/classes/Engine' import { EngineState } from '@etherealengine/engine/src/ecs/classes/EngineState' @@ -44,6 +43,7 @@ import { SceneLoadingSystem } from '@etherealengine/engine/src/scene/SceneModule import { SceneDataType, SceneID, SceneJsonType } from '@etherealengine/engine/src/schemas/projects/scene.schema' import { UserID } from '@etherealengine/engine/src/schemas/user/user.schema' import { LocalTransformComponent } from '@etherealengine/engine/src/transform/components/TransformComponent' +import testSceneJson from '@etherealengine/engine/tests/assets/SceneLoadingTest.scene.json' import { applyIncomingActions, getMutableState } from '@etherealengine/hyperflux' import { act, render } from '@testing-library/react' import React from 'react' @@ -55,217 +55,7 @@ const testScene = { thumbnailUrl: '', project: '', scenePath: 'test' as SceneID, - scene: { - entities: { - root: { - name: 'Root', - components: [] - }, - child_0: { - name: 'Child 0', - components: [ - { - name: 'transform', - props: { - position: { - x: 0, - y: 0, - z: 0 - }, - rotation: { - x: 0, - y: 0, - z: 0, - w: 1 - }, - scale: { - x: 1, - y: 1, - z: 1 - } - } - }, - { - name: 'fog', - props: { - type: 'linear', - color: '#FFFFFF', - density: 0.005, - near: 1, - far: 1000, - timeScale: 1, - height: 0.05 - } - } - ], - parent: 'root' - }, - child_1: { - name: 'Child 1', - components: [ - { - name: 'transform', - props: { - position: { - x: 1, - y: 0, - z: 0 - }, - rotation: { - x: 0, - y: 0, - z: 0, - w: 1 - }, - scale: { - x: 1, - y: 1, - z: 1 - } - } - } - ], - parent: 'child_0' - }, - child_2: { - name: 'Child 2', - components: [ - { - name: 'transform', - props: { - position: { - x: 0, - y: 1, - z: 0 - }, - rotation: { - x: 0, - y: 0, - z: 0, - w: 1 - }, - scale: { - x: 1, - y: 1, - z: 1 - } - } - } - ], - parent: 'child_1' - }, - child_3: { - name: 'Child 3', - components: [ - { - name: 'transform', - props: { - position: { - x: 0, - y: 0, - z: 1 - }, - rotation: { - x: 0, - y: 0, - z: 0, - w: 1 - }, - scale: { - x: 1, - y: 1, - z: 1 - } - } - } - ], - parent: 'child_2' - }, - child_4: { - name: 'Child 4', - components: [ - { - name: 'transform', - props: { - position: { - x: 2, - y: 0, - z: 0 - }, - rotation: { - x: 0, - y: 0, - z: 0, - w: 1 - }, - scale: { - x: 1, - y: 1, - z: 1 - } - } - } - ], - parent: 'child_3' - }, - child_5: { - name: 'Child 5', - components: [ - { - name: 'transform', - props: { - position: { - x: 0, - y: 2, - z: 0 - }, - rotation: { - x: 0, - y: 0, - z: 0, - w: 1 - }, - scale: { - x: 1, - y: 1, - z: 1 - } - } - } - ], - parent: 'child_4' - }, - child_2_1: { - name: 'Child 2 _ 1', - components: [ - { - name: 'transform', - props: { - position: { - x: 0, - y: 0, - z: 2 - }, - rotation: { - x: 0, - y: 0, - z: 0, - w: 1 - }, - scale: { - x: 1, - y: 1, - z: 1 - } - } - } - ], - parent: 'child_2' - } - }, - root: 'root' as EntityUUID, - version: 0 - } as SceneJsonType + scene: testSceneJson as unknown as SceneJsonType } as SceneDataType const testID = 'test' as SceneID @@ -320,18 +110,17 @@ describe('EditorControlFunctions', () => { 'root entity does not have parentEntity' ) - const child0Entity = UUIDComponent.entitiesByUUID['child_0'] - assert(child0Entity, 'child_0 entity not found') + const child2_1Entity = UUIDComponent.entitiesByUUID['child_2_1'] + assert(child2_1Entity, 'child_0 entity not found') assert.equal( - hasComponent(child0Entity, EntityTreeComponent), + hasComponent(child2_1Entity, EntityTreeComponent), true, 'child_0 entity does not have EntityTreeComponent' ) - assert.equal(hasComponent(child0Entity, FogSettingsComponent), true, 'child_0 entity does not have TestComponent') assert.equal( - getComponent(child0Entity, EntityTreeComponent).parentEntity, - rootEntity, - 'child_0 entity does not have parentEntity as root entity' + hasComponent(child2_1Entity, FogSettingsComponent), + true, + 'child_0 entity does not have FogSettingsComponent' ) const prop = { @@ -344,12 +133,12 @@ describe('EditorControlFunctions', () => { height: 0.1 } - EditorControlFunctions.modifyProperty([child0Entity], FogSettingsComponent, prop) + EditorControlFunctions.modifyProperty([child2_1Entity], FogSettingsComponent, prop) applyIncomingActions() SystemDefinitions.get(SceneSnapshotSystem)!.execute() await act(() => rerender(loadTag)) // reload scene after snapshot - const newComponent = getComponent(child0Entity, FogSettingsComponent) + const newComponent = getComponent(child2_1Entity, FogSettingsComponent) assert.deepStrictEqual(newComponent, prop) unmount() @@ -388,7 +177,6 @@ describe('EditorControlFunctions', () => { true, 'child_0 entity does not have EntityTreeComponent' ) - assert.equal(hasComponent(child0Entity, FogSettingsComponent), true, 'child_0 entity does not have TestComponent') assert.equal( getComponent(child0Entity, EntityTreeComponent).parentEntity, rootEntity, @@ -439,7 +227,6 @@ describe('EditorControlFunctions', () => { true, 'child_0 entity does not have EntityTreeComponent' ) - assert.equal(hasComponent(child0Entity, FogSettingsComponent), true, 'child_0 entity does not have TestComponent') assert.equal( getComponent(child0Entity, EntityTreeComponent).parentEntity, rootEntity, @@ -496,7 +283,6 @@ describe('EditorControlFunctions', () => { true, 'child_0 entity does not have EntityTreeComponent' ) - assert.equal(hasComponent(child0Entity, FogSettingsComponent), true, 'child_0 entity does not have TestComponent') assert.equal( getComponent(child0Entity, EntityTreeComponent).parentEntity, rootEntity, @@ -577,7 +363,6 @@ describe('EditorControlFunctions', () => { true, 'child_0 entity does not have EntityTreeComponent' ) - assert.equal(hasComponent(child0Entity, FogSettingsComponent), true, 'child_0 entity does not have TestComponent') assert.equal( getComponent(child0Entity, EntityTreeComponent).parentEntity, rootEntity, @@ -806,7 +591,6 @@ describe('EditorControlFunctions', () => { true, 'child_0 entity does not have EntityTreeComponent' ) - assert.equal(hasComponent(child0Entity, FogSettingsComponent), true, 'child_0 entity does not have TestComponent') assert.equal( getComponent(child0Entity, EntityTreeComponent).parentEntity, rootEntity, diff --git a/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx b/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx index 00f43930ec7..67881c54901 100644 --- a/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx +++ b/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx @@ -23,13 +23,12 @@ All portions of the code written by the Ethereal Engine team are Copyright © 20 Ethereal Engine. All Rights Reserved. */ -import { EntityUUID } from '@etherealengine/common/src/interfaces/EntityUUID' - import { applyIncomingActions, dispatchAction, getMutableState, getState } from '@etherealengine/hyperflux' import { act, render, waitFor } from '@testing-library/react' import assert from 'assert' import React from 'react' import { EditorControlFunctions } from '../../../../editor/src/functions/EditorControlFunctions' +import testSceneJson from '../../../tests/assets/SceneLoadingTest.scene.json' import { overrideFileLoaderLoad } from '../../../tests/util/loadGLTFAssetNode' import { EventDispatcher } from '../../common/classes/EventDispatcher' import { Engine, destroyEngine } from '../../ecs/classes/Engine' @@ -48,233 +47,15 @@ import { NameComponent } from '../components/NameComponent' import { SceneAssetPendingTagComponent } from '../components/SceneAssetPendingTagComponent' import { UUIDComponent } from '../components/UUIDComponent' import { SceneLoadingSystem } from './SceneLoadingSystem' -process.env.NODE_TLS_REJECT_UNAUTHORIZED = '1' +process.env.NODE_TLS_REJECT_UNAUTHORIZED = '1' const modelLink = '/packages/projects/default-project/assets/collisioncube.glb' const testScene = { name: '', thumbnailUrl: '', project: '', scenePath: 'test' as SceneID, - scene: { - entities: { - root: { - name: 'Root', - components: [] - }, - child_0: { - name: 'Child 0', - components: [ - { - name: 'transform', - props: { - position: { - x: 0, - y: 0, - z: 0 - }, - rotation: { - x: 0, - y: 0, - z: 0, - w: 1 - }, - scale: { - x: 1, - y: 1, - z: 1 - } - } - }, - { - name: 'gltf-model', - props: { - src: modelLink, - generateBVH: false, - avoidCameraOcclusion: false - } - } - ], - parent: 'root' - }, - child_1: { - name: 'Child 1', - components: [ - { - name: 'transform', - props: { - position: { - x: 1, - y: 0, - z: 0 - }, - rotation: { - x: 0, - y: 0, - z: 0, - w: 1 - }, - scale: { - x: 1, - y: 1, - z: 1 - } - } - } - ], - parent: 'child_0' - }, - child_2: { - name: 'Child 2', - components: [ - { - name: 'transform', - props: { - position: { - x: 0, - y: 1, - z: 0 - }, - rotation: { - x: 0, - y: 0, - z: 0, - w: 1 - }, - scale: { - x: 1, - y: 1, - z: 1 - } - } - } - ], - parent: 'child_1' - }, - child_3: { - name: 'Child 3', - components: [ - { - name: 'transform', - props: { - position: { - x: 0, - y: 0, - z: 1 - }, - rotation: { - x: 0, - y: 0, - z: 0, - w: 1 - }, - scale: { - x: 1, - y: 1, - z: 1 - } - } - } - ], - parent: 'child_2' - }, - child_4: { - name: 'Child 4', - components: [ - { - name: 'transform', - props: { - position: { - x: 2, - y: 0, - z: 0 - }, - rotation: { - x: 0, - y: 0, - z: 0, - w: 1 - }, - scale: { - x: 1, - y: 1, - z: 1 - } - } - } - ], - parent: 'child_3' - }, - child_5: { - name: 'Child 5', - components: [ - { - name: 'transform', - props: { - position: { - x: 0, - y: 2, - z: 0 - }, - rotation: { - x: 0, - y: 0, - z: 0, - w: 1 - }, - scale: { - x: 1, - y: 1, - z: 1 - } - } - } - ], - parent: 'child_4' - }, - child_2_1: { - name: 'Child 2 _ 1', - components: [ - { - name: 'transform', - props: { - position: { - x: 0, - y: 0, - z: 2 - }, - rotation: { - x: 0, - y: 0, - z: 0, - w: 1 - }, - scale: { - x: 1, - y: 1, - z: 1 - } - } - }, - { - name: 'fog', - props: { - type: 'linear', - color: '#FFFFFF', - density: 0.005, - near: 1, - far: 1000, - timeScale: 1, - height: 0.05 - } - } - ], - parent: 'child_2' - } - }, - root: 'root' as EntityUUID, - version: 0 - } as SceneJsonType + scene: testSceneJson as unknown as SceneJsonType } as SceneDataType const testID = 'test' as SceneID diff --git a/packages/engine/tests/assets/SceneLoadingTest.scene.json b/packages/engine/tests/assets/SceneLoadingTest.scene.json new file mode 100644 index 00000000000..2ace7057e13 --- /dev/null +++ b/packages/engine/tests/assets/SceneLoadingTest.scene.json @@ -0,0 +1,105 @@ +{ + "version": 0, + "entities": { + "root": { + "name": "Root", + "components": [] + }, + "child_0": { + "name": "Child 0", + "components": [ + { + "name": "transform", + "props": { + "position": { "x": 0, "y": 0, "z": 0 }, + "rotation": { "x": 0, "y": 0, "z": 0, "w": 1 }, + "scale": { "x": 1, "y": 1, "z": 1 } + } + }, + { + "name": "gltf-model", + "props": { + "src": "/packages/projects/default-project/assets/collisioncube.glb", + "generateBVH": false, + "avoidCameraOcclusion": false + } + } + ], + "parent": "root" + }, + "child_1": { + "name": "Child 1", + "components": [ + { + "name": "transform", + "props": { "position": { "x": 1, "y": 0, "z": 0 }, "rotation": { "x": 0, "y": 0, "z": 0, "w": 1 }, "scale": { "x": 1, "y": 1, "z": 1 } } + } + ], + "parent": "child_0" + }, + "child_2": { + "name": "Child 2", + "components": [ + { + "name": "transform", + "props": { "position": { "x": 0, "y": 1, "z": 0 }, "rotation": { "x": 0, "y": 0, "z": 0, "w": 1 }, "scale": { "x": 1, "y": 1, "z": 1 } } + } + ], + "parent": "child_1" + }, + "child_3": { + "name": "Child 3", + "components": [ + { + "name": "transform", + "props": { "position": { "x": 0, "y": 0, "z": 1 }, "rotation": { "x": 0, "y": 0, "z": 0, "w": 1 }, "scale": { "x": 1, "y": 1, "z": 1 } } + } + ], + "parent": "child_2" + }, + "child_4": { + "name": "Child 4", + "components": [ + { + "name": "transform", + "props": { "position": { "x": 2, "y": 0, "z": 0 }, "rotation": { "x": 0, "y": 0, "z": 0, "w": 1 }, "scale": { "x": 1, "y": 1, "z": 1 } } + } + ], + "parent": "child_3" + }, + "child_5": { + "name": "Child 5", + "components": [ + { + "name": "transform", + "props": { "position": { "x": 0, "y": 2, "z": 0 }, "rotation": { "x": 0, "y": 0, "z": 0, "w": 1 }, "scale": { "x": 1, "y": 1, "z": 1 } } + } + ], + "parent": "child_4" + }, + "child_2_1": { + "name": "Child 2 _ 1", + "components": [ + { + "name": "transform", + "props": { "position": { "x": 0, "y": 0, "z": 2 }, "rotation": { "x": 0, "y": 0, "z": 0, "w": 1 }, "scale": { "x": 1, "y": 1, "z": 1 } + } + }, + { + "name": "fog", + "props": { + "type": "linear", + "color": "#FFFFFF", + "density": 0.005, + "near": 1, + "far": 1000, + "timeScale": 1, + "height": 0.05 + } + } + ], + "parent": "child_2" + } + }, + "root": "root" +} From 023a718a197ae2fafdbfc710a9325dae9fa435cb Mon Sep 17 00:00:00 2001 From: sybiote Date: Thu, 28 Dec 2023 06:38:58 +0530 Subject: [PATCH 15/15] updated tests to latest dev --- .../functions/EditorControlFunctions.test.tsx | 68 ++++++----- .../scene/systems/SceneLoadingSystem.test.tsx | 109 ++++++++++-------- 2 files changed, 96 insertions(+), 81 deletions(-) diff --git a/packages/editor/src/functions/EditorControlFunctions.test.tsx b/packages/editor/src/functions/EditorControlFunctions.test.tsx index dae0fe3a80b..8a625fc39f4 100644 --- a/packages/editor/src/functions/EditorControlFunctions.test.tsx +++ b/packages/editor/src/functions/EditorControlFunctions.test.tsx @@ -25,10 +25,11 @@ Ethereal Engine. All Rights Reserved. import assert from 'assert' +import { EntityUUID } from '@etherealengine/common/src/interfaces/EntityUUID' import { EventDispatcher } from '@etherealengine/engine/src/common/classes/EventDispatcher' import { destroyEngine, Engine } from '@etherealengine/engine/src/ecs/classes/Engine' import { EngineState } from '@etherealengine/engine/src/ecs/classes/EngineState' -import { Entity } from '@etherealengine/engine/src/ecs/classes/Entity' +import { Entity, UndefinedEntity } from '@etherealengine/engine/src/ecs/classes/Entity' import { SceneSnapshotSystem, SceneState } from '@etherealengine/engine/src/ecs/classes/Scene' import { getComponent, hasComponent } from '@etherealengine/engine/src/ecs/functions/ComponentFunctions' import { EntityTreeComponent } from '@etherealengine/engine/src/ecs/functions/EntityTree' @@ -42,7 +43,7 @@ import { FogType } from '@etherealengine/engine/src/scene/constants/FogType' import { SceneLoadingSystem } from '@etherealengine/engine/src/scene/SceneModule' import { SceneDataType, SceneID, SceneJsonType } from '@etherealengine/engine/src/schemas/projects/scene.schema' import { UserID } from '@etherealengine/engine/src/schemas/user/user.schema' -import { LocalTransformComponent } from '@etherealengine/engine/src/transform/components/TransformComponent' +import { TransformComponent } from '@etherealengine/engine/src/transform/components/TransformComponent' import testSceneJson from '@etherealengine/engine/tests/assets/SceneLoadingTest.scene.json' import { applyIncomingActions, getMutableState } from '@etherealengine/hyperflux' import { act, render } from '@testing-library/react' @@ -110,7 +111,7 @@ describe('EditorControlFunctions', () => { 'root entity does not have parentEntity' ) - const child2_1Entity = UUIDComponent.entitiesByUUID['child_2_1'] + const child2_1Entity = UUIDComponent.getEntityByUUID('child_2_1' as EntityUUID) assert(child2_1Entity, 'child_0 entity not found') assert.equal( hasComponent(child2_1Entity, EntityTreeComponent), @@ -170,7 +171,7 @@ describe('EditorControlFunctions', () => { 'root entity does not have parentEntity' ) - const child0Entity = UUIDComponent.entitiesByUUID['child_0'] + const child0Entity = UUIDComponent.getEntityByUUID('child_0' as EntityUUID) assert(child0Entity, 'child_0 entity not found') assert.equal( hasComponent(child0Entity, EntityTreeComponent), @@ -220,7 +221,7 @@ describe('EditorControlFunctions', () => { 'root entity does not have parentEntity' ) - const child0Entity = UUIDComponent.entitiesByUUID['child_0'] + const child0Entity = UUIDComponent.getEntityByUUID('child_0' as EntityUUID) assert(child0Entity, 'child_0 entity not found') assert.equal( hasComponent(child0Entity, EntityTreeComponent), @@ -233,8 +234,8 @@ describe('EditorControlFunctions', () => { 'child_0 entity does not have parentEntity as root entity' ) - const child2Entity = UUIDComponent.entitiesByUUID['child_2'] - const child2_1Entity = UUIDComponent.entitiesByUUID['child_2_1'] + const child2Entity = UUIDComponent.getEntityByUUID('child_2' as EntityUUID) + const child2_1Entity = UUIDComponent.getEntityByUUID('child_2_1' as EntityUUID) assert(child2_1Entity, 'child_2_1 entity not found') assert.equal( hasComponent(child2_1Entity, EntityTreeComponent), @@ -248,7 +249,7 @@ describe('EditorControlFunctions', () => { ) EditorControlFunctions.createObjectFromSceneElement( - [{ name: ShadowComponent.jsonID }, { name: LocalTransformComponent.jsonID }], + [{ name: ShadowComponent.jsonID }, { name: TransformComponent.jsonID }], child2_1Entity ) applyIncomingActions() @@ -258,7 +259,7 @@ describe('EditorControlFunctions', () => { assert(getComponent(child2_1Entity, EntityTreeComponent).children.length > 0) const entity = getComponent(child2_1Entity, EntityTreeComponent).children[0] assert(hasComponent(entity, ShadowComponent), 'created entity does not have ShadowComponent') - assert(hasComponent(entity, LocalTransformComponent), 'created entity does not have LocalTransformComponent') + assert(hasComponent(entity, TransformComponent), 'created entity does not have LocalTransformComponent') unmount() }) @@ -276,7 +277,7 @@ describe('EditorControlFunctions', () => { 'root entity does not have parentEntity' ) - const child0Entity = UUIDComponent.entitiesByUUID['child_0'] + const child0Entity = UUIDComponent.getEntityByUUID('child_0' as EntityUUID) assert(child0Entity, 'child_0 entity not found') assert.equal( hasComponent(child0Entity, EntityTreeComponent), @@ -289,7 +290,7 @@ describe('EditorControlFunctions', () => { 'child_0 entity does not have parentEntity as root entity' ) - const child2Entity = UUIDComponent.entitiesByUUID['child_2'] + const child2Entity = UUIDComponent.getEntityByUUID('child_2' as EntityUUID) assert(child2Entity, 'child_2 entity not found') assert.equal( hasComponent(child2Entity, EntityTreeComponent), @@ -298,7 +299,7 @@ describe('EditorControlFunctions', () => { ) const child2Children = getComponent(child2Entity, EntityTreeComponent).children - const child3Entity = UUIDComponent.entitiesByUUID['child_3'] + const child3Entity = UUIDComponent.getEntityByUUID('child_3' as EntityUUID) assert(child3Entity, 'child_3 entity not found') assert.equal( hasComponent(child3Entity, EntityTreeComponent), @@ -311,7 +312,7 @@ describe('EditorControlFunctions', () => { 'child_3 entity does not have parentEntity as child_2 entity' ) - const child2_1Entity = UUIDComponent.entitiesByUUID['child_2_1'] + const child2_1Entity = UUIDComponent.getEntityByUUID('child_2_1' as EntityUUID) assert(child2_1Entity, 'child_2_1 entity not found') assert.equal( hasComponent(child2_1Entity, EntityTreeComponent), @@ -356,7 +357,7 @@ describe('EditorControlFunctions', () => { 'root entity does not have parentEntity' ) - const child0Entity = UUIDComponent.entitiesByUUID['child_0'] + const child0Entity = UUIDComponent.getEntityByUUID('child_0' as EntityUUID) assert(child0Entity, 'child_0 entity not found') assert.equal( hasComponent(child0Entity, EntityTreeComponent), @@ -369,8 +370,8 @@ describe('EditorControlFunctions', () => { 'child_0 entity does not have parentEntity as root entity' ) - const child2Entity = UUIDComponent.entitiesByUUID['child_2'] - const child2_1Entity = UUIDComponent.entitiesByUUID['child_2_1'] + const child2Entity = UUIDComponent.getEntityByUUID('child_2' as EntityUUID) + const child2_1Entity = UUIDComponent.getEntityByUUID('child_2_1' as EntityUUID) assert(child2_1Entity, 'child_2_1 entity not found') assert.equal( hasComponent(child2_1Entity, EntityTreeComponent), @@ -384,7 +385,7 @@ describe('EditorControlFunctions', () => { ) EditorControlFunctions.createObjectFromSceneElement( - [{ name: ShadowComponent.jsonID }, { name: LocalTransformComponent.jsonID }], + [{ name: ShadowComponent.jsonID }, { name: TransformComponent.jsonID }], child2_1Entity ) applyIncomingActions() @@ -395,7 +396,7 @@ describe('EditorControlFunctions', () => { ] EditorControlFunctions.createObjectFromSceneElement( - [{ name: ShadowComponent.jsonID }, { name: LocalTransformComponent.jsonID }], + [{ name: ShadowComponent.jsonID }, { name: TransformComponent.jsonID }], child2_1Entity ) applyIncomingActions() @@ -406,7 +407,7 @@ describe('EditorControlFunctions', () => { ] EditorControlFunctions.createObjectFromSceneElement( - [{ name: ShadowComponent.jsonID }, { name: LocalTransformComponent.jsonID }], + [{ name: ShadowComponent.jsonID }, { name: TransformComponent.jsonID }], child2_1Entity ) applyIncomingActions() @@ -452,7 +453,7 @@ describe('EditorControlFunctions', () => { 'root entity does not have parentEntity' ) - const child0Entity = UUIDComponent.entitiesByUUID['child_0'] + const child0Entity = UUIDComponent.getEntityByUUID('child_0' as EntityUUID) assert(child0Entity, 'child_0 entity not found') assert.equal( hasComponent(child0Entity, EntityTreeComponent), @@ -465,7 +466,7 @@ describe('EditorControlFunctions', () => { 'child_0 entity does not have parentEntity as root entity' ) - const child1Entity = UUIDComponent.entitiesByUUID['child_1'] + const child1Entity = UUIDComponent.getEntityByUUID('child_1' as EntityUUID) assert(child1Entity, 'child_1 entity not found') assert.equal( hasComponent(child1Entity, EntityTreeComponent), @@ -478,7 +479,7 @@ describe('EditorControlFunctions', () => { 'child_1 entity does not have parentEntity as child_0 entity' ) - const child2Entity = UUIDComponent.entitiesByUUID['child_2'] + const child2Entity = UUIDComponent.getEntityByUUID('child_2' as EntityUUID) assert(child2Entity, 'child_2 entity not found') assert.equal( hasComponent(child2Entity, EntityTreeComponent), @@ -491,7 +492,7 @@ describe('EditorControlFunctions', () => { 'child_2 entity does not have parentEntity as child_1 entity' ) - const child3Entity = UUIDComponent.entitiesByUUID['child_3'] + const child3Entity = UUIDComponent.getEntityByUUID('child_3' as EntityUUID) assert(child3Entity, 'child_3 entity not found') assert.equal( hasComponent(child3Entity, EntityTreeComponent), @@ -504,7 +505,7 @@ describe('EditorControlFunctions', () => { 'child_3 entity does not have parentEntity as child_2 entity' ) - const child4Entity = UUIDComponent.entitiesByUUID['child_4'] + const child4Entity = UUIDComponent.getEntityByUUID('child_4' as EntityUUID) assert(child4Entity, 'child_4 entity not found') assert.equal( hasComponent(child4Entity, EntityTreeComponent), @@ -517,7 +518,7 @@ describe('EditorControlFunctions', () => { 'child_4 entity does not have parentEntity as child_3 entity' ) - const child5Entity = UUIDComponent.entitiesByUUID['child_5'] + const child5Entity = UUIDComponent.getEntityByUUID('child_5' as EntityUUID) assert(child5Entity, 'child_5 entity not found') assert.equal( hasComponent(child5Entity, EntityTreeComponent), @@ -530,7 +531,7 @@ describe('EditorControlFunctions', () => { 'child_5 entity does not have parentEntity as child_4 entity' ) - const child2_1Entity = UUIDComponent.entitiesByUUID['child_2_1'] + const child2_1Entity = UUIDComponent.getEntityByUUID('child_2_1' as EntityUUID) assert(child2_1Entity, 'child_2_1 entity not found') assert.equal( hasComponent(child2_1Entity, EntityTreeComponent), @@ -542,17 +543,20 @@ describe('EditorControlFunctions', () => { child2Entity, 'child_2_1 entity does not have parentEntity as child_2 entity' ) - const originalEntities = Object.values(UUIDComponent.entitiesByUUID) + const originalEntitiesUUID = Object.keys(UUIDComponent.entitiesByUUIDState).map((x) => x as EntityUUID) const nodes = [child1Entity, child2Entity, child3Entity, child4Entity, child5Entity] EditorControlFunctions.groupObjects(nodes) applyIncomingActions() SystemDefinitions.get(SceneSnapshotSystem)!.execute() await act(() => rerender(loadTag)) // reload scene after snapshot - const newEntites = Object.values(UUIDComponent.entitiesByUUID) - const groupEntity = newEntites.filter((x) => !originalEntities.includes(x))[0] - assert(groupEntity, 'new entity not found') - assert(hasComponent(groupEntity, EntityTreeComponent)) + const newEntitesUUID = Object.keys(UUIDComponent.entitiesByUUIDState).map((x) => x as EntityUUID) + + const groupEntity = UUIDComponent.getEntityByUUID( + newEntitesUUID.filter((x) => !originalEntitiesUUID.includes(x))[0] + ) + assert(groupEntity !== UndefinedEntity, 'new entity not found') + assert(hasComponent(groupEntity as Entity, EntityTreeComponent)) const newGroupChldren = getComponent(groupEntity, EntityTreeComponent).children assert(newGroupChldren.length > 4) for (const node of newGroupChldren) { @@ -584,7 +588,7 @@ describe('EditorControlFunctions', () => { 'root entity does not have parentEntity' ) - const child0Entity = UUIDComponent.entitiesByUUID['child_0'] + const child0Entity = UUIDComponent.getEntityByUUID('child_0' as EntityUUID) assert(child0Entity, 'child_0 entity not found') assert.equal( hasComponent(child0Entity, EntityTreeComponent), diff --git a/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx b/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx index 67881c54901..e0e5ea8af94 100644 --- a/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx +++ b/packages/engine/src/scene/systems/SceneLoadingSystem.test.tsx @@ -23,6 +23,7 @@ All portions of the code written by the Ethereal Engine team are Copyright © 20 Ethereal Engine. All Rights Reserved. */ +import { EntityUUID } from '@etherealengine/common/src/interfaces/EntityUUID' import { applyIncomingActions, dispatchAction, getMutableState, getState } from '@etherealengine/hyperflux' import { act, render, waitFor } from '@testing-library/react' import assert from 'assert' @@ -33,6 +34,7 @@ import { overrideFileLoaderLoad } from '../../../tests/util/loadGLTFAssetNode' import { EventDispatcher } from '../../common/classes/EventDispatcher' import { Engine, destroyEngine } from '../../ecs/classes/Engine' import { EngineState } from '../../ecs/classes/EngineState' +import { UndefinedEntity } from '../../ecs/classes/Entity' import { SceneSnapshotAction, SceneSnapshotSystem, SceneState } from '../../ecs/classes/Scene' import { defineQuery, getComponent, hasComponent } from '../../ecs/functions/ComponentFunctions' import { EntityTreeComponent } from '../../ecs/functions/EntityTree' @@ -108,7 +110,7 @@ describe('SceneLoadingSystem', () => { 'root entity does not have parentEntity' ) - const child0Entity = UUIDComponent.entitiesByUUID['child_0'] + const child0Entity = UUIDComponent.getEntityByUUID('child_0' as EntityUUID) assert(child0Entity, 'child_0 entity not found') assert.equal( hasComponent(child0Entity, EntityTreeComponent), @@ -121,7 +123,7 @@ describe('SceneLoadingSystem', () => { 'child_0 entity does not have parentEntity as root entity' ) - const child1Entity = UUIDComponent.entitiesByUUID['child_1'] + const child1Entity = UUIDComponent.getEntityByUUID('child_1' as EntityUUID) assert(child1Entity, 'child_1 entity not found') assert.equal( hasComponent(child1Entity, EntityTreeComponent), @@ -134,7 +136,7 @@ describe('SceneLoadingSystem', () => { 'child_1 entity does not have parentEntity as child_0 entity' ) - const child2Entity = UUIDComponent.entitiesByUUID['child_2'] + const child2Entity = UUIDComponent.getEntityByUUID('child_2' as EntityUUID) assert(child2Entity, 'child_2 entity not found') assert.equal( hasComponent(child2Entity, EntityTreeComponent), @@ -147,7 +149,7 @@ describe('SceneLoadingSystem', () => { 'child_2 entity does not have parentEntity as child_1 entity' ) - const child3Entity = UUIDComponent.entitiesByUUID['child_3'] + const child3Entity = UUIDComponent.getEntityByUUID('child_3' as EntityUUID) assert(child3Entity, 'child_3 entity not found') assert.equal( hasComponent(child3Entity, EntityTreeComponent), @@ -160,7 +162,7 @@ describe('SceneLoadingSystem', () => { 'child_3 entity does not have parentEntity as child_2 entity' ) - const child4Entity = UUIDComponent.entitiesByUUID['child_4'] + const child4Entity = UUIDComponent.getEntityByUUID('child_4' as EntityUUID) assert(child4Entity, 'child_4 entity not found') assert.equal( hasComponent(child4Entity, EntityTreeComponent), @@ -173,7 +175,7 @@ describe('SceneLoadingSystem', () => { 'child_4 entity does not have parentEntity as child_3 entity' ) - const child5Entity = UUIDComponent.entitiesByUUID['child_5'] + const child5Entity = UUIDComponent.getEntityByUUID('child_5' as EntityUUID) assert(child5Entity, 'child_5 entity not found') assert.equal( hasComponent(child5Entity, EntityTreeComponent), @@ -186,7 +188,7 @@ describe('SceneLoadingSystem', () => { 'child_5 entity does not have parentEntity as child_4 entity' ) - const child2_1Entity = UUIDComponent.entitiesByUUID['child_2_1'] + const child2_1Entity = UUIDComponent.getEntityByUUID('child_2_1' as EntityUUID) assert(child2_1Entity, 'child_2_1 entity not found') assert.equal( hasComponent(child2_1Entity, EntityTreeComponent), @@ -229,7 +231,7 @@ describe('SceneLoadingSystem', () => { 'root entity does not have parentEntity' ) - const child2_1Entity = UUIDComponent.entitiesByUUID['child_2_1'] + const child2_1Entity = UUIDComponent.getEntityByUUID('child_2_1' as EntityUUID) assert(child2_1Entity, 'child_2_1 entity not found') assert.equal( hasComponent(child2_1Entity, EntityTreeComponent), @@ -290,7 +292,7 @@ describe('SceneLoadingSystem', () => { 'root entity does not have parentEntity' ) - const child0Entity = UUIDComponent.entitiesByUUID['child_0'] + const child0Entity = UUIDComponent.getEntityByUUID('child_0' as EntityUUID) assert(child0Entity, 'child_0 entity not found') assert.equal( hasComponent(child0Entity, EntityTreeComponent), @@ -304,8 +306,9 @@ describe('SceneLoadingSystem', () => { ) // check for failure to load - const child1Entity = UUIDComponent.entitiesByUUID['child_1'] - assert.equal(child1Entity, undefined, 'child_1 entity found') + const child1Entity = UUIDComponent.getEntityByUUID('child_1' as EntityUUID) + console.log('DEBUG', child1Entity) + assert.equal(child1Entity, UndefinedEntity, 'child_1 entity found') testScene.scene.entities['child_0'].components = testScene.scene.entities['child_0'].components.filter( (component) => component.name !== 'dynamic-load' ) @@ -355,7 +358,7 @@ describe('SceneLoadingSystem', () => { 'root entity does not have parentEntity' ) - const child0Entity = UUIDComponent.entitiesByUUID['child_0'] + const child0Entity = UUIDComponent.getEntityByUUID('child_0' as EntityUUID) assert(child0Entity, 'child_0 entity not found') assert.equal( hasComponent(child0Entity, EntityTreeComponent), @@ -368,7 +371,7 @@ describe('SceneLoadingSystem', () => { 'child_0 entity does not have parentEntity as root entity' ) - const child1Entity = UUIDComponent.entitiesByUUID['child_1'] + const child1Entity = UUIDComponent.getEntityByUUID('child_1' as EntityUUID) assert(child1Entity, 'child_1 entity not found') assert.equal( hasComponent(child1Entity, EntityTreeComponent), @@ -381,7 +384,7 @@ describe('SceneLoadingSystem', () => { 'child_1 entity does not have parentEntity as child_0 entity' ) - const child2Entity = UUIDComponent.entitiesByUUID['child_2'] + const child2Entity = UUIDComponent.getEntityByUUID('child_2' as EntityUUID) assert(child2Entity, 'child_2 entity not found') assert.equal( hasComponent(child2Entity, EntityTreeComponent), @@ -394,7 +397,7 @@ describe('SceneLoadingSystem', () => { 'child_2 entity does not have parentEntity as child_1 entity' ) - const child3Entity = UUIDComponent.entitiesByUUID['child_3'] + const child3Entity = UUIDComponent.getEntityByUUID('child_3' as EntityUUID) assert(child3Entity, 'child_3 entity not found') assert.equal( hasComponent(child3Entity, EntityTreeComponent), @@ -407,7 +410,7 @@ describe('SceneLoadingSystem', () => { 'child_3 entity does not have parentEntity as child_2 entity' ) - const child4Entity = UUIDComponent.entitiesByUUID['child_4'] + const child4Entity = UUIDComponent.getEntityByUUID('child_4' as EntityUUID) assert(child4Entity, 'child_4 entity not found') assert.equal( hasComponent(child4Entity, EntityTreeComponent), @@ -420,7 +423,7 @@ describe('SceneLoadingSystem', () => { 'child_4 entity does not have parentEntity as child_3 entity' ) - const child5Entity = UUIDComponent.entitiesByUUID['child_5'] + const child5Entity = UUIDComponent.getEntityByUUID('child_5' as EntityUUID) assert(child5Entity, 'child_5 entity not found') assert.equal( hasComponent(child5Entity, EntityTreeComponent), @@ -433,7 +436,7 @@ describe('SceneLoadingSystem', () => { 'child_5 entity does not have parentEntity as child_4 entity' ) - const child2_1Entity = UUIDComponent.entitiesByUUID['child_2_1'] + const child2_1Entity = UUIDComponent.getEntityByUUID('child_2_1' as EntityUUID) assert(child2_1Entity, 'child_2_1 entity not found') assert.equal( hasComponent(child2_1Entity, EntityTreeComponent), @@ -478,7 +481,7 @@ describe('SceneLoadingSystem', () => { ) // load scene with model component - const child0Entity = UUIDComponent.entitiesByUUID['child_0'] + const child0Entity = UUIDComponent.getEntityByUUID('child_0' as EntityUUID) assert(child0Entity, 'child_0 entity not found') assert.equal( @@ -595,7 +598,7 @@ describe('SceneLoadingSystem', () => { 'root entity does not have parentEntity' ) - const child0Entity = UUIDComponent.entitiesByUUID['child_0'] + const child0Entity = UUIDComponent.getEntityByUUID('child_0' as EntityUUID) assert(child0Entity, 'child_0 entity not found') assert.equal( hasComponent(child0Entity, EntityTreeComponent), @@ -608,7 +611,7 @@ describe('SceneLoadingSystem', () => { 'child_0 entity does not have parentEntity as root entity' ) - const child1Entity = UUIDComponent.entitiesByUUID['child_1'] + const child1Entity = UUIDComponent.getEntityByUUID('child_1' as EntityUUID) assert(child1Entity, 'child_1 entity not found') assert.equal( hasComponent(child1Entity, EntityTreeComponent), @@ -621,7 +624,7 @@ describe('SceneLoadingSystem', () => { 'child_1 entity does not have parentEntity as child_0 entity' ) - const child2Entity = UUIDComponent.entitiesByUUID['child_2'] + const child2Entity = UUIDComponent.getEntityByUUID('child_2' as EntityUUID) assert(child2Entity, 'child_2 entity not found') assert.equal( hasComponent(child2Entity, EntityTreeComponent), @@ -634,7 +637,7 @@ describe('SceneLoadingSystem', () => { 'child_2 entity does not have parentEntity as child_1 entity' ) - const child3Entity = UUIDComponent.entitiesByUUID['child_3'] + const child3Entity = UUIDComponent.getEntityByUUID('child_3' as EntityUUID) assert(child3Entity, 'child_3 entity not found') assert.equal( hasComponent(child3Entity, EntityTreeComponent), @@ -647,7 +650,7 @@ describe('SceneLoadingSystem', () => { 'child_3 entity does not have parentEntity as child_2 entity' ) - const child4Entity = UUIDComponent.entitiesByUUID['child_4'] + const child4Entity = UUIDComponent.getEntityByUUID('child_4' as EntityUUID) assert(child4Entity, 'child_4 entity not found') assert.equal( hasComponent(child4Entity, EntityTreeComponent), @@ -660,7 +663,7 @@ describe('SceneLoadingSystem', () => { 'child_4 entity does not have parentEntity as child_3 entity' ) - const child5Entity = UUIDComponent.entitiesByUUID['child_5'] + const child5Entity = UUIDComponent.getEntityByUUID('child_5' as EntityUUID) assert(child5Entity, 'child_5 entity not found') assert.equal( hasComponent(child5Entity, EntityTreeComponent), @@ -673,7 +676,7 @@ describe('SceneLoadingSystem', () => { 'child_5 entity does not have parentEntity as child_4 entity' ) - const child2_1Entity = UUIDComponent.entitiesByUUID['child_2_1'] + const child2_1Entity = UUIDComponent.getEntityByUUID('child_2_1' as EntityUUID) assert(child2_1Entity, 'child_2_1 entity not found') assert.equal( hasComponent(child2_1Entity, EntityTreeComponent), @@ -748,7 +751,7 @@ describe('Snapshots', () => { 'root entity does not have parentEntity' ) - const child0Entity = UUIDComponent.entitiesByUUID['child_0'] + const child0Entity = UUIDComponent.getEntityByUUID('child_0' as EntityUUID) assert(child0Entity, 'child_0 entity not found') assert.equal( hasComponent(child0Entity, EntityTreeComponent), @@ -761,7 +764,7 @@ describe('Snapshots', () => { 'child_0 entity does not have parentEntity as root entity' ) - const child1Entity = UUIDComponent.entitiesByUUID['child_1'] + const child1Entity = UUIDComponent.getEntityByUUID('child_1' as EntityUUID) assert(child1Entity, 'child_1 entity not found') assert.equal( hasComponent(child1Entity, EntityTreeComponent), @@ -774,7 +777,7 @@ describe('Snapshots', () => { 'child_1 entity does not have parentEntity as child_0 entity' ) - const child2Entity = UUIDComponent.entitiesByUUID['child_2'] + const child2Entity = UUIDComponent.getEntityByUUID('child_2' as EntityUUID) assert(child2Entity, 'child_2 entity not found') assert.equal( hasComponent(child2Entity, EntityTreeComponent), @@ -787,7 +790,7 @@ describe('Snapshots', () => { 'child_2 entity does not have parentEntity as child_1 entity' ) - const child3Entity = UUIDComponent.entitiesByUUID['child_3'] + const child3Entity = UUIDComponent.getEntityByUUID('child_3' as EntityUUID) assert(child3Entity, 'child_3 entity not found') assert.equal( hasComponent(child3Entity, EntityTreeComponent), @@ -800,7 +803,7 @@ describe('Snapshots', () => { 'child_3 entity does not have parentEntity as child_2 entity' ) - const child4Entity = UUIDComponent.entitiesByUUID['child_4'] + const child4Entity = UUIDComponent.getEntityByUUID('child_4' as EntityUUID) assert(child4Entity, 'child_4 entity not found') assert.equal( hasComponent(child4Entity, EntityTreeComponent), @@ -813,7 +816,7 @@ describe('Snapshots', () => { 'child_4 entity does not have parentEntity as child_3 entity' ) - const child5Entity = UUIDComponent.entitiesByUUID['child_5'] + const child5Entity = UUIDComponent.getEntityByUUID('child_5' as EntityUUID) assert(child5Entity, 'child_5 entity not found') assert.equal( hasComponent(child5Entity, EntityTreeComponent), @@ -826,7 +829,7 @@ describe('Snapshots', () => { 'child_5 entity does not have parentEntity as child_4 entity' ) - const child2_1Entity = UUIDComponent.entitiesByUUID['child_2_1'] + const child2_1Entity = UUIDComponent.getEntityByUUID('child_2_1' as EntityUUID) assert(child2_1Entity, 'child_2_1 entity not found') assert.equal( hasComponent(child2_1Entity, EntityTreeComponent), @@ -890,7 +893,7 @@ describe('Snapshots', () => { 'root entity does not have parentEntity' ) - const child0Entity = UUIDComponent.entitiesByUUID['child_0'] + const child0Entity = UUIDComponent.getEntityByUUID('child_0' as EntityUUID) assert(child0Entity, 'child_0 entity not found') assert.equal( hasComponent(child0Entity, EntityTreeComponent), @@ -903,7 +906,7 @@ describe('Snapshots', () => { 'child_0 entity does not have parentEntity as root entity' ) - const child1Entity = UUIDComponent.entitiesByUUID['child_1'] + const child1Entity = UUIDComponent.getEntityByUUID('child_1' as EntityUUID) assert(child1Entity, 'child_1 entity not found') assert.equal( hasComponent(child1Entity, EntityTreeComponent), @@ -916,7 +919,7 @@ describe('Snapshots', () => { 'child_1 entity does not have parentEntity as child_0 entity' ) - const child2Entity = UUIDComponent.entitiesByUUID['child_2'] + const child2Entity = UUIDComponent.getEntityByUUID('child_2' as EntityUUID) assert(child2Entity, 'child_2 entity not found') assert.equal( hasComponent(child2Entity, EntityTreeComponent), @@ -929,7 +932,7 @@ describe('Snapshots', () => { 'child_2 entity does not have parentEntity as child_1 entity' ) - const child3Entity = UUIDComponent.entitiesByUUID['child_3'] + const child3Entity = UUIDComponent.getEntityByUUID('child_3' as EntityUUID) assert(child3Entity, 'child_3 entity not found') assert.equal( hasComponent(child3Entity, EntityTreeComponent), @@ -942,7 +945,7 @@ describe('Snapshots', () => { 'child_3 entity does not have parentEntity as child_2 entity' ) - const child4Entity = UUIDComponent.entitiesByUUID['child_4'] + const child4Entity = UUIDComponent.getEntityByUUID('child_4' as EntityUUID) assert(child4Entity, 'child_4 entity not found') assert.equal( hasComponent(child4Entity, EntityTreeComponent), @@ -955,7 +958,7 @@ describe('Snapshots', () => { 'child_4 entity does not have parentEntity as child_3 entity' ) - const child5Entity = UUIDComponent.entitiesByUUID['child_5'] + const child5Entity = UUIDComponent.getEntityByUUID('child_5' as EntityUUID) assert(child5Entity, 'child_5 entity not found') assert.equal( hasComponent(child5Entity, EntityTreeComponent), @@ -968,7 +971,7 @@ describe('Snapshots', () => { 'child_5 entity does not have parentEntity as child_4 entity' ) - const child2_1Entity = UUIDComponent.entitiesByUUID['child_2_1'] + const child2_1Entity = UUIDComponent.getEntityByUUID('child_2_1' as EntityUUID) assert(child2_1Entity, 'child_2_1 entity not found') assert.equal( hasComponent(child2_1Entity, EntityTreeComponent), @@ -986,7 +989,11 @@ describe('Snapshots', () => { SystemDefinitions.get(SceneSnapshotSystem)!.execute() await act(() => rerender(tag)) // reload scene after snapshot - assert.equal(UUIDComponent.entitiesByUUID['child_2_1'], undefined, 'snapshot unchanged, entity was not deleted') + assert.equal( + UUIDComponent.getEntityByUUID('child_2_1' as EntityUUID), + UndefinedEntity, + 'snapshot unchanged, entity was not deleted' + ) dispatchAction(SceneSnapshotAction.undo({ count: 1, sceneID: getState(SceneState).activeScene! })) applyIncomingActions() @@ -1027,7 +1034,7 @@ describe('Snapshots', () => { 'root entity does not have parentEntity' ) - const child0Entity = UUIDComponent.entitiesByUUID['child_0'] + const child0Entity = UUIDComponent.getEntityByUUID('child_0' as EntityUUID) assert(child0Entity, 'child_0 entity not found') assert.equal( hasComponent(child0Entity, EntityTreeComponent), @@ -1040,7 +1047,7 @@ describe('Snapshots', () => { 'child_0 entity does not have parentEntity as root entity' ) - const child1Entity = UUIDComponent.entitiesByUUID['child_1'] + const child1Entity = UUIDComponent.getEntityByUUID('child_1' as EntityUUID) assert(child1Entity, 'child_1 entity not found') assert.equal( hasComponent(child1Entity, EntityTreeComponent), @@ -1053,7 +1060,7 @@ describe('Snapshots', () => { 'child_1 entity does not have parentEntity as child_0 entity' ) - const child2Entity = UUIDComponent.entitiesByUUID['child_2'] + const child2Entity = UUIDComponent.getEntityByUUID('child_2' as EntityUUID) assert(child2Entity, 'child_2 entity not found') assert.equal( hasComponent(child2Entity, EntityTreeComponent), @@ -1066,7 +1073,7 @@ describe('Snapshots', () => { 'child_2 entity does not have parentEntity as child_1 entity' ) - const child3Entity = UUIDComponent.entitiesByUUID['child_3'] + const child3Entity = UUIDComponent.getEntityByUUID('child_3' as EntityUUID) assert(child3Entity, 'child_3 entity not found') assert.equal( hasComponent(child3Entity, EntityTreeComponent), @@ -1079,7 +1086,7 @@ describe('Snapshots', () => { 'child_3 entity does not have parentEntity as child_2 entity' ) - const child4Entity = UUIDComponent.entitiesByUUID['child_4'] + const child4Entity = UUIDComponent.getEntityByUUID('child_4' as EntityUUID) assert(child4Entity, 'child_4 entity not found') assert.equal( hasComponent(child4Entity, EntityTreeComponent), @@ -1092,7 +1099,7 @@ describe('Snapshots', () => { 'child_4 entity does not have parentEntity as child_3 entity' ) - const child5Entity = UUIDComponent.entitiesByUUID['child_5'] + const child5Entity = UUIDComponent.getEntityByUUID('child_5' as EntityUUID) assert(child5Entity, 'child_5 entity not found') assert.equal( hasComponent(child5Entity, EntityTreeComponent), @@ -1105,7 +1112,7 @@ describe('Snapshots', () => { 'child_5 entity does not have parentEntity as child_4 entity' ) - const child2_1Entity = UUIDComponent.entitiesByUUID['child_2_1'] + const child2_1Entity = UUIDComponent.getEntityByUUID('child_2_1' as EntityUUID) assert(child2_1Entity, 'child_2_1 entity not found') assert.equal( hasComponent(child2_1Entity, EntityTreeComponent), @@ -1127,7 +1134,11 @@ describe('Snapshots', () => { // wait somehow const newSnap = SceneState.cloneCurrentSnapshot(getState(SceneState).activeScene!) - assert.equal(UUIDComponent.entitiesByUUID['child_2_1'], undefined, 'snapshot unchanged entity not deleted') + assert.equal( + UUIDComponent.getEntityByUUID('child_2_1' as EntityUUID), + UndefinedEntity, + 'snapshot unchanged entity not deleted' + ) dispatchAction(SceneSnapshotAction.undo({ count: 1, sceneID: getState(SceneState).activeScene! })) applyIncomingActions()