Compare commits
No commits in common. 'v0.2.0' and 'v0.1.1' have entirely different histories.
@ -1,163 +0,0 @@
|
|||||||
import { describe, expect, it, vi } from 'vitest';
|
|
||||||
import { Popup, type LatLngBounds } from 'leaflet';
|
|
||||||
import '../../src/components/leaflet-map.ts';
|
|
||||||
import '../../src/components/leaflet-tile-layer.ts';
|
|
||||||
import '../../src/components/leaflet-marker.ts';
|
|
||||||
|
|
||||||
// The initial (and every re-)frame is deferred to a microtask so the burst of
|
|
||||||
// `layeradd` events during load collapses into one `fitBounds`. Awaiting a
|
|
||||||
// freshly-queued microtask flushes the pending one first.
|
|
||||||
const flush = () =>
|
|
||||||
new Promise<void>((resolve) => {
|
|
||||||
queueMicrotask(resolve);
|
|
||||||
});
|
|
||||||
|
|
||||||
function makeMap(attrs: Record<string, string> = {}) {
|
|
||||||
const map = document.createElement('leaflet-map');
|
|
||||||
for (const [k, v] of Object.entries(attrs)) map.setAttribute(k, v);
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
function marker(lat: number, lng: number) {
|
|
||||||
const m = document.createElement('leaflet-marker');
|
|
||||||
m.setAttribute('lat', String(lat));
|
|
||||||
m.setAttribute('lng', String(lng));
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('<leaflet-map fit-to-markers>', () => {
|
|
||||||
it('frames every marker once on load instead of honouring lat/lng/zoom', async () => {
|
|
||||||
const map = makeMap({ 'fit-to-markers': '', lat: '0', lng: '0', zoom: '2' });
|
|
||||||
map.append(marker(34.0537, -118.2427), marker(33.9416, -118.4085), marker(34.1341, -118.3215));
|
|
||||||
document.body.append(map);
|
|
||||||
|
|
||||||
// Spy after connect but before the microtask flush, so the initial frame is
|
|
||||||
// still pending and gets captured.
|
|
||||||
const spy = vi.spyOn(map.leafletObject!, 'fitBounds');
|
|
||||||
await flush();
|
|
||||||
|
|
||||||
expect(spy).toHaveBeenCalledTimes(1);
|
|
||||||
const bounds = spy.mock.calls[0]![0] as LatLngBounds;
|
|
||||||
expect(bounds.contains([34.0537, -118.2427])).toBe(true);
|
|
||||||
expect(bounds.contains([33.9416, -118.4085])).toBe(true);
|
|
||||||
expect(bounds.contains([34.1341, -118.3215])).toBe(true);
|
|
||||||
expect(spy.mock.calls[0]![1]).toMatchObject({ padding: [20, 20] });
|
|
||||||
|
|
||||||
map.remove();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('passes fit-padding and fit-max-zoom through to fitBounds', async () => {
|
|
||||||
const map = makeMap({ 'fit-to-markers': '', 'fit-padding': '50', 'fit-max-zoom': '12' });
|
|
||||||
map.append(marker(1, 2), marker(3, 4));
|
|
||||||
document.body.append(map);
|
|
||||||
|
|
||||||
const spy = vi.spyOn(map.leafletObject!, 'fitBounds');
|
|
||||||
await flush();
|
|
||||||
|
|
||||||
expect(spy.mock.calls[0]![1]).toMatchObject({ padding: [50, 50], maxZoom: 12 });
|
|
||||||
map.remove();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('re-frames when a marker is added later', async () => {
|
|
||||||
const map = makeMap({ 'fit-to-markers': '' });
|
|
||||||
map.append(marker(10, 10), marker(20, 20));
|
|
||||||
document.body.append(map);
|
|
||||||
await flush();
|
|
||||||
|
|
||||||
const spy = vi.spyOn(map.leafletObject!, 'fitBounds');
|
|
||||||
map.append(marker(40, -100));
|
|
||||||
await flush();
|
|
||||||
|
|
||||||
expect(spy).toHaveBeenCalledTimes(1);
|
|
||||||
expect((spy.mock.calls[0]![0] as LatLngBounds).contains([40, -100])).toBe(true);
|
|
||||||
map.remove();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('activates when the attribute is toggled on after connect', async () => {
|
|
||||||
const map = makeMap({ lat: '0', lng: '0', zoom: '3' });
|
|
||||||
map.append(marker(34, -118), marker(35, -119));
|
|
||||||
document.body.append(map);
|
|
||||||
|
|
||||||
const spy = vi.spyOn(map.leafletObject!, 'fitBounds');
|
|
||||||
await flush();
|
|
||||||
expect(spy).not.toHaveBeenCalled();
|
|
||||||
|
|
||||||
map.setAttribute('fit-to-markers', '');
|
|
||||||
await flush();
|
|
||||||
expect(spy).toHaveBeenCalledTimes(1);
|
|
||||||
map.remove();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('does not reframe when the user pans or zooms', async () => {
|
|
||||||
const map = makeMap({ 'fit-to-markers': '' });
|
|
||||||
map.append(marker(10, 10), marker(20, 20));
|
|
||||||
document.body.append(map);
|
|
||||||
await flush();
|
|
||||||
|
|
||||||
const spy = vi.spyOn(map.leafletObject!, 'fitBounds');
|
|
||||||
// Simulate a manual pan + zoom.
|
|
||||||
map.leafletObject!.setView([0, 0], 6);
|
|
||||||
map.leafletObject!.fire('moveend');
|
|
||||||
map.leafletObject!.fire('zoomend');
|
|
||||||
await flush();
|
|
||||||
|
|
||||||
expect(spy).not.toHaveBeenCalled();
|
|
||||||
map.remove();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('does not reframe when a popup is added to / opened on the map', async () => {
|
|
||||||
const map = makeMap({ 'fit-to-markers': '' });
|
|
||||||
map.append(marker(34, -118), marker(35, -119));
|
|
||||||
document.body.append(map);
|
|
||||||
await flush();
|
|
||||||
|
|
||||||
const spy = vi.spyOn(map.leafletObject!, 'fitBounds');
|
|
||||||
new Popup().setLatLng([34, -118]).setContent('hi').openOn(map.leafletObject!);
|
|
||||||
await flush();
|
|
||||||
|
|
||||||
expect(spy).not.toHaveBeenCalled();
|
|
||||||
map.remove();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('does nothing without the attribute', async () => {
|
|
||||||
const map = makeMap({ lat: '10', lng: '20', zoom: '5' });
|
|
||||||
map.append(marker(1, 2), marker(3, 4));
|
|
||||||
document.body.append(map);
|
|
||||||
|
|
||||||
const spy = vi.spyOn(map.leafletObject!, 'fitBounds');
|
|
||||||
await flush();
|
|
||||||
|
|
||||||
expect(spy).not.toHaveBeenCalled();
|
|
||||||
expect(map.leafletObject!.getZoom()).toBe(5);
|
|
||||||
map.remove();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('leaves the view alone when no layer has a position', async () => {
|
|
||||||
const map = makeMap({ 'fit-to-markers': '', lat: '5', lng: '6', zoom: '4' });
|
|
||||||
const tiles = document.createElement('leaflet-tile-layer');
|
|
||||||
tiles.setAttribute('url', 'https://tile.example/{z}/{x}/{y}.png');
|
|
||||||
map.append(tiles);
|
|
||||||
document.body.append(map);
|
|
||||||
|
|
||||||
const spy = vi.spyOn(map.leafletObject!, 'fitBounds');
|
|
||||||
await flush();
|
|
||||||
|
|
||||||
expect(spy).not.toHaveBeenCalled();
|
|
||||||
expect(map.leafletObject!.getZoom()).toBe(4);
|
|
||||||
map.remove();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('stops re-framing after disconnect', async () => {
|
|
||||||
const map = makeMap({ 'fit-to-markers': '' });
|
|
||||||
map.append(marker(1, 1), marker(2, 2));
|
|
||||||
document.body.append(map);
|
|
||||||
await flush();
|
|
||||||
|
|
||||||
const mapObj = map.leafletObject!;
|
|
||||||
const spy = vi.spyOn(mapObj, 'fitBounds');
|
|
||||||
map.remove();
|
|
||||||
await flush();
|
|
||||||
|
|
||||||
expect(spy).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
Loading…
Reference in New Issue