Newer
Older
reroad-test / 2020-ryusei / aframe-master / tests / components / vive-controls.test.js
@ryusei ryusei on 22 Oct 2020 11 KB パノラマ表示
/* global assert, process, setup, suite, test, THREE */
var entityFactory = require('../helpers').entityFactory;

suite('vive-controls', function () {
  var component;
  var controlsSystem;
  var el;

  setup(function (done) {
    el = entityFactory();
    el.addEventListener('componentinitialized', function (evt) {
      if (evt.detail.name !== 'vive-controls') { return; }
      component = el.components['vive-controls'];
      component.controllersWhenPresent = [
        {id: 'OpenVR Gamepad', index: 0, hand: 'right', pose: {}}
      ];
      controlsSystem = el.sceneEl.systems['tracked-controls-webvr'];
      done();
    });
    el.setAttribute('vive-controls', 'hand: right; model: false');  // To ensure index = 0.
  });

  suite('checkIfControllerPresent', function () {
    test('remember not present if no controllers on first call', function () {
      var addEventListenersSpy = this.sinon.spy(component, 'addEventListeners');
      var injectTrackedControlsSpy = this.sinon.spy(component, 'injectTrackedControls');
      controlsSystem.controllers = [];

      // Mock not looked before.
      component.controllerPresent = false;

      component.checkIfControllerPresent();

      assert.notOk(injectTrackedControlsSpy.called);
      assert.notOk(addEventListenersSpy.called);
      assert.strictEqual(component.controllerPresent, false);  // Not undefined.
    });

    test('does not remove event listeners if no controllers again', function () {
      var addEventListenersSpy = this.sinon.spy(component, 'addEventListeners');
      var injectTrackedControlsSpy = this.sinon.spy(component, 'injectTrackedControls');
      var removeEventListenersSpy = this.sinon.spy(component, 'removeEventListeners');
      controlsSystem.controllers = [];

      // Mock not looked before.
      component.controllerPresent = false;

      component.checkIfControllerPresent();

      assert.notOk(injectTrackedControlsSpy.called);
      assert.notOk(addEventListenersSpy.called);
      assert.notOk(removeEventListenersSpy.called);
      assert.strictEqual(component.controllerPresent, false);  // Not undefined.
    });

    test('attaches events if controller is newly present', function () {
      var addEventListenersSpy = this.sinon.spy(component, 'addEventListeners');
      var injectTrackedControlsSpy = this.sinon.spy(component, 'injectTrackedControls');
      var removeEventListenersSpy = this.sinon.spy(component, 'removeEventListeners');
      controlsSystem.controllers = component.controllersWhenPresent;

      // Mock not looked before.
      component.controllerPresent = false;

      component.checkIfControllerPresent();

      assert.ok(injectTrackedControlsSpy.called);
      assert.ok(addEventListenersSpy.called);
      assert.notOk(removeEventListenersSpy.called);
      assert.ok(component.controllerPresent);
    });

    test('does not inject/attach events again if controller is already present', function () {
      var addEventListenersSpy = this.sinon.spy(component, 'addEventListeners');
      var injectTrackedControlsSpy = this.sinon.spy(component, 'injectTrackedControls');
      var removeEventListenersSpy = this.sinon.spy(component, 'removeEventListeners');
      controlsSystem.controllers = component.controllersWhenPresent;

      // Mock looked before.
      component.controllerEventsActive = true;
      component.controllerPresent = true;

      component.checkIfControllerPresent();

      assert.notOk(injectTrackedControlsSpy.called);
      assert.notOk(addEventListenersSpy.called);
      assert.notOk(removeEventListenersSpy.called);
      assert.ok(component.controllerPresent);
    });

    test('remove event listeners if controller disappears', function () {
      var addEventListenersSpy = this.sinon.spy(component, 'addEventListeners');
      var injectTrackedControlsSpy = this.sinon.spy(component, 'injectTrackedControls');
      var removeEventListenersSpy = this.sinon.spy(component, 'removeEventListeners');
      controlsSystem.controllers = [];

      // Mock looked before.
      component.controllerEventsActive = true;
      component.controllerPresent = true;

      component.checkIfControllerPresent();

      assert.notOk(injectTrackedControlsSpy.called);
      assert.notOk(addEventListenersSpy.called);
      assert.ok(removeEventListenersSpy.called);
      assert.notOk(component.controllerPresent);
    });
  });

  suite('axismove', function () {
    test('emits trackpadmoved on axismove', function (done) {
      controlsSystem.controllers = component.controllersWhenPresent;

      component.checkIfControllerPresent();

      // Install event handler listening for trackpad.
      el.addEventListener('trackpadmoved', function (evt) {
        assert.equal(evt.detail.x, 0.1);
        assert.equal(evt.detail.y, 0.2);
        assert.ok(evt.detail);
        done();
      });

      // Emit axismove.
      el.emit('axismove', {axis: [0.1, 0.2], changed: [true, false]});
    });

    test('does not emit trackpadmoved on axismove with no changes', function (done) {
      controlsSystem.controllers = component.controllersWhenPresent;
      component.checkIfControllerPresent();

      // Install event handler listening for trackpadmoved.
      el.addEventListener('trackpadmoved', function (evt) {
        assert.notOk(evt.detail);
      });

      // Emit axismove.
      el.emit('axismove', {axis: [0.1, 0.2], changed: [false, false]});

      setTimeout(function () { done(); });
    });
  });

  suite('buttonchanged', function () {
    // Generate 3 tests for each button. Verify that it fires up/down/changed for all remapped buttons.
    [ { button: 'trackpad', id: 0 },
      { button: 'trigger', id: 1 },
      { button: 'grip', id: 2 },
      { button: 'menu', id: 3 },
      { button: 'system', id: 4 }
    ].forEach(function (buttonDescription) {
      test('emits ' + buttonDescription.button + 'changed on buttonchanged', function (done) {
        controlsSystem.controllers = component.controllersWhenPresent;
        component.checkIfControllerPresent();
        el.addEventListener(buttonDescription.button + 'changed', function (evt) {
          assert.ok(evt.detail);
          done();
        });
        el.emit('buttonchanged', {id: buttonDescription.id, state: {value: 0.5, pressed: true, touched: true}});
      });

      test('emits ' + buttonDescription.button + 'down on buttondown', function (done) {
        controlsSystem.controllers = component.controllersWhenPresent;
        component.checkIfControllerPresent();
        el.addEventListener(buttonDescription.button + 'down', function (evt) {
          done();
        });
        el.emit('buttondown', {id: buttonDescription.id});
      });

      test('emits ' + buttonDescription.button + 'up on buttonup', function (done) {
        controlsSystem.controllers = component.controllersWhenPresent;
        component.checkIfControllerPresent();
        el.addEventListener(buttonDescription.button + 'up', function (evt) {
          done();
        });
        el.emit('buttonup', {id: buttonDescription.id});
      });
    });
  });

  suite('model', function () {
    test.skip('loads', function (done) {
      component.addEventListeners();
      el.addEventListener('model-loaded', function (evt) {
        assert.ok(component.buttonMeshes);
        assert.ok(component.buttonMeshes.trigger);
        assert.ok(el.getObject3D('mesh'));
        done();
      });
      component.data.model = true;
      component.injectTrackedControls();
    });
  });

  suite.skip('button colors', function () {
    test('has trigger at default color', function (done) {
      component.addEventListeners();
      el.addEventListener('model-loaded', function (evt) {
        var color = component.buttonMeshes.trigger.material.color;
        assert.equal(new THREE.Color(color).getHexString(), 'fafafa');
        done();
      });
      component.data.model = true;
      component.injectTrackedControls();
    });

    test('has trackpad at default color', function (done) {
      component.addEventListeners();
      el.addEventListener('model-loaded', function (evt) {
        var color = component.buttonMeshes.trackpad.material.color;
        assert.equal(new THREE.Color(color).getHexString(), 'fafafa');
        done();
      });
      component.data.model = true;
      component.injectTrackedControls();
    });

    test('has grips at default colors', function (done) {
      component.addEventListeners();
      el.addEventListener('model-loaded', function (evt) {
        var color = component.buttonMeshes.grip.left.material.color;
        assert.equal(new THREE.Color(color).getHexString(), 'fafafa');
        color = component.buttonMeshes.grip.right.material.color;
        assert.equal(new THREE.Color(color).getHexString(), 'fafafa');
        done();
      });
      component.data.model = true;
      component.injectTrackedControls();
    });

    test('sets trigger to highlight color when down', function (done) {
      component.addEventListeners();
      el.addEventListener('model-loaded', function (evt) {
        el.emit('buttondown', {id: 1, state: {}});
        setTimeout(() => {
          var color = component.buttonMeshes.trigger.material.color;
          assert.equal(new THREE.Color(color).getHexString(), '22d1ee');
          done();
        });
      });
      component.data.model = true;
      component.injectTrackedControls();
    });

    test('sets trigger back to default color when up', function (done) {
      component.addEventListeners();
      el.addEventListener('model-loaded', function (evt) {
        component.buttonMeshes.trigger.material.color.set('#22d1ee');
        el.emit('buttonup', {id: 1, state: {}});
        setTimeout(() => {
          var color = component.buttonMeshes.trigger.material.color;
          assert.equal(new THREE.Color(color).getHexString(), 'fafafa');
          done();
        });
      });
      component.data.model = true;
      component.injectTrackedControls();
    });

    test('sets trackpad to highlight color when down', function (done) {
      component.addEventListeners();
      el.addEventListener('model-loaded', function (evt) {
        el.emit('buttondown', {id: 0, state: {}});
        setTimeout(() => {
          var color = component.buttonMeshes.trackpad.material.color;
          assert.equal(new THREE.Color(color).getHexString(), '22d1ee');
          done();
        });
      });
      component.data.model = true;
      component.injectTrackedControls();
    });

    test('does not change color for trigger touch', function (done) {
      component.addEventListeners();
      el.addEventListener('model-loaded', function (evt) {
        el.emit('touchstart', {id: 1, state: {}});
        setTimeout(() => {
          var color = component.buttonMeshes.trigger.material.color;
          assert.equal(new THREE.Color(color).getHexString(), 'fafafa');
          done();
        });
      });
      component.data.model = true;
      component.injectTrackedControls();
    });

    test('does not change color for trackpad touch', function (done) {
      component.addEventListeners();
      el.addEventListener('model-loaded', function (evt) {
        el.emit('touchstart', {id: 0, state: {}});
        setTimeout(() => {
          var color = component.buttonMeshes.trackpad.material.color;
          assert.equal(new THREE.Color(color).getHexString(), 'fafafa');
          done();
        });
      });
      component.data.model = true;
      component.injectTrackedControls();
    });
  });

  suite('event listener', function () {
    test('toggles controllerEventsActive', function () {
      component.controllerEventsActive = false;
      component.addEventListeners();
      assert.ok(component.controllerEventsActive);
      component.removeEventListeners();
      assert.notOk(component.controllerEventsActive);
    });
  });
});