import { Control, FeatureGroup, LayerGroup } from 'leaflet'; import { describe, expect, it } from 'vitest'; import '../../src/components/leaflet-control-zoom.ts'; import '../../src/components/leaflet-control-scale.ts'; import '../../src/components/leaflet-control-attribution.ts'; import '../../src/components/leaflet-control-layers.ts'; import '../../src/components/leaflet-tile-layer.ts'; import '../../src/components/leaflet-layer-group.ts'; import '../../src/components/leaflet-feature-group.ts'; import '../../src/components/leaflet-marker.ts'; describe('leaflet-control-zoom / scale / attribution', () => { it('create their matching Control class with position and options', () => { const zoom = document.createElement('leaflet-control-zoom') as HTMLElement & { leafletObject?: Control.Zoom; }; zoom.setAttribute('position', 'bottomleft'); document.body.append(zoom); expect(zoom.leafletObject).toBeInstanceOf(Control.Zoom); expect(zoom.leafletObject?.options.position).toBe('bottomleft'); zoom.remove(); const scale = document.createElement('leaflet-control-scale') as HTMLElement & { leafletObject?: Control.Scale; }; scale.setAttribute('max-width', '150'); document.body.append(scale); expect(scale.leafletObject).toBeInstanceOf(Control.Scale); expect(scale.leafletObject?.options.maxWidth).toBe(150); scale.remove(); const attribution = document.createElement('leaflet-control-attribution') as HTMLElement & { leafletObject?: Control.Attribution; }; attribution.setAttribute('prefix', 'Test'); document.body.append(attribution); expect(attribution.leafletObject).toBeInstanceOf(Control.Attribution); expect(attribution.leafletObject?.options.prefix).toBe('Test'); attribution.remove(); }); }); describe('leaflet-control-layers', () => { it('sorts existing children into base layers vs overlays by the type attribute', () => { const el = document.createElement('leaflet-control-layers') as HTMLElement & { leafletObject?: Control.Layers; }; const base = document.createElement('leaflet-tile-layer'); base.setAttribute('url', 'https://a.example/{z}/{x}/{y}.png'); base.setAttribute('name', 'Base'); base.setAttribute('type', 'base'); base.setAttribute('active', ''); const overlay = document.createElement('leaflet-tile-layer'); overlay.setAttribute('url', 'https://b.example/{z}/{x}/{y}.png'); overlay.setAttribute('name', 'Overlay'); el.append(base, overlay); document.body.append(el); expect(el.leafletObject).toBeInstanceOf(Control.Layers); // Control.Layers has no public getter for its layer list, so this reaches // into Leaflet's own private `_layers` field -- brittle across Leaflet // versions, but it's the only way to verify the base/overlay split. const layersInternal = el.leafletObject as unknown as { _layers: { name: string; overlay?: boolean }[]; }; const byName = Object.fromEntries( // oxlint-disable-next-line no-underscore-dangle -- Leaflet's own field name layersInternal._layers.map((l) => [l.name, Boolean(l.overlay)]), ); expect(byName['Base']).toBe(false); expect(byName['Overlay']).toBe(true); el.remove(); }); }); describe('leaflet-layer-group / leaflet-feature-group', () => { it('are passthrough WithProps({}) containers that adopt registering children', () => { const group = document.createElement('leaflet-layer-group') as HTMLElement & { leafletObject?: LayerGroup; }; document.body.append(group); expect(group.leafletObject).toBeInstanceOf(LayerGroup); const marker = document.createElement('leaflet-marker'); marker.setAttribute('lat', '1'); marker.setAttribute('lng', '2'); group.append(marker); expect(group.leafletObject?.getLayers()).toHaveLength(1); group.remove(); const feature = document.createElement('leaflet-feature-group') as HTMLElement & { leafletObject?: FeatureGroup; }; document.body.append(feature); expect(feature.leafletObject).toBeInstanceOf(FeatureGroup); feature.remove(); }); });