From 6420f2d3b6ba756c428dcfbf039d725b91483d7c Mon Sep 17 00:00:00 2001
From: Birk Skyum <74932975+birkskyum@users.noreply.github.com>
Date: Fri, 20 Sep 2024 00:53:02 +0200
Subject: [PATCH 01/32] improve unpkg instructions (#4705)
---
build/generate-docs.ts | 14 ++++++++++++++
docs/index.md | 13 +++++--------
2 files changed, 19 insertions(+), 8 deletions(-)
diff --git a/build/generate-docs.ts b/build/generate-docs.ts
index 9208667077..859fd1a55f 100644
--- a/build/generate-docs.ts
+++ b/build/generate-docs.ts
@@ -165,6 +165,19 @@ ${groups['JAVASCRIPT-BINDINGS']}
fs.writeFileSync('docs/plugins.md', pluginsContent, {encoding: 'utf-8'});
}
+function updateMapLibreVersionForUNPKG() {
+
+ // Read index.md
+ const indexPath = 'docs/index.md';
+ let indexContent = fs.readFileSync(indexPath, 'utf-8');
+
+ // Replace the version number
+ indexContent = indexContent.replace(/unpkg\.com\/maplibre-gl@\^(\d+\.\d+\.\d+)/g, `unpkg.com/maplibre-gl@^${packageJson.version}`);
+
+ // Save index.md
+ fs.writeFileSync(indexPath, indexContent);
+}
+
// !!Main flow start here!!
if (!fs.existsSync(typedocConfig.out)) {
throw new Error('Please run typedoc generation first!');
@@ -173,4 +186,5 @@ fs.rmSync(path.join(typedocConfig.out, 'README.md'));
generateReadme();
generateExamplesFolder();
await generatePluginsPage();
+updateMapLibreVersionForUNPKG();
console.log('Docs generation completed, to see it in action run\n npm run start-docs');
diff --git a/docs/index.md b/docs/index.md
index b62bb04376..ca9ecdc1db 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -91,12 +91,9 @@ Note too that if the CSS isn't available by the first render, as soon as the CSS
## CDN
-The MapLibre GL JS (`.js` & `.css`) are distributed via [UNPKG.com](https://unpkg.com).
-You can view a listing of all the files in the MapLibre GL JS package by appending a `/` at the end of the MapLibre slug. This is useful to review other revisions or to review the files at UNPKG or the LICENSE. See examples in the following table:
+MapLibre GL JS is also distributed via UNPKG. Our latest version can installed by adding below tags this in the html `
`. Further instructions on how to select specific versions and semver ranges can be found on at [unpkg.com](https://unpkg.com).
-### Examples
-
-| Use Case | `.js` | `.css` |
-| :------- | :---: | :----: |
-| `latest` | | |
-| Use at least `2.4.x` | | |
+```html
+
+
+```
From ca4e603f5a01399b44deb7ae02127334dd97fa7d Mon Sep 17 00:00:00 2001
From: Birk Skyum <74932975+birkskyum@users.noreply.github.com>
Date: Fri, 20 Sep 2024 00:57:47 +0200
Subject: [PATCH 02/32] refactor(tests): replace jest.done() with platform
await/async/promises (#4684)
---
src/source/canvas_source.test.ts | 20 +-
src/source/geojson_source.test.ts | 56 ++---
src/source/geojson_source_diff.test.ts | 63 ++---
src/source/image_source.test.ts | 12 +-
src/source/raster_tile_source.test.ts | 20 +-
src/source/source_cache.test.ts | 164 +++++++------
src/source/terrain_source_cache.test.ts | 4 +-
src/source/tile_cache.test.ts | 11 +-
src/source/vector_tile_source.test.ts | 4 +-
src/source/vector_tile_worker_source.test.ts | 8 +-
src/source/video_source.test.ts | 4 +-
src/source/worker.test.ts | 12 +-
src/style/style.test.ts | 102 ++++----
src/style/style_layer.test.ts | 12 +-
src/ui/camera.test.ts | 217 ++++++++----------
src/ui/control/geolocate_control.test.ts | 6 +-
src/ui/control/logo_control.test.ts | 16 +-
src/ui/handler/dblclick_zoom.test.ts | 56 ++---
src/ui/handler/scroll_zoom.test.ts | 4 +-
src/ui/handler/tap_drag_zoom.test.ts | 28 +--
src/ui/map_tests/map_basic.test.ts | 12 +-
src/ui/map_tests/map_events.test.ts | 10 +-
src/ui/map_tests/map_feature_state.test.ts | 80 +++----
src/ui/map_tests/map_images.test.ts | 10 +-
src/ui/map_tests/map_is_moving.test.ts | 20 +-
src/ui/map_tests/map_is_rotating.test.ts | 8 +-
src/ui/map_tests/map_is_zooming.test.ts | 15 +-
src/ui/map_tests/map_layer.test.ts | 44 ++--
.../map_query_rendered_features.test.ts | 20 +-
src/ui/map_tests/map_render.test.ts | 20 +-
.../map_request_render_frame.test.ts | 4 +-
src/ui/map_tests/map_style.test.ts | 51 ++--
src/ui/map_tests/map_terrian.test.ts | 4 +-
src/ui/map_tests/map_webgl.test.ts | 12 +-
src/util/actor.test.ts | 4 +-
src/util/evented.test.ts | 5 +-
src/util/test/util.ts | 2 +-
src/util/throttle.test.ts | 21 +-
src/util/util.test.ts | 55 ++---
39 files changed, 565 insertions(+), 651 deletions(-)
diff --git a/src/source/canvas_source.test.ts b/src/source/canvas_source.test.ts
index 306ba5f5ae..fd75dd95a3 100644
--- a/src/source/canvas_source.test.ts
+++ b/src/source/canvas_source.test.ts
@@ -53,7 +53,7 @@ describe('CanvasSource', () => {
map = new StubMap();
});
- test('constructor', done => {
+ test('constructor', () => new Promise(done => {
const source = createSource();
expect(source.minzoom).toBe(0);
@@ -68,7 +68,7 @@ describe('CanvasSource', () => {
});
source.onAdd(map);
- });
+ }));
test('self-validates', () => {
const stub = jest.spyOn(console, 'error').mockImplementation(() => {});
@@ -95,7 +95,7 @@ describe('CanvasSource', () => {
});
- test('can be initialized with HTML element', done => {
+ test('can be initialized with HTML element', () => new Promise(done => {
const el = window.document.createElement('canvas');
const source = createSource({
canvas: el
@@ -109,9 +109,9 @@ describe('CanvasSource', () => {
});
source.onAdd(map);
- });
+ }));
- test('rerenders if animated', done => {
+ test('rerenders if animated', () => new Promise(done => {
const source = createSource();
map.on('rerender', () => {
@@ -120,9 +120,9 @@ describe('CanvasSource', () => {
});
source.onAdd(map);
- });
+ }));
- test('can be static', done => {
+ test('can be static', () => new Promise(done => {
const source = createSource({
animate: false
});
@@ -141,7 +141,7 @@ describe('CanvasSource', () => {
});
source.onAdd(map);
- });
+ }));
test('onRemove stops animation', () => {
const source = createSource();
@@ -177,7 +177,7 @@ describe('CanvasSource', () => {
});
- test('fires idle event on prepare call when there is at least one not loaded tile', done => {
+ test('fires idle event on prepare call when there is at least one not loaded tile', () => new Promise(done => {
const source = createSource();
const tile = new Tile(new OverscaledTileID(1, 0, 1, 0, 0), 512);
source.on('data', (e) => {
@@ -196,7 +196,7 @@ describe('CanvasSource', () => {
update: () => {}
} as any;
source.prepare();
- });
+ }));
});
diff --git a/src/source/geojson_source.test.ts b/src/source/geojson_source.test.ts
index 488275aff7..497b9ef041 100644
--- a/src/source/geojson_source.test.ts
+++ b/src/source/geojson_source.test.ts
@@ -102,15 +102,15 @@ describe('GeoJSONSource#setData', () => {
await setDataPromise;
});
- test('fires "dataloading" event', done => {
+ test('fires "dataloading" event', () => new Promise(done => {
const source = createSource();
source.on('dataloading', () => {
done();
});
source.load();
- });
+ }));
- test('fires "dataabort" event', done => {
+ test('fires "dataabort" event', () => new Promise(done => {
const source = new GeoJSONSource('id', {} as any, wrapDispatcher({
sendAsync(_message) {
return new Promise((resolve) => {
@@ -122,9 +122,9 @@ describe('GeoJSONSource#setData', () => {
done();
});
source.load();
- });
+ }));
- test('respects collectResourceTiming parameter on source', done => {
+ test('respects collectResourceTiming parameter on source', () => new Promise(done => {
const source = createSource({collectResourceTiming: true});
source.map = {
_requestManager: {
@@ -141,7 +141,7 @@ describe('GeoJSONSource#setData', () => {
});
};
source.setData('http://localhost/nonexistent');
- });
+ }));
test('only marks source as loaded when there are no pending loads', async () => {
const source = createSource();
@@ -171,7 +171,7 @@ describe('GeoJSONSource#setData', () => {
expect(source.loaded()).toBeTruthy();
});
- test('marks source as loaded before firing "dataabort" event', done => {
+ test('marks source as loaded before firing "dataabort" event', () => new Promise(done => {
const source = new GeoJSONSource('id', {} as any, wrapDispatcher({
sendAsync(_message: ActorMessage) {
return new Promise((resolve) => {
@@ -184,11 +184,11 @@ describe('GeoJSONSource#setData', () => {
done();
});
source.setData({} as GeoJSON.GeoJSON);
- });
+ }));
});
describe('GeoJSONSource#onRemove', () => {
- test('broadcasts "removeSource" event', done => {
+ test('broadcasts "removeSource" event', () => new Promise(done => {
const source = new GeoJSONSource('id', {data: {}} as GeoJSONSourceOptions, wrapDispatcher({
sendAsync(message: ActorMessage) {
expect(message.type).toBe(MessageType.removeSource);
@@ -201,7 +201,7 @@ describe('GeoJSONSource#onRemove', () => {
}
}), undefined);
source.onRemove();
- });
+ }));
});
describe('GeoJSONSource#update', () => {
@@ -212,7 +212,7 @@ describe('GeoJSONSource#update', () => {
transform.zoom = 15;
transform.setLocationAtPoint(lngLat, point);
- test('sends initial loadData request to dispatcher', done => {
+ test('sends initial loadData request to dispatcher', () => new Promise(done => {
const mockDispatcher = wrapDispatcher({
sendAsync(message: ActorMessage) {
expect(message.type).toBe(MessageType.loadData);
@@ -222,9 +222,9 @@ describe('GeoJSONSource#update', () => {
});
new GeoJSONSource('id', {data: {}} as GeoJSONSourceOptions, mockDispatcher, undefined).load();
- });
+ }));
- test('forwards geojson-vt options with worker request', done => {
+ test('forwards geojson-vt options with worker request', () => new Promise(done => {
const mockDispatcher = wrapDispatcher({
sendAsync(message: ActorMessage) {
expect(message.type).toBe(MessageType.loadData);
@@ -248,9 +248,9 @@ describe('GeoJSONSource#update', () => {
buffer: 16,
generateId: true
} as GeoJSONSourceOptions, mockDispatcher, undefined).load();
- });
+ }));
- test('forwards Supercluster options with worker request', done => {
+ test('forwards Supercluster options with worker request', () => new Promise(done => {
const mockDispatcher = wrapDispatcher({
sendAsync(message) {
expect(message.type).toBe(MessageType.loadData);
@@ -275,9 +275,9 @@ describe('GeoJSONSource#update', () => {
clusterMinPoints: 3,
generateId: true
} as GeoJSONSourceOptions, mockDispatcher, undefined).load();
- });
+ }));
- test('modifying cluster properties after adding a source', done => {
+ test('modifying cluster properties after adding a source', () => new Promise(done => {
// test setCluster function on GeoJSONSource
const mockDispatcher = wrapDispatcher({
sendAsync(message) {
@@ -297,9 +297,9 @@ describe('GeoJSONSource#update', () => {
clusterMinPoints: 3,
generateId: true
} as GeoJSONSourceOptions, mockDispatcher, undefined).setClusterOptions({cluster: true, clusterRadius: 80, clusterMaxZoom: 16});
- });
+ }));
- test('forwards Supercluster options with worker request, ignore max zoom of source', done => {
+ test('forwards Supercluster options with worker request, ignore max zoom of source', () => new Promise(done => {
const mockDispatcher = wrapDispatcher({
sendAsync(message) {
expect(message.type).toBe(MessageType.loadData);
@@ -325,7 +325,7 @@ describe('GeoJSONSource#update', () => {
clusterMinPoints: 3,
generateId: true
} as GeoJSONSourceOptions, mockDispatcher, undefined).load();
- });
+ }));
test('transforms url before making request', () => {
const mapStub = {
@@ -339,7 +339,7 @@ describe('GeoJSONSource#update', () => {
expect(transformSpy).toHaveBeenCalledTimes(1);
expect(transformSpy.mock.calls[0][0]).toBe('https://example.com/data.geojson');
});
- test('fires event when metadata loads', done => {
+ test('fires event when metadata loads', () => new Promise(done => {
const mockDispatcher = wrapDispatcher({
sendAsync(_message: ActorMessage) {
return new Promise((resolve) => {
@@ -355,9 +355,9 @@ describe('GeoJSONSource#update', () => {
});
source.load();
- });
+ }));
- test('fires metadata data event even when initial request is aborted', done => {
+ test('fires metadata data event even when initial request is aborted', () => new Promise(done => {
let requestCount = 0;
const mockDispatcher = wrapDispatcher({
sendAsync(_message) {
@@ -375,9 +375,9 @@ describe('GeoJSONSource#update', () => {
source.load();
source.setData({} as GeoJSON.GeoJSON);
- });
+ }));
- test('fires "error"', done => {
+ test('fires "error"', () => new Promise(done => {
const mockDispatcher = wrapDispatcher({
sendAsync(_message) {
return Promise.reject('error'); // eslint-disable-line prefer-promise-reject-errors
@@ -392,9 +392,9 @@ describe('GeoJSONSource#update', () => {
});
source.load();
- });
+ }));
- test('sends loadData request to dispatcher after data update', done => {
+ test('sends loadData request to dispatcher after data update', () => new Promise(done => {
let expectedLoadDataCalls = 2;
const mockDispatcher = wrapDispatcher({
sendAsync(message) {
@@ -419,7 +419,7 @@ describe('GeoJSONSource#update', () => {
});
source.load();
- });
+ }));
});
describe('GeoJSONSource#getData', () => {
diff --git a/src/source/geojson_source_diff.test.ts b/src/source/geojson_source_diff.test.ts
index 0bb6ab79af..6625b69222 100644
--- a/src/source/geojson_source_diff.test.ts
+++ b/src/source/geojson_source_diff.test.ts
@@ -6,7 +6,7 @@ beforeEach(() => {
});
describe('isUpdateableGeoJSON', () => {
- test('feature without id is not updateable', done => {
+ test('feature without id is not updateable', () => {
// no feature id -> false
expect(isUpdateableGeoJSON({
type: 'Feature',
@@ -16,10 +16,9 @@ describe('isUpdateableGeoJSON', () => {
},
properties: {},
})).toBe(false);
- done();
});
- test('feature with id is updateable', done => {
+ test('feature with id is updateable', () => {
// has a feature id -> true
expect(isUpdateableGeoJSON({
type: 'Feature',
@@ -30,10 +29,9 @@ describe('isUpdateableGeoJSON', () => {
},
properties: {},
})).toBe(true);
- done();
});
- test('promoteId missing is not updateable', done => {
+ test('promoteId missing is not updateable', () => {
expect(isUpdateableGeoJSON({
type: 'Feature',
id: 'feature_id',
@@ -43,10 +41,9 @@ describe('isUpdateableGeoJSON', () => {
},
properties: {},
}, 'propId')).toBe(false);
- done();
});
- test('promoteId present is updateable', done => {
+ test('promoteId present is updateable', () => {
expect(isUpdateableGeoJSON({
type: 'Feature',
geometry: {
@@ -57,10 +54,9 @@ describe('isUpdateableGeoJSON', () => {
propId: 'feature_id',
},
}, 'propId')).toBe(true);
- done();
});
- test('feature collection with unique ids is updateable', done => {
+ test('feature collection with unique ids is updateable', () => {
expect(isUpdateableGeoJSON({
type: 'FeatureCollection',
features: [{
@@ -81,10 +77,9 @@ describe('isUpdateableGeoJSON', () => {
properties: {},
}]
})).toBe(true);
- done();
});
- test('feature collection with unique promoteIds is updateable', done => {
+ test('feature collection with unique promoteIds is updateable', () => {
expect(isUpdateableGeoJSON({
type: 'FeatureCollection',
features: [{
@@ -107,10 +102,9 @@ describe('isUpdateableGeoJSON', () => {
},
}]
}, 'propId')).toBe(true);
- done();
});
- test('feature collection without unique ids is not updateable', done => {
+ test('feature collection without unique ids is not updateable', () => {
expect(isUpdateableGeoJSON({
type: 'FeatureCollection',
features: [{
@@ -122,10 +116,9 @@ describe('isUpdateableGeoJSON', () => {
properties: {},
}]
})).toBe(false);
- done();
});
- test('feature collection with duplicate feature ids is not updateable', done => {
+ test('feature collection with duplicate feature ids is not updateable', () => {
expect(isUpdateableGeoJSON({
type: 'FeatureCollection',
features: [{
@@ -146,17 +139,15 @@ describe('isUpdateableGeoJSON', () => {
properties: {},
}]
})).toBe(false);
- done();
});
- test('geometries are not updateable', done => {
+ test('geometries are not updateable', () => {
expect(isUpdateableGeoJSON({type: 'Point', coordinates: [0, 0]})).toBe(false);
- done();
});
});
describe('toUpdateable', () => {
- test('works with a single feature - feature id', done => {
+ test('works with a single feature - feature id', () => {
const updateable = toUpdateable({
type: 'Feature',
id: 'point',
@@ -166,10 +157,9 @@ describe('toUpdateable', () => {
}, properties: {}});
expect(updateable.size).toBe(1);
expect(updateable.has('point')).toBeTruthy();
- done();
});
- test('works with a single feature - promoteId', done => {
+ test('works with a single feature - promoteId', () => {
const updateable2 = toUpdateable({
type: 'Feature',
geometry: {
@@ -180,10 +170,9 @@ describe('toUpdateable', () => {
}}, 'promoteId');
expect(updateable2.size).toBe(1);
expect(updateable2.has('point')).toBeTruthy();
- done();
});
- test('works with a FeatureCollection - feature id', done => {
+ test('works with a FeatureCollection - feature id', () => {
const updateable = toUpdateable({
type: 'FeatureCollection',
features: [
@@ -206,10 +195,9 @@ describe('toUpdateable', () => {
expect(updateable.size).toBe(2);
expect(updateable.has('point')).toBeTruthy();
expect(updateable.has('point2')).toBeTruthy();
- done();
});
- test('works with a FeatureCollection - promoteId', done => {
+ test('works with a FeatureCollection - promoteId', () => {
const updateable2 = toUpdateable({
type: 'FeatureCollection',
features: [
@@ -234,7 +222,6 @@ describe('toUpdateable', () => {
expect(updateable2.size).toBe(2);
expect(updateable2.has('point')).toBeTruthy();
expect(updateable2.has('point2')).toBeTruthy();
- done();
});
});
@@ -270,7 +257,7 @@ describe('applySourceDiff', () => {
Object.freeze((point2.geometry as GeoJSON.Point).coordinates);
Object.freeze(point2.properties);
- test('adds a feature using the feature id', done => {
+ test('adds a feature using the feature id', () => {
const updateable = new Map();
applySourceDiff(updateable, {
@@ -278,30 +265,27 @@ describe('applySourceDiff', () => {
});
expect(updateable.size).toBe(1);
expect(updateable.has('point')).toBeTruthy();
- done();
});
- test('adds a feature using the promoteId', done => {
+ test('adds a feature using the promoteId', () => {
const updateable = new Map();
applySourceDiff(updateable, {
add: [point2]
}, 'promoteId');
expect(updateable.size).toBe(1);
expect(updateable.has('point2')).toBeTruthy();
- done();
});
- test('removes a feature by its id', done => {
+ test('removes a feature by its id', () => {
const updateable = new Map([['point', point], ['point2', point2]]);
applySourceDiff(updateable, {
remove: ['point2'],
});
expect(updateable.size).toBe(1);
expect(updateable.has('point2')).toBeFalsy();
- done();
});
- test('updates a feature geometry', done => {
+ test('updates a feature geometry', () => {
const updateable = new Map([['point', point]]);
// update -> new geometry
applySourceDiff(updateable, {
@@ -315,10 +299,9 @@ describe('applySourceDiff', () => {
});
expect(updateable.size).toBe(1);
expect((updateable.get('point')?.geometry as GeoJSON.Point).coordinates[0]).toBe(1);
- done();
});
- test('adds properties', done => {
+ test('adds properties', () => {
const updateable = new Map([['point', point]]);
applySourceDiff(updateable, {
update: [{
@@ -334,10 +317,9 @@ describe('applySourceDiff', () => {
expect(Object.keys(properties)).toHaveLength(2);
expect(properties.prop).toBe('value');
expect(properties.prop2).toBe('value2');
- done();
});
- test('updates properties', done => {
+ test('updates properties', () => {
const updateable = new Map([['point', {...point, properties: {prop: 'value', prop2: 'value2'}}]]);
applySourceDiff(updateable, {
update: [{
@@ -352,10 +334,9 @@ describe('applySourceDiff', () => {
expect(Object.keys(properties2)).toHaveLength(2);
expect(properties2.prop).toBe('value');
expect(properties2.prop2).toBe('value3');
- done();
});
- test('removes properties', done => {
+ test('removes properties', () => {
const updateable = new Map([['point', {...point, properties: {prop: 'value', prop2: 'value2'}}]]);
applySourceDiff(updateable, {
update: [{
@@ -367,10 +348,9 @@ describe('applySourceDiff', () => {
const properties3 = updateable.get('point')?.properties!;
expect(Object.keys(properties3)).toHaveLength(1);
expect(properties3.prop).toBe('value');
- done();
});
- test('removes all properties', done => {
+ test('removes all properties', () => {
const updateable = new Map([['point', {...point, properties: {prop: 'value', prop2: 'value2'}}]]);
applySourceDiff(updateable, {
update: [{
@@ -380,6 +360,5 @@ describe('applySourceDiff', () => {
});
expect(updateable.size).toBe(1);
expect(Object.keys(updateable.get('point')?.properties!)).toHaveLength(0);
- done();
});
});
diff --git a/src/source/image_source.test.ts b/src/source/image_source.test.ts
index e1c34d62bc..9b3358eaec 100644
--- a/src/source/image_source.test.ts
+++ b/src/source/image_source.test.ts
@@ -128,7 +128,7 @@ describe('ImageSource', () => {
expect(afterSerialized.coordinates).toEqual([[0, 0], [-1, 0], [-1, -1], [0, -1]]);
});
- test('fires data event when content is loaded', done => {
+ test('fires data event when content is loaded', () => new Promise(done => {
const source = createSource({url: '/image.png'});
source.on('data', (e) => {
if (e.dataType === 'source' && e.sourceDataType === 'content') {
@@ -138,9 +138,9 @@ describe('ImageSource', () => {
});
source.onAdd(new StubMap() as any);
server.respond();
- });
+ }));
- test('fires data event when metadata is loaded', done => {
+ test('fires data event when metadata is loaded', () => new Promise(done => {
const source = createSource({url: '/image.png'});
source.on('data', (e) => {
if (e.dataType === 'source' && e.sourceDataType === 'metadata') {
@@ -149,9 +149,9 @@ describe('ImageSource', () => {
});
source.onAdd(new StubMap() as any);
server.respond();
- });
+ }));
- test('fires idle event on prepare call when there is at least one not loaded tile', done => {
+ test('fires idle event on prepare call when there is at least one not loaded tile', () => new Promise(done => {
const source = createSource({url: '/image.png'});
const tile = new Tile(new OverscaledTileID(1, 0, 1, 0, 0), 512);
source.on('data', (e) => {
@@ -170,7 +170,7 @@ describe('ImageSource', () => {
source.boundsSegments = {} as SegmentVector;
source.texture = {} as Texture;
source.prepare();
- });
+ }));
test('serialize url and coordinates', () => {
const source = createSource({url: '/image.png'});
diff --git a/src/source/raster_tile_source.test.ts b/src/source/raster_tile_source.test.ts
index 0c145d8f63..be8346886a 100644
--- a/src/source/raster_tile_source.test.ts
+++ b/src/source/raster_tile_source.test.ts
@@ -50,7 +50,7 @@ describe('RasterTileSource', () => {
expect(transformSpy.mock.calls[0][1]).toBe('Source');
});
- test('respects TileJSON.bounds', done => {
+ test('respects TileJSON.bounds', () => new Promise(done => {
const source = createSource({
minzoom: 0,
maxzoom: 22,
@@ -65,9 +65,9 @@ describe('RasterTileSource', () => {
done();
}
});
- });
+ }));
- test('does not error on invalid bounds', done => {
+ test('does not error on invalid bounds', () => new Promise(done => {
const source = createSource({
minzoom: 0,
maxzoom: 22,
@@ -82,9 +82,9 @@ describe('RasterTileSource', () => {
done();
}
});
- });
+ }));
- test('respects TileJSON.bounds when loaded from TileJSON', done => {
+ test('respects TileJSON.bounds when loaded from TileJSON', () => new Promise(done => {
server.respondWith('/source.json', JSON.stringify({
minzoom: 0,
maxzoom: 22,
@@ -102,9 +102,9 @@ describe('RasterTileSource', () => {
}
});
server.respond();
- });
+ }));
- test('transforms tile urls before requesting', done => {
+ test('transforms tile urls before requesting', () => new Promise(done => {
server.respondWith('/source.json', JSON.stringify({
minzoom: 0,
maxzoom: 22,
@@ -130,9 +130,9 @@ describe('RasterTileSource', () => {
}
});
server.respond();
- });
+ }));
- test('HttpImageElement used to get image when refreshExpiredTiles is false', done => {
+ test('HttpImageElement used to get image when refreshExpiredTiles is false', () => new Promise(done => {
stubAjaxGetImage(undefined);
server.respondWith('/source.json', JSON.stringify({
minzoom: 0,
@@ -160,7 +160,7 @@ describe('RasterTileSource', () => {
}
});
server.respond();
- });
+ }));
test('supports updating tiles', () => {
const source = createSource({url: '/source.json'});
diff --git a/src/source/source_cache.test.ts b/src/source/source_cache.test.ts
index a363904ffa..a80f7a1e18 100644
--- a/src/source/source_cache.test.ts
+++ b/src/source/source_cache.test.ts
@@ -41,7 +41,7 @@ class SourceMock extends Evented implements Source {
expires: this.sourceOptions.expires
});
}
- return new Promise(resolve => setTimeout(resolve, 0));
+ return sleep(0);
}
loaded() {
return true;
@@ -103,7 +103,7 @@ afterEach(() => {
});
describe('SourceCache#addTile', () => {
- test('loads tile when uncached', done => {
+ test('loads tile when uncached', () => new Promise(done => {
const tileID = new OverscaledTileID(0, 0, 0, 0, 0);
const sourceCache = createSourceCache();
sourceCache._source.loadTile = async (tile) => {
@@ -113,9 +113,9 @@ describe('SourceCache#addTile', () => {
};
sourceCache.onAdd(undefined);
sourceCache._addTile(tileID);
- });
+ }));
- test('adds tile when uncached', done => {
+ test('adds tile when uncached', () => new Promise(done => {
const tileID = new OverscaledTileID(0, 0, 0, 0, 0);
const sourceCache = createSourceCache({}).on('dataloading', (data) => {
expect(data.tile.tileID).toEqual(tileID);
@@ -124,9 +124,9 @@ describe('SourceCache#addTile', () => {
});
sourceCache.onAdd(undefined);
sourceCache._addTile(tileID);
- });
+ }));
- test('updates feature state on added uncached tile', done => {
+ test('updates feature state on added uncached tile', () => new Promise(done => {
const tileID = new OverscaledTileID(0, 0, 0, 0, 0);
let updateFeaturesSpy;
const sourceCache = createSourceCache({});
@@ -140,7 +140,7 @@ describe('SourceCache#addTile', () => {
};
sourceCache.onAdd(undefined);
sourceCache._addTile(tileID);
- });
+ }));
test('uses cached tile', () => {
const tileID = new OverscaledTileID(0, 0, 0, 0, 0);
@@ -278,7 +278,7 @@ describe('SourceCache#addTile', () => {
});
describe('SourceCache#removeTile', () => {
- test('removes tile', done => {
+ test('removes tile', () => new Promise(done => {
const tileID = new OverscaledTileID(0, 0, 0, 0, 0);
const sourceCache = createSourceCache({});
sourceCache._addTile(tileID);
@@ -287,7 +287,7 @@ describe('SourceCache#removeTile', () => {
expect(sourceCache._tiles[tileID.key]).toBeFalsy();
done();
});
- });
+ }));
test('caches (does not unload) loaded tile', () => {
const tileID = new OverscaledTileID(0, 0, 0, 0, 0);
@@ -390,52 +390,51 @@ describe('SourceCache#removeTile', () => {
});
describe('SourceCache / Source lifecycle', () => {
- test('does not fire load or change before source load event', done => {
+ test('does not fire load or change before source load event', () => new Promise((done) => {
const sourceCache = createSourceCache({noLoad: true})
- .on('data', () => done('test failed: data event fired'));
+ .on('data', () => { throw new Error('test failed: data event fired'); });
sourceCache.onAdd(undefined);
setTimeout(() => done(), 1);
- });
+ }));
- test('forward load event', done => {
+ test('forward load event', () => new Promise(done => {
const sourceCache = createSourceCache({}).on('data', (e) => {
if (e.sourceDataType === 'metadata') done();
});
sourceCache.onAdd(undefined);
- });
+ }));
- test('forward change event', done => {
+ test('forward change event', () => new Promise(done => {
const sourceCache = createSourceCache().on('data', (e) => {
if (e.sourceDataType === 'metadata') done();
});
sourceCache.onAdd(undefined);
sourceCache.getSource().fire(new Event('data'));
- });
+ }));
- test('forward error event', done => {
+ test('forward error event', () => new Promise(done => {
const sourceCache = createSourceCache({error: 'Error loading source'}).on('error', (err) => {
expect(err.error).toBe('Error loading source');
done();
});
sourceCache.onAdd(undefined);
- });
+ }));
- test('suppress 404 errors', done => {
+ test('suppress 404 errors', () => {
const sourceCache = createSourceCache({status: 404, message: 'Not found'})
- .on('error', () => done('test failed: error event fired'));
+ .on('error', () => { throw new Error('test failed: error event fired'); });
sourceCache.onAdd(undefined);
- done();
});
- test('loaded() true after source error', done => {
+ test('loaded() true after source error', () => new Promise(done => {
const sourceCache = createSourceCache({error: 'Error loading source'}).on('error', () => {
expect(sourceCache.loaded()).toBeTruthy();
done();
});
sourceCache.onAdd(undefined);
- });
+ }));
- test('loaded() true after tile error', done => {
+ test('loaded() true after tile error', () => new Promise(done => {
const transform = new Transform();
transform.resize(511, 511);
transform.zoom = 0;
@@ -453,9 +452,9 @@ describe('SourceCache / Source lifecycle', () => {
});
sourceCache.onAdd(undefined);
- });
+ }));
- test('loaded() false after source begins loading following error', done => {
+ test('loaded() false after source begins loading following error', () => new Promise(done => {
const sourceCache = createSourceCache({error: 'Error loading source'}).on('error', () => {
sourceCache.on('dataloading', () => {
expect(sourceCache.loaded()).toBeFalsy();
@@ -465,9 +464,9 @@ describe('SourceCache / Source lifecycle', () => {
});
sourceCache.onAdd(undefined);
- });
+ }));
- test('loaded() false when error occurs while source is not loaded', done => {
+ test('loaded() false when error occurs while source is not loaded', () => new Promise(done => {
const sourceCache = createSourceCache({
error: 'Error loading source',
@@ -480,7 +479,7 @@ describe('SourceCache / Source lifecycle', () => {
});
sourceCache.onAdd(undefined);
- });
+ }));
test('reloads tiles after a data event where source is updated', () => {
const transform = new Transform();
@@ -535,7 +534,7 @@ describe('SourceCache / Source lifecycle', () => {
});
describe('SourceCache#update', () => {
- test('loads no tiles if used is false', done => {
+ test('loads no tiles if used is false', () => new Promise(done => {
const transform = new Transform();
transform.resize(512, 512);
transform.zoom = 0;
@@ -549,9 +548,9 @@ describe('SourceCache#update', () => {
}
});
sourceCache.onAdd(undefined);
- });
+ }));
- test('loads covering tiles', done => {
+ test('loads covering tiles', () => new Promise(done => {
const transform = new Transform();
transform.resize(511, 511);
transform.zoom = 0;
@@ -565,9 +564,9 @@ describe('SourceCache#update', () => {
}
});
sourceCache.onAdd(undefined);
- });
+ }));
- test('respects Source#hasTile method if it is present', done => {
+ test('respects Source#hasTile method if it is present', () => new Promise(done => {
const transform = new Transform();
transform.resize(511, 511);
transform.zoom = 1;
@@ -586,9 +585,9 @@ describe('SourceCache#update', () => {
}
});
sourceCache.onAdd(undefined);
- });
+ }));
- test('removes unused tiles', done => {
+ test('removes unused tiles', () => new Promise(done => {
const transform = new Transform();
transform.resize(511, 511);
transform.zoom = 0;
@@ -617,9 +616,9 @@ describe('SourceCache#update', () => {
});
sourceCache.onAdd(undefined);
- });
+ }));
- test('retains parent tiles for pending children', done => {
+ test('retains parent tiles for pending children', () => new Promise(done => {
const transform = new Transform();
(transform as any)._test = 'retains';
transform.resize(511, 511);
@@ -649,9 +648,9 @@ describe('SourceCache#update', () => {
}
});
sourceCache.onAdd(undefined);
- });
+ }));
- test('retains parent tiles for pending children (wrapped)', done => {
+ test('retains parent tiles for pending children (wrapped)', () => new Promise(done => {
const transform = new Transform();
transform.resize(511, 511);
transform.zoom = 0;
@@ -681,9 +680,9 @@ describe('SourceCache#update', () => {
}
});
sourceCache.onAdd(undefined);
- });
+ }));
- test('retains covered child tiles while parent tile is fading in', done => {
+ test('retains covered child tiles while parent tile is fading in', () => new Promise(done => {
const transform = new Transform();
transform.resize(511, 511);
transform.zoom = 2;
@@ -715,9 +714,9 @@ describe('SourceCache#update', () => {
}
});
sourceCache.onAdd(undefined);
- });
+ }));
- test('retains a parent tile for fading even if a tile is partially covered by children', done => {
+ test('retains a parent tile for fading even if a tile is partially covered by children', () => new Promise(done => {
const transform = new Transform();
transform.resize(511, 511);
transform.zoom = 0;
@@ -746,9 +745,9 @@ describe('SourceCache#update', () => {
}
});
sourceCache.onAdd(undefined);
- });
+ }));
- test('retain children for fading fadeEndTime is 0 (added but registerFadeDuration() is not called yet)', done => {
+ test('retain children for fading fadeEndTime is 0 (added but registerFadeDuration() is not called yet)', () => new Promise(done => {
const transform = new Transform();
transform.resize(511, 511);
transform.zoom = 1;
@@ -774,9 +773,9 @@ describe('SourceCache#update', () => {
}
});
sourceCache.onAdd(undefined);
- });
+ }));
- test('retains children when tile.fadeEndTime is in the future', done => {
+ test('retains children when tile.fadeEndTime is in the future', () => new Promise(done => {
const transform = new Transform();
transform.resize(511, 511);
transform.zoom = 1;
@@ -818,9 +817,9 @@ describe('SourceCache#update', () => {
});
sourceCache.onAdd(undefined);
- });
+ }));
- test('retains overscaled loaded children', done => {
+ test('retains overscaled loaded children', () => new Promise(done => {
const transform = new Transform();
transform.resize(511, 511);
transform.zoom = 16;
@@ -856,9 +855,9 @@ describe('SourceCache#update', () => {
}
});
sourceCache.onAdd(undefined);
- });
+ }));
- test('reassigns tiles for large jumps in longitude', done => {
+ test('reassigns tiles for large jumps in longitude', () => new Promise(done => {
const transform = new Transform();
transform.resize(511, 511);
@@ -882,7 +881,7 @@ describe('SourceCache#update', () => {
}
});
sourceCache.onAdd(undefined);
- });
+ }));
});
@@ -1392,7 +1391,7 @@ describe('SourceCache#tilesIn', () => {
});
}
- test('regular tiles', done => {
+ test('regular tiles', () => new Promise(done => {
const transform = new Transform();
transform.resize(512, 512);
transform.zoom = 1;
@@ -1437,7 +1436,7 @@ describe('SourceCache#tilesIn', () => {
}
});
sourceCache.onAdd(undefined);
- });
+ }));
test('reparsed overscaled tiles', () => {
const sourceCache = createSourceCache({
@@ -1488,7 +1487,7 @@ describe('SourceCache#tilesIn', () => {
sourceCache.onAdd(undefined);
});
- test('overscaled tiles', done => {
+ test('overscaled tiles', () => new Promise(done => {
const sourceCache = createSourceCache({
reparseOverscaled: false,
minzoom: 1,
@@ -1510,11 +1509,11 @@ describe('SourceCache#tilesIn', () => {
}
});
sourceCache.onAdd(undefined);
- });
+ }));
});
describe('source cache loaded', () => {
- test('SourceCache#loaded (no errors)', done => {
+ test('SourceCache#loaded (no errors)', () => new Promise(done => {
const sourceCache = createSourceCache();
sourceCache._source.loadTile = async (tile) => {
tile.state = 'loaded';
@@ -1534,9 +1533,9 @@ describe('source cache loaded', () => {
}
});
sourceCache.onAdd(undefined);
- });
+ }));
- test('SourceCache#loaded (with errors)', done => {
+ test('SourceCache#loaded (with errors)', () => new Promise(done => {
const sourceCache = createSourceCache();
sourceCache._source.loadTile = async (tile) => {
tile.state = 'errored';
@@ -1557,9 +1556,9 @@ describe('source cache loaded', () => {
}
});
sourceCache.onAdd(undefined);
- });
+ }));
- test('SourceCache#loaded (unused)', done => {
+ test('SourceCache#loaded (unused)', () => new Promise(done => {
const sourceCache = createSourceCache(undefined, false);
sourceCache._source.loadTile = async (tile) => {
tile.state = 'errored';
@@ -1573,9 +1572,9 @@ describe('source cache loaded', () => {
}
});
sourceCache.onAdd(undefined);
- });
+ }));
- test('SourceCache#loaded (unusedForTerrain)', done => {
+ test('SourceCache#loaded (unusedForTerrain)', () => new Promise(done => {
const sourceCache = createSourceCache(undefined, false);
sourceCache._source.loadTile = async (tile) => {
tile.state = 'errored';
@@ -1590,9 +1589,9 @@ describe('source cache loaded', () => {
}
});
sourceCache.onAdd(undefined);
- });
+ }));
- test('SourceCache#loaded (not loaded when no update)', done => {
+ test('SourceCache#loaded (not loaded when no update)', () => new Promise(done => {
const sourceCache = createSourceCache();
sourceCache._source.loadTile = async (tile) => {
tile.state = 'errored';
@@ -1606,9 +1605,9 @@ describe('source cache loaded', () => {
}
});
sourceCache.onAdd(undefined);
- });
+ }));
- test('SourceCache#loaded (on last tile load)', done => {
+ test('SourceCache#loaded (on last tile load)', () => new Promise(done => {
const sourceCache = createSourceCache();
sourceCache._source.loadTile = async (tile) => {
tile.state = 'loading';
@@ -1643,9 +1642,9 @@ describe('source cache loaded', () => {
sourceCache.onAdd(undefined);
sourceCache.update(tr);
- });
+ }));
- test('SourceCache#loaded (tiles outside bounds, idle)', done => {
+ test('SourceCache#loaded (tiles outside bounds, idle)', () => new Promise(done => {
const japan = new TileBounds([122.74, 19.33, 149.0, 45.67]);
const sourceCache = createSourceCache();
sourceCache._source.loadTile = async (tile) => {
@@ -1685,11 +1684,11 @@ describe('source cache loaded', () => {
tr.zoom = 10;
tr.resize(512, 512);
sourceCache.update(tr);
- });
+ }));
});
describe('source cache get ids', () => {
- test('SourceCache#getIds (ascending order by zoom level)', done => {
+ test('SourceCache#getIds (ascending order by zoom level)', () => {
const ids = [
new OverscaledTileID(0, 0, 0, 0, 0),
new OverscaledTileID(3, 0, 3, 0, 0),
@@ -1708,7 +1707,6 @@ describe('source cache get ids', () => {
new OverscaledTileID(2, 0, 2, 0, 0).key,
new OverscaledTileID(3, 0, 3, 0, 0).key
]);
- done();
});
});
@@ -1917,7 +1915,7 @@ describe('SourceCache#reload', () => {
});
describe('SourceCache reloads expiring tiles', () => {
- test('calls reloadTile when tile expires', done => {
+ test('calls reloadTile when tile expires', () => new Promise(done => {
const coord = new OverscaledTileID(1, 0, 1, 0, 1);
const expiryDate = new Date();
@@ -1930,7 +1928,7 @@ describe('SourceCache reloads expiring tiles', () => {
};
sourceCache._addTile(coord);
- });
+ }));
});
@@ -1988,7 +1986,7 @@ describe('SourceCache#onRemove', () => {
});
describe('SourceCache#usedForTerrain', () => {
- test('loads covering tiles with usedForTerrain with source zoom 0-14', done => {
+ test('loads covering tiles with usedForTerrain with source zoom 0-14', () => new Promise(done => {
const transform = new Transform();
transform.resize(511, 511);
transform.zoom = 10;
@@ -2007,9 +2005,9 @@ describe('SourceCache#usedForTerrain', () => {
}
});
sourceCache.onAdd(undefined);
- });
+ }));
- test('loads covering tiles with usedForTerrain with source zoom 8-14', done => {
+ test('loads covering tiles with usedForTerrain with source zoom 8-14', () => new Promise(done => {
const transform = new Transform();
transform.resize(511, 511);
transform.zoom = 10;
@@ -2027,9 +2025,9 @@ describe('SourceCache#usedForTerrain', () => {
}
});
sourceCache.onAdd(undefined);
- });
+ }));
- test('loads covering tiles with usedForTerrain with source zoom 0-4', done => {
+ test('loads covering tiles with usedForTerrain with source zoom 0-4', () => new Promise(done => {
const transform = new Transform();
transform.resize(511, 511);
transform.zoom = 10;
@@ -2047,9 +2045,9 @@ describe('SourceCache#usedForTerrain', () => {
}
});
sourceCache.onAdd(undefined);
- });
+ }));
- test('loads covering tiles with usedForTerrain with source zoom 4-4', done => {
+ test('loads covering tiles with usedForTerrain with source zoom 4-4', () => new Promise(done => {
const transform = new Transform();
transform.resize(511, 511);
transform.zoom = 10;
@@ -2067,5 +2065,5 @@ describe('SourceCache#usedForTerrain', () => {
}
});
sourceCache.onAdd(undefined);
- });
+ }));
});
diff --git a/src/source/terrain_source_cache.test.ts b/src/source/terrain_source_cache.test.ts
index a947a543fa..3e0b433e4d 100644
--- a/src/source/terrain_source_cache.test.ts
+++ b/src/source/terrain_source_cache.test.ts
@@ -55,7 +55,7 @@ describe('TerrainSourceCache', () => {
let style: Style;
let tsc: TerrainSourceCache;
- beforeAll(done => {
+ beforeAll(() => new Promise(done => {
global.fetch = null;
server = fakeServer.create();
server.respondWith('/source.json', JSON.stringify({
@@ -79,7 +79,7 @@ describe('TerrainSourceCache', () => {
'sources': {},
'layers': []
});
- });
+ }));
afterAll(() => {
server.restore();
diff --git a/src/source/tile_cache.test.ts b/src/source/tile_cache.test.ts
index ee87708587..4a6173653b 100644
--- a/src/source/tile_cache.test.ts
+++ b/src/source/tile_cache.test.ts
@@ -30,22 +30,20 @@ describe('TileCache', () => {
keysExpected(cache, []);
});
- test('get without removing', done => {
+ test('get without removing', () => {
const cache = new TileCache(10, () => {
- done('test "get without removing" failed');
+ throw new Error('test "get without removing" failed');
});
expect(cache.add(idA, tileA)).toBe(cache);
expect(cache.get(idA)).toBe(tileA);
keysExpected(cache, [idA]);
expect(cache.get(idA)).toBe(tileA);
- done();
});
- test('duplicate add', done => {
+ test('duplicate add', () => {
const cache = new TileCache(10, () => {
- done('test "duplicate add" failed');
+ throw new Error('test "duplicate add" failed');
});
-
cache.add(idA, tileA);
cache.add(idA, tileA2);
@@ -54,7 +52,6 @@ describe('TileCache', () => {
expect(cache.getAndRemove(idA)).toBe(tileA);
expect(cache.has(idA)).toBeTruthy();
expect(cache.getAndRemove(idA)).toBe(tileA2);
- done();
});
test('expiry', () => {
diff --git a/src/source/vector_tile_source.test.ts b/src/source/vector_tile_source.test.ts
index bd049c5035..2df1dd5daf 100644
--- a/src/source/vector_tile_source.test.ts
+++ b/src/source/vector_tile_source.test.ts
@@ -78,14 +78,14 @@ describe('VectorTileSource', () => {
expect(transformSpy).toHaveBeenCalledWith('/source.json', 'Source');
});
- test('fires event with metadata property', done => {
+ test('fires event with metadata property', () => new Promise(done => {
server.respondWith('/source.json', JSON.stringify(fixturesSource));
const source = createSource({url: '/source.json'});
source.on('data', (e) => {
if (e.sourceDataType === 'content') done();
});
server.respond();
- });
+ }));
test('fires "dataloading" event', async () => {
server.respondWith('/source.json', JSON.stringify(fixturesSource));
diff --git a/src/source/vector_tile_worker_source.test.ts b/src/source/vector_tile_worker_source.test.ts
index 60f4aefb90..defc3a9798 100644
--- a/src/source/vector_tile_worker_source.test.ts
+++ b/src/source/vector_tile_worker_source.test.ts
@@ -241,7 +241,7 @@ describe('vector tile worker source', () => {
expect(await promise).toBeNull();
});
- test('VectorTileWorkerSource#returns a good error message when failing to parse a tile', done => {
+ test('VectorTileWorkerSource#returns a good error message when failing to parse a tile', () => new Promise(done => {
const source = new VectorTileWorkerSource(actor, new StyleLayerIndex(), []);
const parse = jest.fn();
@@ -262,9 +262,9 @@ describe('vector tile worker source', () => {
server.respond();
expect(parse).not.toHaveBeenCalled();
- });
+ }));
- test('VectorTileWorkerSource#returns a good error message when failing to parse a gzipped tile', done => {
+ test('VectorTileWorkerSource#returns a good error message when failing to parse a gzipped tile', () => new Promise(done => {
const source = new VectorTileWorkerSource(actor, new StyleLayerIndex(), []);
const parse = jest.fn();
@@ -283,7 +283,7 @@ describe('vector tile worker source', () => {
server.respond();
expect(parse).not.toHaveBeenCalled();
- });
+ }));
test('VectorTileWorkerSource provides resource timing information', async () => {
const rawTileData = fs.readFileSync(path.join(__dirname, '/../../test/unit/assets/mbsv5-6-18-23.vector.pbf'));
diff --git a/src/source/video_source.test.ts b/src/source/video_source.test.ts
index d7ef11c150..69d6d3b78c 100644
--- a/src/source/video_source.test.ts
+++ b/src/source/video_source.test.ts
@@ -87,7 +87,7 @@ describe('VideoSource', () => {
expect(source.getVideo()).toBe(el);
});
- test('fires idle event on prepare call when there is at least one not loaded tile', done => {
+ test('fires idle event on prepare call when there is at least one not loaded tile', () => new Promise(done => {
const source = createSource({
type: 'video',
urls: [],
@@ -120,5 +120,5 @@ describe('VideoSource', () => {
bind: () => {}
} as any;
source.prepare();
- });
+ }));
});
diff --git a/src/source/worker.test.ts b/src/source/worker.test.ts
index cbeb595775..7e850b72e5 100644
--- a/src/source/worker.test.ts
+++ b/src/source/worker.test.ts
@@ -154,7 +154,7 @@ describe('Worker generic testing', () => {
global.fetch = null;
});
- test('should validate handlers execution in worker for load tile', done => {
+ test('should validate handlers execution in worker for load tile', () => new Promise(done => {
const server = fakeServer.create();
worker.actor.messageHandlers[MessageType.loadTile]('0', {
type: 'vector',
@@ -168,7 +168,7 @@ describe('Worker generic testing', () => {
done();
});
server.respond();
- });
+ }));
test('isolates different instances\' data', () => {
worker.actor.messageHandlers[MessageType.setLayers]('0', [
@@ -183,7 +183,7 @@ describe('Worker generic testing', () => {
expect(worker.layerIndexes[0]).not.toBe(worker.layerIndexes[1]);
});
- test('worker source messages dispatched to the correct map instance', done => {
+ test('worker source messages dispatched to the correct map instance', () => new Promise(done => {
const externalSourceName = 'test';
worker.actor.sendAsync = (message, abortController) => {
@@ -201,14 +201,14 @@ describe('Worker generic testing', () => {
}).toThrow(`Worker source with name "${externalSourceName}" already registered.`);
worker.actor.messageHandlers[MessageType.loadTile]('999', {type: externalSourceName} as WorkerTileParameters);
- });
+ }));
test('Referrer is set', () => {
worker.actor.messageHandlers[MessageType.setReferrer]('fakeId', 'myMap');
expect(worker.referrer).toBe('myMap');
});
- test('calls callback on error', done => {
+ test('calls callback on error', () => new Promise(done => {
const server = fakeServer.create();
worker.actor.messageHandlers[MessageType.importScript]('0', '/error').catch((err) => {
expect(err).toBeTruthy();
@@ -216,7 +216,7 @@ describe('Worker generic testing', () => {
done();
});
server.respond();
- });
+ }));
test('set images', () => {
expect(worker.availableImages['0']).toBeUndefined();
diff --git a/src/style/style.test.ts b/src/style/style.test.ts
index 5bc79c228c..57f889c3d8 100644
--- a/src/style/style.test.ts
+++ b/src/style/style.test.ts
@@ -152,7 +152,7 @@ describe('Style#loadURL', () => {
expect(spy.mock.calls[0][1]).toBe('Style');
});
- test('validates the style', done => {
+ test('validates the style', () => new Promise(done => {
const style = new Style(getStubMap());
style.on('error', ({error}) => {
@@ -164,7 +164,7 @@ describe('Style#loadURL', () => {
style.loadURL('style.json');
server.respondWith(JSON.stringify(createStyleJSON({version: 'invalid'})));
server.respond();
- });
+ }));
test('cancels pending requests if removed', () => {
const style = new Style(getStubMap());
@@ -371,7 +371,7 @@ describe('Style#loadJSON', () => {
expect(transformSpy.mock.calls[1][1]).toBe('SpriteImage');
});
- test('emits an error on non-existant vector source layer', done => {
+ test('emits an error on non-existant vector source layer', () => new Promise(done => {
const style = createStyle();
style.loadJSON(createStyleJSON({
sources: {
@@ -404,9 +404,9 @@ describe('Style#loadJSON', () => {
done();
});
- });
+ }));
- test('sets up layer event forwarding', done => {
+ test('sets up layer event forwarding', () => new Promise(done => {
const style = new Style(getStubMap());
style.loadJSON(createStyleJSON({
layers: [{
@@ -424,7 +424,7 @@ describe('Style#loadJSON', () => {
style.on('style.load', () => {
style._layers.background.fire(new Event('error', {mapLibre: true}));
});
- });
+ }));
test('sets terrain if defined', async () => {
const map = getStubMap();
@@ -618,7 +618,7 @@ describe('Style#_remove', () => {
});
describe('Style#update', () => {
- test('on error', done => {
+ test('on error', () => new Promise(done => {
const style = createStyle();
style.loadJSON({
'version': 8,
@@ -652,7 +652,7 @@ describe('Style#update', () => {
style.update({} as EvaluationParameters);
});
- });
+ }));
});
describe('Style#setState', () => {
@@ -1167,7 +1167,7 @@ describe('Style#removeSprite', () => {
expect(() => style.removeSprite('test')).toThrow(/load/i);
});
- test('fires an error when trying to delete an non-existing sprite (sprite: undefined)', done => {
+ test('fires an error when trying to delete an non-existing sprite (sprite: undefined)', () => new Promise(done => {
const style = new Style(getStubMap());
style.loadJSON(createStyleJSON());
style.on('style.load', () => {
@@ -1178,9 +1178,9 @@ describe('Style#removeSprite', () => {
style.removeSprite('test');
});
- });
+ }));
- test('fires an error when trying to delete an non-existing sprite (sprite: single url)', done => {
+ test('fires an error when trying to delete an non-existing sprite (sprite: single url)', () => new Promise(done => {
const style = new Style(getStubMap());
style.loadJSON(createStyleJSON({sprite: 'https://example.com/sprite'}));
style.on('style.load', () => {
@@ -1191,9 +1191,9 @@ describe('Style#removeSprite', () => {
style.removeSprite('test');
});
- });
+ }));
- test('fires an error when trying to delete an non-existing sprite (sprite: array)', done => {
+ test('fires an error when trying to delete an non-existing sprite (sprite: array)', () => new Promise(done => {
const style = new Style(getStubMap());
style.loadJSON(createStyleJSON({sprite: [{id: 'default', url: 'https://example.com/sprite'}]}));
style.on('style.load', () => {
@@ -1204,7 +1204,7 @@ describe('Style#removeSprite', () => {
style.removeSprite('test');
});
- });
+ }));
test('removes the sprite when it\'s a single URL', async () => {
const style = new Style(getStubMap());
@@ -1245,7 +1245,7 @@ describe('Style#addLayer', () => {
expect(() => style.addLayer({id: 'background', type: 'background'})).toThrow(/load/i);
});
- test('sets up layer event forwarding', done => {
+ test('sets up layer event forwarding', () => new Promise(done => {
const style = new Style(getStubMap());
style.loadJSON(createStyleJSON());
@@ -1262,9 +1262,9 @@ describe('Style#addLayer', () => {
});
style._layers.background.fire(new Event('error', {mapLibre: true}));
});
- });
+ }));
- test('throws on non-existant vector source layer', done => {
+ test('throws on non-existant vector source layer', () => new Promise(done => {
const style = createStyle();
style.loadJSON(createStyleJSON({
sources: {
@@ -1295,9 +1295,9 @@ describe('Style#addLayer', () => {
done();
});
- });
+ }));
- test('emits error on invalid layer', done => {
+ test('emits error on invalid layer', () => new Promise(done => {
const style = new Style(getStubMap());
style.loadJSON(createStyleJSON());
style.on('style.load', () => {
@@ -1313,7 +1313,7 @@ describe('Style#addLayer', () => {
}
});
});
- });
+ }));
test('#4040 does not mutate source property when provided inline', async () => {
const style = new Style(getStubMap());
@@ -1331,7 +1331,7 @@ describe('Style#addLayer', () => {
expect((layer as any).source).toEqual(source);
});
- test('reloads source', done => {
+ test('reloads source', () => new Promise(done => {
const style = createStyle();
style.loadJSON(extend(createStyleJSON(), {
'sources': {
@@ -1356,9 +1356,9 @@ describe('Style#addLayer', () => {
style.update({} as EvaluationParameters);
}
});
- });
+ }));
- test('#3895 reloads source (instead of clearing) if adding this layer with the same type, immediately after removing it', done => {
+ test('#3895 reloads source (instead of clearing) if adding this layer with the same type, immediately after removing it', () => new Promise((done) => {
const style = createStyle();
style.loadJSON(extend(createStyleJSON(), {
'sources': {
@@ -1386,16 +1386,16 @@ describe('Style#addLayer', () => {
style.on('data', (e) => {
if (e.dataType === 'source' && e.sourceDataType === 'content') {
style.sourceCaches['mapLibre'].reload = () => { done(); };
- style.sourceCaches['mapLibre'].clearTiles = () => { done('test failed'); };
+ style.sourceCaches['mapLibre'].clearTiles = () => { throw new Error('test failed'); };
style.removeLayer('my-layer');
style.addLayer(layer);
style.update({} as EvaluationParameters);
}
});
- });
+ }));
- test('clears source (instead of reloading) if adding this layer with a different type, immediately after removing it', done => {
+ test('clears source (instead of reloading) if adding this layer with a different type, immediately after removing it', () => new Promise((done) => {
const style = createStyle();
style.loadJSON(extend(createStyleJSON(), {
'sources': {
@@ -1421,7 +1421,7 @@ describe('Style#addLayer', () => {
}as LayerSpecification;
style.on('data', (e) => {
if (e.dataType === 'source' && e.sourceDataType === 'content') {
- style.sourceCaches['mapLibre'].reload = () => { done('test failed'); };
+ style.sourceCaches['mapLibre'].reload = () => { throw new Error('test failed'); };
style.sourceCaches['mapLibre'].clearTiles = () => { done(); };
style.removeLayer('my-layer');
style.addLayer(layer);
@@ -1429,7 +1429,7 @@ describe('Style#addLayer', () => {
}
});
- });
+ }));
test('fires "data" event', async () => {
const style = new Style(getStubMap());
@@ -1445,7 +1445,7 @@ describe('Style#addLayer', () => {
await dataPromise;
});
- test('emits error on duplicates', done => {
+ test('emits error on duplicates', () => new Promise(done => {
const style = new Style(getStubMap());
style.loadJSON(createStyleJSON());
const layer = {id: 'background', type: 'background'} as LayerSpecification;
@@ -1459,7 +1459,7 @@ describe('Style#addLayer', () => {
style.addLayer(layer);
style.addLayer(layer);
});
- });
+ }));
test('adds to the end by default', async () => {
const style = new Style(getStubMap());
@@ -1497,7 +1497,7 @@ describe('Style#addLayer', () => {
expect(style._order).toEqual(['c', 'a', 'b']);
});
- test('fire error if before layer does not exist', done => {
+ test('fire error if before layer does not exist', () => new Promise(done => {
const style = new Style(getStubMap());
style.loadJSON(createStyleJSON({
layers: [{
@@ -1517,9 +1517,9 @@ describe('Style#addLayer', () => {
});
style.addLayer(layer, 'z');
});
- });
+ }));
- test('fires an error on non-existant source layer', done => {
+ test('fires an error on non-existant source layer', () => new Promise(done => {
const style = new Style(getStubMap());
style.loadJSON(extend(createStyleJSON(), {
sources: {
@@ -1545,7 +1545,7 @@ describe('Style#addLayer', () => {
style.addLayer(layer);
});
- });
+ }));
});
describe('Style#removeLayer', () => {
@@ -1570,7 +1570,7 @@ describe('Style#removeLayer', () => {
await dataPromise;
});
- test('tears down layer event forwarding', done => {
+ test('tears down layer event forwarding', () => new Promise((done) => {
const style = new Style(getStubMap());
style.loadJSON(createStyleJSON({
layers: [{
@@ -1580,7 +1580,7 @@ describe('Style#removeLayer', () => {
}));
style.on('error', () => {
- done('test failed');
+ throw new Error('test failed');
});
style.on('style.load', () => {
@@ -1593,7 +1593,7 @@ describe('Style#removeLayer', () => {
layer.fire(new Event('error', {mapLibre: true}));
done();
});
- });
+ }));
test('fires an error on non-existence', async () => {
const style = new Style(getStubMap());
@@ -1705,7 +1705,7 @@ describe('Style#moveLayer', () => {
});
describe('Style#setPaintProperty', () => {
- test('#4738 postpones source reload until layers have been broadcast to workers', done => {
+ test('#4738 postpones source reload until layers have been broadcast to workers', () => new Promise(done => {
const style = new Style(getStubMap());
style.loadJSON(extend(createStyleJSON(), {
'sources': {
@@ -1758,7 +1758,7 @@ describe('Style#setPaintProperty', () => {
}
}));
});
- });
+ }));
test('#5802 clones the input', async () => {
const style = new Style(getStubMap());
@@ -1973,7 +1973,7 @@ describe('Style#setFilter', () => {
return style;
}
- test('sets filter', done => {
+ test('sets filter', () => new Promise(done => {
const style = createStyle();
style.on('style.load', () => {
@@ -1989,7 +1989,7 @@ describe('Style#setFilter', () => {
expect(style.getFilter('symbol')).toEqual(['==', 'id', 1]);
style.update({} as EvaluationParameters); // trigger dispatcher broadcast
});
- });
+ }));
test('gets a clone of the filter', async () => {
const style = createStyle();
@@ -2005,7 +2005,7 @@ describe('Style#setFilter', () => {
expect(filter2).not.toBe(filter3);
});
- test('sets again mutated filter', done => {
+ test('sets again mutated filter', () => new Promise(done => {
const style = createStyle();
style.on('style.load', () => {
@@ -2024,7 +2024,7 @@ describe('Style#setFilter', () => {
style.setFilter('symbol', filter);
style.update({} as EvaluationParameters); // trigger dispatcher broadcast
});
- });
+ }));
test('unsets filter', async () => {
const style = createStyle();
@@ -2061,7 +2061,7 @@ describe('Style#setFilter', () => {
style.update({} as EvaluationParameters); // trigger dispatcher broadcast
});
- test('respects validate option', done => {
+ test('respects validate option', () => new Promise(done => {
const style = createStyle();
style.on('style.load', () => {
@@ -2077,7 +2077,7 @@ describe('Style#setFilter', () => {
expect(style.getFilter('symbol')).toBe('notafilter');
style.update({} as EvaluationParameters); // trigger dispatcher broadcast
});
- });
+ }));
});
describe('Style#setLayerZoomRange', () => {
@@ -2102,7 +2102,7 @@ describe('Style#setLayerZoomRange', () => {
return style;
}
- test('sets zoom range', done => {
+ test('sets zoom range', () => new Promise(done => {
const style = createStyle();
style.on('style.load', () => {
@@ -2117,7 +2117,7 @@ describe('Style#setLayerZoomRange', () => {
expect(style.getLayer('symbol').maxzoom).toBe(12);
style.update({} as EvaluationParameters); // trigger dispatcher broadcast
});
- });
+ }));
test('fires an error if layer not found', async () => {
const style = createStyle();
@@ -2187,7 +2187,7 @@ describe('Style#queryRenderedFeatures', () => {
let style;
let transform;
- beforeEach((callback) => {
+ beforeEach(() => new Promise(callback => {
style = new Style(getStubMap());
transform = new Transform();
transform.resize(512, 512);
@@ -2301,7 +2301,7 @@ describe('Style#queryRenderedFeatures', () => {
style._updateSources(transform);
callback();
});
- });
+ }));
afterEach(() => {
style = undefined;
@@ -2421,7 +2421,7 @@ describe('Style#query*Features', () => {
let onError;
let transform;
- beforeEach((callback) => {
+ beforeEach(() => new Promise(callback => {
transform = new Transform();
transform.resize(100, 100);
style = new Style(getStubMap());
@@ -2443,7 +2443,7 @@ describe('Style#query*Features', () => {
.on('style.load', () => {
callback();
});
- });
+ }));
test('querySourceFeatures emits an error on incorrect filter', () => {
expect(style.querySourceFeatures([10, 100], {filter: 7}, transform)).toEqual([]);
diff --git a/src/style/style_layer.test.ts b/src/style/style_layer.test.ts
index 2022f37d82..1ef27ef2b5 100644
--- a/src/style/style_layer.test.ts
+++ b/src/style/style_layer.test.ts
@@ -92,7 +92,7 @@ describe('StyleLayer#setPaintProperty', () => {
expect(layer.getPaintProperty('background-color-transition')).toEqual({duration: 400});
});
- test('emits on an invalid property value', done => {
+ test('emits on an invalid property value', () => new Promise(done => {
const layer = createStyleLayer({
'id': 'background',
'type': 'background'
@@ -104,9 +104,9 @@ describe('StyleLayer#setPaintProperty', () => {
});
layer.setPaintProperty('background-opacity', 5);
- });
+ }));
- test('emits on an invalid transition property value', done => {
+ test('emits on an invalid transition property value', () => new Promise(done => {
const layer = createStyleLayer({
'id': 'background',
'type': 'background'
@@ -119,7 +119,7 @@ describe('StyleLayer#setPaintProperty', () => {
layer.setPaintProperty('background-opacity-transition', {
duration: -10
});
- });
+ }));
test('can unset fill-outline-color #2886', () => {
const layer = createStyleLayer({
@@ -198,7 +198,7 @@ describe('StyleLayer#setLayoutProperty', () => {
expect(layer.getLayoutProperty('text-transform')).toBe('lowercase');
});
- test('emits on an invalid property value', done => {
+ test('emits on an invalid property value', () => new Promise(done => {
const layer = createStyleLayer({
'id': 'symbol',
'type': 'symbol'
@@ -209,7 +209,7 @@ describe('StyleLayer#setLayoutProperty', () => {
});
layer.setLayoutProperty('text-transform', 'invalidValue');
- });
+ }));
test('updates property value', () => {
const layer = createStyleLayer({
diff --git a/src/ui/camera.test.ts b/src/ui/camera.test.ts
index bff2be07dc..8834b99f27 100644
--- a/src/ui/camera.test.ts
+++ b/src/ui/camera.test.ts
@@ -186,7 +186,7 @@ describe('#jumpTo', () => {
expect(camera.getPitch()).toBe(60);
});
- test('emits move events, preserving eventData', done => {
+ test('emits move events, preserving eventData', () => {
let started, moved, ended;
const eventData = {data: 'ok'};
@@ -199,10 +199,9 @@ describe('#jumpTo', () => {
expect(started).toBe('ok');
expect(moved).toBe('ok');
expect(ended).toBe('ok');
- done();
});
- test('emits zoom events, preserving eventData', done => {
+ test('emits zoom events, preserving eventData', () => {
let started, zoomed, ended;
const eventData = {data: 'ok'};
@@ -215,10 +214,9 @@ describe('#jumpTo', () => {
expect(started).toBe('ok');
expect(zoomed).toBe('ok');
expect(ended).toBe('ok');
- done();
});
- test('emits rotate events, preserving eventData', done => {
+ test('emits rotate events, preserving eventData', () => {
let started, rotated, ended;
const eventData = {data: 'ok'};
@@ -231,10 +229,9 @@ describe('#jumpTo', () => {
expect(started).toBe('ok');
expect(rotated).toBe('ok');
expect(ended).toBe('ok');
- done();
});
- test('emits pitch events, preserving eventData', done => {
+ test('emits pitch events, preserving eventData', () => {
let started, pitched, ended;
const eventData = {data: 'ok'};
@@ -247,7 +244,6 @@ describe('#jumpTo', () => {
expect(started).toBe('ok');
expect(pitched).toBe('ok');
expect(ended).toBe('ok');
- done();
});
test('cancels in-progress easing', () => {
@@ -273,7 +269,7 @@ describe('#setCenter', () => {
}).toThrow(Error);
});
- test('emits move events, preserving eventData', done => {
+ test('emits move events, preserving eventData', () => {
let started, moved, ended;
const eventData = {data: 'ok'};
@@ -285,7 +281,6 @@ describe('#setCenter', () => {
expect(started).toBe('ok');
expect(moved).toBe('ok');
expect(ended).toBe('ok');
- done();
});
test('cancels in-progress easing', () => {
@@ -304,7 +299,7 @@ describe('#setZoom', () => {
expect(camera.getZoom()).toBe(3);
});
- test('emits move and zoom events, preserving eventData', done => {
+ test('emits move and zoom events, preserving eventData', () => {
let movestarted, moved, moveended, zoomstarted, zoomed, zoomended;
const eventData = {data: 'ok'};
@@ -323,7 +318,6 @@ describe('#setZoom', () => {
expect(zoomstarted).toBe('ok');
expect(zoomed).toBe('ok');
expect(zoomended).toBe('ok');
- done();
});
test('cancels in-progress easing', () => {
@@ -342,7 +336,7 @@ describe('#setBearing', () => {
expect(camera.getBearing()).toBe(4);
});
- test('emits move and rotate events, preserving eventData', done => {
+ test('emits move and rotate events, preserving eventData', () => {
let movestarted, moved, moveended, rotatestarted, rotated, rotateended;
const eventData = {data: 'ok'};
@@ -361,7 +355,6 @@ describe('#setBearing', () => {
expect(rotatestarted).toBe('ok');
expect(rotated).toBe('ok');
expect(rotateended).toBe('ok');
- done();
});
test('cancels in-progress easing', () => {
@@ -419,7 +412,7 @@ describe('#panBy', () => {
expect(fixedLngLat(camera.getCenter())).toEqual({lng: -70.3125, lat: 0});
});
- test('emits move events, preserving eventData', done => {
+ test('emits move events, preserving eventData', () => new Promise(done => {
const camera = createCamera();
let started, moved;
const eventData = {data: 'ok'};
@@ -435,9 +428,9 @@ describe('#panBy', () => {
});
camera.panBy([100, 0], {duration: 0}, eventData);
- });
+ }));
- test('suppresses movestart if noMoveStart option is true', done => {
+ test('suppresses movestart if noMoveStart option is true', () => new Promise(done => {
const camera = createCamera();
let started;
@@ -452,7 +445,7 @@ describe('#panBy', () => {
});
camera.panBy([100, 0], {duration: 0, noMoveStart: true});
- });
+ }));
});
describe('#panTo', () => {
@@ -481,7 +474,7 @@ describe('#panTo', () => {
expect(fixedLngLat(camera.getCenter())).toEqual({lng: 170.3125, lat: 0});
});
- test('emits move events, preserving eventData', done => {
+ test('emits move events, preserving eventData', () => new Promise(done => {
const camera = createCamera();
let started, moved;
const eventData = {data: 'ok'};
@@ -497,9 +490,9 @@ describe('#panTo', () => {
});
camera.panTo([100, 0], {duration: 0}, eventData);
- });
+ }));
- test('suppresses movestart if noMoveStart option is true', done => {
+ test('suppresses movestart if noMoveStart option is true', () => new Promise(done => {
const camera = createCamera();
let started;
@@ -514,7 +507,7 @@ describe('#panTo', () => {
});
camera.panTo([100, 0], {duration: 0, noMoveStart: true});
- });
+ }));
});
describe('#zoomTo', () => {
@@ -545,7 +538,7 @@ describe('#zoomTo', () => {
expect(fixedLngLat(camera.getCenter())).toEqual(fixedLngLat({lng: -62.66117668978012, lat: 0}));
});
- test('emits move and zoom events, preserving eventData', done => {
+ test('emits move and zoom events, preserving eventData', () => {
const camera = createCamera();
let movestarted, moved, zoomstarted, zoomed;
const eventData = {data: 'ok'};
@@ -571,7 +564,6 @@ describe('#zoomTo', () => {
});
camera.zoomTo(5, {duration: 0}, eventData);
- done();
});
});
@@ -617,7 +609,7 @@ describe('#rotateTo', () => {
expect(fixedLngLat(camera.getCenter())).toEqual(fixedLngLat({lng: -70.3125, lat: 57.3265212252}));
});
- test('emits move and rotate events, preserving eventData', done => {
+ test('emits move and rotate events, preserving eventData', () => {
const camera = createCamera();
let movestarted, moved, rotatestarted, rotated;
const eventData = {data: 'ok'};
@@ -643,7 +635,6 @@ describe('#rotateTo', () => {
});
camera.rotateTo(90, {duration: 0}, eventData);
- done();
});
});
@@ -764,7 +755,7 @@ describe('#easeTo', () => {
expect(fixedLngLat(camera.getCenter())).toEqual(fixedLngLat({lng: -70.3125, lat: 0.000002552471840999715}));
});
- test('emits move, zoom, rotate, and pitch events, preserving eventData', done => {
+ test('emits move, zoom, rotate, and pitch events, preserving eventData', () => {
const camera = createCamera();
let movestarted, moved, zoomstarted, zoomed, rotatestarted, rotated, pitchstarted, pitched;
const eventData = {data: 'ok'};
@@ -817,20 +808,19 @@ describe('#easeTo', () => {
camera.easeTo(
{center: [100, 0], zoom: 3.2, bearing: 90, duration: 0, pitch: 45},
eventData);
- done();
});
- test('does not emit zoom events if not zooming', done => {
+ test('does not emit zoom events if not zooming', () => new Promise((done) => {
const camera = createCamera();
camera
- .on('zoomstart', () => { done('zoomstart failed'); })
- .on('zoom', () => { done('zoom failed'); })
- .on('zoomend', () => { done('zoomend failed'); })
+ .on('zoomstart', () => { throw new Error('zoomstart failed'); })
+ .on('zoom', () => { throw new Error('zoom failed'); })
+ .on('zoomend', () => { throw new Error('zoomend failed'); })
.on('moveend', () => { done(); });
camera.easeTo({center: [100, 0], duration: 0});
- });
+ }));
test('stops existing ease', () => {
const camera = createCamera();
@@ -839,7 +829,7 @@ describe('#easeTo', () => {
expect(camera.getCenter()).toEqual({lng: 100, lat: 0});
});
- test('can be called from within a moveend event handler', done => {
+ test('can be called from within a moveend event handler', () => new Promise(done => {
const camera = createCamera();
const stub = jest.spyOn(browser, 'now');
@@ -872,9 +862,9 @@ describe('#easeTo', () => {
stub.mockImplementation(() => 10);
camera.simulateFrame();
}, 0);
- });
+ }));
- test('pans eastward across the antimeridian', done => {
+ test('pans eastward across the antimeridian', () => new Promise(done => {
const camera = createCamera();
const stub = jest.spyOn(browser, 'now');
@@ -904,9 +894,9 @@ describe('#easeTo', () => {
camera.simulateFrame();
}, 0);
}, 0);
- });
+ }));
- test('does not pan eastward across the antimeridian on a single-globe mercator map', done => {
+ test('does not pan eastward across the antimeridian on a single-globe mercator map', () => new Promise(done => {
const camera = createCamera({renderWorldCopies: false, zoom: 2});
camera.setCenter([170, 0]);
const initialLng = camera.getCenter().lng;
@@ -915,9 +905,9 @@ describe('#easeTo', () => {
done();
});
camera.easeTo({center: [210, 0], duration: 0});
- });
+ }));
- test('pans westward across the antimeridian', done => {
+ test('pans westward across the antimeridian', () => new Promise(done => {
const camera = createCamera();
const stub = jest.spyOn(browser, 'now');
@@ -947,9 +937,9 @@ describe('#easeTo', () => {
camera.simulateFrame();
}, 0);
}, 0);
- });
+ }));
- test('does not pan westward across the antimeridian on a single-globe mercator map', done => {
+ test('does not pan westward across the antimeridian on a single-globe mercator map', () => new Promise(done => {
const camera = createCamera({renderWorldCopies: false, zoom: 2});
camera.setCenter([-170, 0]);
const initialLng = camera.getCenter().lng;
@@ -958,9 +948,9 @@ describe('#easeTo', () => {
done();
});
camera.easeTo({center: [-210, 0], duration: 0});
- });
+ }));
- test('animation occurs when prefers-reduced-motion: reduce is set but overridden by essential: true', done => {
+ test('animation occurs when prefers-reduced-motion: reduce is set but overridden by essential: true', () => new Promise(done => {
const camera = createCamera();
Object.defineProperty(browser, 'prefersReducedMotion', {value: true});
const stubNow = jest.spyOn(browser, 'now');
@@ -991,16 +981,16 @@ describe('#easeTo', () => {
camera.simulateFrame();
}, 0);
}, 0);
- });
+ }));
- test('duration is 0 when prefers-reduced-motion: reduce is set', done => {
+ test('duration is 0 when prefers-reduced-motion: reduce is set', () => new Promise(done => {
const camera = createCamera();
Object.defineProperty(browser, 'prefersReducedMotion', {value: true});
assertTransitionTime(done, camera, 0, 10);
camera.easeTo({center: [100, 0], zoom: 3.2, bearing: 90, duration: 1000});
- });
+ }));
- test('jumpTo on("move") during easeTo with zoom, pitch, etc', (done) => {
+ test('jumpTo on("move") during easeTo with zoom, pitch, etc', () => new Promise(done => {
const camera = createCamera();
camera.on('moveend', (e: Event & {done?: true}) => {
@@ -1018,9 +1008,9 @@ describe('#easeTo', () => {
camera.simulateFrame();
camera.simulateFrame();
- });
+ }));
- test('jumpTo on("zoom") during easeTo', (done) => {
+ test('jumpTo on("zoom") during easeTo', () => new Promise(done => {
const camera = createCamera();
camera.on('moveend', (e: Event & {done?: true}) => {
@@ -1038,9 +1028,9 @@ describe('#easeTo', () => {
camera.simulateFrame();
camera.simulateFrame();
- });
+ }));
- test('jumpTo on("pitch") during easeTo', (done) => {
+ test('jumpTo on("pitch") during easeTo', () => new Promise(done => {
const camera = createCamera();
camera.on('moveend', (e: Event & {done?: true}) => {
@@ -1058,9 +1048,9 @@ describe('#easeTo', () => {
camera.simulateFrame();
camera.simulateFrame();
- });
+ }));
- test('jumpTo on("rotate") during easeTo', (done) => {
+ test('jumpTo on("rotate") during easeTo', () => new Promise(done => {
const camera = createCamera();
camera.on('moveend', (e: Event & {done?: true}) => {
@@ -1078,7 +1068,7 @@ describe('#easeTo', () => {
camera.simulateFrame();
camera.simulateFrame();
- });
+ }));
});
describe('#flyTo', () => {
@@ -1121,7 +1111,7 @@ describe('#flyTo', () => {
expect(camera.getZoom()).toBe(2);
});
- test('Zoom out from the same position to the same position with animation', done => {
+ test('Zoom out from the same position to the same position with animation', () => new Promise(done => {
const pos = {lng: 0, lat: 0};
const camera = createCamera({zoom: 20, center: pos});
const stub = jest.spyOn(browser, 'now');
@@ -1137,7 +1127,7 @@ describe('#flyTo', () => {
stub.mockImplementation(() => 3);
camera.simulateFrame();
- });
+ }));
test('rotates to specified bearing', () => {
const camera = createCamera();
@@ -1208,7 +1198,7 @@ describe('#flyTo', () => {
expect(fixedLngLat(camera.getCenter())).toEqual({lng: 170.3125, lat: 0});
});
- test('emits move, zoom, rotate, and pitch events, preserving eventData', done => {
+ test('emits move, zoom, rotate, and pitch events, preserving eventData', () => {
expect.assertions(18);
const camera = createCamera();
@@ -1263,10 +1253,9 @@ describe('#flyTo', () => {
camera.flyTo(
{center: [100, 0], zoom: 3.2, bearing: 90, duration: 0, pitch: 45, animate: false},
eventData);
- done();
});
- test('for short flights, emits (solely) move events, preserving eventData', done => {
+ test('for short flights, emits (solely) move events, preserving eventData', () => new Promise(done => {
//As I type this, the code path for guiding super-short flights is (and will probably remain) different.
//As such; it deserves a separate test case. This test case flies the map from A to A.
const camera = createCamera({center: [100, 0]});
@@ -1322,17 +1311,16 @@ describe('#flyTo', () => {
camera.simulateFrame();
}, 0);
}, 0);
- });
+ }));
- test('stops existing ease', done => {
+ test('stops existing ease', () => {
const camera = createCamera();
camera.flyTo({center: [200, 0], duration: 100});
camera.flyTo({center: [100, 0], duration: 0});
expect(fixedLngLat(camera.getCenter())).toEqual({lng: 100, lat: 0});
- done();
});
- test('can be called from within a moveend event handler', done => {
+ test('can be called from within a moveend event handler', () => new Promise(done => {
const camera = createCamera();
const stub = jest.spyOn(browser, 'now');
stub.mockImplementation(() => 0);
@@ -1362,9 +1350,9 @@ describe('#flyTo', () => {
}, 0);
}, 0);
}, 0);
- });
+ }));
- test('ascends', done => {
+ test('ascends', () => new Promise(done => {
const camera = createCamera();
camera.setZoom(18);
let ascended;
@@ -1394,9 +1382,9 @@ describe('#flyTo', () => {
camera.simulateFrame();
}, 0);
}, 0);
- });
+ }));
- test('pans eastward across the prime meridian', done => {
+ test('pans eastward across the prime meridian', () => new Promise(done => {
const camera = createCamera();
const stub = jest.spyOn(browser, 'now');
@@ -1426,9 +1414,9 @@ describe('#flyTo', () => {
camera.simulateFrame();
}, 0);
}, 0);
- });
+ }));
- test('pans westward across the prime meridian', done => {
+ test('pans westward across the prime meridian', () => new Promise(done => {
const camera = createCamera();
const stub = jest.spyOn(browser, 'now');
@@ -1458,9 +1446,9 @@ describe('#flyTo', () => {
camera.simulateFrame();
}, 0);
}, 0);
- });
+ }));
- test('pans eastward across the antimeridian', done => {
+ test('pans eastward across the antimeridian', () => new Promise(done => {
const camera = createCamera();
const stub = jest.spyOn(browser, 'now');
@@ -1490,9 +1478,9 @@ describe('#flyTo', () => {
camera.simulateFrame();
}, 0);
}, 0);
- });
+ }));
- test('pans westward across the antimeridian', done => {
+ test('pans westward across the antimeridian', () => new Promise(done => {
const camera = createCamera();
const stub = jest.spyOn(browser, 'now');
@@ -1522,9 +1510,9 @@ describe('#flyTo', () => {
camera.simulateFrame();
}, 0);
}, 0);
- });
+ }));
- test('does not pan eastward across the antimeridian if no world copies', done => {
+ test('does not pan eastward across the antimeridian if no world copies', () => new Promise(done => {
const camera = createCamera({renderWorldCopies: false});
const stub = jest.spyOn(browser, 'now');
@@ -1554,9 +1542,9 @@ describe('#flyTo', () => {
camera.simulateFrame();
}, 0);
}, 0);
- });
+ }));
- test('does not pan westward across the antimeridian if no world copies', done => {
+ test('does not pan westward across the antimeridian if no world copies', () => new Promise(done => {
const camera = createCamera({renderWorldCopies: false});
const stub = jest.spyOn(browser, 'now');
@@ -1586,9 +1574,9 @@ describe('#flyTo', () => {
camera.simulateFrame();
}, 0);
}, 0);
- });
+ }));
- test('jumps back to world 0 when crossing the antimeridian', done => {
+ test('jumps back to world 0 when crossing the antimeridian', () => new Promise(done => {
const camera = createCamera();
const stub = jest.spyOn(browser, 'now');
@@ -1617,9 +1605,9 @@ describe('#flyTo', () => {
camera.simulateFrame();
}, 0);
}, 0);
- });
+ }));
- test('peaks at the specified zoom level', done => {
+ test('peaks at the specified zoom level', () => new Promise(done => {
const camera = createCamera({zoom: 20});
const stub = jest.spyOn(browser, 'now');
@@ -1629,7 +1617,7 @@ describe('#flyTo', () => {
camera.on('zoom', () => {
const zoom = camera.getZoom();
if (zoom < 1) {
- fail(`${zoom} should be >= ${minZoom} during flyTo`);
+ throw new Error(`${zoom} should be >= ${minZoom} during flyTo`);
}
if (camera.getZoom() < (minZoom + 1)) {
@@ -1654,9 +1642,9 @@ describe('#flyTo', () => {
camera.simulateFrame();
}, 0);
}, 0);
- });
+ }));
- test('respects transform\'s maxZoom', done => {
+ test('respects transform\'s maxZoom', () => new Promise(done => {
const transform = new Transform(2, 10, 0, 60, false);
transform.resize(512, 512);
@@ -1679,9 +1667,9 @@ describe('#flyTo', () => {
stub.mockImplementation(() => 10);
camera.simulateFrame();
}, 0);
- });
+ }));
- test('respects transform\'s minZoom', done => {
+ test('respects transform\'s minZoom', () => new Promise(done => {
const transform = new Transform(2, 10, 0, 60, false);
transform.resize(512, 512);
@@ -1704,9 +1692,9 @@ describe('#flyTo', () => {
stub.mockImplementation(() => 10);
camera.simulateFrame();
}, 0);
- });
+ }));
- test('resets duration to 0 if it exceeds maxDuration', done => {
+ test('resets duration to 0 if it exceeds maxDuration', () => new Promise(done => {
let startTime, endTime, timeDiff;
const camera = createCamera({center: [37.63454, 55.75868], zoom: 18});
@@ -1720,14 +1708,14 @@ describe('#flyTo', () => {
});
camera.flyTo({center: [-122.3998631, 37.7884307], maxDuration: 100});
- });
+ }));
- test('flys instantly when prefers-reduce-motion:reduce is set', done => {
+ test('flys instantly when prefers-reduce-motion:reduce is set', () => new Promise(done => {
const camera = createCamera();
Object.defineProperty(browser, 'prefersReducedMotion', {value: true});
assertTransitionTime(done, camera, 0, 10);
camera.flyTo({center: [100, 0], bearing: 90, animate: true});
- });
+ }));
test('check elevation events freezeElevation=false', async () => {
const camera = createCamera();
@@ -1777,7 +1765,7 @@ describe('#flyTo', () => {
expect(terrainCallbacks.finalize).toBe(1);
});
- test('check elevation callbacks', done => {
+ test('check elevation callbacks', () => {
const camera = createCamera();
camera.terrain = {
getElevationForLngLatZoom: () => 100,
@@ -1801,10 +1789,7 @@ describe('#flyTo', () => {
camera._finalizeElevation();
expect(camera._elevationFreeze).toBeFalsy();
-
- done();
});
-
});
describe('#isEasing', () => {
@@ -1819,7 +1804,7 @@ describe('#isEasing', () => {
expect(camera.isEasing()).toBeTruthy();
});
- test('returns false when done panning', done => {
+ test('returns false when done panning', () => new Promise(done => {
const camera = createCamera();
camera.on('moveend', () => {
expect(!camera.isEasing()).toBeTruthy();
@@ -1832,7 +1817,7 @@ describe('#isEasing', () => {
stub.mockImplementation(() => 1);
camera.simulateFrame();
}, 0);
- });
+ }));
test('returns true when zooming', () => {
const camera = createCamera();
@@ -1841,7 +1826,7 @@ describe('#isEasing', () => {
expect(camera.isEasing()).toBeTruthy();
});
- test('returns false when done zooming', done => {
+ test('returns false when done zooming', () => new Promise(done => {
const camera = createCamera();
camera.on('moveend', () => {
expect(!camera.isEasing()).toBeTruthy();
@@ -1854,7 +1839,7 @@ describe('#isEasing', () => {
stub.mockImplementation(() => 1);
camera.simulateFrame();
}, 0);
- });
+ }));
test('returns true when rotating', () => {
const camera = createCamera();
@@ -1862,7 +1847,7 @@ describe('#isEasing', () => {
expect(camera.isEasing()).toBeTruthy();
});
- test('returns false when done rotating', done => {
+ test('returns false when done rotating', () => new Promise(done => {
const camera = createCamera();
camera.on('moveend', () => {
expect(!camera.isEasing()).toBeTruthy();
@@ -1875,7 +1860,7 @@ describe('#isEasing', () => {
stub.mockImplementation(() => 1);
camera.simulateFrame();
}, 0);
- });
+ }));
});
describe('#stop', () => {
@@ -1893,7 +1878,7 @@ describe('#stop', () => {
expect(!camera._rotating).toBeTruthy();
});
- test('emits moveend if panning, preserving eventData', done => {
+ test('emits moveend if panning, preserving eventData', () => new Promise(done => {
const camera = createCamera();
const eventData = {data: 'ok'};
@@ -1904,9 +1889,9 @@ describe('#stop', () => {
camera.panTo([100, 0], {}, eventData);
camera.stop();
- });
+ }));
- test('emits moveend if zooming, preserving eventData', done => {
+ test('emits moveend if zooming, preserving eventData', () => new Promise(done => {
const camera = createCamera();
const eventData = {data: 'ok'};
@@ -1917,9 +1902,9 @@ describe('#stop', () => {
camera.zoomTo(3.2, {}, eventData);
camera.stop();
- });
+ }));
- test('emits moveend if rotating, preserving eventData', done => {
+ test('emits moveend if rotating, preserving eventData', () => new Promise(done => {
const camera = createCamera();
const eventData = {data: 'ok'};
@@ -1930,9 +1915,9 @@ describe('#stop', () => {
camera.rotateTo(90, {}, eventData);
camera.stop();
- });
+ }));
- test('does not emit moveend if not moving', done => {
+ test('does not emit moveend if not moving', () => new Promise(done => {
const camera = createCamera();
const eventData = {data: 'ok'};
@@ -1950,7 +1935,7 @@ describe('#stop', () => {
stub.mockImplementation(() => 1);
camera.simulateFrame();
}, 0);
- });
+ }));
});
describe('#cameraForBounds', () => {
@@ -2204,7 +2189,7 @@ describe('queryTerrainElevation', () => {
describe('#transformCameraUpdate', () => {
- test('invoke transformCameraUpdate callback during jumpTo', done => {
+ test('invoke transformCameraUpdate callback during jumpTo', () => new Promise(done => {
const camera = createCamera();
let callbackCount = 0;
@@ -2225,9 +2210,9 @@ describe('#transformCameraUpdate', () => {
});
camera.jumpTo({center: [100, 0]});
- });
+ }));
- test('invoke transformCameraUpdate callback during easeTo', done => {
+ test('invoke transformCameraUpdate callback during easeTo', () => new Promise(done => {
expect.assertions(2);
const camera = createCamera();
const stub = jest.spyOn(browser, 'now');
@@ -2261,9 +2246,9 @@ describe('#transformCameraUpdate', () => {
camera.simulateFrame();
}, 0);
}, 0);
- });
+ }));
- test('invoke transformCameraUpdate callback during flyTo', done => {
+ test('invoke transformCameraUpdate callback during flyTo', () => new Promise(done => {
expect.assertions(2);
const camera = createCamera();
const stub = jest.spyOn(browser, 'now');
@@ -2297,7 +2282,7 @@ describe('#transformCameraUpdate', () => {
camera.simulateFrame();
}, 0);
}, 0);
- });
+ }));
test('transformCameraUpdate overrides proposed camera settings', () => {
const camera = createCamera();
diff --git a/src/ui/control/geolocate_control.test.ts b/src/ui/control/geolocate_control.test.ts
index e8c2282f59..e1c0b7dc56 100644
--- a/src/ui/control/geolocate_control.test.ts
+++ b/src/ui/control/geolocate_control.test.ts
@@ -85,11 +85,7 @@ describe('GeolocateControl with no options', () => {
test('does not throw if removed quickly', () => {
(checkGeolocationSupport as any as jest.SpyInstance).mockReset()
.mockImplementationOnce(() => {
- return new Promise(resolve => {
- setTimeout(() => {
- resolve(true);
- }, 10);
- });
+ return sleep(10);
});
const geolocate = new GeolocateControl(undefined);
diff --git a/src/ui/control/logo_control.test.ts b/src/ui/control/logo_control.test.ts
index 7d5d55490e..71b29a1022 100644
--- a/src/ui/control/logo_control.test.ts
+++ b/src/ui/control/logo_control.test.ts
@@ -28,7 +28,7 @@ describe('LogoControl', () => {
)).toHaveLength(0);
});
- test('is not displayed when the maplibreLogo property is false', done => {
+ test('is not displayed when the maplibreLogo property is false', () => new Promise(done => {
const map = createMap(undefined, false);
map.on('load', () => {
expect(map.getContainer().querySelectorAll(
@@ -36,9 +36,9 @@ describe('LogoControl', () => {
)).toHaveLength(0);
done();
});
- });
+ }));
- test('appears in bottom-left when maplibreLogo is true and logoPosition is undefined', done => {
+ test('appears in bottom-left when maplibreLogo is true and logoPosition is undefined', () => new Promise(done => {
const map = createMap(undefined, true);
map.on('load', () => {
expect(map.getContainer().querySelectorAll(
@@ -46,9 +46,9 @@ describe('LogoControl', () => {
)).toHaveLength(1);
done();
});
- });
+ }));
- test('appears in the position specified by the position option', done => {
+ test('appears in the position specified by the position option', () => new Promise(done => {
const map = createMap('top-left', true);
map.on('load', () => {
expect(map.getContainer().querySelectorAll(
@@ -56,7 +56,7 @@ describe('LogoControl', () => {
)).toHaveLength(1);
done();
});
- });
+ }));
test('appears in compact mode if container is less then 640 pixel wide', () => {
const map = createMap(undefined, true);
@@ -75,7 +75,7 @@ describe('LogoControl', () => {
).toHaveLength(1);
});
- test('has `rel` noopener and nofollow', done => {
+ test('has `rel` noopener and nofollow', () => new Promise(done => {
const map = createMap(undefined, true);
map.on('load', () => {
@@ -84,5 +84,5 @@ describe('LogoControl', () => {
expect(logo).toHaveProperty('rel', 'noopener nofollow');
done();
});
- });
+ }));
});
diff --git a/src/ui/handler/dblclick_zoom.test.ts b/src/ui/handler/dblclick_zoom.test.ts
index d4d231f9c3..c7a706484c 100644
--- a/src/ui/handler/dblclick_zoom.test.ts
+++ b/src/ui/handler/dblclick_zoom.test.ts
@@ -1,23 +1,22 @@
import simulate from '../../../test/unit/lib/simulate_interaction';
-import {beforeMapTest} from '../../util/test/util';
+import {beforeMapTest, sleep} from '../../util/test/util';
import {Map, MapOptions} from '../map';
function createMap() {
return new Map({container: window.document.createElement('div')} as any as MapOptions);
}
-function simulateDoubleTap(map, delay = 100) {
+async function simulateDoubleTap(map, delay = 100) {
const canvas = map.getCanvas();
- return new Promise(resolve => {
- simulate.touchstart(canvas, {touches: [{target: canvas, clientX: 0, clientY: 0}]});
- simulate.touchend(canvas);
- setTimeout(() => {
- simulate.touchstart(canvas, {touches: [{target: canvas, clientX: 0, clientY: 0}]});
- simulate.touchend(canvas);
- map._renderTaskQueue.run();
- resolve(undefined);
- }, delay);
- });
+
+ simulate.touchstart(canvas, {touches: [{target: canvas, clientX: 0, clientY: 0}]});
+ simulate.touchend(canvas);
+
+ await sleep(delay);
+
+ simulate.touchstart(canvas, {touches: [{target: canvas, clientX: 0, clientY: 0}]});
+ simulate.touchend(canvas);
+ map._renderTaskQueue.run();
}
beforeEach(() => {
@@ -87,16 +86,12 @@ describe('dbclick_zoom', () => {
const canvas = map.getCanvas();
- await new Promise(resolve => {
- simulate.touchstart(canvas, {touches: [{clientX: 0, clientY: 0}]});
- simulate.touchend(canvas);
- setTimeout(() => {
- simulate.touchstart(canvas, {touches: [{clientX: 30.5, clientY: 30.5}]});
- simulate.touchend(canvas);
- map._renderTaskQueue.run();
- resolve(undefined);
- }, 100);
- });
+ simulate.touchstart(canvas, {touches: [{clientX: 0, clientY: 0}]});
+ simulate.touchend(canvas);
+ await sleep(100);
+ simulate.touchstart(canvas, {touches: [{clientX: 30.5, clientY: 30.5}]});
+ simulate.touchend(canvas);
+ map._renderTaskQueue.run();
expect(zoom).not.toHaveBeenCalled();
@@ -145,17 +140,12 @@ describe('dbclick_zoom', () => {
const canvas = map.getCanvas();
- await new Promise(resolve => {
- simulate.touchstart(canvas);
- simulate.touchend(canvas);
- simulate.touchstart(canvas);
- setTimeout(() => {
- simulate.touchend(canvas);
- map._renderTaskQueue.run();
- resolve(undefined);
- }, 300);
- });
-
+ simulate.touchstart(canvas);
+ simulate.touchend(canvas);
+ simulate.touchstart(canvas);
+ await sleep(300);
+ simulate.touchend(canvas);
+ map._renderTaskQueue.run();
expect(zoom).not.toHaveBeenCalled();
});
});
diff --git a/src/ui/handler/scroll_zoom.test.ts b/src/ui/handler/scroll_zoom.test.ts
index 395c5f0d54..364b426487 100644
--- a/src/ui/handler/scroll_zoom.test.ts
+++ b/src/ui/handler/scroll_zoom.test.ts
@@ -70,7 +70,7 @@ describe('ScrollZoomHandler', () => {
map.remove();
});
- test('Zooms for single mouse wheel tick with non-magical deltaY', done => {
+ test('Zooms for single mouse wheel tick with non-magical deltaY', () => new Promise(done => {
const browserNow = jest.spyOn(browser, 'now');
const now = 1555555555555;
browserNow.mockReturnValue(now);
@@ -86,7 +86,7 @@ describe('ScrollZoomHandler', () => {
map.remove();
done();
});
- });
+ }));
test('Zooms for multiple mouse wheel ticks', () => {
const browserNow = jest.spyOn(browser, 'now');
diff --git a/src/ui/handler/tap_drag_zoom.test.ts b/src/ui/handler/tap_drag_zoom.test.ts
index cc8eefecff..bc3813f6b4 100644
--- a/src/ui/handler/tap_drag_zoom.test.ts
+++ b/src/ui/handler/tap_drag_zoom.test.ts
@@ -1,4 +1,4 @@
-import {beforeMapTest} from '../../util/test/util';
+import {beforeMapTest, sleep} from '../../util/test/util';
import simulate from '../../../test/unit/lib/simulate_interaction';
import {Map, MapOptions} from '../map';
@@ -62,7 +62,7 @@ describe('tap_drag_zoom', () => {
});
- test('TapDragZoomHandler does not fire zoom on tap and drag if touchstart events are > 500ms apart', done => {
+ test('TapDragZoomHandler does not fire zoom on tap and drag if touchstart events are > 500ms apart', async () => {
const map = createMap();
const target = map.getCanvas();
@@ -74,18 +74,18 @@ describe('tap_drag_zoom', () => {
simulate.touchstart(target, pointTouchOptions);
simulate.touchend(target);
- setTimeout(() => {
- simulate.touchstart(target, pointTouchOptions);
- simulate.touchmove(target, {
- touches: [{target, clientX: 100, clientY: 110}]
- });
- map._renderTaskQueue.run();
-
- expect(zoomstart).not.toHaveBeenCalled();
- expect(zoom).not.toHaveBeenCalled();
- expect(zoomend).not.toHaveBeenCalled();
- done();
- }, 510);
+
+ await sleep(510);
+
+ simulate.touchstart(target, pointTouchOptions);
+ simulate.touchmove(target, {
+ touches: [{target, clientX: 100, clientY: 110}]
+ });
+ map._renderTaskQueue.run();
+
+ expect(zoomstart).not.toHaveBeenCalled();
+ expect(zoom).not.toHaveBeenCalled();
+ expect(zoomend).not.toHaveBeenCalled();
});
test('TapDragZoomHandler does not zoom on double-tap and drag if touchstart events are in different locations (>30px apart)', () => {
diff --git a/src/ui/map_tests/map_basic.test.ts b/src/ui/map_tests/map_basic.test.ts
index 093f1dfb3b..0364eacd83 100644
--- a/src/ui/map_tests/map_basic.test.ts
+++ b/src/ui/map_tests/map_basic.test.ts
@@ -110,7 +110,7 @@ describe('Map', () => {
await promise;
});
- test('Map#isStyleLoaded', done => {
+ test('Map#isStyleLoaded', () => new Promise(done => {
const style = createStyle();
const map = createMap({style});
@@ -119,9 +119,9 @@ describe('Map', () => {
expect(map.isStyleLoaded()).toBe(true);
done();
});
- });
+ }));
- test('Map#areTilesLoaded', done => {
+ test('Map#areTilesLoaded', () => new Promise(done => {
const style = createStyle();
const map = createMap({style});
expect(map.areTilesLoaded()).toBe(true);
@@ -134,7 +134,7 @@ describe('Map', () => {
expect(map.areTilesLoaded()).toBe(true);
done();
});
- });
+ }));
});
test('#remove', () => {
@@ -162,7 +162,7 @@ describe('Map', () => {
expect(control.onRemove).toHaveBeenCalledTimes(1);
});
- test('#remove calls onRemove on added controls before style is destroyed', done => {
+ test('#remove calls onRemove on added controls before style is destroyed', () => new Promise(done => {
const map = createMap();
let onRemoveCalled = 0;
let style;
@@ -184,7 +184,7 @@ describe('Map', () => {
expect(onRemoveCalled).toBe(1);
done();
});
- });
+ }));
test('#remove broadcasts removeMap to worker', () => {
const map = createMap();
diff --git a/src/ui/map_tests/map_events.test.ts b/src/ui/map_tests/map_events.test.ts
index dcdc30f15b..a17fd673be 100644
--- a/src/ui/map_tests/map_events.test.ts
+++ b/src/ui/map_tests/map_events.test.ts
@@ -924,10 +924,10 @@ describe('map events', () => {
map.remove();
});
- test('emits load event after a style is set', done => {
+ test('emits load event after a style is set', () => new Promise((done) => {
const map = new Map({container: window.document.createElement('div')} as any as MapOptions);
- const fail = () => done('test failed');
+ const fail = () => { throw new Error('test failed'); };
const pass = () => done();
map.on('load', fail);
@@ -937,7 +937,7 @@ describe('map events', () => {
map.on('load', pass);
map.setStyle(createStyle());
}, 1);
- });
+ }));
test('no idle event during move', async () => {
const style = createStyle();
@@ -987,7 +987,7 @@ describe('map events', () => {
expect(stub.mock.calls[0][0]).toBe(error);
});
- test('calls listeners', done => {
+ test('calls listeners', () => new Promise(done => {
const map = createMap();
const error = new Error('test');
map.on('error', (event) => {
@@ -995,7 +995,7 @@ describe('map events', () => {
done();
});
map.fire(new ErrorEvent(error));
- });
+ }));
});
});
diff --git a/src/ui/map_tests/map_feature_state.test.ts b/src/ui/map_tests/map_feature_state.test.ts
index b45390823e..b3160b8169 100644
--- a/src/ui/map_tests/map_feature_state.test.ts
+++ b/src/ui/map_tests/map_feature_state.test.ts
@@ -6,7 +6,7 @@ beforeEach(() => {
});
describe('#setFeatureState', () => {
- test('sets state', done => {
+ test('sets state', () => new Promise(done => {
const map = createMap({
style: {
'version': 8,
@@ -22,8 +22,8 @@ describe('#setFeatureState', () => {
expect(fState.hover).toBe(true);
done();
});
- });
- test('works with string ids', done => {
+ }));
+ test('works with string ids', () => new Promise(done => {
const map = createMap({
style: {
'version': 8,
@@ -39,8 +39,8 @@ describe('#setFeatureState', () => {
expect(fState.hover).toBe(true);
done();
});
- });
- test('parses feature id as an int', done => {
+ }));
+ test('parses feature id as an int', () => new Promise(done => {
const map = createMap({
style: {
'version': 8,
@@ -56,8 +56,8 @@ describe('#setFeatureState', () => {
expect(fState.hover).toBe(true);
done();
});
- });
- test('throw before loaded', done => {
+ }));
+ test('throw before loaded', () => {
const map = createMap({
style: {
'version': 8,
@@ -70,10 +70,8 @@ describe('#setFeatureState', () => {
expect(() => {
map.setFeatureState({source: 'geojson', id: 12345}, {'hover': true});
}).toThrow(Error);
-
- done();
});
- test('fires an error if source not found', done => {
+ test('fires an error if source not found', () => new Promise(done => {
const map = createMap({
style: {
'version': 8,
@@ -90,8 +88,8 @@ describe('#setFeatureState', () => {
});
map.setFeatureState({source: 'vector', id: 12345}, {'hover': true});
});
- });
- test('fires an error if sourceLayer not provided for a vector source', done => {
+ }));
+ test('fires an error if sourceLayer not provided for a vector source', () => new Promise(done => {
const map = createMap({
style: {
'version': 8,
@@ -111,8 +109,8 @@ describe('#setFeatureState', () => {
});
(map as any).setFeatureState({source: 'vector', sourceLayer: 0, id: 12345}, {'hover': true});
});
- });
- test('fires an error if id not provided', done => {
+ }));
+ test('fires an error if id not provided', () => new Promise(done => {
const map = createMap({
style: {
'version': 8,
@@ -132,12 +130,12 @@ describe('#setFeatureState', () => {
});
(map as any).setFeatureState({source: 'vector', sourceLayer: '1'}, {'hover': true});
});
- });
+ }));
});
describe('#removeFeatureState', () => {
- test('accepts "0" id', done => {
+ test('accepts "0" id', () => new Promise(done => {
const map = createMap({
style: {
'version': 8,
@@ -155,8 +153,8 @@ describe('#removeFeatureState', () => {
expect(fState.click).toBe(true);
done();
});
- });
- test('accepts string id', done => {
+ }));
+ test('accepts string id', () => new Promise(done => {
const map = createMap({
style: {
'version': 8,
@@ -174,8 +172,8 @@ describe('#removeFeatureState', () => {
expect(fState.click).toBe(true);
done();
});
- });
- test('remove specific state property', done => {
+ }));
+ test('remove specific state property', () => new Promise(done => {
const map = createMap({
style: {
'version': 8,
@@ -192,8 +190,8 @@ describe('#removeFeatureState', () => {
expect(fState.hover).toBeUndefined();
done();
});
- });
- test('remove all state properties of one feature', done => {
+ }));
+ test('remove all state properties of one feature', () => new Promise(done => {
const map = createMap({
style: {
'version': 8,
@@ -213,8 +211,8 @@ describe('#removeFeatureState', () => {
done();
});
- });
- test('remove properties for zero-based feature IDs.', done => {
+ }));
+ test('remove properties for zero-based feature IDs.', () => new Promise(done => {
const map = createMap({
style: {
'version': 8,
@@ -234,8 +232,8 @@ describe('#removeFeatureState', () => {
done();
});
- });
- test('other properties persist when removing specific property', done => {
+ }));
+ test('other properties persist when removing specific property', () => new Promise(done => {
const map = createMap({
style: {
'version': 8,
@@ -254,8 +252,8 @@ describe('#removeFeatureState', () => {
done();
});
- });
- test('remove all state properties of all features in source', done => {
+ }));
+ test('remove all state properties of all features in source', () => new Promise(done => {
const map = createMap({
style: {
'version': 8,
@@ -281,8 +279,8 @@ describe('#removeFeatureState', () => {
done();
});
- });
- test('specific state deletion should not interfere with broader state deletion', done => {
+ }));
+ test('specific state deletion should not interfere with broader state deletion', () => new Promise(done => {
const map = createMap({
style: {
'version': 8,
@@ -318,8 +316,8 @@ describe('#removeFeatureState', () => {
done();
});
- });
- test('add/remove and remove/add state', done => {
+ }));
+ test('add/remove and remove/add state', () => new Promise(done => {
const map = createMap({
style: {
'version': 8,
@@ -345,8 +343,8 @@ describe('#removeFeatureState', () => {
done();
});
- });
- test('throw before loaded', done => {
+ }));
+ test('throw before loaded', () => {
const map = createMap({
style: {
'version': 8,
@@ -359,10 +357,8 @@ describe('#removeFeatureState', () => {
expect(() => {
(map as any).removeFeatureState({source: 'geojson', id: 12345}, {'hover': true});
}).toThrow(Error);
-
- done();
});
- test('fires an error if source not found', done => {
+ test('fires an error if source not found', () => new Promise(done => {
const map = createMap({
style: {
'version': 8,
@@ -379,8 +375,8 @@ describe('#removeFeatureState', () => {
});
(map as any).removeFeatureState({source: 'vector', id: 12345}, {'hover': true});
});
- });
- test('fires an error if sourceLayer not provided for a vector source', done => {
+ }));
+ test('fires an error if sourceLayer not provided for a vector source', () => new Promise(done => {
const map = createMap({
style: {
'version': 8,
@@ -400,8 +396,8 @@ describe('#removeFeatureState', () => {
});
(map as any).removeFeatureState({source: 'vector', sourceLayer: 0, id: 12345}, {'hover': true});
});
- });
- test('fires an error if state property is provided without a feature id', done => {
+ }));
+ test('fires an error if state property is provided without a feature id', () => new Promise(done => {
const map = createMap({
style: {
'version': 8,
@@ -421,5 +417,5 @@ describe('#removeFeatureState', () => {
});
(map as any).removeFeatureState({source: 'vector', sourceLayer: '1'}, {'hover': true});
});
- });
+ }));
});
diff --git a/src/ui/map_tests/map_images.test.ts b/src/ui/map_tests/map_images.test.ts
index 4367012604..c2261e39d7 100644
--- a/src/ui/map_tests/map_images.test.ts
+++ b/src/ui/map_tests/map_images.test.ts
@@ -6,7 +6,7 @@ beforeEach(() => {
global.fetch = null;
});
-test('#listImages', done => {
+test('#listImages', () => new Promise(done => {
const map = createMap();
map.on('load', () => {
@@ -19,7 +19,7 @@ test('#listImages', done => {
expect(images[0]).toBe('img');
done();
});
-});
+}));
test('#listImages throws an error if called before "load"', () => {
const map = createMap();
@@ -147,7 +147,7 @@ test('map getImage matches addImage, StyleImageInterface SDF', () => {
expect(gotImage.sdf).toBe(true);
});
-test('map does not fire `styleimagemissing` for empty icon values', done => {
+test('map does not fire `styleimagemissing` for empty icon values', () => new Promise((done) => {
const map = createMap();
map.on('load', () => {
@@ -169,7 +169,7 @@ test('map does not fire `styleimagemissing` for empty icon values', done => {
});
map.on('styleimagemissing', ({id}) => {
- done(`styleimagemissing fired for value ${id}`);
+ throw new Error(`styleimagemissing fired for value ${id}`);
});
});
-});
+}));
diff --git a/src/ui/map_tests/map_is_moving.test.ts b/src/ui/map_tests/map_is_moving.test.ts
index 3acc68283d..814578985a 100644
--- a/src/ui/map_tests/map_is_moving.test.ts
+++ b/src/ui/map_tests/map_is_moving.test.ts
@@ -27,7 +27,7 @@ describe('Map#isMoving', () => {
expect(map.isMoving()).toBe(false);
});
- test('returns true during a camera zoom animation', done => {
+ test('returns true during a camera zoom animation', () => new Promise(done => {
map.on('zoomstart', () => {
expect(map.isMoving()).toBe(true);
});
@@ -38,9 +38,9 @@ describe('Map#isMoving', () => {
});
map.zoomTo(5, {duration: 0});
- });
+ }));
- test('returns true when drag panning', done => {
+ test('returns true when drag panning', () => new Promise(done => {
map.on('movestart', () => {
expect(map.isMoving()).toBe(true);
});
@@ -64,9 +64,9 @@ describe('Map#isMoving', () => {
simulate.mouseup(map.getCanvas());
map._renderTaskQueue.run();
- });
+ }));
- test('returns true when drag rotating', done => {
+ test('returns true when drag rotating', () => new Promise(done => {
// Prevent inertial rotation.
jest.spyOn(browser, 'now').mockImplementation(() => { return 0; });
@@ -95,9 +95,9 @@ describe('Map#isMoving', () => {
simulate.mouseup(map.getCanvas(), {buttons: 0, button: 2});
map._renderTaskQueue.run();
- });
+ }));
- test('returns true when scroll zooming', done => {
+ test('returns true when scroll zooming', () => new Promise(done => {
map.on('zoomstart', () => {
expect(map.isMoving()).toBe(true);
});
@@ -117,9 +117,9 @@ describe('Map#isMoving', () => {
setTimeout(() => {
map._renderTaskQueue.run();
}, 400);
- });
+ }));
- test('returns true when drag panning and scroll zooming interleave', done => {
+ test('returns true when drag panning and scroll zooming interleave', () => new Promise(done => {
map.on('dragstart', () => {
expect(map.isMoving()).toBe(true);
});
@@ -160,5 +160,5 @@ describe('Map#isMoving', () => {
setTimeout(() => {
map._renderTaskQueue.run();
}, 400);
- });
+ }));
});
diff --git a/src/ui/map_tests/map_is_rotating.test.ts b/src/ui/map_tests/map_is_rotating.test.ts
index 02870b4420..7dc3bd4a00 100644
--- a/src/ui/map_tests/map_is_rotating.test.ts
+++ b/src/ui/map_tests/map_is_rotating.test.ts
@@ -24,7 +24,7 @@ describe('Map#isRotating', () => {
expect(map.isRotating()).toBe(false);
});
- test('returns true during a camera rotate animation', done => {
+ test('returns true during a camera rotate animation', () => new Promise(done => {
map.on('rotatestart', () => {
expect(map.isRotating()).toBe(true);
});
@@ -35,9 +35,9 @@ describe('Map#isRotating', () => {
});
map.rotateTo(5, {duration: 0});
- });
+ }));
- test('returns true when drag rotating', done => {
+ test('returns true when drag rotating', () => new Promise(done => {
// Prevent inertial rotation.
jest.spyOn(browser, 'now').mockImplementation(() => { return 0; });
@@ -58,5 +58,5 @@ describe('Map#isRotating', () => {
simulate.mouseup(map.getCanvas(), {buttons: 0, button: 2});
map._renderTaskQueue.run();
- });
+ }));
});
diff --git a/src/ui/map_tests/map_is_zooming.test.ts b/src/ui/map_tests/map_is_zooming.test.ts
index ec0e52ba3d..44e507e7d9 100644
--- a/src/ui/map_tests/map_is_zooming.test.ts
+++ b/src/ui/map_tests/map_is_zooming.test.ts
@@ -14,14 +14,13 @@ beforeEach(() => {
describe('Map#isZooming', () => {
- test('returns false by default', done => {
+ test('returns false by default', () => {
const map = createMap();
expect(map.isZooming()).toBe(false);
map.remove();
- done();
});
- test('returns true during a camera zoom animation', done => {
+ test('returns true during a camera zoom animation', () => new Promise(done => {
const map = createMap();
map.on('zoomstart', () => {
@@ -35,9 +34,9 @@ describe('Map#isZooming', () => {
});
map.zoomTo(5, {duration: 0});
- });
+ }));
- test('returns true when scroll zooming', done => {
+ test('returns true when scroll zooming', () => new Promise(done => {
const map = createMap();
map.on('zoomstart', () => {
@@ -60,9 +59,9 @@ describe('Map#isZooming', () => {
setTimeout(() => {
map._renderTaskQueue.run();
}, 400);
- });
+ }));
- test('returns true when double-click zooming', done => {
+ test('returns true when double-click zooming', () => new Promise(done => {
const map = createMap();
map.on('zoomstart', () => {
@@ -83,5 +82,5 @@ describe('Map#isZooming', () => {
now += 500;
map._renderTaskQueue.run();
- });
+ }));
});
diff --git a/src/ui/map_tests/map_layer.test.ts b/src/ui/map_tests/map_layer.test.ts
index 60ee28febb..efdfeef7c5 100644
--- a/src/ui/map_tests/map_layer.test.ts
+++ b/src/ui/map_tests/map_layer.test.ts
@@ -75,7 +75,7 @@ test('#getLayer', async () => {
expect(mapLayer.source).toBe(layer.source);
});
-test('#removeLayer restores Map#loaded() to true', done => {
+test('#removeLayer restores Map#loaded() to true', () => new Promise(done => {
const map = createMap({
style: extend(createStyle(), {
sources: {
@@ -104,10 +104,10 @@ test('#removeLayer restores Map#loaded() to true', done => {
}
});
});
-});
+}));
describe('#getLayersOrder', () => {
- test('returns ids of layers in the correct order', done => {
+ test('returns ids of layers in the correct order', () => new Promise(done => {
const map = createMap({
style: extend(createStyle(), {
'sources': {
@@ -133,11 +133,11 @@ describe('#getLayersOrder', () => {
expect(map.getLayersOrder()).toEqual(['custom', 'raster']);
done();
});
- });
+ }));
});
describe('#setLayoutProperty', () => {
- test('sets property', done => {
+ test('sets property', () => new Promise(done => {
const map = createMap({
style: {
'version': 8,
@@ -173,7 +173,7 @@ describe('#setLayoutProperty', () => {
expect(map.getLayoutProperty('symbol', 'text-transform')).toBe('lowercase');
done();
});
- });
+ }));
test('throw before loaded', () => {
const map = createMap({
@@ -190,7 +190,7 @@ describe('#setLayoutProperty', () => {
});
- test('fires an error if layer not found', done => {
+ test('fires an error if layer not found', () => new Promise(done => {
const map = createMap({
style: {
version: 8,
@@ -206,7 +206,7 @@ describe('#setLayoutProperty', () => {
});
map.setLayoutProperty('non-existant', 'text-transform', 'lowercase');
});
- });
+ }));
test('fires a data event', async () => {
// background layers do not have a source
@@ -231,7 +231,7 @@ describe('#setLayoutProperty', () => {
expect(e.dataType).toBe('style');
});
- test('sets visibility on background layer', done => {
+ test('sets visibility on background layer', () => new Promise(done => {
// background layers do not have a source
const map = createMap({
style: {
@@ -252,9 +252,9 @@ describe('#setLayoutProperty', () => {
expect(map.getLayoutProperty('background', 'visibility')).toBe('visible');
done();
});
- });
+ }));
- test('sets visibility on raster layer', done => {
+ test('sets visibility on raster layer', () => new Promise(done => {
const map = createMap({
style: {
'version': 8,
@@ -283,9 +283,9 @@ describe('#setLayoutProperty', () => {
expect(map.getLayoutProperty('satellite', 'visibility')).toBe('visible');
done();
});
- });
+ }));
- test('sets visibility on video layer', done => {
+ test('sets visibility on video layer', () => new Promise(done => {
const map = createMap({
style: {
'version': 8,
@@ -317,9 +317,9 @@ describe('#setLayoutProperty', () => {
expect(map.getLayoutProperty('shore', 'visibility')).toBe('visible');
done();
});
- });
+ }));
- test('sets visibility on image layer', done => {
+ test('sets visibility on image layer', () => new Promise(done => {
const map = createMap({
style: {
'version': 8,
@@ -351,12 +351,12 @@ describe('#setLayoutProperty', () => {
expect(map.getLayoutProperty('image', 'visibility')).toBe('visible');
done();
});
- });
+ }));
});
describe('#getLayoutProperty', () => {
- test('fires an error if layer not found', done => {
+ test('fires an error if layer not found', () => new Promise(done => {
const map = createMap({
style: {
version: 8,
@@ -372,12 +372,12 @@ describe('#getLayoutProperty', () => {
});
(map as any).getLayoutProperty('non-existant', 'text-transform', 'lowercase');
});
- });
+ }));
});
describe('#setPaintProperty', () => {
- test('sets property', done => {
+ test('sets property', () => new Promise(done => {
const map = createMap({
style: {
'version': 8,
@@ -394,7 +394,7 @@ describe('#setPaintProperty', () => {
expect(map.getPaintProperty('background', 'background-color')).toBe('red');
done();
});
- });
+ }));
test('#3373 paint property should be synchronized with an update', async () => {
const colors = ['red', 'blue'];
@@ -436,7 +436,7 @@ describe('#setPaintProperty', () => {
});
- test('fires an error if layer not found', done => {
+ test('fires an error if layer not found', () => new Promise(done => {
const map = createMap({
style: {
version: 8,
@@ -452,6 +452,6 @@ describe('#setPaintProperty', () => {
});
map.setPaintProperty('non-existant', 'background-color', 'red');
});
- });
+ }));
});
diff --git a/src/ui/map_tests/map_query_rendered_features.test.ts b/src/ui/map_tests/map_query_rendered_features.test.ts
index 15ec77fd5a..ae21156dd2 100644
--- a/src/ui/map_tests/map_query_rendered_features.test.ts
+++ b/src/ui/map_tests/map_query_rendered_features.test.ts
@@ -8,7 +8,7 @@ beforeEach(() => {
describe('#queryRenderedFeatures', () => {
- test('if no arguments provided', done => {
+ test('if no arguments provided', () => new Promise(done => {
createMap({}, (err, map) => {
expect(err).toBeFalsy();
const spy = jest.spyOn(map.style, 'queryRenderedFeatures');
@@ -22,9 +22,9 @@ describe('#queryRenderedFeatures', () => {
done();
});
- });
+ }));
- test('if only "geometry" provided', done => {
+ test('if only "geometry" provided', () => new Promise(done => {
createMap({}, (err, map) => {
expect(err).toBeFalsy();
const spy = jest.spyOn(map.style, 'queryRenderedFeatures');
@@ -39,9 +39,9 @@ describe('#queryRenderedFeatures', () => {
done();
});
- });
+ }));
- test('if only "params" provided', done => {
+ test('if only "params" provided', () => new Promise(done => {
createMap({}, (err, map) => {
expect(err).toBeFalsy();
const spy = jest.spyOn(map.style, 'queryRenderedFeatures');
@@ -55,9 +55,9 @@ describe('#queryRenderedFeatures', () => {
done();
});
- });
+ }));
- test('if both "geometry" and "params" provided', done => {
+ test('if both "geometry" and "params" provided', () => new Promise(done => {
createMap({}, (err, map) => {
expect(err).toBeFalsy();
const spy = jest.spyOn(map.style, 'queryRenderedFeatures');
@@ -71,9 +71,9 @@ describe('#queryRenderedFeatures', () => {
done();
});
- });
+ }));
- test('if "geometry" with unwrapped coords provided', done => {
+ test('if "geometry" with unwrapped coords provided', () => new Promise(done => {
createMap({}, (err, map) => {
expect(err).toBeFalsy();
const spy = jest.spyOn(map.style, 'queryRenderedFeatures');
@@ -83,7 +83,7 @@ describe('#queryRenderedFeatures', () => {
expect(spy.mock.calls[0][0]).toEqual([{x: 612, y: 100}]);
done();
});
- });
+ }));
test('returns an empty array when no style is loaded', () => {
const map = createMap({style: undefined});
diff --git a/src/ui/map_tests/map_render.test.ts b/src/ui/map_tests/map_render.test.ts
index 8571e9d554..fe88f809f1 100644
--- a/src/ui/map_tests/map_render.test.ts
+++ b/src/ui/map_tests/map_render.test.ts
@@ -13,7 +13,7 @@ afterEach(() => {
server.restore();
});
-test('render stabilizes', done => {
+test('render stabilizes', () => new Promise((done) => {
const style = createStyle();
style.sources.mapbox = {
type: 'vector',
@@ -35,41 +35,41 @@ test('render stabilizes', done => {
timer = setTimeout(() => {
map.off('render', undefined);
map.on('render', () => {
- done('test failed');
+ throw new Error('test failed');
});
expect((map as any)._frameId).toBeFalsy();
done();
}, 100);
});
-});
+}));
-test('no render after idle event', done => {
+test('no render after idle event', () => new Promise((done) => {
const style = createStyle();
const map = createMap({style});
map.on('idle', () => {
map.on('render', () => {
- done('test failed');
+ throw new Error('test failed');
});
setTimeout(() => {
done();
}, 100);
});
-});
+}));
-test('no render before style loaded', done => {
+test('no render before style loaded', () => new Promise((done) => {
server.respondWith('/styleUrl', JSON.stringify(createStyle()));
const map = createMap({style: '/styleUrl'});
jest.spyOn(map, 'triggerRepaint').mockImplementationOnce(() => {
if (!map.style._loaded) {
- done('test failed');
+ throw new Error('test failed');
}
});
map.on('render', () => {
if (map.style._loaded) {
done();
} else {
- done('test failed');
+ throw new Error('test failed');
}
});
@@ -77,7 +77,7 @@ test('no render before style loaded', done => {
// Once style is loaded, it will trigger the update.
map._update();
server.respond();
-});
+}));
test('#redraw', async () => {
const map = createMap();
diff --git a/src/ui/map_tests/map_request_render_frame.test.ts b/src/ui/map_tests/map_request_render_frame.test.ts
index e9c514f7ea..c4f57937bb 100644
--- a/src/ui/map_tests/map_request_render_frame.test.ts
+++ b/src/ui/map_tests/map_request_render_frame.test.ts
@@ -6,7 +6,7 @@ beforeEach(() => {
describe('requestRenderFrame', () => {
- test('Map#_requestRenderFrame schedules a new render frame if necessary', (done) => {
+ test('Map#_requestRenderFrame schedules a new render frame if necessary', () => new Promise(done => {
const map = createMap();
const spy = jest.spyOn(map, 'triggerRepaint');
map._requestRenderFrame(() => {});
@@ -20,7 +20,7 @@ describe('requestRenderFrame', () => {
map.remove();
done();
});
- });
+ }));
test('Map#_requestRenderFrame should not schedule a render frame before style load', () => {
const map = createMap();
diff --git a/src/ui/map_tests/map_style.test.ts b/src/ui/map_tests/map_style.test.ts
index 08fa992a0c..748d93093e 100644
--- a/src/ui/map_tests/map_style.test.ts
+++ b/src/ui/map_tests/map_style.test.ts
@@ -111,7 +111,7 @@ describe('#setStyle', () => {
spy.mockRestore();
});
- test('style transform overrides unmodified map transform', done => {
+ test('style transform overrides unmodified map transform', () => new Promise(done => {
const map = new Map({container: window.document.createElement('div')} as any as MapOptions);
map.transform.lngRange = [-120, 140];
map.transform.latRange = [-60, 80];
@@ -126,9 +126,9 @@ describe('#setStyle', () => {
expect(fixedNum(map.transform.pitch)).toBe(50);
done();
});
- });
+ }));
- test('style transform does not override map transform modified via options', done => {
+ test('style transform does not override map transform modified via options', () => new Promise(done => {
const map = new Map({container: window.document.createElement('div'), zoom: 10, center: [-77.0186, 38.8888]} as any as MapOptions);
expect(map.transform.unmodified).toBeFalsy();
map.setStyle(createStyle());
@@ -139,9 +139,9 @@ describe('#setStyle', () => {
expect(fixedNum(map.transform.pitch)).toBe(0);
done();
});
- });
+ }));
- test('style transform does not override map transform modified via setters', done => {
+ test('style transform does not override map transform modified via setters', () => new Promise(done => {
const map = new Map({container: window.document.createElement('div')} as any as MapOptions);
expect(map.transform.unmodified).toBeTruthy();
map.setZoom(10);
@@ -155,7 +155,7 @@ describe('#setStyle', () => {
expect(fixedNum(map.transform.pitch)).toBe(0);
done();
});
- });
+ }));
test('passing null removes style', () => {
const map = createMap();
@@ -185,7 +185,7 @@ describe('#setStyle', () => {
spyWorkerPoolRelease.mockClear();
});
- test('transformStyle should copy the source and the layer into next style', done => {
+ test('transformStyle should copy the source and the layer into next style', () => new Promise(done => {
const style = extend(createStyle(), {
sources: {
maplibre: {
@@ -231,9 +231,9 @@ describe('#setStyle', () => {
expect(loadedStyle.layers).toHaveLength(1);
done();
});
- });
+ }));
- test('delayed setStyle with transformStyle should copy the source and the layer into next style with diffing', done => {
+ test('delayed setStyle with transformStyle should copy the source and the layer into next style with diffing', () => new Promise(done => {
const style = extend(createStyle(), {
sources: {
maplibre: {
@@ -279,9 +279,9 @@ describe('#setStyle', () => {
expect(loadedStyle.layers).toHaveLength(1);
done();
}, 100);
- });
+ }));
- test('transformStyle should get called when passed to setStyle after the map is initialised without a style', done => {
+ test('transformStyle should get called when passed to setStyle after the map is initialised without a style', () => new Promise(done => {
const map = createMap({deleteStyle: true});
map.setStyle(createStyle(), {
diff: true,
@@ -314,9 +314,9 @@ describe('#setStyle', () => {
expect(loadedStyle.layers[0].id).toBe('layerId0');
done();
});
- });
+ }));
- test('map load should be fired when transformStyle is used on setStyle after the map is initialised without a style', done => {
+ test('map load should be fired when transformStyle is used on setStyle after the map is initialised without a style', () => new Promise(done => {
const map = createMap({deleteStyle: true});
map.setStyle({version: 8, sources: {}, layers: []}, {
diff: true,
@@ -327,7 +327,7 @@ describe('#setStyle', () => {
}
});
map.on('load', () => done());
- });
+ }));
test('Override default style validation', () => {
let validationOption = true;
@@ -342,14 +342,13 @@ describe('#setStyle', () => {
});
describe('#getStyle', () => {
- test('returns undefined if the style has not loaded yet', done => {
+ test('returns undefined if the style has not loaded yet', () => {
const style = createStyle();
const map = createMap({style});
expect(map.getStyle()).toBeUndefined();
- done();
});
- test('returns the style', done => {
+ test('returns the style', () => new Promise(done => {
const style = createStyle();
const map = createMap({style});
@@ -357,7 +356,7 @@ describe('#getStyle', () => {
expect(map.getStyle()).toEqual(style);
done();
});
- });
+ }));
test('returns the previous style even if modified', async () => {
const style = {
@@ -383,7 +382,7 @@ describe('#getStyle', () => {
expect(map.getStyle()).toEqual(style);
});
- test('returns the style with added sources', done => {
+ test('returns the style with added sources', () => new Promise(done => {
const style = createStyle();
const map = createMap({style});
@@ -394,9 +393,9 @@ describe('#getStyle', () => {
}));
done();
});
- });
+ }));
- test('fires an error on checking if non-existant source is loaded', done => {
+ test('fires an error on checking if non-existant source is loaded', () => new Promise(done => {
const style = createStyle();
const map = createMap({style});
@@ -407,9 +406,9 @@ describe('#getStyle', () => {
});
map.isSourceLoaded('geojson');
});
- });
+ }));
- test('returns the style with added layers', done => {
+ test('returns the style with added layers', () => new Promise(done => {
const style = createStyle();
const map = createMap({style});
const layer = {
@@ -424,7 +423,7 @@ describe('#getStyle', () => {
}));
done();
});
- });
+ }));
test('a layer can be added even if a map is created without a style', () => {
const map = createMap({deleteStyle: true});
@@ -454,7 +453,7 @@ describe('#getStyle', () => {
});
});
- test('returns the style with added source and layer', done => {
+ test('returns the style with added source and layer', () => new Promise(done => {
const style = createStyle();
const map = createMap({style});
const source = createStyleSource();
@@ -473,7 +472,7 @@ describe('#getStyle', () => {
}));
done();
});
- });
+ }));
test('creates a new Style if diff fails', () => {
const style = createStyle();
diff --git a/src/ui/map_tests/map_terrian.test.ts b/src/ui/map_tests/map_terrian.test.ts
index ef75fabca7..077a127d0b 100644
--- a/src/ui/map_tests/map_terrian.test.ts
+++ b/src/ui/map_tests/map_terrian.test.ts
@@ -17,7 +17,7 @@ afterEach(() => {
});
describe('#setTerrain', () => {
- test('warn when terrain and hillshade source identical', done => {
+ test('warn when terrain and hillshade source identical', () => new Promise(done => {
server.respondWith('/source.json', JSON.stringify({
minzoom: 5,
maxzoom: 12,
@@ -40,7 +40,7 @@ describe('#setTerrain', () => {
expect(console.warn).toHaveBeenCalledTimes(1);
done();
});
- });
+ }));
});
describe('#getTerrain', () => {
diff --git a/src/ui/map_tests/map_webgl.test.ts b/src/ui/map_tests/map_webgl.test.ts
index 5cec7241dd..889e44fbad 100644
--- a/src/ui/map_tests/map_webgl.test.ts
+++ b/src/ui/map_tests/map_webgl.test.ts
@@ -5,23 +5,23 @@ beforeEach(() => {
global.fetch = null;
});
-test('does not fire "webglcontextlost" after #remove has been called', done => {
+test('does not fire "webglcontextlost" after #remove has been called', () => new Promise((done) => {
const map = createMap();
const canvas = map.getCanvas();
- map.once('webglcontextlost', () => done('"webglcontextlost" fired after #remove has been called'));
+ map.once('webglcontextlost', () => { throw new Error('"webglcontextlost" fired after #remove has been called'); });
map.remove();
// Dispatch the event manually because at the time of this writing, gl does not support
// the WEBGL_lose_context extension.
canvas.dispatchEvent(new window.Event('webglcontextlost'));
done();
-});
+}));
-test('does not fire "webglcontextrestored" after #remove has been called', done => {
+test('does not fire "webglcontextrestored" after #remove has been called', () => new Promise((done) => {
const map = createMap();
const canvas = map.getCanvas();
map.once('webglcontextlost', () => {
- map.once('webglcontextrestored', () => done('"webglcontextrestored" fired after #remove has been called'));
+ map.once('webglcontextrestored', () => { throw new Error('"webglcontextrestored" fired after #remove has been called'); });
map.remove();
canvas.dispatchEvent(new window.Event('webglcontextrestored'));
done();
@@ -30,7 +30,7 @@ test('does not fire "webglcontextrestored" after #remove has been called', done
// Dispatch the event manually because at the time of this writing, gl does not support
// the WEBGL_lose_context extension.
canvas.dispatchEvent(new window.Event('webglcontextlost'));
-});
+}));
test('WebGL error while creating map', () => {
const original = HTMLCanvasElement.prototype.getContext;
diff --git a/src/util/actor.test.ts b/src/util/actor.test.ts
index 72bc9157b2..fc0d9a2659 100644
--- a/src/util/actor.test.ts
+++ b/src/util/actor.test.ts
@@ -116,7 +116,7 @@ describe('Actor', () => {
expect(spy).not.toHaveBeenCalled();
});
- test('#remove unbinds event listener', done => {
+ test('#remove unbinds event listener', () => new Promise(done => {
const actor = new Actor({
addEventListener(type, callback, useCapture) {
this._addEventListenerArgs = [type, callback, useCapture];
@@ -127,7 +127,7 @@ describe('Actor', () => {
}
} as ActorTarget, null);
actor.remove();
- });
+ }));
test('send a message that is rejected', async () => {
const worker = workerFactory() as any as WorkerGlobalScopeInterface & ActorTarget;
diff --git a/src/util/evented.test.ts b/src/util/evented.test.ts
index 90883ec874..3fb0fd3b75 100644
--- a/src/util/evented.test.ts
+++ b/src/util/evented.test.ts
@@ -105,13 +105,12 @@ describe('Evented', () => {
});
- test('does not immediately call listeners added within another listener', done => {
+ test('does not immediately call listeners added within another listener', () => {
const evented = new Evented();
evented.on('a', () => {
- evented.on('a', () => done('fail'));
+ evented.on('a', () => { throw new Error('fail'); });
});
evented.fire(new Event('a'));
- done();
});
test('has backward compatibility for fire(string, object) API', () => {
diff --git a/src/util/test/util.ts b/src/util/test/util.ts
index 78cf03df93..c6cc332026 100644
--- a/src/util/test/util.ts
+++ b/src/util/test/util.ts
@@ -149,7 +149,7 @@ export function bufferToArrayBuffer(data: Buffer): ArrayBuffer {
* @returns - a promise that resolves after the specified amount of time
*/
export const sleep = (milliseconds: number = 0) => {
- return new Promise(resolve => setTimeout(resolve, milliseconds));
+ return new Promise(resolve => setTimeout(resolve, milliseconds));
};
export function waitForMetadataEvent(source: Evented): Promise {
diff --git a/src/util/throttle.test.ts b/src/util/throttle.test.ts
index 169d335f50..88eea13f45 100644
--- a/src/util/throttle.test.ts
+++ b/src/util/throttle.test.ts
@@ -1,3 +1,4 @@
+import {sleep} from './test/util';
import {throttle} from './throttle';
describe('throttle', () => {
@@ -8,18 +9,16 @@ describe('throttle', () => {
expect(executionCount).toBe(0);
});
- test('executes unthrottled function once per tick when period is 0', done => {
+ test('executes unthrottled function once per tick when period is 0', async () => {
let executionCount = 0;
const throttledFunction = throttle(() => { executionCount++; }, 0);
throttledFunction();
throttledFunction();
expect(executionCount).toBe(1);
- setTimeout(() => {
- throttledFunction();
- throttledFunction();
- expect(executionCount).toBe(2);
- done();
- }, 0);
+ await sleep(0);
+ throttledFunction();
+ throttledFunction();
+ expect(executionCount).toBe(2);
});
test('executes unthrottled function immediately once when period is > 0', () => {
@@ -31,15 +30,13 @@ describe('throttle', () => {
expect(executionCount).toBe(1);
});
- test('queues exactly one execution of unthrottled function when period is > 0', done => {
+ test('queues exactly one execution of unthrottled function when period is > 0', async () => {
let executionCount = 0;
const throttledFunction = throttle(() => { executionCount++; }, 5);
throttledFunction();
throttledFunction();
throttledFunction();
- setTimeout(() => {
- expect(executionCount).toBe(2);
- done();
- }, 10);
+ await sleep(10);
+ expect(executionCount).toBe(2);
});
});
diff --git a/src/util/util.test.ts b/src/util/util.test.ts
index 850c1c5ea0..22b9eac7a8 100644
--- a/src/util/util.test.ts
+++ b/src/util/util.test.ts
@@ -14,7 +14,7 @@ describe('util', () => {
expect(pick({a: 1, b: 2, c: 3}, ['a', 'c', 'd'] as any)).toEqual({a: 1, c: 3});
expect(typeof uniqueId() === 'number').toBeTruthy();
- test('isPowerOfTwo', done => {
+ test('isPowerOfTwo', () => {
expect(isPowerOfTwo(1)).toBe(true);
expect(isPowerOfTwo(2)).toBe(true);
expect(isPowerOfTwo(256)).toBe(true);
@@ -22,10 +22,9 @@ describe('util', () => {
expect(isPowerOfTwo(0)).toBe(false);
expect(isPowerOfTwo(-42)).toBe(false);
expect(isPowerOfTwo(42)).toBe(false);
- done();
});
- test('nextPowerOfTwo', done => {
+ test('nextPowerOfTwo', () => {
expect(nextPowerOfTwo(1)).toBe(1);
expect(nextPowerOfTwo(2)).toBe(2);
expect(nextPowerOfTwo(256)).toBe(256);
@@ -33,10 +32,9 @@ describe('util', () => {
expect(nextPowerOfTwo(0)).toBe(1);
expect(nextPowerOfTwo(-42)).toBe(1);
expect(nextPowerOfTwo(42)).toBe(64);
- done();
});
- test('nextPowerOfTwo', done => {
+ test('nextPowerOfTwo', () => {
expect(isPowerOfTwo(nextPowerOfTwo(1))).toBe(true);
expect(isPowerOfTwo(nextPowerOfTwo(2))).toBe(true);
expect(isPowerOfTwo(nextPowerOfTwo(256))).toBe(true);
@@ -44,32 +42,28 @@ describe('util', () => {
expect(isPowerOfTwo(nextPowerOfTwo(0))).toBe(true);
expect(isPowerOfTwo(nextPowerOfTwo(-42))).toBe(true);
expect(isPowerOfTwo(nextPowerOfTwo(42))).toBe(true);
- done();
});
- test('clamp', done => {
+ test('clamp', () => {
expect(clamp(0, 0, 1)).toBe(0);
expect(clamp(1, 0, 1)).toBe(1);
expect(clamp(200, 0, 180)).toBe(180);
expect(clamp(-200, 0, 180)).toBe(0);
- done();
});
- test('wrap', done => {
+ test('wrap', () => {
expect(wrap(0, 0, 1)).toBe(1);
expect(wrap(1, 0, 1)).toBe(1);
expect(wrap(200, 0, 180)).toBe(20);
expect(wrap(-200, 0, 180)).toBe(160);
- done();
});
- test('bezier', done => {
+ test('bezier', () => {
const curve = bezier(0, 0, 0.25, 1);
expect(curve instanceof Function).toBeTruthy();
expect(curve(0)).toBe(0);
expect(curve(1)).toBe(1);
expect(curve(0.5)).toBe(0.8230854638965502);
- done();
});
test('mapObject', () => {
@@ -84,7 +78,7 @@ describe('util', () => {
}, that)).toEqual({map: 'BOX'});
});
- test('filterObject', done => {
+ test('filterObject', () => {
expect.assertions(6);
expect(filterObject({}, () => { expect(false).toBeTruthy(); })).toEqual({});
const that = {};
@@ -98,10 +92,9 @@ describe('util', () => {
expect(filterObject({map: 'box', box: 'map'}, (value) => {
return value === 'box';
})).toEqual({map: 'box'});
- done();
});
- test('deepEqual', done => {
+ test('deepEqual', () => {
const a = {
foo: 'bar',
bar: {
@@ -118,86 +111,75 @@ describe('util', () => {
expect(deepEqual(a, null)).toBeFalsy();
expect(deepEqual(null, c)).toBeFalsy();
expect(deepEqual(null, null)).toBeTruthy();
-
- done();
});
});
describe('util clone', () => {
- test('array', done => {
+ test('array', () => {
const input = [false, 1, 'two'];
const output = clone(input);
expect(input).not.toBe(output);
expect(input).toEqual(output);
- done();
});
- test('object', done => {
+ test('object', () => {
const input = {a: false, b: 1, c: 'two'};
const output = clone(input);
expect(input).not.toBe(output);
expect(input).toEqual(output);
- done();
});
- test('deep object', done => {
+ test('deep object', () => {
const input = {object: {a: false, b: 1, c: 'two'}};
const output = clone(input);
expect(input.object).not.toBe(output.object);
expect(input.object).toEqual(output.object);
- done();
});
- test('deep array', done => {
+ test('deep array', () => {
const input = {array: [false, 1, 'two']};
const output = clone(input);
expect(input.array).not.toBe(output.array);
expect(input.array).toEqual(output.array);
- done();
});
});
describe('util arraysIntersect', () => {
- test('intersection', done => {
+ test('intersection', () => {
const a = ['1', '2', '3'];
const b = ['5', '4', '3'];
expect(arraysIntersect(a, b)).toBe(true);
- done();
});
- test('no intersection', done => {
+ test('no intersection', () => {
const a = ['1', '2', '3'];
const b = ['4', '5', '6'];
expect(arraysIntersect(a, b)).toBe(false);
- done();
});
-
});
describe('util isCounterClockwise', () => {
- test('counter clockwise', done => {
+ test('counter clockwise', () => {
const a = new Point(0, 0);
const b = new Point(1, 0);
const c = new Point(1, 1);
expect(isCounterClockwise(a, b, c)).toBe(true);
- done();
});
- test('clockwise', done => {
+ test('clockwise', () => {
const a = new Point(0, 0);
const b = new Point(1, 0);
const c = new Point(1, 1);
expect(isCounterClockwise(c, b, a)).toBe(false);
- done();
});
});
describe('util parseCacheControl', () => {
- test('max-age', done => {
+ test('max-age', () => {
expect(parseCacheControl('max-age=123456789')).toEqual({
'max-age': 123456789
});
@@ -207,10 +189,7 @@ describe('util parseCacheControl', () => {
});
expect(parseCacheControl('max-age=null')).toEqual({});
-
- done();
});
-
});
describe('util findLineIntersection', () => {
From 1ffbb6d39f71dadbcf5402544f7ac3bdc235042d Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Fri, 20 Sep 2024 08:44:16 +0000
Subject: [PATCH 03/32] Bump devtools-protocol from 0.0.1356896 to 0.0.1358005
(#4725)
Bumps [devtools-protocol](https://github.com/ChromeDevTools/devtools-protocol) from 0.0.1356896 to 0.0.1358005.
- [Changelog](https://github.com/ChromeDevTools/devtools-protocol/blob/master/changelog.md)
- [Commits](https://github.com/ChromeDevTools/devtools-protocol/compare/v0.0.1356896...v0.0.1358005)
---
updated-dependencies:
- dependency-name: devtools-protocol
dependency-type: direct:development
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
package-lock.json | 8 ++++----
package.json | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 3364982db8..d957f3404d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -77,7 +77,7 @@
"cssnano": "^7.0.6",
"d3": "^7.9.0",
"d3-queue": "^3.0.7",
- "devtools-protocol": "^0.0.1356896",
+ "devtools-protocol": "^0.0.1358005",
"diff": "^7.0.0",
"dts-bundle-generator": "^9.5.1",
"eslint": "^8.57.0",
@@ -5203,9 +5203,9 @@
}
},
"node_modules/devtools-protocol": {
- "version": "0.0.1356896",
- "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1356896.tgz",
- "integrity": "sha512-qOUld6ut/Lseta6Pi5CYQQgRCC9j1T+bMxTJ/YQ7WI+q1owo5jNd44+ST5hoWnHTlRqPhG8tSrzuCnHVLTXx4A==",
+ "version": "0.0.1358005",
+ "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1358005.tgz",
+ "integrity": "sha512-gQ8/zj6d5zKpKkhR8ppQyittBI1GonHiL8FLg0LaSCVtmlur7YC0tg7Aa+iK7XCVtUo5ZO5pSUi9b0BDerYGKg==",
"dev": true
},
"node_modules/diff": {
diff --git a/package.json b/package.json
index b8206fb498..a9c9044cf8 100644
--- a/package.json
+++ b/package.json
@@ -85,7 +85,7 @@
"cssnano": "^7.0.6",
"d3": "^7.9.0",
"d3-queue": "^3.0.7",
- "devtools-protocol": "^0.0.1356896",
+ "devtools-protocol": "^0.0.1358005",
"diff": "^7.0.0",
"dts-bundle-generator": "^9.5.1",
"eslint": "^8.57.0",
From 12bfadaf406eb2c15b69e29d9242d6818259b30b Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Fri, 20 Sep 2024 08:44:32 +0000
Subject: [PATCH 04/32] Bump @types/react from 18.3.7 to 18.3.8 (#4726)
Bumps [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) from 18.3.7 to 18.3.8.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)
---
updated-dependencies:
- dependency-name: "@types/react"
dependency-type: direct:development
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
package-lock.json | 8 ++++----
package.json | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index d957f3404d..0d8626a6a1 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -63,7 +63,7 @@
"@types/offscreencanvas": "^2019.7.3",
"@types/pixelmatch": "^5.2.6",
"@types/pngjs": "^6.0.5",
- "@types/react": "^18.3.7",
+ "@types/react": "^18.3.8",
"@types/react-dom": "^18.3.0",
"@types/request": "^2.48.12",
"@types/shuffle-seed": "^1.1.3",
@@ -2799,9 +2799,9 @@
"license": "MIT"
},
"node_modules/@types/react": {
- "version": "18.3.7",
- "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.7.tgz",
- "integrity": "sha512-KUnDCJF5+AiZd8owLIeVHqmW9yM4sqmDVf2JRJiBMFkGvkoZ4/WyV2lL4zVsoinmRS/W3FeEdZLEWFRofnT2FQ==",
+ "version": "18.3.8",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.8.tgz",
+ "integrity": "sha512-syBUrW3/XpnW4WJ41Pft+I+aPoDVbrBVQGEnbD7NijDGlVC+8gV/XKRY+7vMDlfPpbwYt0l1vd/Sj8bJGMbs9Q==",
"dev": true,
"dependencies": {
"@types/prop-types": "*",
diff --git a/package.json b/package.json
index a9c9044cf8..8f52995877 100644
--- a/package.json
+++ b/package.json
@@ -72,7 +72,7 @@
"@types/offscreencanvas": "^2019.7.3",
"@types/pixelmatch": "^5.2.6",
"@types/pngjs": "^6.0.5",
- "@types/react": "^18.3.7",
+ "@types/react": "^18.3.8",
"@types/react-dom": "^18.3.0",
"@types/request": "^2.48.12",
"@types/shuffle-seed": "^1.1.3",
From be7e20920554d5ed873448c96e5fa73e7e2ce565 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Fri, 20 Sep 2024 08:45:07 +0000
Subject: [PATCH 05/32] Bump rollup from 4.22.0 to 4.22.1 (#4727)
Bumps [rollup](https://github.com/rollup/rollup) from 4.22.0 to 4.22.1.
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rollup/rollup/compare/v4.22.0...v4.22.1)
---
updated-dependencies:
- dependency-name: rollup
dependency-type: direct:development
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
package-lock.json | 136 +++++++++++++++++++++++-----------------------
package.json | 2 +-
2 files changed, 69 insertions(+), 69 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 0d8626a6a1..bfdf225f8a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -113,7 +113,7 @@
"puppeteer": "^23.4.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
- "rollup": "^4.22.0",
+ "rollup": "^4.22.1",
"rollup-plugin-sourcemaps": "^0.6.3",
"rw": "^1.3.3",
"semver": "^7.6.3",
@@ -2010,9 +2010,9 @@
"dev": true
},
"node_modules/@rollup/rollup-android-arm-eabi": {
- "version": "4.22.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.0.tgz",
- "integrity": "sha512-/IZQvg6ZR0tAkEi4tdXOraQoWeJy9gbQ/cx4I7k9dJaCk9qrXEcdouxRVz5kZXt5C2bQ9pILoAA+KB4C/d3pfw==",
+ "version": "4.22.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.1.tgz",
+ "integrity": "sha512-GrXxNVBes13Q3wSBjdZlmu4VulFhfNs1eP2/pX5dmx6cE1XgfV2/BfqdGt4d2Z7Zqp+qnYSf7zvIB4buc+2DwA==",
"cpu": [
"arm"
],
@@ -2023,9 +2023,9 @@
]
},
"node_modules/@rollup/rollup-android-arm64": {
- "version": "4.22.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.0.tgz",
- "integrity": "sha512-ETHi4bxrYnvOtXeM7d4V4kZWixib2jddFacJjsOjwbgYSRsyXYtZHC4ht134OsslPIcnkqT+TKV4eU8rNBKyyQ==",
+ "version": "4.22.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.1.tgz",
+ "integrity": "sha512-Cr/dpKRc4tjK13SCZJrSDXSaKjL/fekn04BWMCJ+Pj4vPCp8rixvtArrnWUYycOdRNi7kx3MSClcvEP7C2nvCw==",
"cpu": [
"arm64"
],
@@ -2036,9 +2036,9 @@
]
},
"node_modules/@rollup/rollup-darwin-arm64": {
- "version": "4.22.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.0.tgz",
- "integrity": "sha512-ZWgARzhSKE+gVUX7QWaECoRQsPwaD8ZR0Oxb3aUpzdErTvlEadfQpORPXkKSdKbFci9v8MJfkTtoEHnnW9Ulng==",
+ "version": "4.22.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.1.tgz",
+ "integrity": "sha512-IwEyoeCZoO1lpY5Er5t3UK/Aq5q2W/ubLmu3pYW4as0htn4NbJagBaVNr1aVhRTXUxrYvcPhxQCqodShnocLdA==",
"cpu": [
"arm64"
],
@@ -2049,9 +2049,9 @@
]
},
"node_modules/@rollup/rollup-darwin-x64": {
- "version": "4.22.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.0.tgz",
- "integrity": "sha512-h0ZAtOfHyio8Az6cwIGS+nHUfRMWBDO5jXB8PQCARVF6Na/G6XS2SFxDl8Oem+S5ZsHQgtsI7RT4JQnI1qrlaw==",
+ "version": "4.22.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.1.tgz",
+ "integrity": "sha512-LSbJhEOTz557VBcJOWspdGyiFbMTNgLxbWnup7bDj1elpNTK04E3M1qLlvGzPKPmk+uG6XlbT8xAUSKkyn0g8w==",
"cpu": [
"x64"
],
@@ -2062,9 +2062,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
- "version": "4.22.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.0.tgz",
- "integrity": "sha512-9pxQJSPwFsVi0ttOmqLY4JJ9pg9t1gKhK0JDbV1yUEETSx55fdyCjt39eBQ54OQCzAF0nVGO6LfEH1KnCPvelA==",
+ "version": "4.22.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.1.tgz",
+ "integrity": "sha512-F4DgRk//u604Np1eFoGUzE9TgGE6LMvjnX2tM24ePB34JlED9utc4T3iK5x8CWC/agH+zuN7q/hJF5AtWR+JOA==",
"cpu": [
"arm"
],
@@ -2075,9 +2075,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
- "version": "4.22.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.0.tgz",
- "integrity": "sha512-YJ5Ku5BmNJZb58A4qSEo3JlIG4d3G2lWyBi13ABlXzO41SsdnUKi3HQHe83VpwBVG4jHFTW65jOQb8qyoR+qzg==",
+ "version": "4.22.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.1.tgz",
+ "integrity": "sha512-Gl5pbijcb6QOJRvHkmU/O1G65ZnKxwSHhPQRuGdmcxmX/mBM+wNHoai7wvpCoPVsdhkc+KUqgu/MydP8wovGAA==",
"cpu": [
"arm"
],
@@ -2088,9 +2088,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
- "version": "4.22.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.0.tgz",
- "integrity": "sha512-U4G4u7f+QCqHlVg1Nlx+qapZy+QoG+NV6ux+upo/T7arNGwKvKP2kmGM4W5QTbdewWFgudQxi3kDNST9GT1/mg==",
+ "version": "4.22.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.1.tgz",
+ "integrity": "sha512-GsvZqPloVOrh3G2nmZmwNSNGqWLf3L3a0nFDO1zecwucAYxEFgZkrvqQrVMT+zUjChaHPBp0eoTOQMWSKFcV8w==",
"cpu": [
"arm64"
],
@@ -2101,9 +2101,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
- "version": "4.22.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.0.tgz",
- "integrity": "sha512-aQpNlKmx3amwkA3a5J6nlXSahE1ijl0L9KuIjVOUhfOh7uw2S4piR3mtpxpRtbnK809SBtyPsM9q15CPTsY7HQ==",
+ "version": "4.22.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.1.tgz",
+ "integrity": "sha512-+vZ1jrJeEEYLbMqeKDfgcl8v7zjymdAGTr7xUdQL6c4nC+S+BZHo3Mrp/9ij2qpAveC0Iaz9DIiFplcO0joapQ==",
"cpu": [
"arm64"
],
@@ -2114,9 +2114,9 @@
]
},
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
- "version": "4.22.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.0.tgz",
- "integrity": "sha512-9fx6Zj/7vve/Fp4iexUFRKb5+RjLCff6YTRQl4CoDhdMfDoobWmhAxQWV3NfShMzQk1Q/iCnageFyGfqnsmeqQ==",
+ "version": "4.22.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.1.tgz",
+ "integrity": "sha512-6psD9nKw+wLj9bMhArTkzKt5etA6kb+cBJQws4MovI9gQSRkdX4nyYZofBfgTtaZtymQl7uRfe1I75guePal5A==",
"cpu": [
"ppc64"
],
@@ -2127,9 +2127,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
- "version": "4.22.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.0.tgz",
- "integrity": "sha512-VWQiCcN7zBgZYLjndIEh5tamtnKg5TGxyZPWcN9zBtXBwfcGSZ5cHSdQZfQH/GB4uRxk0D3VYbOEe/chJhPGLQ==",
+ "version": "4.22.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.1.tgz",
+ "integrity": "sha512-xzbqImk1h5abj0bPU5XQVrqBhLHl2zTygG6+vES2TrgmNSiaPzn39aqI8QtdqmGYz507ZVI2qocTTfVwW23SmQ==",
"cpu": [
"riscv64"
],
@@ -2140,9 +2140,9 @@
]
},
"node_modules/@rollup/rollup-linux-s390x-gnu": {
- "version": "4.22.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.0.tgz",
- "integrity": "sha512-EHmPnPWvyYqncObwqrosb/CpH3GOjE76vWVs0g4hWsDRUVhg61hBmlVg5TPXqF+g+PvIbqkC7i3h8wbn4Gp2Fg==",
+ "version": "4.22.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.1.tgz",
+ "integrity": "sha512-Hz5iwqYv08PpEC75z0GAgLlOY+cLAb0PVx578mLW0naugNfG0WQqoDzQoJWiivmtTdgmwoH5YXDnjZJb7MDlhA==",
"cpu": [
"s390x"
],
@@ -2153,9 +2153,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
- "version": "4.22.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.0.tgz",
- "integrity": "sha512-tsSWy3YQzmpjDKnQ1Vcpy3p9Z+kMFbSIesCdMNgLizDWFhrLZIoN21JSq01g+MZMDFF+Y1+4zxgrlqPjid5ohg==",
+ "version": "4.22.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.1.tgz",
+ "integrity": "sha512-ot1DPlQZGGiZYNyE/PF3jbT6juuG0W5oiguHQEvjoZZ3+FSxMfdJnBz1P71QeqICSOlSFG9Z31oA/uXyuxDEVw==",
"cpu": [
"x64"
],
@@ -2166,9 +2166,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
- "version": "4.22.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.0.tgz",
- "integrity": "sha512-anr1Y11uPOQrpuU8XOikY5lH4Qu94oS6j0xrulHk3NkLDq19MlX8Ng/pVipjxBJ9a2l3+F39REZYyWQFkZ4/fw==",
+ "version": "4.22.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.1.tgz",
+ "integrity": "sha512-euksHNkKlXS9RKKHSBBPtloSEUGPg1eRVGfOkXSSIj5W9LdkMfOefsTlVf2g8kuayZW/98nIJ83Fnou9OaZNXA==",
"cpu": [
"x64"
],
@@ -2179,9 +2179,9 @@
]
},
"node_modules/@rollup/rollup-win32-arm64-msvc": {
- "version": "4.22.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.0.tgz",
- "integrity": "sha512-7LB+Bh+Ut7cfmO0m244/asvtIGQr5pG5Rvjz/l1Rnz1kDzM02pSX9jPaS0p+90H5I1x4d1FkCew+B7MOnoatNw==",
+ "version": "4.22.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.1.tgz",
+ "integrity": "sha512-jDS/ShZxlA3HKtgm25CcbApOVsr/0Zkdu/E+3xK4UO0PT912yqyh7jNpTmZZJAiPDQoSDI9FOqrjSbnlpW6IFg==",
"cpu": [
"arm64"
],
@@ -2192,9 +2192,9 @@
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
- "version": "4.22.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.0.tgz",
- "integrity": "sha512-+3qZ4rer7t/QsC5JwMpcvCVPRcJt1cJrYS/TMJZzXIJbxWFQEVhrIc26IhB+5Z9fT9umfVc+Es2mOZgl+7jdJQ==",
+ "version": "4.22.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.1.tgz",
+ "integrity": "sha512-yNEeuvH2b+susSgUCfpRelIRjB1CmErHyqA7KsQ/NCjY401rpChVqw5df/H5AUPCKNDqgBMbtrtl9F6z7N9LTg==",
"cpu": [
"ia32"
],
@@ -2205,9 +2205,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
- "version": "4.22.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.0.tgz",
- "integrity": "sha512-YdicNOSJONVx/vuPkgPTyRoAPx3GbknBZRCOUkK84FJ/YTfs/F0vl/YsMscrB6Y177d+yDRcj+JWMPMCgshwrA==",
+ "version": "4.22.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.1.tgz",
+ "integrity": "sha512-UgdylcqjcgJSNMhrjMJpJ4T3zriTmiUd2COh1mJHwDShrhhMkpZ/j4M5e4GsvBFviaxtrJtufr0FnKfm2UfOSw==",
"cpu": [
"x64"
],
@@ -11682,9 +11682,9 @@
"license": "Unlicense"
},
"node_modules/rollup": {
- "version": "4.22.0",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.0.tgz",
- "integrity": "sha512-W21MUIFPZ4+O2Je/EU+GP3iz7PH4pVPUXSbEZdatQnxo29+3rsUjgrJmzuAZU24z7yRAnFN6ukxeAhZh/c7hzg==",
+ "version": "4.22.1",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.1.tgz",
+ "integrity": "sha512-rit4zY5uPX0jrzTidez3rFr0MD30Rpu3S8VxwXFDfBVAzkk9U28s5MF3/R6u5bIHN6CQnf7zbiwVQbqBkyrU/A==",
"dev": true,
"dependencies": {
"@types/estree": "1.0.5"
@@ -11697,22 +11697,22 @@
"npm": ">=8.0.0"
},
"optionalDependencies": {
- "@rollup/rollup-android-arm-eabi": "4.22.0",
- "@rollup/rollup-android-arm64": "4.22.0",
- "@rollup/rollup-darwin-arm64": "4.22.0",
- "@rollup/rollup-darwin-x64": "4.22.0",
- "@rollup/rollup-linux-arm-gnueabihf": "4.22.0",
- "@rollup/rollup-linux-arm-musleabihf": "4.22.0",
- "@rollup/rollup-linux-arm64-gnu": "4.22.0",
- "@rollup/rollup-linux-arm64-musl": "4.22.0",
- "@rollup/rollup-linux-powerpc64le-gnu": "4.22.0",
- "@rollup/rollup-linux-riscv64-gnu": "4.22.0",
- "@rollup/rollup-linux-s390x-gnu": "4.22.0",
- "@rollup/rollup-linux-x64-gnu": "4.22.0",
- "@rollup/rollup-linux-x64-musl": "4.22.0",
- "@rollup/rollup-win32-arm64-msvc": "4.22.0",
- "@rollup/rollup-win32-ia32-msvc": "4.22.0",
- "@rollup/rollup-win32-x64-msvc": "4.22.0",
+ "@rollup/rollup-android-arm-eabi": "4.22.1",
+ "@rollup/rollup-android-arm64": "4.22.1",
+ "@rollup/rollup-darwin-arm64": "4.22.1",
+ "@rollup/rollup-darwin-x64": "4.22.1",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.22.1",
+ "@rollup/rollup-linux-arm-musleabihf": "4.22.1",
+ "@rollup/rollup-linux-arm64-gnu": "4.22.1",
+ "@rollup/rollup-linux-arm64-musl": "4.22.1",
+ "@rollup/rollup-linux-powerpc64le-gnu": "4.22.1",
+ "@rollup/rollup-linux-riscv64-gnu": "4.22.1",
+ "@rollup/rollup-linux-s390x-gnu": "4.22.1",
+ "@rollup/rollup-linux-x64-gnu": "4.22.1",
+ "@rollup/rollup-linux-x64-musl": "4.22.1",
+ "@rollup/rollup-win32-arm64-msvc": "4.22.1",
+ "@rollup/rollup-win32-ia32-msvc": "4.22.1",
+ "@rollup/rollup-win32-x64-msvc": "4.22.1",
"fsevents": "~2.3.2"
}
},
diff --git a/package.json b/package.json
index 8f52995877..04eaa3168d 100644
--- a/package.json
+++ b/package.json
@@ -121,7 +121,7 @@
"puppeteer": "^23.4.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
- "rollup": "^4.22.0",
+ "rollup": "^4.22.1",
"rollup-plugin-sourcemaps": "^0.6.3",
"rw": "^1.3.3",
"semver": "^7.6.3",
From 57d7d83d80c29468dc75c3ad1767ddae162e062f Mon Sep 17 00:00:00 2001
From: Birk Skyum <74932975+birkskyum@users.noreply.github.com>
Date: Sat, 21 Sep 2024 21:22:58 +0200
Subject: [PATCH 06/32] Fix hash router for urls ending with a hash (#4730)
---
CHANGELOG.md | 1 +
src/ui/hash.test.ts | 65 +++++++++++++++++++++++++++++++++++++++++++++
src/ui/hash.ts | 2 +-
3 files changed, 67 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 38fb176441..b31338276a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,7 @@
### 🐞 Bug fixes
- Fix circle won't render on mesa 24.1 with AMD GPU ([#4062](https://github.com/maplibre/maplibre-gl-js/issues/4062))
+- Fix hash router for urls ending with a hashtag ([#4730](https://github.com/maplibre/maplibre-gl-js/pull/4730))
- _...Add new stuff here..._
## 4.7.0
diff --git a/src/ui/hash.test.ts b/src/ui/hash.test.ts
index c3c676f7d9..7809a9f9f4 100644
--- a/src/ui/hash.test.ts
+++ b/src/ui/hash.test.ts
@@ -327,6 +327,71 @@ describe('hash', () => {
expect(window.location.hash).toBe('#baz&foo=bar');
});
+ test('initialize http://localhost/#', () => {
+ window.location.href = 'http://localhost/#';
+ createHash().addTo(map);
+ map.setZoom(3);
+ expect(window.location.hash).toBe('#3/0/0');
+ expect(window.location.href).toBe('http://localhost/#3/0/0');
+ map.setCenter([2.0, 1.0]);
+ expect(window.location.hash).toBe('#3/1/2');
+ expect(window.location.href).toBe('http://localhost/#3/1/2');
+ });
+
+ test('initialize http://localhost/##', () => {
+ window.location.href = 'http://localhost/##';
+ createHash().addTo(map);
+ map.setZoom(3);
+ expect(window.location.hash).toBe('#3/0/0');
+ expect(window.location.href).toBe('http://localhost/#3/0/0');
+ map.setCenter([2.0, 1.0]);
+ expect(window.location.hash).toBe('#3/1/2');
+ expect(window.location.href).toBe('http://localhost/#3/1/2');
+ });
+
+ test('initialize http://localhost#', () => {
+ window.location.href = 'http://localhost#';
+ createHash().addTo(map);
+ map.setZoom(4);
+ expect(window.location.hash).toBe('#4/0/0');
+ expect(window.location.href).toBe('http://localhost/#4/0/0');
+ map.setCenter([2.0, 1.0]);
+ expect(window.location.hash).toBe('#4/1/2');
+ expect(window.location.href).toBe('http://localhost/#4/1/2');
+ });
+
+ test('initialize http://localhost/', () => {
+ window.location.href = 'http://localhost/';
+ createHash().addTo(map);
+ map.setZoom(5);
+ expect(window.location.hash).toBe('#5/0/0');
+ expect(window.location.href).toBe('http://localhost/#5/0/0');
+ map.setCenter([2.0, 1.0]);
+ expect(window.location.hash).toBe('#5/1/2');
+ expect(window.location.href).toBe('http://localhost/#5/1/2');
+ });
+
+ test('initialize default value for window.location.href', () => {
+ createHash().addTo(map);
+ map.setZoom(5);
+ expect(window.location.hash).toBe('#5/0/0');
+ expect(window.location.href).toBe('http://localhost/#5/0/0');
+ map.setCenter([2.0, 1.0]);
+ expect(window.location.hash).toBe('#5/1/2');
+ expect(window.location.href).toBe('http://localhost/#5/1/2');
+ });
+
+ test('initialize http://localhost', () => {
+ window.location.href = 'http://localhost';
+ createHash().addTo(map);
+ map.setZoom(4);
+ expect(window.location.hash).toBe('#4/0/0');
+ expect(window.location.href).toBe('http://localhost/#4/0/0');
+ map.setCenter([2.0, 1.0]);
+ expect(window.location.hash).toBe('#4/1/2');
+ expect(window.location.href).toBe('http://localhost/#4/1/2');
+ });
+
test('map#remove', () => {
const container = window.document.createElement('div');
Object.defineProperty(container, 'clientWidth', {value: 512});
diff --git a/src/ui/hash.ts b/src/ui/hash.ts
index 40b23b91c9..b647205520 100644
--- a/src/ui/hash.ts
+++ b/src/ui/hash.ts
@@ -118,7 +118,7 @@ export class Hash {
_updateHashUnthrottled = () => {
// Replace if already present, else append the updated hash string
- const location = window.location.href.replace(/(#.+)?$/, this.getHashString());
+ const location = window.location.href.replace(/(#.*)?$/, this.getHashString());
window.history.replaceState(window.history.state, null, location);
};
From 8ff7d2a9adfd6def3160b4e2fa98b9e56f466a3c Mon Sep 17 00:00:00 2001
From: Birk Skyum <74932975+birkskyum@users.noreply.github.com>
Date: Sun, 22 Sep 2024 09:15:06 +0200
Subject: [PATCH 07/32] hash-router example (#4731)
* hash-router example
* wording
---
docs/assets/examples/hash-router.png | Bin 0 -> 270779 bytes
test/examples/hash-router.html | 49 +++++++++++++++++++++++++++
2 files changed, 49 insertions(+)
create mode 100644 docs/assets/examples/hash-router.png
create mode 100644 test/examples/hash-router.html
diff --git a/docs/assets/examples/hash-router.png b/docs/assets/examples/hash-router.png
new file mode 100644
index 0000000000000000000000000000000000000000..b389dd4b59ff0b88c09e861c1276d9a9d045836c
GIT binary patch
literal 270779
zcmYhiWl$Vpw=N2U5AIGvaF+ykhakZQXK+Yx31M(|m%%L%2=30{F2OapySs(UKHs;`
zxldJBSHC~IyVhEdtZ-EoIZPlK5DpFwQ$b!@9S#n$3Jwnb8Ws8Ngl%F5@9l=>D6i`R
z2ZxUTKNmb)dM3%+A-s#aoFrVu7{$Tc1EQ6LvIHDlbu9X`2@)J4wW@-&geC<3xD6#U
zQ``OQHKS4Ktk$~#bk?wJXB%kOnWTz9OC25e883m{S?ZEur;vd!nwEG!zZPrTp>X;p6ILlH02Ds>|4w$QP&Mao&uHssBJw
zaZ_o_Q8?CtDrRf3m{oR4W}De{xq&?_1v}XBCLML|QK@&Cp0!8Z%*RsQ;nVrGCRT^<
zE9&hS!McmyeU`RE|Ba30L`zc=`<&zJ1!8vk;QGcSLBwo}$BG3RWd78?4668;{)g$l
z9B23spd`A+LrjfAwnA{Jnhr(yl61tedxO(tumioGmigvGU0rg1m?zuZqgy^WCRfeH
zY|USAO27`w5Y?IAuil$pm^Pkh(FLDhJ<(6vg93<@gwLy^zP`
z`%~7Tryd94)1t43Ex~K8FLJ#HK3^r;U=w+_{>$`!Ju_pJXs8DhI$L?-&`KjxcD;6<
zNt)l6$6-sPw9%KMS@lRCQ4$y-)tQRBn14vr&g?Mj<->qE`$DJnU_kPJFsF<6r~5aO
zp4W3R7eyvpu8xgAdZmT2#sWf$MHdTl_=o~z$4^GFH!j?*yjWDDjJMjM0g1sHP?w!E
zWa1h7g_KK=IP_4G_HNAl3tU6ZPXIquWgav;-k!$
zP{hmn`^bi!Mzb&v-uGYojLDMgDhodm<4*?%rm|BdoX!3$aOE!eytRL4A8LY=&@#DZ
zgW5TDvMU+4wBx5pb@7=raR;w|+G3Q@`mpVLaUoR_^;U0S4^vcO1Y{%zj1jU-X393v
zwJ3Z$1abdbkt^OI7czRn#lb7PJgAwqFM|}aR0*Fvr?7Jf#vV^M9PCC*X=Fby3Nbjn
zAnsyWIt~8zxJ^}8U<4g+o)5$qSZYR&_8_W1jGFkS=wCS-m;LhXKgi;V4)eb-^8Ae`
zyrYJzgB!0~H?nR1S6V0gP7YRtIw7x}UeyP80fg1;cy~P0Xjg2c9Z)PMOBu`I8-mFl
z@XTa-N+T76KU1y=3x`@2)&N*BVXq-Rw$bj0w(zg#+XPe@I88hWT`cpVj-L+t=PCmH
z$^+`cFH*`D1T7Mdxx9+zdZtu*;aubczme_V*hv*~({!@Hzx@iu;mCLexYrP*B&|Ty
zP{ee8|I5P#Ej_E;lIttPWv<`oFYJ7Wll1oFK;sYEGU7x60qh!4<|x_F3v+s-KEtO%
zD4&CGXRv>+zFiOeMp}=cIdn;(PTB|4uj!4mpTZC@4BC
z)D+wmg$#ziI{SA8~OB7q(T6HSXsMiA;BjSB94c#Lq<{bh=XJ
zprL2B-T#PY<_|gW>S}YsER<#TwXota}6{x5W)%4=#L+fAtaT1$DiH1
z0Z|Fw3SFi@O%io89E^@u#|#rWE~E4*-$V
z{bJETZN->jfxrGCz{v~0Ls;bM17hUi;xZJ2uWon@a2P7#%=O#yntQc7Yr*uuB+)6mSyg82d>!HYyz#{!n!%V;^fJur%#T%Nwn}dbPVqmm0YO={oX#d`+kbo|N^Isv2B^SH6bW!+qp5U}
z#t2JNSwOhA0@RUxgCnm2yzs%{aU;?*7XDrlx5x~CD@lNx88vMJ{uI*>z|XTG$U4Mn
z02RgHpi7U_43_m_svH9&6ia6)zQWVU6jr+jZE#g9`rSM1tp-dcX_2FNMk=|5W@Owu
zGJkEAZ5x@OGEV0k7)gN#bE&IGI*UT9GiGPi=SvRk7Bl2ROP;P4oS6_EZ;=onpB1V>
z{alcR;5yNjYl>Ky6&cg_A;|$E-HC@O@LrXn@E
z1h_WgNYV)HH{irw^qU#!WoHO~5zxihbT?jjFQV^;1yL=9Tnrje9@L=hAYb7(uj6no
z*w+1p^?dIJ_8Pkf_@xkdHC5=hTrLGSwAI_C9Q$z4
z$|L1Ik(6FlupuU`k&YN!rJ#=wBtlF}0;sqo=R;TclNdj+pC^XwWs!H2D7W^W+nO4#
zd-$hI4T4GsHJt%H%<`atxDut2Bb&~;nvh$j3B8}dSz2Iy5*&s;i01gr3AHm|4(Wqr
znOVLokLAoBlbdg&zj0@$K>_Q_XG(H&iS1!9M~E<>Xf*k!0kPxs9*gPc^?UdOjgUl{
z(cx}6F3`ZoL{fKiCr9>JOhEl3;`#CM16x52$}F&
z#Oyi7$9xW)q0-U&4~SEnN?tm{I!h61`I$oyq5&S@n|nK3@~}=eM`n;cBM0+bY;CWp
zu}-L**6g=z3gu)(c@p3cuF*KqAyvW&m+qNk3u0wik{kN*`j0wxDoo@RM?E&$2RnZa
zDQe<&A6A-vsGky7p{U~#S#yQTa=kCs>%}rfb{3Oy=UKoA&{UB&ByJje+9VR*Qh^+<
z5E#lC@2e6_FeS&KTUYRhK#wRRc@FqVTR7yWxK7j!_p&|T2WpgrZ!0nE1Q*E_Zp-s3
z8I?ToMVg4B0wA7gJOB5*o-ZX+RG<`5YU(N>`YajOhWA@?NaKHS^a#)Ib@YOXr-Yb9
zvy*-L{5jrbf;uir8|}LL*muJzpuzchtR&}U7KoQlxW)8lc0(pZlKvWxpBbE+F^dGO
zQRi!G7|pw>9Y^X6i#%!WFQf3amlUqkK&kDFQL>mfUh282W4LZygH;BcFKQby7R~m>
zDFl+bkDm4rWVddt8`GwPuD_0k-i=y{oeixjUSl=Clu7K9kOF+{K7|ay(B0EYohFB5
z;U!XnrM{sfz(3fxg|L^h=A<;tGMd%@g8$#?k2KOfCOa9r>Ohg+1FyScS>McOAC3xh
zG_`rR0cA?0DDtAa&Nb!K&DWIB6i4bo`3T@9xjny^##+hN+9_)L=0=m
zIRv?KktBI`DYt|hRZb)AcfAK_eHILT8s-)GDg>U*a6Jhus5dPb#^1j?@w3>Q{Mt0J
zX7)A^hCBwB*tRp}PIlH;b5beO;^Lmybe-TgZHf!8_|0$m4V>U`B1tc^edGfdZ7Li%
z@U#Ef9xm~d&RGlZsWEmoFvb?b(&GP~PVAOY#-+RcF!fKDLS>sPjj4FP2}gRo22tv^
zz`+7(z;BwGvozd!x|h1QYLOXOcdoFfCpr6lYgRwdk>^7dGZKjkNBY#>oU=kwAr|_?
z#9e$nSqE1ot{41*#)sKf$A!1eS~OqVQ?;fouQf
z_Jfn|q~%v+O!#h=kYKw*%pSIW3D~k`X*bAU(>+b8G8VF4!?xqU(@2rZg1V3}H1QjI
zbVDjusgtd;x|^Vj@J|GL4!(^f6?CMx31cMBXmoSO^y^p;jRK*{AkNgDCGb$hW69NX
z+P-TXA}h$$+Hn!F4~ebm5*Dd$v{cPY?iE&0gwsBu0dlG*5YI9Ph5UNuyBt;TKQ7Y(%k9*2%s5W*;nc};_()zi
z=d5^uW7LW!lDHI^fISPPc2G=;Rj~W{!4PcDfhHrpN2!*4F~nb|^R1^47VY?Hs|J44
zs{*K*M@(V=F2ub+p8&e%r>6(Z1v8^$#`_>u#%KyV8?qT}40mDuC=Lb0FVdC>`0Ex>
zu;v(O_-aZh4__nCrh0HX{7jCQ>2U^P5GScU%5-pRJD0?DZD^7j34Ac~D5&_mBnq$n
zaul$zXxQIz%J!k_^Hc~cXm}p8Cvr9k`G4!B6>TAd0-<&4h;|ag+=-NgZB$cr!w7cH
zh-BX1-fAyOAt@q*WTr$DY=Awv&yskXR*z$Gv9l@H7xltr)%A$Yy5aOnEw>Y6R59m2
z@AE{-^@wv)ZFcXBYC-M?B8)5zYobKjrHy5J*Xv)A$@};(1bq6fzmMjGM^0E(i}B2OJvP9
zSUCyp@jLX@5vJ`qzuTZ)h2^6hZNKacGOgW()14gdL++2dqvA@3+JAhamX)wHkIEQ^
zB68M8=w3f%?L&PgkA$yi=M6}j&UDlz1gW+%8f7oMTU)rYN;j9B4csWxd$8?eyU(09
zbZUa?!Q_@r#N-qzpN4HrKCkK5yZ|aG9EDO#2PF>ujPKxvvpLCXpEe>e^0L3=tFcKQ
z0pk1^dJ2i15u#-=Lk=`Id}ZJhVhN?>=h%b|P)!nR!~To`c=_Rlmh-8iWhq1GI9O59
zyrWMw<%t)Q