]> git.r.bdr.sh - rbdr/serpentity/blobdiff - test/integration.js
Make node components event emitters
[rbdr/serpentity] / test / integration.js
index 872c54b674696d0970339764a96ba2bae6a85944..d87474250f6b1e414615a27653341da9f51d543d 100644 (file)
@@ -1,4 +1,4 @@
-import { describe, it, beforeEach } from 'node:test';
+import { describe, it, beforeEach, mock } from 'node:test';
 import assert from 'node:assert';
 import Serpentity, { Component, Entity, Node, System } from '../lib/serpentity.js';
 
 import assert from 'node:assert';
 import Serpentity, { Component, Entity, Node, System } from '../lib/serpentity.js';
 
@@ -10,14 +10,51 @@ const internals = {
       this.testNodes = engine.getNodes(internals.node);
       this.addedCalled = true;
       this.addedEngine = engine;
       this.testNodes = engine.getNodes(internals.node);
       this.addedCalled = true;
       this.addedEngine = engine;
+      this.emittedEvents = [];
+      this.beforeCall = null;
+      this.afterCall = null;
+
+      this.changeObserver = (event) => {
+          this.emittedEvents.push(event)
+      };
+
+      this.nodeAddedObserver = ({ node }) => {
+        node.test.addEventListener('change', this.changeObserver);
+      };
+
+      this.nodeRemovedObserver = ({ node }) => {
+        node.test.removeEventListener('change', this.changeObserver);
+      };
+
+      for (const node of this.testNodes) {
+        node.test.addEventListener('change', this.changeObserver);
+      }
+
+      this.testNodes.addEventListener('nodeAdded', this.nodeAddedObserver);
+      this.testNodes.addEventListener('nodeRemoved', this.nodeRemovedObserver);
+
       super.added(); // not needed, but takes care of coverage :P
     }
 
     removed(engine) {
 
       super.added(); // not needed, but takes care of coverage :P
     }
 
     removed(engine) {
 
+      this.testNodes.removeEventListener('nodeAdded', this.nodeAddedObserver);
+      this.nodeAddedObserver = null;
+
+      this.testNodes.removeEventListener('nodeRemoved', this.nodeRemovedObserver);
+      this.nodeRemovedObserver = null;
+
+      for (const node of this.testNodes) {
+        node.test.removeEventListener('change', this.changeObserver);
+      }
+      this.changeObserver = null;
+
       this.testNodes = null;
       this.removedCalled = true;
       this.removedEngine = engine;
       this.testNodes = null;
       this.removedCalled = true;
       this.removedEngine = engine;
+      this.emittedEvents = null;
+      this.beforeCall = null;
+      this.afterCall = null;
       super.removed(); // not needed, but takes care of coverage :P
     }
 
       super.removed(); // not needed, but takes care of coverage :P
     }
 
@@ -27,7 +64,9 @@ const internals = {
       this.updateDt = dt;
 
       for (const node of this.testNodes) {
       this.updateDt = dt;
 
       for (const node of this.testNodes) {
+        this.beforeCall = this.beforeCall === null ? node.test.called : this.beforeCall;
         node.test.called = true;
         node.test.called = true;
+        this.afterCall = this.afterCall === null ? node.test.called : this.afterCall;
         node.entity.called = true;
       }
 
         node.entity.called = true;
       }
 
@@ -145,6 +184,25 @@ describe('Engine', () => {
     assert(!!internals.context.lowPrioritySystem.updateCalled);
   });
 
     assert(!!internals.context.lowPrioritySystem.updateCalled);
   });
 
+  it('should keep proxied object behavior as expected', () => {
+
+    internals.context.engine.update(internals.delta);
+
+    assert(internals.context.highPrioritySystem.beforeCall === false);
+    assert(internals.context.highPrioritySystem.afterCall === true);
+  });
+
+  it('should emit an event for every changed property', () => {
+
+    internals.context.engine.update(internals.delta);
+
+    assert(internals.context.regularSystem.emittedEvents[0].property === 'called');
+    assert(internals.context.regularSystem.emittedEvents[0].from === false);
+    assert(internals.context.regularSystem.emittedEvents[0].to === true);
+    // 3 systems x 2 entities.
+    assert(internals.context.regularSystem.emittedEvents.length === 6);
+  });
+
   it('should call update callback in the order of priorities', () => {
 
     internals.context.engine.update(internals.delta);
   it('should call update callback in the order of priorities', () => {
 
     internals.context.engine.update(internals.delta);
@@ -272,4 +330,15 @@ describe('Engine', () => {
     assert(!internals.context.firstEntity.called);
     assert(!!internals.context.secondEntity.called);
   });
     assert(!internals.context.firstEntity.called);
     assert(!!internals.context.secondEntity.called);
   });
+
+  it('should not add duplicate entities', () => {
+
+    const originalEntitiesLength = internals.context.engine.entities.length;
+    const added = internals.context.engine.addEntity(internals.context.firstEntity);
+    const finalEntitiesLength = internals.context.engine.entities.length;
+
+    assert(!added);
+
+    assert.deepEqual(finalEntitiesLength, originalEntitiesLength);
+  });
 });
 });