You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
leaflet-components/test/integration.test.ts

85 lines
3.6 KiB
TypeScript

import { FeatureGroup, Map as LMap, Marker, Popup, TileLayer } from 'leaflet';
import { describe, expect, it } from 'vitest';
import '../src/components/leaflet-map.ts';
import '../src/components/leaflet-tile-layer.ts';
import '../src/components/leaflet-feature-group.ts';
import '../src/components/leaflet-marker.ts';
import '../src/components/leaflet-popup.ts';
// Exercises the registration-bubbling protocol end to end across a small real
// tree, rather than one component at a time: <leaflet-register> events bubble
// from marker -> feature-group -> map, and popup binds to its parent marker
// instead of bubbling past it.
describe('component tree wiring', () => {
it('wires a map + tile-layer + feature-group + marker + popup tree together', () => {
const map = document.createElement('leaflet-map') as HTMLElement & {
leafletObject?: LMap;
};
map.setAttribute('lat', '51.5');
map.setAttribute('lng', '-0.09');
map.setAttribute('zoom', '13');
const tiles = document.createElement('leaflet-tile-layer') as HTMLElement & {
leafletObject?: TileLayer;
};
tiles.setAttribute('url', 'https://tile.example/{z}/{x}/{y}.png');
const group = document.createElement('leaflet-feature-group') as HTMLElement & {
leafletObject?: FeatureGroup;
};
const marker = document.createElement('leaflet-marker') as HTMLElement & {
leafletObject?: Marker;
};
marker.setAttribute('lat', '51.51');
marker.setAttribute('lng', '-0.1');
const popup = document.createElement('leaflet-popup') as HTMLElement & {
leafletObject?: Popup;
};
popup.innerHTML = 'hello';
marker.append(popup);
group.append(marker);
map.append(tiles, group);
document.body.append(map);
// tile-layer and feature-group both registered directly onto the map.
expect(map.leafletObject?.hasLayer(tiles.leafletObject!)).toBe(true);
expect(map.leafletObject?.hasLayer(group.leafletObject!)).toBe(true);
// marker registered onto the feature-group (which, per Leaflet's own
// LayerGroup.onAdd, also adds each child directly onto the map so it
// renders -- hasLayer is true on both, membership is what distinguishes them).
expect(group.leafletObject?.hasLayer(marker.leafletObject!)).toBe(true);
expect(map.leafletObject?.hasLayer(marker.leafletObject!)).toBe(true);
expect(group.leafletObject?.getLayers()).toEqual([marker.leafletObject]);
// popup bound to the marker, not registered as a map layer at all.
expect(marker.leafletObject?.getPopup()).toBe(popup.leafletObject);
// A marker added later goes through the same path.
const marker2 = document.createElement('leaflet-marker') as HTMLElement & {
leafletObject?: Marker;
};
marker2.setAttribute('lat', '1');
marker2.setAttribute('lng', '2');
group.append(marker2);
expect(group.leafletObject?.hasLayer(marker2.leafletObject!)).toBe(true);
// Disconnecting a child removes it from the map (WithProps calls the
// Leaflet object's own .remove(), which detaches from its _map).
// leafletObject is gone once disconnected, so capture the reference first.
// Note this is a pre-existing Leaflet quirk, not something WithProps
// introduces: Layer#remove() only detaches from the map, it does not tell
// an owning LayerGroup/FeatureGroup to forget it (that needs the group's
// own removeLayer()) -- so the group's hasLayer() stays stale/true here.
const removedMarkerObj = marker.leafletObject!;
marker.remove();
expect(map.leafletObject?.hasLayer(removedMarkerObj)).toBe(false);
expect(group.leafletObject?.hasLayer(removedMarkerObj)).toBe(true);
map.remove();
});
});