maplibre-gl 6.0.0 → 6.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/readme.md +0 -2
- package/dist/maplibre-gl-dev.mjs +433 -573
- package/dist/maplibre-gl-dev.mjs.map +1 -1
- package/dist/maplibre-gl-shared-dev.mjs +984 -850
- package/dist/maplibre-gl-shared-dev.mjs.map +1 -1
- package/dist/maplibre-gl-shared.mjs +2 -2
- package/dist/maplibre-gl-shared.mjs.map +1 -1
- package/dist/maplibre-gl-worker-dev.mjs +14 -12
- package/dist/maplibre-gl-worker-dev.mjs.map +1 -1
- package/dist/maplibre-gl-worker.mjs +2 -2
- package/dist/maplibre-gl-worker.mjs.map +1 -1
- package/dist/maplibre-gl.css +1 -1
- package/dist/maplibre-gl.d.ts +119 -42
- package/dist/maplibre-gl.mjs +22 -22
- package/dist/maplibre-gl.mjs.map +1 -1
- package/package.json +20 -22
- package/src/css/maplibre-gl.css +4 -0
- package/src/data/bucket/circle_bucket.ts +3 -2
- package/src/data/bucket/fill_bucket.ts +3 -2
- package/src/data/bucket/fill_extrusion_bucket.test.ts +22 -0
- package/src/data/bucket/fill_extrusion_bucket.ts +17 -4
- package/src/data/bucket/line_bucket.test.ts +5 -5
- package/src/data/bucket/line_bucket.ts +3 -2
- package/src/data/bucket/round_polygon_corners.test.ts +159 -0
- package/src/data/bucket/round_polygon_corners.ts +121 -0
- package/src/data/bucket/symbol_bucket.test.ts +7 -7
- package/src/data/dem_data.test.ts +23 -23
- package/src/data/feature_position_map.test.ts +1 -1
- package/src/data/segment.test.ts +14 -14
- package/src/geo/bounds.test.ts +4 -4
- package/src/geo/lng_lat_bounds.test.ts +1 -1
- package/src/geo/projection/covering_tiles.bench.ts +39 -0
- package/src/geo/projection/covering_tiles.test.ts +3 -7
- package/src/geo/projection/covering_tiles.ts +37 -2
- package/src/geo/projection/globe_covering_tiles_details_provider.ts +4 -4
- package/src/geo/projection/globe_projection.test.ts +2 -2
- package/src/geo/projection/globe_projection.ts +6 -15
- package/src/geo/projection/globe_transform.test.ts +3 -6
- package/src/geo/projection/globe_transform.ts +4 -7
- package/src/geo/projection/mercator_covering_tiles_details_provider.ts +4 -4
- package/src/geo/projection/mercator_projection.ts +1 -13
- package/src/geo/projection/mercator_transform.test.ts +1 -1
- package/src/geo/projection/mercator_transform.ts +2 -1
- package/src/geo/projection/mercator_utils.test.ts +8 -8
- package/src/geo/projection/projection.ts +0 -27
- package/src/geo/projection/projection_data.ts +8 -0
- package/src/geo/projection/projection_factory.ts +3 -3
- package/src/geo/projection/vertical_perspective_projection.ts +3 -60
- package/src/geo/projection/vertical_perspective_transform.ts +16 -23
- package/src/geo/transform_interface.ts +1 -2
- package/src/index.test.ts +7 -12
- package/src/index.ts +4 -2
- package/src/render/glyph_manager.test.ts +7 -22
- package/src/render/painter.test.ts +2 -0
- package/src/render/painter.ts +8 -11
- package/src/render/subdivision.bench.ts +39 -0
- package/src/render/subdivision.test.ts +22 -23
- package/src/render/subdivision.ts +46 -0
- package/src/render/terrain.test.ts +68 -34
- package/src/render/terrain.ts +69 -26
- package/src/shaders/glsl/_projection_globe.fragment.glsl +12 -0
- package/src/shaders/glsl/_projection_globe.fragment.glsl.g.ts +2 -0
- package/src/shaders/glsl/_projection_globe.vertex.glsl +29 -10
- package/src/shaders/glsl/_projection_globe.vertex.glsl.g.ts +1 -1
- package/src/shaders/glsl/_projection_mercator.fragment.glsl +4 -0
- package/src/shaders/glsl/_projection_mercator.fragment.glsl.g.ts +2 -0
- package/src/shaders/glsl/line.fragment.glsl +2 -0
- package/src/shaders/glsl/line.fragment.glsl.g.ts +1 -1
- package/src/shaders/glsl/line_gradient.fragment.glsl +2 -0
- package/src/shaders/glsl/line_gradient.fragment.glsl.g.ts +1 -1
- package/src/shaders/glsl/line_gradient_sdf.fragment.glsl +2 -0
- package/src/shaders/glsl/line_gradient_sdf.fragment.glsl.g.ts +1 -1
- package/src/shaders/glsl/line_pattern.fragment.glsl +2 -0
- package/src/shaders/glsl/line_pattern.fragment.glsl.g.ts +1 -1
- package/src/shaders/glsl/line_sdf.fragment.glsl +2 -0
- package/src/shaders/glsl/line_sdf.fragment.glsl.g.ts +1 -1
- package/src/shaders/shaders.ts +4 -6
- package/src/source/canvas_source.test.ts +1 -1
- package/src/source/geojson_source.test.ts +32 -4
- package/src/source/geojson_source.ts +41 -0
- package/src/source/geojson_source_diff.test.ts +2 -2
- package/src/source/geojson_worker_source.test.ts +9 -5
- package/src/source/image_source.test.ts +137 -62
- package/src/source/image_source.ts +49 -12
- package/src/source/raster_dem_tile_source.test.ts +2 -2
- package/src/source/raster_tile_source.test.ts +64 -9
- package/src/source/raster_tile_source.ts +2 -1
- package/src/source/rtl_text_plugin_main_thread.test.ts +14 -14
- package/src/source/source.test.ts +8 -8
- package/src/source/vector_tile_source.test.ts +1 -1
- package/src/source/vector_tile_worker_source.test.ts +7 -5
- package/src/source/video_source.test.ts +1 -1
- package/src/source/worker.test.ts +1 -1
- package/src/source/worker_tile.test.ts +10 -8
- package/src/style/light.test.ts +9 -9
- package/src/style/light.ts +3 -3
- package/src/style/load_glyph_range.test.ts +8 -8
- package/src/style/load_sprite.test.ts +1 -1
- package/src/style/properties.test.ts +94 -2
- package/src/style/properties.ts +30 -1
- package/src/style/sky.test.ts +9 -9
- package/src/style/sky.ts +2 -2
- package/src/style/style.test.ts +38 -36
- package/src/style/style.ts +3 -3
- package/src/style/style_layer/color_relief_style_layer.test.ts +1 -1
- package/src/style/style_layer/fill_extrusion_style_layer.ts +6 -3
- package/src/style/style_layer/fill_extrusion_style_layer_properties.g.ts +14 -1
- package/src/style/style_layer/raster_style_layer.test.ts +2 -2
- package/src/style/style_layer.test.ts +5 -51
- package/src/style/validate_style.test.ts +1 -1
- package/src/symbol/collision_index.test.ts +1 -1
- package/src/symbol/grid_index.test.ts +1 -1
- package/src/tile/terrain_tile_manager.test.ts +2 -2
- package/src/tile/tile_id.test.ts +5 -5
- package/src/tile/tile_manager.test.ts +113 -72
- package/src/tile/tile_manager.ts +2 -2
- package/src/tile/tile_manager_in_view_tiles.test.ts +2 -2
- package/src/ui/camera.test.ts +138 -135
- package/src/ui/control/geolocate_control.test.ts +7 -30
- package/src/ui/handler/dblclick_zoom.test.ts +2 -2
- package/src/ui/handler/mouse.ts +15 -7
- package/src/ui/handler/mouse_handler_interface.test.ts +21 -1
- package/src/ui/handler/scroll_zoom.test.ts +2 -0
- package/src/ui/handler_manager.test.ts +7 -7
- package/src/ui/hash.test.ts +1 -0
- package/src/ui/map.ts +45 -20
- package/src/ui/map_tests/map_basic.test.ts +11 -23
- package/src/ui/map_tests/map_calculate_camera_options.test.ts +6 -6
- package/src/ui/map_tests/map_events.test.ts +5 -7
- package/src/ui/map_tests/map_global_state.test.ts +3 -3
- package/src/ui/map_tests/map_images.test.ts +4 -3
- package/src/ui/map_tests/map_is_moving.test.ts +1 -1
- package/src/ui/map_tests/map_is_rotating.test.ts +1 -1
- package/src/ui/map_tests/map_layer.test.ts +2 -1
- package/src/ui/map_tests/map_options.test.ts +1 -5
- package/src/ui/map_tests/map_pitch.test.ts +6 -6
- package/src/ui/map_tests/map_refresh_tiles.test.ts +2 -2
- package/src/ui/map_tests/map_render.test.ts +1 -1
- package/src/ui/map_tests/map_set_lod_params.test.ts +1 -1
- package/src/ui/map_tests/map_style.test.ts +9 -1
- package/src/ui/map_tests/map_terrain.test.ts +41 -1
- package/src/ui/map_tests/map_zoom.test.ts +15 -15
- package/src/ui/marker.test.ts +71 -14
- package/src/ui/marker.ts +30 -6
- package/src/ui/popup.test.ts +3 -3
- package/src/util/actor.test.ts +6 -6
- package/src/util/ajax.test.ts +27 -39
- package/src/util/browser.test.ts +7 -9
- package/src/util/create_tile_mesh.test.ts +2 -2
- package/src/util/dispatcher.test.ts +1 -1
- package/src/util/evented.test.ts +4 -1
- package/src/util/fast_maths.test.ts +4 -4
- package/src/util/image_request.test.ts +6 -4
- package/src/util/primitives/bounding_volume_cache.ts +3 -1
- package/src/util/struct_array.test.ts +2 -2
- package/src/util/task_queue.test.ts +1 -1
- package/src/util/test/util.ts +1 -0
- package/src/util/time_control.test.ts +2 -2
- package/src/util/transferable_grid_index.test.ts +1 -1
- package/src/util/util.test.ts +27 -13
- package/src/util/verticalize_punctuation.test.ts +4 -4
- package/src/util/web_worker_transfer.test.ts +5 -5
- package/src/webgl/draw/draw_custom.test.ts +13 -13
- package/src/webgl/draw/draw_debug.test.ts +1 -1
- package/src/webgl/draw/draw_fill.test.ts +13 -12
- package/src/webgl/draw/draw_symbol.test.ts +17 -16
- package/src/webgl/program/program_uniforms.ts +0 -3
- package/src/webgl/program/projection_program.ts +12 -10
- package/src/webgl/program/terrain_program.test.ts +2 -2
- package/src/webgl/program.ts +6 -4
- package/src/webgl/render_to_texture.test.ts +5 -5
- package/src/webgl/state.test.ts +1 -1
- package/src/webgl/texture.test.ts +3 -3
- package/src/webgl/vertex_buffer.test.ts +1 -1
- package/build/rolldown_plugins.ts +0 -18
- package/src/geo/projection/globe_projection_error_measurement.ts +0 -229
- package/src/shaders/glsl/projection_error_measurement.fragment.glsl +0 -5
- package/src/shaders/glsl/projection_error_measurement.fragment.glsl.g.ts +0 -2
- package/src/shaders/glsl/projection_error_measurement.vertex.glsl +0 -22
- package/src/shaders/glsl/projection_error_measurement.vertex.glsl.g.ts +0 -2
- package/src/webgl/program/projection_error_measurement_program.ts +0 -23
|
@@ -49,11 +49,7 @@ describe('mapOptions', () => {
|
|
|
49
49
|
let idleTriggered = false;
|
|
50
50
|
const fadeDuration = 100;
|
|
51
51
|
const spy = vi.spyOn(Style.prototype, 'update').mockImplementation((parameters: EvaluationParameters) => {
|
|
52
|
-
|
|
53
|
-
expect(parameters.fadeDuration).toBe(0);
|
|
54
|
-
} else {
|
|
55
|
-
expect(parameters.fadeDuration).toBe(fadeDuration);
|
|
56
|
-
}
|
|
52
|
+
expect(parameters.fadeDuration).toBe(idleTriggered ? fadeDuration : 0);
|
|
57
53
|
});
|
|
58
54
|
const style = createStyle();
|
|
59
55
|
const map = createMap({style, fadeDuration});
|
|
@@ -31,7 +31,7 @@ test('ignore minPitchs over maxPitch', () => {
|
|
|
31
31
|
const map = createMap({pitch: 0, maxPitch: 10});
|
|
32
32
|
expect(() => {
|
|
33
33
|
map.setMinPitch(20);
|
|
34
|
-
}).toThrow();
|
|
34
|
+
}).toThrow('minPitch must be between 0 and the current maxPitch, inclusive');
|
|
35
35
|
map.setPitch(0);
|
|
36
36
|
expect(map.getPitch()).toBe(0);
|
|
37
37
|
});
|
|
@@ -89,7 +89,7 @@ test('ignore maxPitchs over minPitch', () => {
|
|
|
89
89
|
const map = createMap({minPitch: 10});
|
|
90
90
|
expect(() => {
|
|
91
91
|
map.setMaxPitch(0);
|
|
92
|
-
}).toThrow();
|
|
92
|
+
}).toThrow('maxPitch must be greater than the current minPitch');
|
|
93
93
|
map.setPitch(10);
|
|
94
94
|
expect(map.getPitch()).toBe(10);
|
|
95
95
|
});
|
|
@@ -140,8 +140,8 @@ test('fire move and pitch events when pitch is changed due to minPitch change',
|
|
|
140
140
|
map.on('pitch', handleEvent);
|
|
141
141
|
map.on('pitchend', handleEvent);
|
|
142
142
|
map.setMinPitch(11);
|
|
143
|
-
expect(map.getPitch()).
|
|
144
|
-
expect(map.getMinPitch()).
|
|
143
|
+
expect(map.getPitch()).toBe(11);
|
|
144
|
+
expect(map.getMinPitch()).toBe(11);
|
|
145
145
|
expect(handleEvent).toHaveBeenCalledTimes(6);
|
|
146
146
|
});
|
|
147
147
|
|
|
@@ -155,7 +155,7 @@ test('fire move and pitch events when pitch is changed due to maxPitch change',
|
|
|
155
155
|
map.on('pitch', handleEvent);
|
|
156
156
|
map.on('pitchend', handleEvent);
|
|
157
157
|
map.setMaxPitch(10);
|
|
158
|
-
expect(map.getPitch()).
|
|
159
|
-
expect(map.getMaxPitch()).
|
|
158
|
+
expect(map.getPitch()).toBe(10);
|
|
159
|
+
expect(map.getMaxPitch()).toBe(10);
|
|
160
160
|
expect(handleEvent).toHaveBeenCalledTimes(6);
|
|
161
161
|
});
|
|
@@ -30,7 +30,7 @@ describe('Map::refreshTiles', () => {
|
|
|
30
30
|
map.style.tileManagers['source-id1'].refreshTiles = spy;
|
|
31
31
|
|
|
32
32
|
map.refreshTiles('source-id1', [{x: 1024, y: 1023, z: 11}]);
|
|
33
|
-
expect(spy).
|
|
33
|
+
expect(spy).toHaveBeenCalledTimes(1);
|
|
34
34
|
expect(spy.mock.calls[0][0]).toEqual([new CanonicalTileID(11, 1024, 1023)]);
|
|
35
35
|
});
|
|
36
36
|
|
|
@@ -43,7 +43,7 @@ describe('Map::refreshTiles', () => {
|
|
|
43
43
|
map.style.tileManagers['source-id1'].reload = spy;
|
|
44
44
|
|
|
45
45
|
map.refreshTiles('source-id1');
|
|
46
|
-
expect(spy).
|
|
46
|
+
expect(spy).toHaveBeenCalledTimes(1);
|
|
47
47
|
expect(spy.mock.calls[0][0]).toBe(true);
|
|
48
48
|
});
|
|
49
49
|
});
|
|
@@ -42,7 +42,7 @@ test('set tile LOD params for a non-existent source', async () => {
|
|
|
42
42
|
|
|
43
43
|
expect(map.getSource('source-id1').calculateTileZoom).toBeUndefined();
|
|
44
44
|
expect(map.getSource('source-id2').calculateTileZoom).toBeUndefined();
|
|
45
|
-
expect(() => {map.setSourceTileLodParams(1, 1, 'non-existent-source-id');}).
|
|
45
|
+
expect(() => {map.setSourceTileLodParams(1, 1, 'non-existent-source-id');}).toThrow('There is no source with ID "non-existent-source-id", cannot set LOD parameters');
|
|
46
46
|
expect(map.getSource('source-id1').calculateTileZoom).toBeUndefined();
|
|
47
47
|
expect(map.getSource('source-id2').calculateTileZoom).toBeUndefined();
|
|
48
48
|
});
|
|
@@ -78,12 +78,14 @@ describe('setStyle', () => {
|
|
|
78
78
|
]);
|
|
79
79
|
});
|
|
80
80
|
|
|
81
|
-
test('can be called more than once', () => {
|
|
81
|
+
test('can be called more than once', async () => {
|
|
82
82
|
const map = createMap();
|
|
83
83
|
|
|
84
84
|
map.setStyle({version: 8, sources: {}, layers: []}, {diff: false});
|
|
85
85
|
map.setStyle({version: 8, sources: {}, layers: []}, {diff: false});
|
|
86
|
+
await map.once('style.load');
|
|
86
87
|
|
|
88
|
+
expect(map.getStyle()).toEqual({version: 8, sources: {}, layers: []});
|
|
87
89
|
});
|
|
88
90
|
|
|
89
91
|
test('setStyle back to the first style should work', async () => {
|
|
@@ -477,12 +479,16 @@ describe('getStyle', () => {
|
|
|
477
479
|
type: 'background'
|
|
478
480
|
} as LayerSpecification;
|
|
479
481
|
map.addLayer(layer);
|
|
482
|
+
|
|
483
|
+
expect(map.getLayer('background')).toBeDefined();
|
|
480
484
|
});
|
|
481
485
|
|
|
482
486
|
test('a source can be added even if a map is created without a style', () => {
|
|
483
487
|
const map = createMap({deleteStyle: true});
|
|
484
488
|
const source = createStyleSource();
|
|
485
489
|
map.addSource('fill', source);
|
|
490
|
+
|
|
491
|
+
expect(map.getSource('fill')).toBeDefined();
|
|
486
492
|
});
|
|
487
493
|
|
|
488
494
|
test('a layer can be added with an embedded source specification', () => {
|
|
@@ -496,6 +502,8 @@ describe('getStyle', () => {
|
|
|
496
502
|
type: 'symbol',
|
|
497
503
|
source
|
|
498
504
|
});
|
|
505
|
+
|
|
506
|
+
expect(map.getLayer('foo')).toBeDefined();
|
|
499
507
|
});
|
|
500
508
|
|
|
501
509
|
test('returns the style with added source and layer', async () => {
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import {describe, beforeEach, afterEach, test, expect, vi} from 'vitest';
|
|
2
|
-
import {createMap, beforeMapTest} from '../../util/test/util.ts';
|
|
2
|
+
import {createMap, beforeMapTest, waitForEvent} from '../../util/test/util.ts';
|
|
3
3
|
import {LngLat} from '../../geo/lng_lat.ts';
|
|
4
4
|
import {fakeServer, type FakeServer} from 'nise';
|
|
5
5
|
import {type Terrain} from '../../render/terrain.ts';
|
|
6
6
|
import {MercatorTransform} from '../../geo/projection/mercator_transform.ts';
|
|
7
|
+
import {AttributionControl, defaultAttributionControlOptions} from '../control/attribution_control.ts';
|
|
7
8
|
import {type Map} from '../map.ts';
|
|
8
9
|
|
|
9
10
|
let server: FakeServer;
|
|
@@ -67,6 +68,45 @@ describe('setTerrain', () => {
|
|
|
67
68
|
expect(errorSpy).not.toHaveBeenCalled();
|
|
68
69
|
expect(map.getTerrain()).toEqual({source: 'dem', exaggeration: 2});
|
|
69
70
|
});
|
|
71
|
+
|
|
72
|
+
test('drops the previous source attribution when switching terrain to a new source', async () => {
|
|
73
|
+
const attribution = new AttributionControl();
|
|
74
|
+
map.addControl(attribution);
|
|
75
|
+
await map.once('style.load');
|
|
76
|
+
const demALoaded = waitForEvent(map, 'sourcedata', (e) => e.sourceId === 'dem-a' && e.sourceDataType === 'metadata');
|
|
77
|
+
const demBLoaded = waitForEvent(map, 'sourcedata', (e) => e.sourceId === 'dem-b' && e.sourceDataType === 'metadata');
|
|
78
|
+
map.addSource('dem-a', {type: 'raster-dem', tiles: ['http://example.com/{z}/{x}/{y}.png'], tileSize: 256, attribution: 'DEM A'});
|
|
79
|
+
map.addSource('dem-b', {type: 'raster-dem', tiles: ['http://example.com/{z}/{x}/{y}.png'], tileSize: 256, attribution: 'DEM B'});
|
|
80
|
+
await Promise.all([demALoaded, demBLoaded]);
|
|
81
|
+
|
|
82
|
+
map.setTerrain({source: 'dem-a'});
|
|
83
|
+
const terrainEvent = map.once('terrain');
|
|
84
|
+
map.setTerrain({source: 'dem-b'});
|
|
85
|
+
await terrainEvent;
|
|
86
|
+
|
|
87
|
+
const innerContainer = map.getContainer().querySelector('.maplibregl-ctrl-attrib-inner');
|
|
88
|
+
expect(innerContainer.innerHTML).toBe(`DEM B | ${defaultAttributionControlOptions.customAttribution}`);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test('invalidates cached elevation when terrain source data changes without a tile', async () => {
|
|
92
|
+
await map.once('load');
|
|
93
|
+
map.addSource('terrainrgb', {
|
|
94
|
+
type: 'raster-dem',
|
|
95
|
+
tiles: ['http://example.com/{z}/{x}/{y}.png']
|
|
96
|
+
});
|
|
97
|
+
map.setTerrain({source: 'terrainrgb'});
|
|
98
|
+
if (!map.terrain) throw new Error('Expected terrain to be set');
|
|
99
|
+
const resetElevationCache = vi.spyOn(map.terrain, 'resetElevationCache');
|
|
100
|
+
|
|
101
|
+
map._terrainDataCallback({
|
|
102
|
+
dataType: 'source',
|
|
103
|
+
sourceId: 'terrainrgb',
|
|
104
|
+
sourceDataType: 'content',
|
|
105
|
+
source: {type: 'raster-dem'}
|
|
106
|
+
} as any);
|
|
107
|
+
|
|
108
|
+
expect(resetElevationCache).toHaveBeenCalledTimes(1);
|
|
109
|
+
});
|
|
70
110
|
});
|
|
71
111
|
|
|
72
112
|
describe('getTerrain', () => {
|
|
@@ -32,7 +32,7 @@ test('ignore minZooms over maxZoom', () => {
|
|
|
32
32
|
const map = createMap({zoom: 2, maxZoom: 5});
|
|
33
33
|
expect(() => {
|
|
34
34
|
map.setMinZoom(6);
|
|
35
|
-
}).toThrow();
|
|
35
|
+
}).toThrow('minZoom must be between -2 and the current maxZoom, inclusive');
|
|
36
36
|
map.setZoom(0);
|
|
37
37
|
expect(map.getZoom()).toBe(0);
|
|
38
38
|
});
|
|
@@ -62,7 +62,7 @@ test('ignore maxZooms over minZoom', () => {
|
|
|
62
62
|
const map = createMap({minZoom: 5});
|
|
63
63
|
expect(() => {
|
|
64
64
|
map.setMaxZoom(4);
|
|
65
|
-
}).toThrow();
|
|
65
|
+
}).toThrow('maxZoom must be greater than the current minZoom');
|
|
66
66
|
map.setZoom(5);
|
|
67
67
|
expect(map.getZoom()).toBe(5);
|
|
68
68
|
});
|
|
@@ -102,16 +102,16 @@ test('transformCameraUpdate is called after changing min or max zoom', async ()
|
|
|
102
102
|
map.setMaxZoom(18);
|
|
103
103
|
map.setZoom(18);
|
|
104
104
|
await map.once('style.load');
|
|
105
|
-
expect(map.getZoom()).
|
|
106
|
-
expect(map.getMinZoom()).
|
|
107
|
-
expect(map.getMaxZoom()).
|
|
105
|
+
expect(map.getZoom()).toBe(18);
|
|
106
|
+
expect(map.getMinZoom()).toBe(5);
|
|
107
|
+
expect(map.getMaxZoom()).toBe(18);
|
|
108
108
|
const transformCameraUpdate = vi.fn(t => t);
|
|
109
109
|
map.setTransformCameraUpdate(transformCameraUpdate);
|
|
110
110
|
|
|
111
111
|
map.setMaxZoom(16);
|
|
112
|
-
expect(map.getZoom()).
|
|
113
|
-
expect(map.getMinZoom()).
|
|
114
|
-
expect(map.getMaxZoom()).
|
|
112
|
+
expect(map.getZoom()).toBe(16);
|
|
113
|
+
expect(map.getMinZoom()).toBe(5);
|
|
114
|
+
expect(map.getMaxZoom()).toBe(16);
|
|
115
115
|
expect(transformCameraUpdate.mock.calls[0][0]).toMatchObject({
|
|
116
116
|
zoom: 16,
|
|
117
117
|
minZoom: 5,
|
|
@@ -127,9 +127,9 @@ test('transformCameraUpdate is called after changing min or max zoom', async ()
|
|
|
127
127
|
|
|
128
128
|
map.setMinZoom(6);
|
|
129
129
|
map.setTransformCameraUpdate(transformCameraUpdate);
|
|
130
|
-
expect(map.getZoom()).
|
|
131
|
-
expect(map.getMinZoom()).
|
|
132
|
-
expect(map.getMaxZoom()).
|
|
130
|
+
expect(map.getZoom()).toBe(6);
|
|
131
|
+
expect(map.getMinZoom()).toBe(6);
|
|
132
|
+
expect(map.getMaxZoom()).toBe(16);
|
|
133
133
|
expect(transformCameraUpdate.mock.calls[2][0]).toMatchObject({
|
|
134
134
|
zoom: 6,
|
|
135
135
|
minZoom: 6,
|
|
@@ -147,8 +147,8 @@ test('fire move and zoom events when zoom is changed due to minZoom change', ()
|
|
|
147
147
|
map.on('zoom', handleEvent);
|
|
148
148
|
map.on('zoomend', handleEvent);
|
|
149
149
|
map.setMinZoom(11);
|
|
150
|
-
expect(map.getZoom()).
|
|
151
|
-
expect(map.getMinZoom()).
|
|
150
|
+
expect(map.getZoom()).toBe(11);
|
|
151
|
+
expect(map.getMinZoom()).toBe(11);
|
|
152
152
|
expect(handleEvent).toHaveBeenCalledTimes(6);
|
|
153
153
|
});
|
|
154
154
|
|
|
@@ -162,7 +162,7 @@ test('fire move and zoom events when zoom is changed due to maxZoom change', ()
|
|
|
162
162
|
map.on('zoom', handleEvent);
|
|
163
163
|
map.on('zoomend', handleEvent);
|
|
164
164
|
map.setMaxZoom(10);
|
|
165
|
-
expect(map.getZoom()).
|
|
166
|
-
expect(map.getMaxZoom()).
|
|
165
|
+
expect(map.getZoom()).toBe(10);
|
|
166
|
+
expect(map.getMaxZoom()).toBe(10);
|
|
167
167
|
expect(handleEvent).toHaveBeenCalledTimes(6);
|
|
168
168
|
});
|
package/src/ui/marker.test.ts
CHANGED
|
@@ -35,7 +35,7 @@ describe('marker', () => {
|
|
|
35
35
|
|
|
36
36
|
test('Marker uses a default marker element with custom color', () => {
|
|
37
37
|
const marker = new Marker({color: '#123456'});
|
|
38
|
-
expect(marker.getElement().innerHTML.
|
|
38
|
+
expect(marker.getElement().innerHTML).toContain('#123456');
|
|
39
39
|
});
|
|
40
40
|
|
|
41
41
|
test('Marker uses a default marker element with custom scale', () => {
|
|
@@ -53,22 +53,16 @@ describe('marker', () => {
|
|
|
53
53
|
.addTo(map);
|
|
54
54
|
|
|
55
55
|
// initial dimensions of svg element
|
|
56
|
-
expect(
|
|
57
|
-
|
|
58
|
-
).toBeTruthy();
|
|
59
|
-
expect(defaultMarker.getElement().children[0].getAttribute('width').includes('27')).toBeTruthy();
|
|
56
|
+
expect(defaultMarker.getElement().children[0].getAttribute('height')).toContain('41');
|
|
57
|
+
expect(defaultMarker.getElement().children[0].getAttribute('width')).toContain('27');
|
|
60
58
|
|
|
61
59
|
// (41 * 0.8) = 32.8, (27 * 0.8) = 21.6
|
|
62
|
-
expect(
|
|
63
|
-
|
|
64
|
-
).toBeTruthy();
|
|
65
|
-
expect(
|
|
66
|
-
smallerMarker.getElement().children[0].getAttribute('width').includes('21.6')
|
|
67
|
-
).toBeTruthy();
|
|
60
|
+
expect(smallerMarker.getElement().children[0].getAttribute('height')).toContain('32.8');
|
|
61
|
+
expect(smallerMarker.getElement().children[0].getAttribute('width')).toContain('21.6');
|
|
68
62
|
|
|
69
63
|
// (41 * 2) = 82, (27 * 2) = 54
|
|
70
|
-
expect(largerMarker.getElement().children[0].getAttribute('height').
|
|
71
|
-
expect(largerMarker.getElement().children[0].getAttribute('width').
|
|
64
|
+
expect(largerMarker.getElement().children[0].getAttribute('height')).toContain('82');
|
|
65
|
+
expect(largerMarker.getElement().children[0].getAttribute('width')).toContain('54');
|
|
72
66
|
|
|
73
67
|
});
|
|
74
68
|
|
|
@@ -290,11 +284,57 @@ describe('marker', () => {
|
|
|
290
284
|
expect(markerWithHtmlElement.getElement().getAttribute('aria-label')).toBe('custom aria label');
|
|
291
285
|
});
|
|
292
286
|
|
|
293
|
-
test('
|
|
287
|
+
test('default non-interactive Marker uses role=img for the aria-label', () => {
|
|
294
288
|
const map = createMap({locale: {'Marker.Title': 'alt title'}});
|
|
295
289
|
const marker = new Marker().setLngLat([0, 0]).addTo(map);
|
|
296
290
|
|
|
291
|
+
expect(marker.getElement().getAttribute('role')).toBe('img');
|
|
292
|
+
map.remove();
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
test('default Marker uses role=button when interactive via popup', () => {
|
|
296
|
+
const map = createMap();
|
|
297
|
+
const marker = new Marker()
|
|
298
|
+
.setLngLat([0, 0])
|
|
299
|
+
.setPopup(new Popup().setText('popup'))
|
|
300
|
+
.addTo(map);
|
|
301
|
+
|
|
297
302
|
expect(marker.getElement().getAttribute('role')).toBe('button');
|
|
303
|
+
|
|
304
|
+
marker.setPopup();
|
|
305
|
+
expect(marker.getElement().getAttribute('role')).toBe('img');
|
|
306
|
+
map.remove();
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
test('default Marker uses role=button when draggable', () => {
|
|
310
|
+
const map = createMap();
|
|
311
|
+
const marker = new Marker({draggable: true}).setLngLat([0, 0]).addTo(map);
|
|
312
|
+
|
|
313
|
+
expect(marker.getElement().getAttribute('role')).toBe('button');
|
|
314
|
+
|
|
315
|
+
marker.setDraggable(false);
|
|
316
|
+
expect(marker.getElement().getAttribute('role')).toBe('img');
|
|
317
|
+
map.remove();
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
test('custom Marker element does not get automatic accessibility attributes', () => {
|
|
321
|
+
const map = createMap();
|
|
322
|
+
const element = document.createElement('div');
|
|
323
|
+
const marker = new Marker({element}).setLngLat([0, 0]).addTo(map);
|
|
324
|
+
|
|
325
|
+
expect(marker.getElement().hasAttribute('aria-label')).toBe(false);
|
|
326
|
+
expect(marker.getElement().hasAttribute('role')).toBe(false);
|
|
327
|
+
map.remove();
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
test('explicit role on the default Marker element is preserved', () => {
|
|
331
|
+
const map = createMap();
|
|
332
|
+
const marker = new Marker().setLngLat([0, 0]);
|
|
333
|
+
marker.getElement().setAttribute('role', 'presentation');
|
|
334
|
+
marker.addTo(map);
|
|
335
|
+
|
|
336
|
+
expect(marker.getElement().getAttribute('role')).toBe('presentation');
|
|
337
|
+
map.remove();
|
|
298
338
|
});
|
|
299
339
|
|
|
300
340
|
test('Marker anchor defaults to center', () => {
|
|
@@ -491,6 +531,23 @@ describe('marker', () => {
|
|
|
491
531
|
map.remove();
|
|
492
532
|
});
|
|
493
533
|
|
|
534
|
+
test('Marker.setDraggable toggles the draggable cursor class', () => {
|
|
535
|
+
const map = createMap();
|
|
536
|
+
const marker = new Marker({draggable: true})
|
|
537
|
+
.setLngLat([0, 0])
|
|
538
|
+
.addTo(map);
|
|
539
|
+
|
|
540
|
+
expect(marker.getElement().classList).toContain('maplibregl-marker-draggable');
|
|
541
|
+
|
|
542
|
+
marker.setDraggable(false);
|
|
543
|
+
expect(marker.getElement().classList).not.toContain('maplibregl-marker-draggable');
|
|
544
|
+
|
|
545
|
+
marker.setDraggable(true);
|
|
546
|
+
expect(marker.getElement().classList).toContain('maplibregl-marker-draggable');
|
|
547
|
+
|
|
548
|
+
map.remove();
|
|
549
|
+
});
|
|
550
|
+
|
|
494
551
|
test('Marker with draggable:true fires dragstart, drag, and dragend events at appropriate times in response to mouse-triggered drag with map-inherited clickTolerance', () => {
|
|
495
552
|
const map = createMap();
|
|
496
553
|
const marker = new Marker({draggable: true})
|
package/src/ui/marker.ts
CHANGED
|
@@ -227,6 +227,7 @@ export class Marker extends Evented<MarkerEventType> {
|
|
|
227
227
|
_opacityWhenCovered: string;
|
|
228
228
|
_opacityTimeout: ReturnType<typeof setTimeout>;
|
|
229
229
|
_subpixelPositioning: boolean;
|
|
230
|
+
_roleManaged: boolean;
|
|
230
231
|
|
|
231
232
|
/**
|
|
232
233
|
* @param options - the options
|
|
@@ -241,6 +242,7 @@ export class Marker extends Evented<MarkerEventType> {
|
|
|
241
242
|
this._clickTolerance = options?.clickTolerance || 0;
|
|
242
243
|
this._subpixelPositioning = options?.subpixelPositioning || false;
|
|
243
244
|
this._isDragging = false;
|
|
245
|
+
this._roleManaged = false;
|
|
244
246
|
this._state = 'inactive';
|
|
245
247
|
this._rotation = options?.rotation || 0;
|
|
246
248
|
this._rotationAlignment = options?.rotationAlignment || 'auto';
|
|
@@ -393,15 +395,11 @@ export class Marker extends Evented<MarkerEventType> {
|
|
|
393
395
|
this.remove();
|
|
394
396
|
this._map = map;
|
|
395
397
|
|
|
396
|
-
if (!this._element.hasAttribute('aria-label')) {
|
|
398
|
+
if (this._defaultMarker && !this._element.hasAttribute('aria-label')) {
|
|
397
399
|
this._element.setAttribute('aria-label', map._getUIString('Marker.Title'));
|
|
398
400
|
}
|
|
399
401
|
|
|
400
|
-
|
|
401
|
-
// since div is interactive and cannot have aria-label without a role
|
|
402
|
-
if (!this._element.hasAttribute('role')) {
|
|
403
|
-
this._element.setAttribute('role', 'button');
|
|
404
|
-
}
|
|
402
|
+
this._updateAccessibilityRole();
|
|
405
403
|
|
|
406
404
|
map.getCanvasContainer().appendChild(this._element);
|
|
407
405
|
map.on('move', this._update);
|
|
@@ -553,6 +551,7 @@ export class Marker extends Evented<MarkerEventType> {
|
|
|
553
551
|
this._element.addEventListener('keypress', this._onKeyPress);
|
|
554
552
|
}
|
|
555
553
|
|
|
554
|
+
this._updateAccessibilityRole();
|
|
556
555
|
return this;
|
|
557
556
|
}
|
|
558
557
|
|
|
@@ -857,6 +856,7 @@ export class Marker extends Evented<MarkerEventType> {
|
|
|
857
856
|
*/
|
|
858
857
|
setDraggable(shouldBeDraggable?: boolean): this {
|
|
859
858
|
this._draggable = !!shouldBeDraggable; // convert possible undefined value to false
|
|
859
|
+
this._element.classList.toggle('maplibregl-marker-draggable', this._draggable);
|
|
860
860
|
|
|
861
861
|
// handle case where map may not exist yet
|
|
862
862
|
// e.g. when setDraggable is called before addTo
|
|
@@ -870,6 +870,7 @@ export class Marker extends Evented<MarkerEventType> {
|
|
|
870
870
|
}
|
|
871
871
|
}
|
|
872
872
|
|
|
873
|
+
this._updateAccessibilityRole();
|
|
873
874
|
return this;
|
|
874
875
|
}
|
|
875
876
|
|
|
@@ -881,6 +882,29 @@ export class Marker extends Evented<MarkerEventType> {
|
|
|
881
882
|
return this._draggable;
|
|
882
883
|
}
|
|
883
884
|
|
|
885
|
+
/**
|
|
886
|
+
* Keep the default marker role aligned with interactivity.
|
|
887
|
+
* Default markers need a role because `aria-label` is set in {@link Marker.addTo}.
|
|
888
|
+
* Non-interactive markers use `role=img`; interactive ones (draggable or with a popup) use `role=button`.
|
|
889
|
+
* Click listeners are application-owned and do not automatically change the role.
|
|
890
|
+
* Custom marker elements are left alone so applications own their a11y tree.
|
|
891
|
+
* Explicit roles set by the application are preserved.
|
|
892
|
+
*/
|
|
893
|
+
_updateAccessibilityRole(): void {
|
|
894
|
+
if (!this._defaultMarker) {
|
|
895
|
+
return;
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
// Preserve an explicit role chosen by the application unless we previously managed it.
|
|
899
|
+
if (this._element.hasAttribute('role') && !this._roleManaged) {
|
|
900
|
+
return;
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
const role = (this._draggable || !!this._popup) ? 'button' : 'img';
|
|
904
|
+
this._element.setAttribute('role', role);
|
|
905
|
+
this._roleManaged = true;
|
|
906
|
+
}
|
|
907
|
+
|
|
884
908
|
/**
|
|
885
909
|
* Sets the `rotation` property of the marker.
|
|
886
910
|
* @param rotation - The rotation angle of the marker (clockwise, in degrees), relative to its respective {@link Marker.setRotationAlignment} setting.
|
package/src/ui/popup.test.ts
CHANGED
|
@@ -333,7 +333,7 @@ describe('popup', () => {
|
|
|
333
333
|
expect(popup._pos).toEqual(map.project([5, 0]));
|
|
334
334
|
});
|
|
335
335
|
|
|
336
|
-
test('Popup wraps position after map move if it would otherwise go offscreen (
|
|
336
|
+
test('Popup wraps position after map move if it would otherwise go offscreen (left)', () => {
|
|
337
337
|
const map = createMap({width: 1024}); // longitude bounds: [-360, 360]
|
|
338
338
|
|
|
339
339
|
const popup = new Popup()
|
|
@@ -613,7 +613,7 @@ describe('popup', () => {
|
|
|
613
613
|
).toContain('maplibregl-popup-track-pointer');
|
|
614
614
|
});
|
|
615
615
|
|
|
616
|
-
test('Pointer-tracked popup with content set later is tagged with right class
|
|
616
|
+
test('Pointer-tracked popup with content set later is tagged with right class', () => {
|
|
617
617
|
const map = createMap();
|
|
618
618
|
const popup = new Popup()
|
|
619
619
|
.trackPointer()
|
|
@@ -626,7 +626,7 @@ describe('popup', () => {
|
|
|
626
626
|
).toContain('maplibregl-popup-track-pointer');
|
|
627
627
|
});
|
|
628
628
|
|
|
629
|
-
test('Pointer-tracked popup that is set afterwards is tagged with right class
|
|
629
|
+
test('Pointer-tracked popup that is set afterwards is tagged with right class', () => {
|
|
630
630
|
const map = createMap();
|
|
631
631
|
const popup = new Popup()
|
|
632
632
|
.addTo(map);
|
package/src/util/actor.test.ts
CHANGED
|
@@ -144,7 +144,7 @@ describe('Actor', () => {
|
|
|
144
144
|
const worker = await workerFactory() as any as WorkerGlobalScopeInterface & ActorTarget;
|
|
145
145
|
const actor = new Actor(worker, '1');
|
|
146
146
|
|
|
147
|
-
const spy = vi.fn().
|
|
147
|
+
const spy = vi.fn().mockResolvedValue({});
|
|
148
148
|
worker.worker.actor.registerMessageHandler(MessageType.getClusterExpansionZoom, spy);
|
|
149
149
|
|
|
150
150
|
worker.worker.actor.invoker.trigger = async () => {
|
|
@@ -209,7 +209,7 @@ describe('Actor', () => {
|
|
|
209
209
|
|
|
210
210
|
worker.worker.actor.mapId = '2';
|
|
211
211
|
|
|
212
|
-
const spy = vi.fn().
|
|
212
|
+
const spy = vi.fn().mockResolvedValue({});
|
|
213
213
|
worker.worker.actor.registerMessageHandler(MessageType.getClusterExpansionZoom, spy);
|
|
214
214
|
|
|
215
215
|
actor.sendAsync({type: MessageType.getClusterExpansionZoom, data: {} as any, targetMapId: '1'});
|
|
@@ -223,7 +223,7 @@ describe('Actor', () => {
|
|
|
223
223
|
const worker = await workerFactory() as any as WorkerGlobalScopeInterface & ActorTarget;
|
|
224
224
|
const actor = new Actor(worker, '1');
|
|
225
225
|
|
|
226
|
-
const spy = vi.fn().
|
|
226
|
+
const spy = vi.fn().mockResolvedValue({});
|
|
227
227
|
worker.worker.actor.registerMessageHandler(MessageType.getClusterExpansionZoom, spy);
|
|
228
228
|
|
|
229
229
|
actor.target.postMessage({type: 'getClusterExpansionZoom', data: {} as any, origin: 'https://example.com'});
|
|
@@ -237,7 +237,7 @@ describe('Actor', () => {
|
|
|
237
237
|
const worker = await workerFactory() as any as WorkerGlobalScopeInterface & ActorTarget;
|
|
238
238
|
const actor = new Actor(worker, '1');
|
|
239
239
|
|
|
240
|
-
const spy = vi.fn().
|
|
240
|
+
const spy = vi.fn().mockResolvedValue({});
|
|
241
241
|
worker.worker.actor.registerMessageHandler(MessageType.getClusterExpansionZoom, spy);
|
|
242
242
|
|
|
243
243
|
actor.target.postMessage({type: MessageType.getClusterExpansionZoom, data: {} as any, origin: 'null'});
|
|
@@ -251,7 +251,7 @@ describe('Actor', () => {
|
|
|
251
251
|
const worker = await workerFactory() as any as WorkerGlobalScopeInterface & ActorTarget;
|
|
252
252
|
const actor = new Actor(worker, '1');
|
|
253
253
|
|
|
254
|
-
const spy = vi.fn().
|
|
254
|
+
const spy = vi.fn().mockResolvedValue({});
|
|
255
255
|
worker.worker.actor.registerMessageHandler(MessageType.getClusterExpansionZoom, spy);
|
|
256
256
|
|
|
257
257
|
actor.target.postMessage({type: MessageType.getClusterExpansionZoom, data: {} as any, origin: 'file://'});
|
|
@@ -265,7 +265,7 @@ describe('Actor', () => {
|
|
|
265
265
|
const worker = await workerFactory() as any as WorkerGlobalScopeInterface & ActorTarget;
|
|
266
266
|
const actor = new Actor(worker, '1');
|
|
267
267
|
|
|
268
|
-
const spy = vi.fn().
|
|
268
|
+
const spy = vi.fn().mockResolvedValue({});
|
|
269
269
|
worker.worker.actor.registerMessageHandler(MessageType.getClusterExpansionZoom, spy);
|
|
270
270
|
|
|
271
271
|
actor.target.postMessage({type: MessageType.getClusterExpansionZoom, data: {} as any, origin: 'resource://android'});
|
package/src/util/ajax.test.ts
CHANGED
|
@@ -20,6 +20,12 @@ function readAsText(blob) {
|
|
|
20
20
|
});
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
async function expectRejection(promise: Promise<unknown>): Promise<AJAXError> {
|
|
24
|
+
const error = await promise.catch((e) => e);
|
|
25
|
+
expect(error).toBeInstanceOf(Error);
|
|
26
|
+
return error as AJAXError;
|
|
27
|
+
}
|
|
28
|
+
|
|
23
29
|
const originalFetch = global.fetch;
|
|
24
30
|
|
|
25
31
|
describe('ajax', () => {
|
|
@@ -37,18 +43,14 @@ describe('ajax', () => {
|
|
|
37
43
|
request.respond(404, undefined, '404 Not Found');
|
|
38
44
|
});
|
|
39
45
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
expect(ajaxError.statusText).toBe('Not Found');
|
|
49
|
-
expect(ajaxError.url).toBe('http://example.com/test.bin');
|
|
50
|
-
expect(body).toBe('404 Not Found');
|
|
51
|
-
}
|
|
46
|
+
const promise = getArrayBuffer({url: 'http://example.com/test.bin'}, new AbortController());
|
|
47
|
+
server.respond();
|
|
48
|
+
|
|
49
|
+
const ajaxError = await expectRejection(promise);
|
|
50
|
+
expect(ajaxError.status).toBe(404);
|
|
51
|
+
expect(ajaxError.statusText).toBe('Not Found');
|
|
52
|
+
expect(ajaxError.url).toBe('http://example.com/test.bin');
|
|
53
|
+
await expect(readAsText(ajaxError.body)).resolves.toBe('404 Not Found');
|
|
52
54
|
});
|
|
53
55
|
|
|
54
56
|
test('getJSON', async () => {
|
|
@@ -68,11 +70,8 @@ describe('ajax', () => {
|
|
|
68
70
|
});
|
|
69
71
|
const promise = getJSON({url: ''}, new AbortController());
|
|
70
72
|
server.respond();
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
} catch (error) {
|
|
74
|
-
expect(error).toBeTruthy();
|
|
75
|
-
}
|
|
73
|
+
|
|
74
|
+
await expect(promise).rejects.toThrow(SyntaxError);
|
|
76
75
|
});
|
|
77
76
|
|
|
78
77
|
test('getJSON, 404', async () => {
|
|
@@ -82,16 +81,11 @@ describe('ajax', () => {
|
|
|
82
81
|
const promise = getJSON({url: 'http://example.com/test.json'}, new AbortController());
|
|
83
82
|
server.respond();
|
|
84
83
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
expect(ajaxError.status).toBe(404);
|
|
91
|
-
expect(ajaxError.statusText).toBe('Not Found');
|
|
92
|
-
expect(ajaxError.url).toBe('http://example.com/test.json');
|
|
93
|
-
expect(body).toBe('404 Not Found');
|
|
94
|
-
}
|
|
84
|
+
const ajaxError = await expectRejection(promise);
|
|
85
|
+
expect(ajaxError.status).toBe(404);
|
|
86
|
+
expect(ajaxError.statusText).toBe('Not Found');
|
|
87
|
+
expect(ajaxError.url).toBe('http://example.com/test.json');
|
|
88
|
+
await expect(readAsText(ajaxError.body)).resolves.toBe('404 Not Found');
|
|
95
89
|
});
|
|
96
90
|
|
|
97
91
|
test('getJSON, aborted', async () => {
|
|
@@ -103,12 +97,9 @@ describe('ajax', () => {
|
|
|
103
97
|
abortController.abort();
|
|
104
98
|
server.respond();
|
|
105
99
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
expect(ensureError(error).name).toBe('AbortError');
|
|
110
|
-
expect(isAbortError(error)).toBe(true);
|
|
111
|
-
}
|
|
100
|
+
const error = await expectRejection(promise);
|
|
101
|
+
expect(ensureError(error).name).toBe('AbortError');
|
|
102
|
+
expect(isAbortError(error)).toBe(true);
|
|
112
103
|
});
|
|
113
104
|
|
|
114
105
|
test('getJSON with fetch, aborted', async () => {
|
|
@@ -126,12 +117,9 @@ describe('ajax', () => {
|
|
|
126
117
|
abortController.abort();
|
|
127
118
|
server.respond();
|
|
128
119
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
expect(ensureError(error).name).toBe('AbortError');
|
|
133
|
-
expect(isAbortError(error)).toBe(true);
|
|
134
|
-
}
|
|
120
|
+
const error = await expectRejection(promise);
|
|
121
|
+
expect(ensureError(error).name).toBe('AbortError');
|
|
122
|
+
expect(isAbortError(error)).toBe(true);
|
|
135
123
|
});
|
|
136
124
|
|
|
137
125
|
test('getReferrer method (outside Worker), same origin https URL', () => {
|