]>
git.r.bdr.sh - rbdr/serpentity/blob - test/integration.js
3 const Code
= require('code'); // assertion library
4 const Lab
= require('lab');
5 const Serpentity
= require('..');
8 system: class TestSystem
extends Serpentity
.System
{
11 this.testNodes
= engine
.getNodes(internals
.node
);
12 this.addedCalled
= true;
13 this.addedEngine
= engine
;
18 this.testNodes
= null;
19 this.removedCalled
= true;
20 this.removedEngine
= engine
;
25 this.updateCalled
= Date
.now();
28 for (const node
of this.testNodes
) {
29 node
.test
.called
= true;
30 node
.entity
.called
= true;
33 while (Date
.now() === this.updateCalled
) { /* pass some time */ }
36 component: class TestComponent
extends Serpentity
.Component
{
44 node: class TestNode
extends Serpentity
.Node
{},
48 // adds a component to the node
49 internals
.node
.types
= {
50 test: internals
.component
53 const lab
= exports
.lab
= Lab
.script();
55 lab
.experiment('loading', () => {
57 lab
.test('Serpentity should be exported', (done
) => {
59 Code
.expect(typeof Serpentity
).to
.not
.be
.undefined();
63 lab
.test('Serpentity should include the Entity class', (done
) => {
65 Code
.expect(typeof Serpentity
.Entity
).to
.not
.be
.undefined();
69 lab
.test('Serpentity should include the Component class', (done
) => {
71 Code
.expect(typeof Serpentity
.Component
).to
.not
.be
.undefined();
75 lab
.test('Serpentity should include the System class', (done
) => {
77 Code
.expect(typeof Serpentity
.System
).to
.not
.be
.undefined();
81 lab
.test('Serpentity should include the Node class', (done
) => {
83 Code
.expect(typeof Serpentity
.Node
).to
.not
.be
.undefined();
87 lab
.test('Serpentity should include the NodeCollection class', (done
) => {
89 Code
.expect(typeof Serpentity
.NodeCollection
).to
.not
.be
.undefined();
94 lab
.experiment('Engine Tests', () => {
96 lab
.beforeEach((done
) => {
98 this.engine
= new Serpentity();
100 this.regularSystem
= new internals
.system();
101 this.highPrioritySystem
= new internals
.system();
102 this.lowPrioritySystem
= new internals
.system();
104 this.firstEntity
= new Serpentity
.Entity();
105 this.firstEntity
.addComponent(new internals
.component());
106 this.secondEntity
= new Serpentity
.Entity();
107 this.secondEntity
.addComponent(new internals
.component());
108 this.emptyEntity
= new Serpentity
.Entity();
110 // Add entity before the systems
111 this.engine
.addEntity(this.firstEntity
);
113 this.engine
.addSystem(this.regularSystem
, 100);
114 this.engine
.addSystem(this.highPrioritySystem
, 0);
115 this.engine
.addSystem(this.lowPrioritySystem
, 1000);
117 // Add entity after the systems
118 this.engine
.addEntity(this.secondEntity
);
119 this.engine
.addEntity(this.emptyEntity
);
124 lab
.test('Engine should call added callback on added systems', (done
) => {
126 // Ensure the added callback is being called
127 Code
.expect(this.regularSystem
.addedCalled
).to
.be
.true();
128 Code
.expect(this.highPrioritySystem
.addedCalled
).to
.be
.true();
129 Code
.expect(this.lowPrioritySystem
.addedCalled
).to
.be
.true();
134 lab
.test('Engine should send the engine instance in added callback', (done
) => {
136 // Ensure the added callback is sending the engine
137 Code
.expect(this.regularSystem
.addedEngine
instanceof Serpentity
).to
.be
.true();
138 Code
.expect(this.highPrioritySystem
.addedEngine
instanceof Serpentity
).to
.be
.true();
139 Code
.expect(this.lowPrioritySystem
.addedEngine
instanceof Serpentity
).to
.be
.true();
144 lab
.test('Engine should not add duplicate systems', (done
) => {
146 const originalSystemsLength
= this.engine
.systems
.length
;
147 const added
= this.engine
.addSystem(this.regularSystem
, 0);
148 const newSystemsLength
= this.engine
.systems
.length
;
150 // Ensure we don't add the same system twice
151 Code
.expect(added
).to
.be
.false();
152 Code
.expect(originalSystemsLength
).to
.be
.equal(newSystemsLength
);
157 lab
.test('Engine should call update callback on added systems', (done
) => {
159 this.engine
.update(internals
.delta
);
161 // Ensure update function called
162 Code
.expect(!!this.regularSystem
.updateCalled
).to
.be
.true();
163 Code
.expect(!!this.highPrioritySystem
.updateCalled
).to
.be
.true();
164 Code
.expect(!!this.lowPrioritySystem
.updateCalled
).to
.be
.true();
169 lab
.test('Engine should call update callback in the order of priorities', (done
) => {
171 this.engine
.update(internals
.delta
);
173 // Ensure order of priorities
174 Code
.expect(this.regularSystem
.updateCalled
).to
.be
.lessThan(this.lowPrioritySystem
.updateCalled
);
175 Code
.expect(this.regularSystem
.updateCalled
).to
.be
.greaterThan(this.highPrioritySystem
.updateCalled
);
180 lab
.test('Engine should send the delta in the update callback', (done
) => {
182 this.engine
.update(internals
.delta
);
184 // Ensure delta is being sent
185 Code
.expect(this.regularSystem
.updateDt
).to
.be
.equal(internals
.delta
);
186 Code
.expect(this.highPrioritySystem
.updateDt
).to
.be
.equal(internals
.delta
);
187 Code
.expect(this.lowPrioritySystem
.updateDt
).to
.be
.equal(internals
.delta
);
192 lab
.test('System remove callback', (done
) => {
194 const originalSystemLength
= this.engine
.systems
.length
;
195 const originalRemoved
= this.engine
.removeSystem(this.lowPrioritySystem
);
196 const intermediateSystemLength
= this.engine
.systems
.length
;
197 const finalRemoved
= this.engine
.removeSystem(this.lowPrioritySystem
);
198 const finalSystemLength
= this.engine
.systems
.length
;
199 this.engine
.update(internals
.delta
);
201 // Check for return value
202 Code
.expect(originalRemoved
).to
.be
.true();
203 Code
.expect(finalRemoved
).to
.be
.false();
205 // Confirm that only removed if found by checking length of systems
207 Code
.expect(originalSystemLength
).to
.be
.above(intermediateSystemLength
);
208 Code
.expect(finalSystemLength
).to
.be
.equal(intermediateSystemLength
);
210 // Ensure callback is sent
211 Code
.expect(!!this.regularSystem
.removedCalled
).to
.be
.false();
212 Code
.expect(!!this.highPrioritySystem
.removedCalled
).to
.be
.false();
213 Code
.expect(!!this.lowPrioritySystem
.removedCalled
).to
.be
.true();
215 // Ensure update is no longer sent
216 Code
.expect(!!this.regularSystem
.updateCalled
).to
.be
.true();
217 Code
.expect(!!this.highPrioritySystem
.updateCalled
).to
.be
.true();
218 Code
.expect(!!this.lowPrioritySystem
.updateCalled
).to
.be
.false();
223 lab
.test('Entity node selection', (done
) => {
225 this.engine
.update(internals
.delta
);
227 // Ensure component is called for each entity
228 Code
.expect(!!this.firstEntity
._components
[0].called
).to
.be
.true();
229 Code
.expect(!!this.secondEntity
._components
[0].called
).to
.be
.true();
231 // Ensure entity not in node collection not called
232 Code
.expect(!!this.firstEntity
.called
).to
.be
.true();
233 Code
.expect(!!this.secondEntity
.called
).to
.be
.true();
234 Code
.expect(!!this.emptyEntity
.called
).to
.be
.false();
239 lab
.test('Entity node removal', (done
) => {
241 this.engine
.removeEntity(this.secondEntity
);
242 this.engine
.update(internals
.delta
);
244 Code
.expect(!!this.firstEntity
._components
[0].called
).to
.be
.true();
245 Code
.expect(!!this.secondEntity
._components
[0].called
).to
.be
.false();
247 Code
.expect(!!this.firstEntity
.called
).to
.be
.true();
248 Code
.expect(!!this.secondEntity
.called
).to
.be
.false();
249 Code
.expect(!!this.emptyEntity
.called
).to
.be
.false();
254 lab
.test('Entity should not add duplicate components', (done
) => {
255 const originalComponentsLength
= this.secondEntity
._components
.length
;
256 const result
= this.secondEntity
.addComponent(new internals
.component());
257 const newComponentsLength
= this.secondEntity
._components
.length
;
259 Code
.expect(result
).to
.be
.false();
260 Code
.expect(originalComponentsLength
).to
.be
.equal(newComponentsLength
);
265 lab
.test('Entity should allow access to components by class', (done
) => {
266 const firstComponent
= this.firstEntity
.getComponent(internals
.component
);
267 const emptyComponent
= this.emptyEntity
.getComponent(internals
.component
);
269 Code
.expect(firstComponent
instanceof internals
.component
).to
.be
.true();
270 Code
.expect(emptyComponent
).to
.be
.equal(undefined);
275 lab
.test('Engine should not add duplicate entities', (done
) => {
276 const originalEntitiesLength
= this.engine
.entities
.length
;
277 const added
= this.engine
.addEntity(this.firstEntity
);
278 const finalEntitiesLength
= this.engine
.entities
.length
;
280 Code
.expect(added
).to
.be
.false();
282 Code
.expect(originalEntitiesLength
).to
.be
.equal(finalEntitiesLength
);
286 lab
.test('Engine should remove entities', (done
) => {
288 const originalEntityLength
= this.engine
.entities
.length
;
289 const originalRemoved
= this.engine
.removeEntity(this.firstEntity
);
290 const intermediateEntityLength
= this.engine
.entities
.length
;
291 const finalRemoved
= this.engine
.removeEntity(this.firstEntity
);
292 const finalEntityLength
= this.engine
.entities
.length
;
293 this.engine
.update(internals
.delta
);
295 // Check for return value
296 Code
.expect(originalRemoved
).to
.be
.true();
297 Code
.expect(finalRemoved
).to
.be
.false();
299 // Confirm that only removed if found by checking length of systems
301 Code
.expect(originalEntityLength
).to
.be
.above(intermediateEntityLength
);
302 Code
.expect(finalEntityLength
).to
.be
.equal(intermediateEntityLength
);
304 // Ensure callback is sent
305 Code
.expect(!!this.firstEntity
.called
).to
.be
.false();
306 Code
.expect(!!this.secondEntity
.called
).to
.be
.true();