From f46c36ed976abd05be52be5cc980ccbd9e9265f3 Mon Sep 17 00:00:00 2001 From: Brian Ambielli Date: Fri, 17 May 2019 09:18:52 -0500 Subject: [PATCH] fixes #8256 --- src/ui/handler/scroll_zoom.js | 9 ++- test/README.md | 3 +- test/unit/ui/handler/scroll_zoom.test.js | 89 ++++++++++++++++++++++++ 3 files changed, 97 insertions(+), 4 deletions(-) diff --git a/src/ui/handler/scroll_zoom.js b/src/ui/handler/scroll_zoom.js index 3f018c748eb..eab8bbf8556 100644 --- a/src/ui/handler/scroll_zoom.js +++ b/src/ui/handler/scroll_zoom.js @@ -215,9 +215,12 @@ class ScrollZoomHandler { } this._active = true; - this._zooming = true; - this._map.fire(new Event('movestart', {originalEvent: e})); - this._map.fire(new Event('zoomstart', {originalEvent: e})); + if (!this.isZooming()) { + this._zooming = true; + this._map.fire(new Event('movestart', {originalEvent: e})); + this._map.fire(new Event('zoomstart', {originalEvent: e})); + } + if (this._finishTimeout) { clearTimeout(this._finishTimeout); } diff --git a/test/README.md b/test/README.md index ed53f9218df..79dcfe71133 100644 --- a/test/README.md +++ b/test/README.md @@ -12,7 +12,8 @@ There are two test suites associated with Mapbox GL JS To run individual tests: - - Unit tests: `yarn test-unit path/to/file.test.js` where the path begins within the `/test/unit/` directory + - Unit tests: `yarn test-unit path/to/file.test.js` where path *does not include* `test/unit/` + - e.g. `yarn test-unit ui/handler/scroll_zoom.test.js` - Render tests: `yarn test-render render-test-name` (e.g. `yarn test-render background-color/default`) ## Writing Unit Tests diff --git a/test/unit/ui/handler/scroll_zoom.test.js b/test/unit/ui/handler/scroll_zoom.test.js index 6cecaf7551f..21177f00505 100644 --- a/test/unit/ui/handler/scroll_zoom.test.js +++ b/test/unit/ui/handler/scroll_zoom.test.js @@ -4,6 +4,7 @@ import window from '../../../../src/util/window'; import Map from '../../../../src/ui/map'; import DOM from '../../../../src/util/dom'; import simulate from 'mapbox-gl-js-test/simulate_interaction'; +import sinon from 'sinon'; function createMap(t) { t.stub(Map.prototype, '_detectMissingCSS'); @@ -148,5 +149,93 @@ test('ScrollZoomHandler', (t) => { t.end(); }); + t.test('emits one movestart event and one moveend event while zooming', (t) => { + const clock = sinon.useFakeTimers(now); + const map = createMap(t); + + let startCount = 0; + map.on('movestart', () => { + startCount += 1; + }); + + let endCount = 0; + map.on('moveend', () => { + endCount += 1; + }); + + const events = [ + [2, {type: 'trackpad', deltaY: -1}], + [7, {type: 'trackpad', deltaY: -2}], + [30, {type: 'wheel', deltaY: -5}] + ]; + + const end = now + 50; + let lastWheelEvent = now; + + while (now++ < end) { + if (events.length && lastWheelEvent + events[0][0] === now) { + const [, event] = events.shift(); + simulate.wheel(map.getCanvas(), event); + lastWheelEvent = now; + } + if (now % 20 === 0) { + map._renderTaskQueue.run(); + } + } + + clock.tick(200); + + t.equal(startCount, 1); + t.equal(endCount, 1); + + clock.restore(); + + t.end(); + }); + + t.test('emits one zoomstart event and one zoomend event while zooming', (t) => { + const clock = sinon.useFakeTimers(now); + const map = createMap(t); + + let startCount = 0; + map.on('zoomstart', () => { + startCount += 1; + }); + + let endCount = 0; + map.on('zoomend', () => { + endCount += 1; + }); + + const events = [ + [2, {type: 'trackpad', deltaY: -1}], + [7, {type: 'trackpad', deltaY: -2}], + [30, {type: 'wheel', deltaY: -5}], + ]; + + const end = now + 50; + let lastWheelEvent = now; + + while (now++ < end) { + if (events.length && lastWheelEvent + events[0][0] === now) { + const [, event] = events.shift(); + simulate.wheel(map.getCanvas(), event); + lastWheelEvent = now; + } + if (now % 20 === 0) { + map._renderTaskQueue.run(); + } + } + + clock.tick(200); + + t.equal(startCount, 1); + t.equal(endCount, 1); + + clock.restore(); + + t.end(); + }); + t.end(); });