Browse Source

Single test for Base class complete.

duncan law 6 years ago
parent
commit
da057a717b

+ 144 - 0
src/Cameras/Inputs/MockCameraPointersInput.ts

@@ -0,0 +1,144 @@
+import { Nullable } from "../../types";
+import { Camera } from "../../Cameras/camera";
+import { CameraInputTypes } from "../../Cameras/cameraInputsManager";
+import { PointerTouch } from "../../Events/pointerEvents";
+import { BaseCameraPointersInput } from "../../Cameras/Inputs/BaseCameraPointersInput";
+
+/**
+ * Mock class to be used by UnitTests.
+ */
+export class MockCameraPointersInput extends BaseCameraPointersInput {
+  /**
+   * Defines the camera the input is attached to.
+   */
+  public camera: Camera;
+
+  /**
+   * Count how many times callback methods are called.
+   */
+  public countOnDoubleTap: number;
+  public countOnTouch: number;
+  public countOnMultiTouch: number;
+  public countOnContextMenu: number;
+  public countOnButtonDown: number;
+  public countOnButtonUp: number;
+  public countOnLostFocus: number;
+
+  /**
+   * Store arguments when callback methods are called.
+   */
+  public valuesOnDoubleTap: any[];
+  public valuesOnTouch: any[];
+  public valuesOnMultiTouch: any[];
+  public valuesOnContextMenu: any[];
+  public valuesOnButtonDown: any[];
+  public valuesOnButtonUp: any[];
+
+  public reset(): void {
+    this.countOnDoubleTap = 0;
+    this.countOnTouch = 0;
+    this.countOnMultiTouch = 0;
+    this.countOnContextMenu = 0;
+    this.countOnButtonDown = 0;
+    this.countOnButtonUp = 0;
+    this.countOnLostFocus = 0;
+
+    this.valuesOnDoubleTap = [];
+    this.valuesOnTouch = [];
+    this.valuesOnMultiTouch = [];
+    this.valuesOnContextMenu = [];
+    this.valuesOnButtonDown = [];
+    this.valuesOnButtonUp = [];
+  }
+
+  constructor() {
+    super();
+    this.reset();
+  }
+
+  /**
+   * The class name of the current input.
+   */
+  protected _className = "MockCameraPointersInput";
+
+  /**
+   * Called on pointer POINTERDOUBLETAP event.
+   * Override this method to provide functionality on POINTERDOUBLETAP event.
+   */
+  protected onDoubleTap(type: string) {
+    this.countOnDoubleTap++;
+    this.valuesOnDoubleTap.push(type);
+  }
+
+  /**
+   * Called on pointer POINTERMOVE event if only a single touch is active.
+   * Override this method to provide functionality.
+   */
+  protected onTouch(point: Nullable<PointerTouch>,
+    offsetX: number,
+    offsetY: number): void {
+      this.countOnTouch++;
+      this.valuesOnTouch.push([point, offsetX, offsetY]);
+    }
+
+  /**
+   * Called on pointer POINTERMOVE event if multiple touches are active.
+   * Override this method to provide functionality.
+   */
+  protected onMultiTouch(pointA: Nullable<PointerTouch>,
+    pointB: Nullable<PointerTouch>,
+    previousPinchSquaredDistance: number,
+    pinchSquaredDistance: number,
+    previousMultiTouchPanPosition: Nullable<PointerTouch>,
+    multiTouchPanPosition: Nullable<PointerTouch>): void {
+      this.countOnMultiTouch++;
+      this.valuesOnMultiTouch.push([
+        pointA,
+        pointB,
+        previousPinchSquaredDistance,
+        pinchSquaredDistance,
+        previousMultiTouchPanPosition,
+        multiTouchPanPosition,
+      ]);
+    }
+
+  /**
+   * Called on JS contextmenu event.
+   * Override this method to provide functionality.
+   */
+  protected onContextMenu(evt: PointerEvent): void {
+    evt.preventDefault();
+    this.countOnContextMenu++;
+    this.valuesOnContextMenu.push([evt,]);
+  }
+
+  /**
+   * Called each time a new POINTERDOWN event occurs. Ie, for each button
+   * press.
+   * Override this method to provide functionality.
+   */
+  protected onButtonDown(evt: PointerEvent, buttonCount: number): void {
+    this.countOnButtonDown++;
+    this.valuesOnButtonDown.push([evt, buttonCount]);
+  }
+
+  /**
+   * Called each time a new POINTERUP event occurs. Ie, for each button
+   * release.
+   * Override this method to provide functionality.
+   */
+  protected onButtonUp(evt: PointerEvent): void {
+    this.countOnButtonUp++;
+    this.valuesOnButtonUp.push([evt,]);
+  }
+
+  /**
+   * Called when window becomes inactive.
+   * Override this method to provide functionality.
+   */
+  protected onLostFocus(): void {
+    this.countOnLostFocus++;
+  }
+}
+(<any>CameraInputTypes)["MockCameraPointersInput"] = MockCameraPointersInput;
+

+ 1 - 0
src/Cameras/Inputs/index.ts

@@ -3,6 +3,7 @@ export * from "./arcRotateCameraKeyboardMoveInput";
 export * from "./arcRotateCameraMouseWheelInput";
 export * from "./arcRotateCameraPointersInput";
 export * from "./arcRotateCameraVRDeviceOrientationInput";
+export * from "./MockCameraPointersInput";
 export * from "./flyCameraKeyboardInput";
 export * from "./flyCameraMouseInput";
 export * from "./followCameraKeyboardMoveInput";

+ 160 - 56
tests/unit/babylon/src/Cameras/babylon.arcRotateInput.tests.ts

@@ -28,9 +28,165 @@ enum ValChange {
 }
 
 /**
+ * Make a mock Event.
+ * Many PointerEvent properties are read-only so using real "new PointerEvent()"
+ * is unpractical.
+ */
+function eventTemplate(target: HTMLElement): MockPointerEvent {
+  let returnVal = {
+    target,
+    button: 0,
+    preventDefault: () => {},
+  };
+  return returnVal;
+}
+
+/**
+ * Simulate PointerEvent in ArcRotateCameraPointersInput instance.
+ */
+function simulateEvent(cameraInput: BABYLON.ArcRotateCameraPointersInput,
+                       event: MockPointerEvent) {
+  console.log(event);
+  let pointerInfo = {};
+  switch (event.type) {
+    case "pointerdown":
+      pointerInfo = {type: BABYLON.PointerEventTypes.POINTERDOWN, event};
+      // Cast "camera" to <any> to relax "private" classification.
+      (<any>cameraInput)._pointerInput(pointerInfo, undefined);
+      break;
+    case "pointerup":
+      pointerInfo = {type: BABYLON.PointerEventTypes.POINTERUP, event};
+      // Cast "camera" to <any> to relax "private" classification.
+      (<any>cameraInput)._pointerInput(pointerInfo, undefined);
+      break;
+    case "pointermove":
+      pointerInfo = {type: BABYLON.PointerEventTypes.POINTERMOVE, event};
+      // Cast "camera" to <any> to relax "private" classification.
+      (<any>cameraInput)._pointerInput(pointerInfo, undefined);
+      break;
+    case "blur":
+      // Cast "camera" to <any> to relax "private" classification.
+      (<any>cameraInput)._onLostFocus();
+      break;
+    case "POINTERDOUBLETAP":
+      // Not a real DOM event. Just a shortcut to trigger
+      // PointerEventTypes.POINTERMOVE on the Input class.
+      pointerInfo = {type: BABYLON.PointerEventTypes.POINTERDOUBLETAP, event};
+      // Cast "camera" to <any> to relax "private" classification.
+      (<any>cameraInput)._pointerInput(pointerInfo, undefined);
+      break;
+    default:
+      console.error("Invalid pointer event: " + event.type);
+  }
+}
+
+/**
  * Test the things.
  */
-describe('arcRotateCameraInput', function() {
+describe('BaseRotateCameraInput', function() {
+  /**
+   * Sets the timeout of all the tests to 10 seconds.
+   */
+  this.timeout(10000);
+
+  before(function(done) {
+    // runs before all tests in this block
+    this.timeout(180000);
+    (BABYLONDEVTOOLS).Loader
+      .useDist()
+      .testMode()
+      .load(function() {
+        // Force apply promise polyfill for consistent behavior between
+        // PhantomJS, IE11, and other browsers.
+        BABYLON.PromisePolyfill.Apply(true);
+        done();
+      });
+
+    this._canvas = document.createElement("canvas");
+    this._engine = new BABYLON.NullEngine();
+    this._scene = new BABYLON.Scene(this._engine);
+    
+    // Set up an instance of a Camera with the ArcRotateCameraPointersInput.
+    this.camera = new BABYLON.ArcRotateCamera(
+      "MockCameraOriginal", 0, 0, 0, new BABYLON.Vector3(0, 0, 0), this._scene);
+    this.cameraInput = new BABYLON.MockCameraPointersInput();
+    this.cameraInput.camera = this.camera;
+    this.cameraInput.attachControl(this._canvas);
+  });
+
+  beforeEach(function() {
+    // runs before each test in this block
+    this.cameraInput.reset();
+  });
+
+  describe('one button drag', function() {
+    it('should call "onTouch method"', function() {
+      var event: MockPointerEvent = eventTemplate(<HTMLElement>this._canvas);
+
+      // Button down.
+      event.type = "pointerdown";
+      event.clientX = 100;
+      event.clientY = 200;
+      event.button = 0;
+      simulateEvent(this.cameraInput, event);
+      expect(this.cameraInput.countOnDoubleTap).to.equal(0);
+      expect(this.cameraInput.countOnTouch).to.equal(0);
+      expect(this.cameraInput.countOnMultiTouch).to.equal(0);
+      expect(this.cameraInput.countOnContextMenu).to.equal(0);
+      expect(this.cameraInput.countOnButtonDown).to.equal(1);
+      expect(this.cameraInput.countOnButtonUp).to.equal(0);
+      expect(this.cameraInput.countOnLostFocus).to.equal(0);
+      
+      // Start moving.
+      event.type = "pointermove";
+      event.button = 0;
+      simulateEvent(this.cameraInput, event);
+      expect(this.cameraInput.countOnDoubleTap).to.equal(0);
+      expect(this.cameraInput.countOnTouch).to.equal(1);
+      expect(this.cameraInput.countOnMultiTouch).to.equal(0);
+      expect(this.cameraInput.countOnContextMenu).to.equal(0);
+      expect(this.cameraInput.countOnButtonDown).to.equal(1);
+      expect(this.cameraInput.countOnButtonUp).to.equal(0);
+      expect(this.cameraInput.countOnLostFocus).to.equal(0);
+      // Move just started; No value yet.
+      expect(this.cameraInput.valuesOnTouch[0][1]).to.equal(0);
+      expect(this.cameraInput.valuesOnTouch[0][2]).to.equal(0);
+
+      // Drag.
+      event.type = "pointermove";
+      event.clientX = 1000;
+      event.button = 0;
+      simulateEvent(this.cameraInput, event);
+      expect(this.cameraInput.countOnDoubleTap).to.equal(0);
+      expect(this.cameraInput.countOnTouch).to.equal(2);
+      expect(this.cameraInput.countOnMultiTouch).to.equal(0);
+      expect(this.cameraInput.countOnContextMenu).to.equal(0);
+      expect(this.cameraInput.countOnButtonDown).to.equal(1);
+      expect(this.cameraInput.countOnButtonUp).to.equal(0);
+      expect(this.cameraInput.countOnLostFocus).to.equal(0);
+      // Pointer dragged in X direction.
+      expect(this.cameraInput.valuesOnTouch[1][1]).to.above(0);
+      expect(this.cameraInput.valuesOnTouch[1][2]).to.equal(0);
+
+      // Button up.
+      event.type = "pointerup";
+      event.button = 0;
+      simulateEvent(this.cameraInput, event);
+      expect(this.cameraInput.countOnDoubleTap).to.equal(0);
+      expect(this.cameraInput.countOnTouch).to.equal(2);
+      expect(this.cameraInput.countOnMultiTouch).to.equal(0);
+      expect(this.cameraInput.countOnContextMenu).to.equal(0);
+      expect(this.cameraInput.countOnButtonDown).to.equal(1);
+      expect(this.cameraInput.countOnButtonUp).to.equal(1);
+      expect(this.cameraInput.countOnLostFocus).to.equal(0);
+      // No more dragging.
+      expect(this.cameraInput.valuesOnTouch[0][1]).to.equal(0);
+      expect(this.cameraInput.valuesOnTouch[0][2]).to.equal(0);
+    });
+  });
+});
+
+describe.skip('ArcRotateCameraInput', function() {
   /**
    * Sets the timeout of all the tests to 10 seconds.
    */
@@ -104,59 +260,6 @@ describe('arcRotateCameraInput', function() {
     console.log(info);
   };
 
-  /**
-   * Make a mock Event.
-   * Many PointerEvent properties are read-only so using real "new PointerEvent()"
-   * is unpractical.
-   */
-  function eventTemplate(target: HTMLElement): MockPointerEvent {
-    let returnVal = {
-      target,
-      button: 0,
-      preventDefault: () => {},
-    };
-    return returnVal;
-  }
-
-  /**
-   * Simulate PointerEvent in ArcRotateCameraPointersInput instance.
-   */
-  function simulateEvent(cameraInput: BABYLON.ArcRotateCameraPointersInput,
-                         event: MockPointerEvent) {
-    console.log(event);
-    let pointerInfo = {};
-    switch (event.type) {
-      case "pointerdown":
-        pointerInfo = {type: BABYLON.PointerEventTypes.POINTERDOWN, event};
-        // Cast "camera" to <any> to relax "private" classification.
-        (<any>cameraInput)._pointerInput(pointerInfo, undefined);
-        break;
-      case "pointerup":
-        pointerInfo = {type: BABYLON.PointerEventTypes.POINTERUP, event};
-        // Cast "camera" to <any> to relax "private" classification.
-        (<any>cameraInput)._pointerInput(pointerInfo, undefined);
-        break;
-      case "pointermove":
-        pointerInfo = {type: BABYLON.PointerEventTypes.POINTERMOVE, event};
-        // Cast "camera" to <any> to relax "private" classification.
-        (<any>cameraInput)._pointerInput(pointerInfo, undefined);
-        break;
-      case "blur":
-        // Cast "camera" to <any> to relax "private" classification.
-        (<any>cameraInput)._onLostFocus();
-        break;
-      case "POINTERDOUBLETAP":
-        // Not a real DOM event. Just a shortcut to trigger
-        // PointerEventTypes.POINTERMOVE on the Input class.
-        pointerInfo = {type: BABYLON.PointerEventTypes.POINTERDOUBLETAP, event};
-        // Cast "camera" to <any> to relax "private" classification.
-        (<any>cameraInput)._pointerInput(pointerInfo, undefined);
-        break;
-      default:
-        console.error("Invalid pointer event: " + event.type);
-    }
-  }
-
   before(function(done) {
     // runs before all tests in this block
     this.timeout(180000);
@@ -520,6 +623,7 @@ describe('arcRotateCameraInput', function() {
     });
   });
 
-  //describe('two button drag', function() {
-  //});
+  describe('two button drag', function() {
+
+  });
 });