var assert = chai.assert; var expect = chai.expect; import Mouse from '../core/input/mouse.js'; import * as eventUtils from '../core/util/events.js'; /* jshint newcap: false, expr: true */ describe('Mouse Event Handling', function() { "use strict"; sinon.stub(eventUtils, 'setCapture'); // This function is only used on target (the canvas) // and for these tests we can assume that the canvas is 100x100 // located at coordinates 10x10 sinon.stub(Element.prototype, 'getBoundingClientRect').returns( {left: 10, right: 110, top: 10, bottom: 110, width: 100, height: 100}); var target = document.createElement('canvas'); // The real constructors might not work everywhere we // want to run these tests var mouseevent, touchevent; mouseevent = touchevent = function(typeArg, MouseEventInit) { var e = { type: typeArg }; for (var key in MouseEventInit) { e[key] = MouseEventInit[key]; } e.stopPropagation = sinon.spy(); e.preventDefault = sinon.spy(); return e; }; describe('Decode Mouse Events', function() { it('should decode mousedown events', function(done) { var mouse = new Mouse({ onMouseButton: function(x, y, down, bmask) { expect(bmask).to.be.equal(0x01); expect(down).to.be.equal(1); done(); }, target: target }); mouse._handleMouseDown(mouseevent('mousedown', { button: '0x01' })); }); it('should decode mouseup events', function(done) { var calls = 0; var mouse = new Mouse({ onMouseButton: function(x, y, down, bmask) { expect(bmask).to.be.equal(0x01); if (calls++ === 1) { expect(down).to.not.be.equal(1); done(); } }, target: target }); mouse._handleMouseDown(mouseevent('mousedown', { button: '0x01' })); mouse._handleMouseUp(mouseevent('mouseup', { button: '0x01' })); }); it('should decode mousemove events', function(done) { var mouse = new Mouse({ onMouseMove: function(x, y) { // Note that target relative coordinates are sent expect(x).to.be.equal(40); expect(y).to.be.equal(10); done(); }, target: target }); mouse._handleMouseMove(mouseevent('mousemove', { clientX: 50, clientY: 20 })); }); it('should decode mousewheel events', function(done) { var calls = 0; var mouse = new Mouse({ onMouseButton: function(x, y, down, bmask) { calls++; expect(bmask).to.be.equal(1<<6); if (calls === 1) { expect(down).to.be.equal(1); } else if (calls === 2) { expect(down).to.not.be.equal(1); done(); } }, target: target }); mouse._handleMouseWheel(mouseevent('mousewheel', { deltaX: 50, deltaY: 0, deltaMode: 0})); }); }); describe('Double-click for Touch', function() { beforeEach(function () { this.clock = sinon.useFakeTimers(); }); afterEach(function () { this.clock.restore(); }); it('should use same pos for 2nd tap if close enough', function(done) { var calls = 0; var mouse = new Mouse({ onMouseButton: function(x, y, down, bmask) { calls++; if (calls === 1) { expect(down).to.be.equal(1); expect(x).to.be.equal(68); expect(y).to.be.equal(36); } else if (calls === 3) { expect(down).to.be.equal(1); expect(x).to.be.equal(68); expect(y).to.be.equal(36); done(); } }, target: target }); // touch events are sent in an array of events // with one item for each touch point mouse._handleMouseDown(touchevent( 'touchstart', { touches: [{ clientX: 78, clientY: 46 }]})); this.clock.tick(10); mouse._handleMouseUp(touchevent( 'touchend', { touches: [{ clientX: 79, clientY: 45 }]})); this.clock.tick(200); mouse._handleMouseDown(touchevent( 'touchstart', { touches: [{ clientX: 67, clientY: 35 }]})); this.clock.tick(10); mouse._handleMouseUp(touchevent( 'touchend', { touches: [{ clientX: 66, clientY: 36 }]})); }); it('should not modify 2nd tap pos if far apart', function(done) { var calls = 0; var mouse = new Mouse({ onMouseButton: function(x, y, down, bmask) { calls++; if (calls === 1) { expect(down).to.be.equal(1); expect(x).to.be.equal(68); expect(y).to.be.equal(36); } else if (calls === 3) { expect(down).to.be.equal(1); expect(x).to.not.be.equal(68); expect(y).to.not.be.equal(36); done(); } }, target: target }); mouse._handleMouseDown(touchevent( 'touchstart', { touches: [{ clientX: 78, clientY: 46 }]})); this.clock.tick(10); mouse._handleMouseUp(touchevent( 'touchend', { touches: [{ clientX: 79, clientY: 45 }]})); this.clock.tick(200); mouse._handleMouseDown(touchevent( 'touchstart', { touches: [{ clientX: 57, clientY: 35 }]})); this.clock.tick(10); mouse._handleMouseUp(touchevent( 'touchend', { touches: [{ clientX: 56, clientY: 36 }]})); }); it('should not modify 2nd tap pos if not soon enough', function(done) { var calls = 0; var mouse = new Mouse({ onMouseButton: function(x, y, down, bmask) { calls++; if (calls === 1) { expect(down).to.be.equal(1); expect(x).to.be.equal(68); expect(y).to.be.equal(36); } else if (calls === 3) { expect(down).to.be.equal(1); expect(x).to.not.be.equal(68); expect(y).to.not.be.equal(36); done(); } }, target: target }); mouse._handleMouseDown(touchevent( 'touchstart', { touches: [{ clientX: 78, clientY: 46 }]})); this.clock.tick(10); mouse._handleMouseUp(touchevent( 'touchend', { touches: [{ clientX: 79, clientY: 45 }]})); this.clock.tick(500); mouse._handleMouseDown(touchevent( 'touchstart', { touches: [{ clientX: 67, clientY: 35 }]})); this.clock.tick(10); mouse._handleMouseUp(touchevent( 'touchend', { touches: [{ clientX: 66, clientY: 36 }]})); }); it('should not modify 2nd tap pos if not touch', function(done) { var calls = 0; var mouse = new Mouse({ onMouseButton: function(x, y, down, bmask) { calls++; if (calls === 1) { expect(down).to.be.equal(1); expect(x).to.be.equal(68); expect(y).to.be.equal(36); } else if (calls === 3) { expect(down).to.be.equal(1); expect(x).to.not.be.equal(68); expect(y).to.not.be.equal(36); done(); } }, target: target }); mouse._handleMouseDown(mouseevent( 'mousedown', { button: '0x01', clientX: 78, clientY: 46 })); this.clock.tick(10); mouse._handleMouseUp(mouseevent( 'mouseup', { button: '0x01', clientX: 79, clientY: 45 })); this.clock.tick(200); mouse._handleMouseDown(mouseevent( 'mousedown', { button: '0x01', clientX: 67, clientY: 35 })); this.clock.tick(10); mouse._handleMouseUp(mouseevent( 'mouseup', { button: '0x01', clientX: 66, clientY: 36 })); }); }); });