import { CRS, TileLayer } from 'leaflet'; import { describe, expect, it } from 'vitest'; import '../../src/components/leaflet-tile-layer.ts'; import '../../src/components/leaflet-tile-layer-wms.ts'; // Stands in for a plugin's CRS-providing element: a plain custom element, // no base class from this package, that fires leaflet-crs-changed on // connect -- exactly the shape a third party would write. class TestCRSProvider extends HTMLElement { crs?: CRS; connectedCallback(): void { this.dispatchEvent( new CustomEvent('leaflet-crs-changed', { bubbles: true, detail: { crs: this.crs ?? null } }), ); } } customElements.define('test-crs-provider', TestCRSProvider); describe('leaflet-tile-layer', () => { it('creates a TileLayer from the url attribute with tileLayerProps options', () => { const el = document.createElement('leaflet-tile-layer'); el.setAttribute('url', 'https://tile.example/{z}/{x}/{y}.png'); el.setAttribute('subdomains', 'abcd'); el.setAttribute('tms', ''); el.setAttribute('max-native-zoom', '17'); document.body.append(el); expect(el.leafletObject).toBeInstanceOf(TileLayer); // Leaflet itself splits a string subdomains option into a character array. expect(el.leafletObject?.options.subdomains).toEqual(['a', 'b', 'c', 'd']); expect(el.leafletObject?.options.tms).toBe(true); expect(el.leafletObject?.options.maxNativeZoom).toBe(17); el.remove(); }); it('defaults zIndex to 1, matching Leaflet', () => { const el = document.createElement('leaflet-tile-layer'); el.setAttribute('url', 'https://tile.example/{z}/{x}/{y}.png'); document.body.append(el); expect(el.leafletObject?.options.zIndex).toBe(1); el.remove(); }); }); describe('leaflet-tile-layer-wms', () => { it('shares base tileLayerProps with leaflet-tile-layer (previously missing entirely)', () => { const el = document.createElement('leaflet-tile-layer-wms'); el.setAttribute('url', 'https://wms.example/service'); el.setAttribute('layers', 'basic'); el.setAttribute('attribution', 'Example'); el.setAttribute('min-zoom', '2'); document.body.append(el); expect(el.leafletObject).toBeInstanceOf(TileLayer.WMS); expect(el.leafletObject?.options.attribution).toBe('Example'); expect(el.leafletObject?.options.minZoom).toBe(2); expect(el.leafletObject?.wmsParams.layers).toBe('basic'); el.remove(); }); it('resolves crs by name to the matching Leaflet CRS instance', () => { const el = document.createElement('leaflet-tile-layer-wms'); el.setAttribute('url', 'https://wms.example/service'); el.setAttribute('layers', 'basic'); el.setAttribute('crs', 'EPSG4326'); document.body.append(el); expect(el.leafletObject?.options.crs).toBe(CRS.EPSG4326); el.remove(); }); it('picks up a CRS Leaflet does not ship from a nested provider element', () => { const pluginCrs = { ...CRS.EPSG3857 } as CRS; const el = document.createElement('leaflet-tile-layer-wms'); el.setAttribute('url', 'https://wms.example/service'); el.setAttribute('layers', 'basic'); document.body.append(el); // No attribute and no provider yet -- Leaflet's own default (null, falls // back to the map's crs internally) applies, nothing of ours sets it. expect(el.leafletObject?.options.crs).toBeNull(); const provider = document.createElement('test-crs-provider') as TestCRSProvider; provider.crs = pluginCrs; const objectBeforeRecreate = el.leafletObject; // Connecting fires leaflet-crs-changed, bubbling to el. el.append(provider); // crs is construction-only: picking it up means a rebuilt object. expect(el.leafletObject).not.toBe(objectBeforeRecreate); expect(el.leafletObject?.options.crs).toBe(pluginCrs); el.remove(); }); it('a nested provider overrides the crs attribute', () => { const pluginCrs = { ...CRS.EPSG3857 } as CRS; const el = document.createElement('leaflet-tile-layer-wms'); el.setAttribute('url', 'https://wms.example/service'); el.setAttribute('layers', 'basic'); el.setAttribute('crs', 'EPSG4326'); const provider = document.createElement('test-crs-provider') as TestCRSProvider; provider.crs = pluginCrs; el.append(provider); document.body.append(el); expect(el.leafletObject?.options.crs).toBe(pluginCrs); el.remove(); }); });