Skip to content

Commit e6398a6

Browse files
committed
Updated tests
1 parent bc023ca commit e6398a6

File tree

4 files changed

+127
-166
lines changed

4 files changed

+127
-166
lines changed

src/geo/lng_lat_bounds.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,12 @@ describe('LngLatBounds', () => {
423423
const bounds = new LngLatBounds([-180, 5], [-175, 10]);
424424
expect(tileBounds.intersects(bounds)).toBe(true);
425425
});
426+
427+
test('entire worlds tile should return true', () => {
428+
const tileBounds = new LngLatBounds([270, -88.97061836630758], [-270, 88.97061836630758]);
429+
const bounds = new LngLatBounds([0, 0], [10, 10]);
430+
expect(tileBounds.intersects(bounds)).toBe(true);
431+
});
426432
});
427433
});
428434
});

src/source/geojson_source.test.ts

Lines changed: 96 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,20 @@
1-
import {describe, test, expect, vi, /*beforeEach*/} from 'vitest';
1+
import {describe, test, expect, vi, beforeEach} from 'vitest';
22
import {Tile} from '../tile/tile';
33
import {OverscaledTileID} from '../tile/tile_id';
4-
import {GeoJSONSource, type GeoJSONSourceOptions} from './geojson_source';
4+
import {GeoJSONSource, type GeoJSONSourceShouldReloadTileOptions, type GeoJSONSourceOptions} from './geojson_source';
55
import {EXTENT} from '../data/extent';
66
import {LngLat} from '../geo/lng_lat';
77
import {extend} from '../util/util';
88
import {SubdivisionGranularitySetting} from '../render/subdivision_granularity_settings';
99
import {MercatorTransform} from '../geo/projection/mercator_transform';
1010
import {sleep, waitForEvent} from '../util/test/util';
11-
//import {FeatureIndex, GEOJSON_TILE_LAYER_NAME} from '../data/feature_index';
1211
import {type ActorMessage, MessageType} from '../util/actor_messages';
1312
import type {IReadonlyTransform} from '../geo/transform_interface';
1413
import type {Dispatcher} from '../util/dispatcher';
1514
import type {RequestManager} from '../util/request_manager';
1615
import type {Actor} from '../util/actor';
1716
import type {MapSourceDataEvent} from '../ui/events';
1817
import type {GeoJSONSourceDiff, UpdateableGeoJSON} from './geojson_source_diff';
19-
//import type {VectorTileFeatureLike, VectorTileLayerLike} from '@maplibre/vt-pbf';
2018

2119
const wrapDispatcher = (dispatcher) => {
2220
return {
@@ -641,12 +639,8 @@ describe('GeoJSONSource.updateData', () => {
641639
add: [{id: '5', type: 'Feature', properties: {}, geometry: {type: 'LineString', coordinates: []}}],
642640
update: [{id: '6', addOrUpdateProperties: [], newGeometry: {type: 'LineString', coordinates: []}}]
643641
} satisfies GeoJSONSourceDiff;
644-
source.updateData(update1);
645-
source.updateData(update2);
646-
647-
// Wait for both updateData calls to be performed
648-
await waitForEvent(source, 'data', (e: MapSourceDataEvent) => e.sourceDataType === 'metadata');
649-
await waitForEvent(source, 'data', (e: MapSourceDataEvent) => e.sourceDataType === 'metadata');
642+
await source.updateData(update1, true);
643+
await source.updateData(update2, true);
650644

651645
expect(spy).toHaveBeenCalledTimes(2);
652646
expect(spy.mock.calls[0][0].data.dataDiff).toEqual(update1);
@@ -775,18 +769,6 @@ describe('GeoJSONSource.updateData', () => {
775769
expect(spy.mock.calls[2][0].data.dataDiff).toEqual(update1);
776770
});
777771

778-
test('updateData with waitForCompletion=true returns promise that resolves to this', async () => {
779-
const source = new GeoJSONSource('id', {} as any, wrapDispatcher({
780-
sendAsync(_message: ActorMessage<MessageType>) {
781-
return new Promise((resolve) => {
782-
setTimeout(() => resolve({abandoned: true}), 0);
783-
});
784-
}
785-
}), undefined);
786-
const result = source.updateData({add: []} as GeoJSONSourceDiff, true);
787-
expect(result).toBeInstanceOf(Promise);
788-
});
789-
790772
test('throws error when updating data that is not compatible with updateData', async () => {
791773
const initialData: GeoJSON.FeatureCollection = {
792774
type: 'FeatureCollection',
@@ -925,8 +907,7 @@ describe('GeoJSONSource.applyDiff', () => {
925907
const diff: GeoJSONSourceDiff = {
926908
update: [{id: 0, newGeometry: {type: 'Point', coordinates: [0, 1]}}]
927909
};
928-
source.updateData(diff);
929-
await waitForEvent(source, 'data', (e: MapSourceDataEvent) => e.sourceDataType === 'metadata');
910+
await source.updateData(diff, true);
930911

931912
expect(source.serialize().data).toEqual({
932913
type: 'FeatureCollection',
@@ -936,92 +917,86 @@ describe('GeoJSONSource.applyDiff', () => {
936917
});
937918
});
938919
});
939-
/*
920+
940921
describe('GeoJSONSource.shoudReloadTile', () => {
941922
let source: GeoJSONSource;
923+
let tile: Tile;
942924

943925
beforeEach(() => {
944926
source = new GeoJSONSource('id', {data: {}} as GeoJSONSourceOptions, mockDispatcher, undefined);
927+
tile = new Tile(new OverscaledTileID(0, 0, 0, 0, 0), source.tileSize);
945928
});
946929

947-
function getMockTile(z: number, x: number, y: number, features: Array<Partial<VectorTileFeatureLike>>) {
948-
const tile = new Tile(new OverscaledTileID(z, 0, z, x, y), source.tileSize);
949-
tile.latestFeatureIndex = new FeatureIndex(tile.tileID, source.promoteId);
950-
tile.latestFeatureIndex.vtLayers = {
951-
[GEOJSON_TILE_LAYER_NAME]: {
952-
feature: (i: number) => features[i] || {}
953-
} as VectorTileLayerLike
954-
};
930+
test('returns true when tile is still loading', () => {
931+
const result = source.shouldReloadTile(tile, {} as GeoJSONSourceShouldReloadTileOptions);
955932

956-
for (let i = 0; i < features.length; i++) {
957-
tile.latestFeatureIndex.insert(features[i] as VectorTileFeatureLike, [], i, 0, 0, false);
958-
}
959-
return tile;
960-
}
933+
expect(result).toBe(true);
934+
});
961935

962-
test('returns true when diff.removeAll is true', () => {
963-
const diff: GeoJSONSourceDiff = {removeAll: true};
936+
test('returns false when tile has been unloaded', () => {
937+
tile.state = 'unloaded';
964938

965-
const result = source._getShouldReloadTileOptions(diff);
939+
const result = source.shouldReloadTile(tile, {} as GeoJSONSourceShouldReloadTileOptions);
966940

967-
expect(result).toBe(undefined);
941+
expect(result).toBe(false);
968942
});
969943

970-
test('returns true when tile contains a feature that is being updated', () => {
971-
const tile = getMockTile(0, 0, 0, [{id: 0}]);
972-
const diff: GeoJSONSourceDiff = {
973-
update: [{
974-
id: 0,
975-
newGeometry: {type: 'Point', coordinates: [0, 0]}
976-
}]
977-
};
944+
test('fires undefined when diff.removeAll is true', async () => {
945+
tile.state = 'loaded';
946+
const diff: GeoJSONSourceDiff = {removeAll: true};
978947

979-
const result = source.shouldReloadTile(tile, source._getShouldReloadTileOptions(diff));
948+
let shouldReloadTileOptions: GeoJSONSourceShouldReloadTileOptions = undefined;
949+
source.on('data', (e) => {
950+
if (e.shouldReloadTileOptions) {
951+
shouldReloadTileOptions = e.shouldReloadTileOptions;
952+
}
953+
});
954+
await source.updateData(diff, true);
980955

981-
expect(result).toBe(true);
956+
expect(shouldReloadTileOptions).toBeUndefined();
982957
});
983958

984-
test('returns true when tile contains a feature that is being updated via addOrUpdateProperties', () => {
985-
const tile = getMockTile(0, 0, 0, [{id: 0}]);
959+
test('returns true when tile contains a feature that is being updated', async () => {
960+
tile.state = 'loaded';
986961
const diff: GeoJSONSourceDiff = {
987962
update: [{
988963
id: 0,
989-
addOrUpdateProperties: [{key: 'foo', value: true}]
964+
newGeometry: {type: 'Point', coordinates: [1, 1]}
990965
}]
991966
};
992967

993-
const result = source.shouldReloadTile(tile, source._getShouldReloadTileOptions(diff));
968+
let shouldReloadTileOptions: GeoJSONSourceShouldReloadTileOptions = undefined;
969+
source.on('data', (e) => {
970+
if (e.shouldReloadTileOptions) {
971+
shouldReloadTileOptions = e.shouldReloadTileOptions;
972+
}
973+
});
974+
await source.setData({type: 'FeatureCollection', features: [{type: 'Feature', id: 0, properties: {}, geometry: {type: 'Point', coordinates: [0, 0]}}]}, true);
975+
await source.updateData(diff, true);
976+
const result = source.shouldReloadTile(tile, shouldReloadTileOptions);
994977

995-
expect(result).toBe(true);
978+
expect(result).toBeTruthy();
996979
});
997-
998-
test('returns true when tile contains a feature that is being removed', () => {
999-
const tile = getMockTile(0, 0, 0, [{id: 0}]);
980+
981+
test('returns false when tile contains a feature that is being removed but was never added', async () => {
982+
tile.state = 'loaded';
1000983
const diff: GeoJSONSourceDiff = {remove: [0]};
984+
let shouldReloadTileOptions: GeoJSONSourceShouldReloadTileOptions = undefined;
985+
source.on('data', (e) => {
986+
if (e.shouldReloadTileOptions) {
987+
shouldReloadTileOptions = e.shouldReloadTileOptions;
988+
}
989+
});
990+
await source.updateData(diff, true);
991+
const result = source.shouldReloadTile(tile, shouldReloadTileOptions);
1001992

1002-
const result = source.shouldReloadTile(tile, source._getShouldReloadTileOptions(diff));
1003-
1004-
expect(result).toBe(true);
1005-
});
1006-
1007-
test('returns true when updated feature new geometry intersects tile bounds', () => {
1008-
// Feature update with new geometry at 0,0 should intersect with tile 0/0/0
1009-
const tile = getMockTile(0, 0, 0, [{id: 0}]);
1010-
const diff: GeoJSONSourceDiff = {
1011-
update: [{
1012-
id: 0,
1013-
newGeometry: {type: 'Point', coordinates: [0, 0]}
1014-
}]
1015-
};
1016-
1017-
const result = source.shouldReloadTile(tile, source._getShouldReloadTileOptions(diff));
1018-
1019-
expect(result).toBe(true);
993+
expect(result).toBe(false);
1020994
});
1021995

1022-
test('returns false when diff has no changes affecting the tile', () => {
996+
test('returns false when diff has no changes affecting the tile', async () => {
1023997
// Feature far away from tile bounds
1024-
const tile = getMockTile(10, 500, 500, [{id: 0}]);
998+
const tile = new Tile(new OverscaledTileID(10, 0, 10, 500, 500), source.tileSize);
999+
tile.state = 'loaded';
10251000
const diff: GeoJSONSourceDiff = {
10261001
add: [{
10271002
id: 1,
@@ -1030,90 +1005,61 @@ describe('GeoJSONSource.shoudReloadTile', () => {
10301005
geometry: {type: 'Point', coordinates: [-170, -80]}
10311006
}]
10321007
};
1033-
1034-
const result = source.shouldReloadTile(tile, source._getShouldReloadTileOptions(diff));
1035-
1036-
expect(result).toBe(false);
1037-
});
1038-
1039-
test('returns false when diff is empty', () => {
1040-
const tile = getMockTile(0, 0, 0, []);
1041-
const diff: GeoJSONSourceDiff = {};
1042-
1043-
const result = source.shouldReloadTile(tile, source._getShouldReloadTileOptions(diff));
1008+
let shouldReloadTileOptions: GeoJSONSourceShouldReloadTileOptions = undefined;
1009+
source.on('data', (e) => {
1010+
if (e.shouldReloadTileOptions) {
1011+
shouldReloadTileOptions = e.shouldReloadTileOptions;
1012+
}
1013+
});
1014+
await source.updateData(diff, true);
1015+
const result = source.shouldReloadTile(tile, shouldReloadTileOptions);
10441016

10451017
expect(result).toBe(false);
10461018
});
1047-
1048-
test('returns false when tile has been unloaded', () => {
1049-
const tile = getMockTile(0, 0, 0, []);
1050-
tile.latestFeatureIndex = null;
1051-
tile.state = 'unloaded';
1052-
1019+
1020+
test('returns false when diff is empty', async () => {
1021+
tile.state = 'loaded';
10531022
const diff: GeoJSONSourceDiff = {};
10541023

1055-
const result = source.shouldReloadTile(tile, source._getShouldReloadTileOptions(diff));
1024+
let shouldReloadTileOptions: GeoJSONSourceShouldReloadTileOptions = undefined;
1025+
source.on('data', (e) => {
1026+
if (e.shouldReloadTileOptions) {
1027+
shouldReloadTileOptions = e.shouldReloadTileOptions;
1028+
}
1029+
});
1030+
await source.updateData(diff, true);
1031+
const result = source.shouldReloadTile(tile, shouldReloadTileOptions);
10561032

10571033
expect(result).toBe(false);
10581034
});
1059-
1060-
test('returns true when tile is still loading', () => {
1061-
const tile = getMockTile(0, 0, 0, []);
1062-
tile.latestFeatureIndex = null;
1063-
1064-
const diff: GeoJSONSourceDiff = {};
1065-
1066-
const result = source.shouldReloadTile(tile, source._getShouldReloadTileOptions(diff));
1067-
1068-
expect(result).toBe(true);
1069-
});
1070-
1071-
test('handles string feature ids', () => {
1035+
1036+
test('handles string feature ids and returns no bounds since feature does not exist', async () => {
10721037
const diff: GeoJSONSourceDiff = {remove: ['abc']};
10731038

1074-
const result = source._getShouldReloadTileOptions(diff);
1075-
1076-
expect(result).toBe(undefined);
1077-
});
1078-
1079-
test('handles promoteId', () => {
1080-
source.promoteId = 'id';
1081-
const tile = getMockTile(0, 0, 0, [{id: 0, properties: {id: 'abc'}}]);
1082-
const diff: GeoJSONSourceDiff = {remove: ['abc']};
1083-
1084-
const result = source.shouldReloadTile(tile, source._getShouldReloadTileOptions(diff));
1039+
let shouldReloadTileOptions: GeoJSONSourceShouldReloadTileOptions = undefined;
1040+
source.on('data', (e) => {
1041+
if (e.shouldReloadTileOptions) {
1042+
shouldReloadTileOptions = e.shouldReloadTileOptions;
1043+
}
1044+
});
1045+
await source.updateData(diff, true);
10851046

1086-
expect(result).toBe(true);
1047+
expect(shouldReloadTileOptions.affectedBounds).toHaveLength(0);
10871048
});
10881049

1089-
test('handles cluster', () => {
1090-
const diff: GeoJSONSourceDiff = {remove: ['abc']};
1091-
source._options.cluster = true;
1092-
1093-
const result = source._getShouldReloadTileOptions(diff);
1094-
1095-
expect(result).toBe(undefined);
1096-
});
1050+
test('handles cluster', async () => {
1051+
const diff: GeoJSONSourceDiff = {remove: [1]};
1052+
source = new GeoJSONSource('id', {data: {}, cluster: true} as GeoJSONSourceOptions, mockDispatcher, undefined);
10971053

1098-
test('handles features that span the international date line', () => {
1099-
const diff: GeoJSONSourceDiff = {
1100-
add: [{
1101-
type: 'Feature',
1102-
properties: {},
1103-
geometry: {
1104-
type: 'LineString',
1105-
coordinates: [
1106-
[-185, 10],
1107-
[-175, 10]
1108-
],
1109-
}
1110-
}]
1111-
};
1054+
let shouldReloadTileOptions: GeoJSONSourceShouldReloadTileOptions = undefined;
1055+
source.on('data', (e) => {
1056+
if (e.shouldReloadTileOptions) {
1057+
shouldReloadTileOptions = e.shouldReloadTileOptions;
1058+
}
1059+
});
1060+
await source.updateData(diff, true);
11121061

1113-
expect(source.shouldReloadTile(getMockTile(5, 1, 15, []), source._getShouldReloadTileOptions(diff))).toBe(false);
1114-
expect(source.shouldReloadTile(getMockTile(5, 0, 15, []), source._getShouldReloadTileOptions(diff))).toBe(true);
1115-
expect(source.shouldReloadTile(getMockTile(5, 31, 15, []), source._getShouldReloadTileOptions(diff))).toBe(true);
1062+
expect(shouldReloadTileOptions).toBeUndefined();
11161063
});
11171064

1118-
});
1119-
*/
1065+
});

src/source/geojson_source.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -485,10 +485,12 @@ export class GeoJSONSource extends Evented implements Source {
485485
* @internal
486486
*/
487487
shouldReloadTile(tile: Tile, {affectedBounds}: GeoJSONSourceShouldReloadTileOptions) : boolean {
488-
if (!tile.latestFeatureIndex) {
489-
return tile.state !== 'unloaded';
488+
if (tile.state === 'loading') {
489+
return true;
490+
}
491+
if (tile.state === 'unloaded') {
492+
return false;
490493
}
491-
492494
// Update the tile if it WILL NOW contain an updated feature.
493495
const {buffer, extent} = this.workerOptions.geojsonVtOptions;
494496
const tileBounds = tileIdToLngLatBounds(

0 commit comments

Comments
 (0)