1027 lines
35 KiB
JavaScript
1027 lines
35 KiB
JavaScript
const expect = chai.expect;
|
|
|
|
import EventTargetMixin from '../core/util/eventtarget.js';
|
|
|
|
import GestureHandler from '../core/input/gesturehandler.js';
|
|
|
|
class DummyTarget extends EventTargetMixin {
|
|
}
|
|
|
|
describe('Gesture handler', function () {
|
|
let target, handler;
|
|
let gestures;
|
|
let clock;
|
|
let touches;
|
|
|
|
before(function () {
|
|
clock = sinon.useFakeTimers();
|
|
});
|
|
|
|
after(function () {
|
|
clock.restore();
|
|
});
|
|
|
|
beforeEach(function () {
|
|
target = new DummyTarget();
|
|
gestures = sinon.spy();
|
|
target.addEventListener('gesturestart', gestures);
|
|
target.addEventListener('gesturemove', gestures);
|
|
target.addEventListener('gestureend', gestures);
|
|
touches = [];
|
|
handler = new GestureHandler();
|
|
handler.attach(target);
|
|
});
|
|
|
|
afterEach(function () {
|
|
if (handler) {
|
|
handler.detach();
|
|
}
|
|
target = null;
|
|
gestures = null;
|
|
});
|
|
|
|
function touchStart(id, x, y) {
|
|
let touch = { identifier: id,
|
|
clientX: x, clientY: y };
|
|
touches.push(touch);
|
|
let ev = { type: 'touchstart',
|
|
touches: touches,
|
|
targetTouches: touches,
|
|
changedTouches: [ touch ],
|
|
stopPropagation: sinon.spy(),
|
|
preventDefault: sinon.spy() };
|
|
target.dispatchEvent(ev);
|
|
}
|
|
|
|
function touchMove(id, x, y) {
|
|
let touch = touches.find(t => t.identifier === id);
|
|
touch.clientX = x;
|
|
touch.clientY = y;
|
|
let ev = { type: 'touchmove',
|
|
touches: touches,
|
|
targetTouches: touches,
|
|
changedTouches: [ touch ],
|
|
stopPropagation: sinon.spy(),
|
|
preventDefault: sinon.spy() };
|
|
target.dispatchEvent(ev);
|
|
}
|
|
|
|
function touchEnd(id) {
|
|
let idx = touches.findIndex(t => t.identifier === id);
|
|
let touch = touches.splice(idx, 1)[0];
|
|
let ev = { type: 'touchend',
|
|
touches: touches,
|
|
targetTouches: touches,
|
|
changedTouches: [ touch ],
|
|
stopPropagation: sinon.spy(),
|
|
preventDefault: sinon.spy() };
|
|
target.dispatchEvent(ev);
|
|
}
|
|
|
|
describe('Single finger tap', function () {
|
|
it('should handle single finger tap', function () {
|
|
touchStart(1, 20.0, 30.0);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
touchEnd(1);
|
|
|
|
expect(gestures).to.have.been.calledTwice;
|
|
|
|
expect(gestures.firstCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturestart',
|
|
detail: { type: 'onetap',
|
|
clientX: 20.0,
|
|
clientY: 30.0 } }));
|
|
|
|
expect(gestures.secondCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gestureend',
|
|
detail: { type: 'onetap',
|
|
clientX: 20.0,
|
|
clientY: 30.0 } }));
|
|
});
|
|
});
|
|
|
|
describe('Two finger tap', function () {
|
|
it('should handle two finger tap', function () {
|
|
touchStart(1, 20.0, 30.0);
|
|
touchStart(2, 30.0, 50.0);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
touchEnd(1);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
touchEnd(2);
|
|
|
|
expect(gestures).to.have.been.calledTwice;
|
|
|
|
expect(gestures.firstCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturestart',
|
|
detail: { type: 'twotap',
|
|
clientX: 25.0,
|
|
clientY: 40.0 } }));
|
|
|
|
expect(gestures.secondCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gestureend',
|
|
detail: { type: 'twotap',
|
|
clientX: 25.0,
|
|
clientY: 40.0 } }));
|
|
});
|
|
|
|
it('should ignore slow starting two finger tap', function () {
|
|
touchStart(1, 20.0, 30.0);
|
|
|
|
clock.tick(500);
|
|
|
|
touchStart(2, 30.0, 50.0);
|
|
touchEnd(1);
|
|
touchEnd(2);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
});
|
|
|
|
it('should ignore slow ending two finger tap', function () {
|
|
touchStart(1, 20.0, 30.0);
|
|
touchStart(2, 30.0, 50.0);
|
|
touchEnd(1);
|
|
|
|
clock.tick(500);
|
|
|
|
touchEnd(2);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
});
|
|
|
|
it('should ignore slow two finger tap', function () {
|
|
touchStart(1, 20.0, 30.0);
|
|
touchStart(2, 30.0, 50.0);
|
|
|
|
clock.tick(1500);
|
|
|
|
touchEnd(1);
|
|
touchEnd(2);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
});
|
|
});
|
|
|
|
describe('Three finger tap', function () {
|
|
it('should handle three finger tap', function () {
|
|
touchStart(1, 20.0, 30.0);
|
|
touchStart(2, 30.0, 50.0);
|
|
touchStart(3, 40.0, 40.0);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
touchEnd(1);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
touchEnd(2);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
touchEnd(3);
|
|
|
|
expect(gestures).to.have.been.calledTwice;
|
|
|
|
expect(gestures.firstCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturestart',
|
|
detail: { type: 'threetap',
|
|
clientX: 30.0,
|
|
clientY: 40.0 } }));
|
|
|
|
expect(gestures.secondCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gestureend',
|
|
detail: { type: 'threetap',
|
|
clientX: 30.0,
|
|
clientY: 40.0 } }));
|
|
});
|
|
|
|
it('should ignore slow starting three finger tap', function () {
|
|
touchStart(1, 20.0, 30.0);
|
|
touchStart(2, 30.0, 50.0);
|
|
|
|
clock.tick(500);
|
|
|
|
touchStart(3, 40.0, 40.0);
|
|
touchEnd(1);
|
|
touchEnd(2);
|
|
touchEnd(3);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
});
|
|
|
|
it('should ignore slow ending three finger tap', function () {
|
|
touchStart(1, 20.0, 30.0);
|
|
touchStart(2, 30.0, 50.0);
|
|
touchStart(3, 40.0, 40.0);
|
|
touchEnd(1);
|
|
touchEnd(2);
|
|
|
|
clock.tick(500);
|
|
|
|
touchEnd(3);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
});
|
|
|
|
it('should ignore three finger drag', function () {
|
|
touchStart(1, 20.0, 30.0);
|
|
touchStart(2, 30.0, 50.0);
|
|
touchStart(3, 40.0, 40.0);
|
|
|
|
touchMove(1, 120.0, 130.0);
|
|
touchMove(2, 130.0, 150.0);
|
|
touchMove(3, 140.0, 140.0);
|
|
|
|
touchEnd(1);
|
|
touchEnd(2);
|
|
touchEnd(3);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
});
|
|
|
|
it('should ignore slow three finger tap', function () {
|
|
touchStart(1, 20.0, 30.0);
|
|
touchStart(2, 30.0, 50.0);
|
|
touchStart(3, 40.0, 40.0);
|
|
|
|
clock.tick(1500);
|
|
|
|
touchEnd(1);
|
|
touchEnd(2);
|
|
touchEnd(3);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
});
|
|
});
|
|
|
|
describe('Single finger drag', function () {
|
|
it('should handle horizontal single finger drag', function () {
|
|
touchStart(1, 20.0, 30.0);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
touchMove(1, 40.0, 30.0);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
touchMove(1, 80.0, 30.0);
|
|
|
|
expect(gestures).to.have.been.calledTwice;
|
|
|
|
expect(gestures.firstCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturestart',
|
|
detail: { type: 'drag',
|
|
clientX: 20.0,
|
|
clientY: 30.0 } }));
|
|
|
|
expect(gestures.secondCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturemove',
|
|
detail: { type: 'drag',
|
|
clientX: 80.0,
|
|
clientY: 30.0 } }));
|
|
|
|
gestures.resetHistory();
|
|
|
|
touchEnd(1);
|
|
|
|
expect(gestures).to.have.been.calledOnceWith(
|
|
sinon.match({ type: 'gestureend',
|
|
detail: { type: 'drag',
|
|
clientX: 80.0,
|
|
clientY: 30.0 } }));
|
|
});
|
|
|
|
it('should handle vertical single finger drag', function () {
|
|
touchStart(1, 20.0, 30.0);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
touchMove(1, 20.0, 50.0);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
touchMove(1, 20.0, 90.0);
|
|
|
|
expect(gestures).to.have.been.calledTwice;
|
|
|
|
expect(gestures.firstCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturestart',
|
|
detail: { type: 'drag',
|
|
clientX: 20.0,
|
|
clientY: 30.0 } }));
|
|
|
|
expect(gestures.secondCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturemove',
|
|
detail: { type: 'drag',
|
|
clientX: 20.0,
|
|
clientY: 90.0 } }));
|
|
|
|
gestures.resetHistory();
|
|
|
|
touchEnd(1);
|
|
|
|
expect(gestures).to.have.been.calledOnceWith(
|
|
sinon.match({ type: 'gestureend',
|
|
detail: { type: 'drag',
|
|
clientX: 20.0,
|
|
clientY: 90.0 } }));
|
|
});
|
|
|
|
it('should handle diagonal single finger drag', function () {
|
|
touchStart(1, 120.0, 130.0);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
touchMove(1, 90.0, 100.0);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
touchMove(1, 60.0, 70.0);
|
|
|
|
expect(gestures).to.have.been.calledTwice;
|
|
|
|
expect(gestures.firstCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturestart',
|
|
detail: { type: 'drag',
|
|
clientX: 120.0,
|
|
clientY: 130.0 } }));
|
|
|
|
expect(gestures.secondCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturemove',
|
|
detail: { type: 'drag',
|
|
clientX: 60.0,
|
|
clientY: 70.0 } }));
|
|
|
|
gestures.resetHistory();
|
|
|
|
touchEnd(1);
|
|
|
|
expect(gestures).to.have.been.calledOnceWith(
|
|
sinon.match({ type: 'gestureend',
|
|
detail: { type: 'drag',
|
|
clientX: 60.0,
|
|
clientY: 70.0 } }));
|
|
});
|
|
});
|
|
|
|
describe('Long press', function () {
|
|
it('should handle long press', function () {
|
|
touchStart(1, 20.0, 30.0);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
clock.tick(1500);
|
|
|
|
expect(gestures).to.have.been.calledOnceWith(
|
|
sinon.match({ type: 'gesturestart',
|
|
detail: { type: 'longpress',
|
|
clientX: 20.0,
|
|
clientY: 30.0 } }));
|
|
|
|
gestures.resetHistory();
|
|
|
|
touchEnd(1);
|
|
|
|
expect(gestures).to.have.been.calledOnceWith(
|
|
sinon.match({ type: 'gestureend',
|
|
detail: { type: 'longpress',
|
|
clientX: 20.0,
|
|
clientY: 30.0 } }));
|
|
});
|
|
|
|
it('should handle long press drag', function () {
|
|
touchStart(1, 20.0, 30.0);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
clock.tick(1500);
|
|
|
|
expect(gestures).to.have.been.calledOnceWith(
|
|
sinon.match({ type: 'gesturestart',
|
|
detail: { type: 'longpress',
|
|
clientX: 20.0,
|
|
clientY: 30.0 } }));
|
|
|
|
gestures.resetHistory();
|
|
|
|
touchMove(1, 120.0, 50.0);
|
|
|
|
expect(gestures).to.have.been.calledOnceWith(
|
|
sinon.match({ type: 'gesturemove',
|
|
detail: { type: 'longpress',
|
|
clientX: 120.0,
|
|
clientY: 50.0 } }));
|
|
|
|
gestures.resetHistory();
|
|
|
|
touchEnd(1);
|
|
|
|
expect(gestures).to.have.been.calledOnceWith(
|
|
sinon.match({ type: 'gestureend',
|
|
detail: { type: 'longpress',
|
|
clientX: 120.0,
|
|
clientY: 50.0 } }));
|
|
});
|
|
});
|
|
|
|
describe('Two finger drag', function () {
|
|
it('should handle fast and distinct horizontal two finger drag', function () {
|
|
touchStart(1, 20.0, 30.0);
|
|
touchStart(2, 30.0, 30.0);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
touchMove(1, 40.0, 30.0);
|
|
touchMove(2, 50.0, 30.0);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
touchMove(2, 90.0, 30.0);
|
|
touchMove(1, 80.0, 30.0);
|
|
|
|
expect(gestures).to.have.been.calledTwice;
|
|
|
|
expect(gestures.firstCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturestart',
|
|
detail: { type: 'twodrag',
|
|
clientX: 25.0,
|
|
clientY: 30.0,
|
|
magnitudeX: 0.0,
|
|
magnitudeY: 0.0 } }));
|
|
|
|
expect(gestures.secondCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturemove',
|
|
detail: { type: 'twodrag',
|
|
clientX: 25.0,
|
|
clientY: 30.0,
|
|
magnitudeX: 60.0,
|
|
magnitudeY: 0.0 } }));
|
|
|
|
gestures.resetHistory();
|
|
|
|
touchEnd(1);
|
|
|
|
expect(gestures).to.have.been.calledOnceWith(
|
|
sinon.match({ type: 'gestureend',
|
|
detail: { type: 'twodrag',
|
|
clientX: 25.0,
|
|
clientY: 30.0,
|
|
magnitudeX: 60.0,
|
|
magnitudeY: 0.0 } }));
|
|
});
|
|
|
|
it('should handle fast and distinct vertical two finger drag', function () {
|
|
touchStart(1, 20.0, 30.0);
|
|
touchStart(2, 30.0, 30.0);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
touchMove(1, 20.0, 100.0);
|
|
touchMove(2, 30.0, 40.0);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
touchMove(2, 30.0, 90.0);
|
|
|
|
expect(gestures).to.have.been.calledTwice;
|
|
|
|
expect(gestures.firstCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturestart',
|
|
detail: { type: 'twodrag',
|
|
clientX: 25.0,
|
|
clientY: 30.0,
|
|
magnitudeX: 0.0,
|
|
magnitudeY: 0.0 } }));
|
|
|
|
expect(gestures.secondCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturemove',
|
|
detail: { type: 'twodrag',
|
|
clientX: 25.0,
|
|
clientY: 30.0,
|
|
magnitudeX: 0.0,
|
|
magnitudeY: 65.0 } }));
|
|
|
|
gestures.resetHistory();
|
|
|
|
touchEnd(1);
|
|
|
|
expect(gestures).to.have.been.calledOnceWith(
|
|
sinon.match({ type: 'gestureend',
|
|
detail: { type: 'twodrag',
|
|
clientX: 25.0,
|
|
clientY: 30.0,
|
|
magnitudeX: 0.0,
|
|
magnitudeY: 65.0 } }));
|
|
});
|
|
|
|
it('should handle fast and distinct diagonal two finger drag', function () {
|
|
touchStart(1, 120.0, 130.0);
|
|
touchStart(2, 130.0, 130.0);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
touchMove(1, 80.0, 90.0);
|
|
touchMove(2, 100.0, 130.0);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
touchMove(2, 60.0, 70.0);
|
|
|
|
expect(gestures).to.have.been.calledTwice;
|
|
|
|
expect(gestures.firstCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturestart',
|
|
detail: { type: 'twodrag',
|
|
clientX: 125.0,
|
|
clientY: 130.0,
|
|
magnitudeX: 0.0,
|
|
magnitudeY: 0.0 } }));
|
|
|
|
expect(gestures.secondCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturemove',
|
|
detail: { type: 'twodrag',
|
|
clientX: 125.0,
|
|
clientY: 130.0,
|
|
magnitudeX: -55.0,
|
|
magnitudeY: -50.0 } }));
|
|
|
|
gestures.resetHistory();
|
|
|
|
touchEnd(1);
|
|
|
|
expect(gestures).to.have.been.calledOnceWith(
|
|
sinon.match({ type: 'gestureend',
|
|
detail: { type: 'twodrag',
|
|
clientX: 125.0,
|
|
clientY: 130.0,
|
|
magnitudeX: -55.0,
|
|
magnitudeY: -50.0 } }));
|
|
});
|
|
|
|
it('should ignore fast almost two finger dragging', function () {
|
|
touchStart(1, 20.0, 30.0);
|
|
touchStart(2, 30.0, 30.0);
|
|
touchMove(1, 80.0, 30.0);
|
|
touchMove(2, 70.0, 30.0);
|
|
touchEnd(1);
|
|
touchEnd(2);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
clock.tick(1500);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
});
|
|
|
|
it('should handle slow horizontal two finger drag', function () {
|
|
touchStart(1, 50.0, 40.0);
|
|
touchStart(2, 60.0, 40.0);
|
|
touchMove(1, 80.0, 40.0);
|
|
touchMove(2, 110.0, 40.0);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
clock.tick(60);
|
|
|
|
expect(gestures).to.have.been.calledTwice;
|
|
|
|
expect(gestures.firstCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturestart',
|
|
detail: { type: 'twodrag',
|
|
clientX: 55.0,
|
|
clientY: 40.0,
|
|
magnitudeX: 0.0,
|
|
magnitudeY: 0.0 } }));
|
|
|
|
expect(gestures.secondCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturemove',
|
|
detail: { type: 'twodrag',
|
|
clientX: 55.0,
|
|
clientY: 40.0,
|
|
magnitudeX: 40.0,
|
|
magnitudeY: 0.0 } }));
|
|
});
|
|
|
|
it('should handle slow vertical two finger drag', function () {
|
|
touchStart(1, 40.0, 40.0);
|
|
touchStart(2, 40.0, 60.0);
|
|
touchMove(2, 40.0, 80.0);
|
|
touchMove(1, 40.0, 100.0);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
clock.tick(60);
|
|
|
|
expect(gestures).to.have.been.calledTwice;
|
|
|
|
expect(gestures.firstCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturestart',
|
|
detail: { type: 'twodrag',
|
|
clientX: 40.0,
|
|
clientY: 50.0,
|
|
magnitudeX: 0.0,
|
|
magnitudeY: 0.0 } }));
|
|
|
|
expect(gestures.secondCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturemove',
|
|
detail: { type: 'twodrag',
|
|
clientX: 40.0,
|
|
clientY: 50.0,
|
|
magnitudeX: 0.0,
|
|
magnitudeY: 40.0 } }));
|
|
});
|
|
|
|
it('should handle slow diagonal two finger drag', function () {
|
|
touchStart(1, 50.0, 40.0);
|
|
touchStart(2, 40.0, 60.0);
|
|
touchMove(1, 70.0, 60.0);
|
|
touchMove(2, 90.0, 110.0);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
clock.tick(60);
|
|
|
|
expect(gestures).to.have.been.calledTwice;
|
|
|
|
expect(gestures.firstCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturestart',
|
|
detail: { type: 'twodrag',
|
|
clientX: 45.0,
|
|
clientY: 50.0,
|
|
magnitudeX: 0.0,
|
|
magnitudeY: 0.0 } }));
|
|
|
|
expect(gestures.secondCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturemove',
|
|
detail: { type: 'twodrag',
|
|
clientX: 45.0,
|
|
clientY: 50.0,
|
|
magnitudeX: 35.0,
|
|
magnitudeY: 35.0 } }));
|
|
});
|
|
|
|
it('should ignore too slow two finger drag', function () {
|
|
touchStart(1, 20.0, 30.0);
|
|
|
|
clock.tick(500);
|
|
|
|
touchStart(2, 30.0, 30.0);
|
|
touchMove(1, 40.0, 30.0);
|
|
touchMove(2, 50.0, 30.0);
|
|
touchMove(1, 80.0, 30.0);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
});
|
|
});
|
|
|
|
describe('Pinch', function () {
|
|
it('should handle pinching distinctly and fast inwards', function () {
|
|
touchStart(1, 0.0, 0.0);
|
|
touchStart(2, 130.0, 130.0);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
touchMove(1, 50.0, 40.0);
|
|
touchMove(2, 100.0, 130.0);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
touchMove(2, 60.0, 70.0);
|
|
|
|
expect(gestures).to.have.been.calledTwice;
|
|
|
|
expect(gestures.firstCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturestart',
|
|
detail: { type: 'pinch',
|
|
clientX: 65.0,
|
|
clientY: 65.0,
|
|
magnitudeX: 130.0,
|
|
magnitudeY: 130.0 } }));
|
|
|
|
expect(gestures.secondCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturemove',
|
|
detail: { type: 'pinch',
|
|
clientX: 65.0,
|
|
clientY: 65.0,
|
|
magnitudeX: 10.0,
|
|
magnitudeY: 30.0 } }));
|
|
|
|
gestures.resetHistory();
|
|
|
|
touchEnd(1);
|
|
|
|
expect(gestures).to.have.been.calledOnceWith(
|
|
sinon.match({ type: 'gestureend',
|
|
detail: { type: 'pinch',
|
|
clientX: 65.0,
|
|
clientY: 65.0,
|
|
magnitudeX: 10.0,
|
|
magnitudeY: 30.0 } }));
|
|
});
|
|
|
|
it('should handle pinching fast and distinctly outwards', function () {
|
|
touchStart(1, 100.0, 100.0);
|
|
touchStart(2, 110.0, 100.0);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
touchMove(1, 130.0, 70.0);
|
|
touchMove(2, 0.0, 200.0);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
touchMove(1, 180.0, 20.0);
|
|
|
|
expect(gestures).to.have.been.calledTwice;
|
|
|
|
expect(gestures.firstCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturestart',
|
|
detail: { type: 'pinch',
|
|
clientX: 105.0,
|
|
clientY: 100.0,
|
|
magnitudeX: 10.0,
|
|
magnitudeY: 0.0 } }));
|
|
|
|
expect(gestures.secondCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturemove',
|
|
detail: { type: 'pinch',
|
|
clientX: 105.0,
|
|
clientY: 100.0,
|
|
magnitudeX: 180.0,
|
|
magnitudeY: 180.0 } }));
|
|
|
|
gestures.resetHistory();
|
|
|
|
touchEnd(1);
|
|
|
|
expect(gestures).to.have.been.calledOnceWith(
|
|
sinon.match({ type: 'gestureend',
|
|
detail: { type: 'pinch',
|
|
clientX: 105.0,
|
|
clientY: 100.0,
|
|
magnitudeX: 180.0,
|
|
magnitudeY: 180.0 } }));
|
|
});
|
|
|
|
it('should ignore fast almost pinching', function () {
|
|
touchStart(1, 20.0, 30.0);
|
|
touchStart(2, 130.0, 130.0);
|
|
touchMove(1, 80.0, 70.0);
|
|
touchEnd(1);
|
|
touchEnd(2);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
clock.tick(1500);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
});
|
|
|
|
it('should handle pinching inwards slowly', function () {
|
|
touchStart(1, 0.0, 0.0);
|
|
touchStart(2, 130.0, 130.0);
|
|
touchMove(1, 50.0, 40.0);
|
|
touchMove(2, 100.0, 130.0);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
clock.tick(60);
|
|
|
|
expect(gestures).to.have.been.calledTwice;
|
|
|
|
expect(gestures.firstCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturestart',
|
|
detail: { type: 'pinch',
|
|
clientX: 65.0,
|
|
clientY: 65.0,
|
|
magnitudeX: 130.0,
|
|
magnitudeY: 130.0 } }));
|
|
|
|
expect(gestures.secondCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturemove',
|
|
detail: { type: 'pinch',
|
|
clientX: 65.0,
|
|
clientY: 65.0,
|
|
magnitudeX: 50.0,
|
|
magnitudeY: 90.0 } }));
|
|
});
|
|
|
|
it('should handle pinching outwards slowly', function () {
|
|
touchStart(1, 100.0, 130.0);
|
|
touchStart(2, 110.0, 130.0);
|
|
touchMove(2, 200.0, 130.0);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
clock.tick(60);
|
|
|
|
expect(gestures).to.have.been.calledTwice;
|
|
|
|
expect(gestures.firstCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturestart',
|
|
detail: { type: 'pinch',
|
|
clientX: 105.0,
|
|
clientY: 130.0,
|
|
magnitudeX: 10.0,
|
|
magnitudeY: 0.0 } }));
|
|
|
|
expect(gestures.secondCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturemove',
|
|
detail: { type: 'pinch',
|
|
clientX: 105.0,
|
|
clientY: 130.0,
|
|
magnitudeX: 100.0,
|
|
magnitudeY: 0.0 } }));
|
|
});
|
|
|
|
it('should ignore pinching too slowly', function () {
|
|
touchStart(1, 0.0, 0.0);
|
|
|
|
clock.tick(500);
|
|
|
|
touchStart(2, 130.0, 130.0);
|
|
touchMove(2, 100.0, 130.0);
|
|
touchMove(1, 50.0, 40.0);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
});
|
|
});
|
|
|
|
describe('Ignoring', function () {
|
|
it('should ignore extra touches during gesture', function () {
|
|
touchStart(1, 20.0, 30.0);
|
|
touchMove(1, 40.0, 30.0);
|
|
touchMove(1, 80.0, 30.0);
|
|
|
|
expect(gestures).to.have.been.calledTwice;
|
|
|
|
expect(gestures.firstCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturestart',
|
|
detail: { type: 'drag' } }));
|
|
expect(gestures.secondCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturemove',
|
|
detail: { type: 'drag' } }));
|
|
|
|
gestures.resetHistory();
|
|
|
|
touchStart(2, 10.0, 10.0);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
touchMove(1, 100.0, 50.0);
|
|
|
|
expect(gestures).to.have.been.calledOnceWith(
|
|
sinon.match({ type: 'gesturemove',
|
|
detail: { type: 'drag',
|
|
clientX: 100.0,
|
|
clientY: 50.0 } }));
|
|
|
|
gestures.resetHistory();
|
|
|
|
touchEnd(1);
|
|
|
|
expect(gestures).to.have.been.calledOnceWith(
|
|
sinon.match({ type: 'gestureend',
|
|
detail: { type: 'drag',
|
|
clientX: 100.0,
|
|
clientY: 50.0 } }));
|
|
});
|
|
|
|
it('should ignore extra touches when waiting for gesture to end', function () {
|
|
touchStart(1, 20.0, 30.0);
|
|
touchStart(2, 30.0, 30.0);
|
|
touchMove(1, 40.0, 30.0);
|
|
touchMove(2, 90.0, 30.0);
|
|
touchMove(1, 80.0, 30.0);
|
|
|
|
expect(gestures).to.have.been.calledTwice;
|
|
|
|
expect(gestures.firstCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturestart',
|
|
detail: { type: 'twodrag' } }));
|
|
expect(gestures.secondCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturemove',
|
|
detail: { type: 'twodrag' } }));
|
|
|
|
gestures.resetHistory();
|
|
|
|
touchEnd(1);
|
|
|
|
expect(gestures).to.have.been.calledOnceWith(
|
|
sinon.match({ type: 'gestureend',
|
|
detail: { type: 'twodrag' } }));
|
|
|
|
gestures.resetHistory();
|
|
|
|
touchStart(3, 10.0, 10.0);
|
|
touchEnd(3);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
});
|
|
|
|
it('should ignore extra touches after gesture', function () {
|
|
touchStart(1, 20.0, 30.0);
|
|
touchMove(1, 40.0, 30.0);
|
|
touchMove(1, 80.0, 30.0);
|
|
|
|
expect(gestures).to.have.been.calledTwice;
|
|
|
|
expect(gestures.firstCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturestart',
|
|
detail: { type: 'drag' } }));
|
|
expect(gestures.secondCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturemove',
|
|
detail: { type: 'drag' } }));
|
|
|
|
gestures.resetHistory();
|
|
|
|
touchStart(2, 10.0, 10.0);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
touchMove(1, 100.0, 50.0);
|
|
|
|
expect(gestures).to.have.been.calledOnceWith(
|
|
sinon.match({ type: 'gesturemove',
|
|
detail: { type: 'drag' } }));
|
|
|
|
gestures.resetHistory();
|
|
|
|
touchEnd(1);
|
|
|
|
expect(gestures).to.have.been.calledOnceWith(
|
|
sinon.match({ type: 'gestureend',
|
|
detail: { type: 'drag' } }));
|
|
|
|
gestures.resetHistory();
|
|
|
|
touchEnd(2);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
// Check that everything is reseted after trailing ignores are released
|
|
|
|
touchStart(3, 20.0, 30.0);
|
|
touchEnd(3);
|
|
|
|
expect(gestures).to.have.been.calledTwice;
|
|
|
|
expect(gestures.firstCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturestart',
|
|
detail: { type: 'onetap' } }));
|
|
expect(gestures.secondCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gestureend',
|
|
detail: { type: 'onetap' } }));
|
|
});
|
|
|
|
it('should properly reset after a gesture', function () {
|
|
touchStart(1, 20.0, 30.0);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
touchEnd(1);
|
|
|
|
expect(gestures).to.have.been.calledTwice;
|
|
|
|
expect(gestures.firstCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturestart',
|
|
detail: { type: 'onetap',
|
|
clientX: 20.0,
|
|
clientY: 30.0 } }));
|
|
|
|
expect(gestures.secondCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gestureend',
|
|
detail: { type: 'onetap',
|
|
clientX: 20.0,
|
|
clientY: 30.0 } }));
|
|
|
|
gestures.resetHistory();
|
|
|
|
touchStart(2, 70.0, 80.0);
|
|
|
|
expect(gestures).to.not.have.been.called;
|
|
|
|
touchEnd(2);
|
|
|
|
expect(gestures).to.have.been.calledTwice;
|
|
|
|
expect(gestures.firstCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gesturestart',
|
|
detail: { type: 'onetap',
|
|
clientX: 70.0,
|
|
clientY: 80.0 } }));
|
|
|
|
expect(gestures.secondCall).to.have.been.calledWith(
|
|
sinon.match({ type: 'gestureend',
|
|
detail: { type: 'onetap',
|
|
clientX: 70.0,
|
|
clientY: 80.0 } }));
|
|
});
|
|
});
|
|
});
|