diff --git a/tests/test.mouse.js b/tests/test.mouse.js new file mode 100644 index 00000000..d75340e4 --- /dev/null +++ b/tests/test.mouse.js @@ -0,0 +1,226 @@ +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 })); + }); + + }); + +});