Skip to content
This repository was archived by the owner on Aug 21, 2024. It is now read-only.

Commit 0f8ebec

Browse files
authored
[IR-2055] Unit Test - Camera (#10247)
* tst: Add `CameraSystem.test.tsx` stub file * chg: Remove `deprecated` tag from System.reactor (as per request) * tst: UnitTest skeleton for `CameraEntityState` with event sourcing * tst: Fix `CameraComponent` assert on the wrong entity * tst: Renamed the `CameraEntityState` to be more descriptive * tst: Unit Tests for `SpectateEntityState` from `SpectateSystem.tsx`
1 parent 47995c6 commit 0f8ebec

3 files changed

Lines changed: 268 additions & 1 deletion

File tree

packages/ecs/src/SystemFunctions.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ export interface System {
6262
* Defaults to 'variable'.
6363
*/
6464
timeStep: number | 'variable'
65-
/** @deprecated use defineState reactor instead */
6665
reactor?: FC
6766
insert?: InsertSystem
6867
preSystems: SystemUUID[]
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/*
2+
CPAL-1.0 License
3+
4+
The contents of this file are subject to the Common Public Attribution License
5+
Version 1.0. (the "License"); you may not use this file except in compliance
6+
with the License. You may obtain a copy of the License at
7+
https://github.com/EtherealEngine/etherealengine/blob/dev/LICENSE.
8+
The License is based on the Mozilla Public License Version 1.1, but Sections 14
9+
and 15 have been added to cover use of software over a computer network and
10+
provide for limited attribution for the Original Developer. In addition,
11+
Exhibit A has been modified to be consistent with Exhibit B.
12+
13+
Software distributed under the License is distributed on an "AS IS" basis,
14+
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
15+
specific language governing rights and limitations under the License.
16+
17+
The Original Code is Ethereal Engine.
18+
19+
The Original Developer is the Initial Developer. The Initial Developer of the
20+
Original Code is the Ethereal Engine team.
21+
22+
All portions of the code written by the Ethereal Engine team are Copyright © 2021-2023
23+
Ethereal Engine. All Rights Reserved.
24+
*/
25+
26+
import { act, render } from '@testing-library/react'
27+
import assert from 'assert'
28+
import React from 'react'
29+
30+
import { NetworkId } from '@etherealengine/common/src/interfaces/NetworkId'
31+
import { UserID } from '@etherealengine/common/src/schema.type.module'
32+
import {
33+
Engine,
34+
SystemDefinitions,
35+
UUIDComponent,
36+
UndefinedEntity,
37+
createEntity,
38+
destroyEngine,
39+
getComponent,
40+
hasComponent,
41+
removeEntity,
42+
setComponent
43+
} from '@etherealengine/ecs'
44+
import { PeerID, applyIncomingActions, dispatchAction } from '@etherealengine/hyperflux'
45+
import {
46+
Network,
47+
NetworkPeerFunctions,
48+
NetworkState,
49+
NetworkTopics,
50+
NetworkWorldUserStateSystem
51+
} from '@etherealengine/network'
52+
import { createMockNetwork } from '../../../../network/tests/createMockNetwork'
53+
import { createEngine } from '../../initializeEngine'
54+
import { CameraActions } from '../CameraState'
55+
import { CameraComponent } from '../components/CameraComponent'
56+
57+
describe('CameraSystem', async () => {
58+
let viewerEntity = UndefinedEntity
59+
60+
describe('CameraEntityState', async () => {
61+
beforeEach(async () => {
62+
createEngine()
63+
createMockNetwork()
64+
Engine.instance.store.defaultDispatchDelay = () => 0
65+
viewerEntity = createEntity()
66+
setComponent(viewerEntity, UUIDComponent, UUIDComponent.generateUUID())
67+
})
68+
69+
afterEach(() => {
70+
removeEntity(viewerEntity)
71+
return destroyEngine()
72+
})
73+
74+
const NetworkWorldUserStateSystemReactor = SystemDefinitions.get(NetworkWorldUserStateSystem)!.reactor!
75+
const tag = <NetworkWorldUserStateSystemReactor />
76+
77+
it('should create a camera entity and apply a CameraComponent to that entity', async () => {
78+
const hostUserId = 'world' as UserID
79+
const userId = 'user id' as UserID
80+
const peerID = Engine.instance.store.peerID
81+
const peerID2 = 'peer id 2' as PeerID
82+
const CameraUUID = UUIDComponent.generateUUID()
83+
84+
Engine.instance.userID = userId
85+
const network: Network = NetworkState.worldNetwork
86+
87+
NetworkPeerFunctions.createPeer(network, peerID, 0, hostUserId, 0)
88+
NetworkPeerFunctions.createPeer(network, peerID2, 1, userId, 1)
89+
const objNetId = 3 as NetworkId
90+
91+
const { rerender, unmount } = render(tag)
92+
await act(() => rerender(tag))
93+
94+
dispatchAction(
95+
CameraActions.spawnCamera({
96+
parentUUID: getComponent(viewerEntity, UUIDComponent),
97+
entityUUID: CameraUUID,
98+
ownerID: network.hostUserID, // from host
99+
networkId: objNetId,
100+
$topic: NetworkTopics.world,
101+
$peer: Engine.instance.store.peerID
102+
})
103+
)
104+
applyIncomingActions()
105+
106+
const cameraEntity = UUIDComponent.getEntityByUUID(CameraUUID)
107+
assert.ok(cameraEntity, "The spawnCamera Action didn't create an entity.")
108+
assert.ok(
109+
hasComponent(cameraEntity, CameraComponent),
110+
"The spawnCamera Action didn't apply the CameraComponent to the entity"
111+
)
112+
113+
unmount()
114+
})
115+
})
116+
})
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
/*
2+
CPAL-1.0 License
3+
4+
The contents of this file are subject to the Common Public Attribution License
5+
Version 1.0. (the "License"); you may not use this file except in compliance
6+
with the License. You may obtain a copy of the License at
7+
https://github.com/EtherealEngine/etherealengine/blob/dev/LICENSE.
8+
The License is based on the Mozilla Public License Version 1.1, but Sections 14
9+
and 15 have been added to cover use of software over a computer network and
10+
provide for limited attribution for the Original Developer. In addition,
11+
Exhibit A has been modified to be consistent with Exhibit B.
12+
13+
Software distributed under the License is distributed on an "AS IS" basis,
14+
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
15+
specific language governing rights and limitations under the License.
16+
17+
The Original Code is Ethereal Engine.
18+
19+
The Original Developer is the Initial Developer. The Initial Developer of the
20+
Original Code is the Ethereal Engine team.
21+
22+
All portions of the code written by the Ethereal Engine team are Copyright © 2021-2023
23+
Ethereal Engine. All Rights Reserved.
24+
*/
25+
26+
import { act, render } from '@testing-library/react'
27+
import assert from 'assert'
28+
import React from 'react'
29+
30+
import { UserID } from '@etherealengine/common/src/schema.type.module'
31+
import {
32+
Engine,
33+
SystemDefinitions,
34+
UUIDComponent,
35+
UndefinedEntity,
36+
createEntity,
37+
destroyEngine,
38+
removeEntity,
39+
setComponent
40+
} from '@etherealengine/ecs'
41+
import { PeerID, applyIncomingActions, dispatchAction, getState } from '@etherealengine/hyperflux'
42+
import {
43+
Network,
44+
NetworkPeerFunctions,
45+
NetworkState,
46+
NetworkTopics,
47+
NetworkWorldUserStateSystem
48+
} from '@etherealengine/network'
49+
import { createMockNetwork } from '../../../../network/tests/createMockNetwork'
50+
import { createEngine } from '../../initializeEngine'
51+
import { SpectateActions, SpectateEntityState } from './SpectateSystem'
52+
53+
describe('SpectateSystem', async () => {
54+
let viewerEntity = UndefinedEntity
55+
56+
describe('SpectateEntityState', async () => {
57+
beforeEach(async () => {
58+
createEngine()
59+
createMockNetwork()
60+
Engine.instance.store.defaultDispatchDelay = () => 0
61+
viewerEntity = createEntity()
62+
setComponent(viewerEntity, UUIDComponent, UUIDComponent.generateUUID())
63+
})
64+
65+
afterEach(() => {
66+
removeEntity(viewerEntity)
67+
return destroyEngine()
68+
})
69+
70+
const NetworkWorldUserStateSystemReactor = SystemDefinitions.get(NetworkWorldUserStateSystem)!.reactor!
71+
const tag = <NetworkWorldUserStateSystemReactor />
72+
73+
it('should start spectating an entity when the `spectateEntity` action is dispatched', async () => {
74+
const hostUserId = 'world' as UserID
75+
const userId = 'user id' as UserID
76+
const peerID = Engine.instance.store.peerID
77+
const peerID2 = 'peer id 2' as PeerID
78+
const peerID3 = 'peer id 3' as PeerID
79+
const spectatorID = 'spectator id' as UserID
80+
81+
Engine.instance.userID = userId
82+
const network: Network = NetworkState.worldNetwork
83+
84+
NetworkPeerFunctions.createPeer(network, peerID, 0, hostUserId, 0)
85+
NetworkPeerFunctions.createPeer(network, peerID2, 1, userId, 1)
86+
NetworkPeerFunctions.createPeer(network, peerID3, 2, userId, 2)
87+
88+
const { rerender, unmount } = render(tag)
89+
await act(() => rerender(tag))
90+
91+
dispatchAction(
92+
SpectateActions.spectateEntity({
93+
spectatorUserID: spectatorID,
94+
spectatingUserID: userId,
95+
$topic: NetworkTopics.world,
96+
$peer: Engine.instance.store.peerID
97+
})
98+
)
99+
applyIncomingActions()
100+
const state = getState(SpectateEntityState)[spectatorID]
101+
assert.notEqual(state, undefined, "The spectator's SpectateEntityState should not be undefined after `getState`")
102+
assert.equal(state.spectating, userId, 'The spectator is not spectating the correct userID')
103+
104+
unmount()
105+
})
106+
107+
it('should stop spectating an entity when the `exitSpectate` action is dispatched', async () => {
108+
const hostUserId = 'world' as UserID
109+
const userId = 'user id' as UserID
110+
const peerID = Engine.instance.store.peerID
111+
const peerID2 = 'peer id 2' as PeerID
112+
const peerID3 = 'peer id 3' as PeerID
113+
const spectatorID = 'spectator id' as UserID
114+
115+
Engine.instance.userID = userId
116+
const network: Network = NetworkState.worldNetwork
117+
118+
NetworkPeerFunctions.createPeer(network, peerID, 0, hostUserId, 0)
119+
NetworkPeerFunctions.createPeer(network, peerID2, 1, userId, 1)
120+
NetworkPeerFunctions.createPeer(network, peerID3, 2, userId, 2)
121+
122+
const { rerender, unmount } = render(tag)
123+
await act(() => rerender(tag))
124+
125+
dispatchAction(
126+
SpectateActions.spectateEntity({
127+
spectatorUserID: spectatorID,
128+
spectatingUserID: userId,
129+
$topic: NetworkTopics.world,
130+
$peer: Engine.instance.store.peerID
131+
})
132+
)
133+
applyIncomingActions()
134+
const before = getState(SpectateEntityState)[spectatorID]
135+
assert.notEqual(before, undefined, "The spectator's SpectateEntityState should not be undefined after `getState`")
136+
assert.equal(before.spectating, userId, 'The spectator is not spectating the correct userID')
137+
138+
dispatchAction(
139+
SpectateActions.exitSpectate({
140+
spectatorUserID: spectatorID,
141+
$topic: NetworkTopics.world,
142+
$peer: Engine.instance.store.peerID
143+
})
144+
)
145+
applyIncomingActions()
146+
const after = getState(SpectateEntityState)[spectatorID]
147+
assert.equal(after, undefined, "The spectator's SpectateEntityState should be undefined after exitSpectate")
148+
149+
unmount()
150+
})
151+
})
152+
})

0 commit comments

Comments
 (0)