diff --git a/.gitignore b/.gitignore index f8c61a0..89e18a4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ node_modules dist coverage -.vscode cypress \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..f9cc48e --- /dev/null +++ b/.prettierrc @@ -0,0 +1,7 @@ +{ + "printWidth": 80, + "tabWidth": 2, + "semi": false, + "singleQuote": true, + "trailingComma": "all" +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..71e5074 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "editor.defaultFormatter": "esbenp.prettier-vscode", + "typescript.format.enable": false, + "[typescript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "editor.formatOnSave": true +} diff --git a/demo/addRemoveDataAfterInitialization.html b/demo/addRemoveDataAfterInitialization.html index 221307d..368daa3 100644 --- a/demo/addRemoveDataAfterInitialization.html +++ b/demo/addRemoveDataAfterInitialization.html @@ -1,68 +1,90 @@ - - - - DEMO - Leaflet Dynamic Layers - - - - -
- Click adds layer to map, and to layers references. -
- Click adds layer to map, and to layers references. -
- Click adds layer to map, and to layers references. -
- Click adds layer to layers references only. -
- Click removes layer from map. Reference to layer still available. + + + + DEMO - Leaflet Dynamic Layers + + + + +
+ + Click adds layer to map, and to layers references. +
+ Click adds layer to map, + and to layers references. +
+ Click adds + layer to map, and to layers references. +
+ + Click adds layer to layers references only. +
+ + Click removes layer from map. Reference to layer still available. - - \ No newline at end of file + + diff --git a/demo/assets/newark_nj_1922.jpg b/demo/assets/newark_nj_1922.jpg new file mode 100644 index 0000000..1f4ae59 Binary files /dev/null and b/demo/assets/newark_nj_1922.jpg differ diff --git a/demo/initialize.html b/demo/initialize.html index fc0a939..e47335f 100644 --- a/demo/initialize.html +++ b/demo/initialize.html @@ -1,83 +1,100 @@ - - - - DEMO - Leaflet Dynamic Layers - - - - -
+ + + +
- - \ No newline at end of file + + diff --git a/demo/togglingLayers.html b/demo/togglingLayers.html new file mode 100644 index 0000000..f0e30df --- /dev/null +++ b/demo/togglingLayers.html @@ -0,0 +1,120 @@ + + + + DEMO - Leaflet Dynamic Layers + + + + +
+ + +
+ +
+ + + + + + + diff --git a/package-lock.json b/package-lock.json index 99e1f3d..e75a488 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "leaflet-declarative-layers", - "version": "0.4.1", + "version": "0.5.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -5797,6 +5797,12 @@ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, + "prettier": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz", + "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==", + "dev": true + }, "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -7269,6 +7275,12 @@ "tsutils": "^2.29.0" } }, + "tslint-config-prettier": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz", + "integrity": "sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==", + "dev": true + }, "tsutils": { "version": "2.29.0", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", diff --git a/package.json b/package.json index d87dc02..ce7a9ad 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,11 @@ { "name": "leaflet-declarative-layers", - "version": "0.4.1", + "version": "0.5.0", "description": "", "private": false, "scripts": { "clean": "rm -rf ./dist", - "lint": "tslint src/**/*.ts --format stylish", + "lint": "tslint src/**/*.ts test/**/*.ts", "bundle": "npm run clean && webpack --mode=production", "bundle-dev": "npm run clean && webpack --mode=development", "test": "karma start", @@ -41,9 +41,11 @@ "karma-jasmine": "^2.0.1", "karma-typescript": "^4.1.1", "lodash": "^4.17.15", + "prettier": "^2.0.5", "ts-loader": "^6.2.1", "ts-mocks": "^2.6.0", "tslint": "^5.20.1", + "tslint-config-prettier": "^1.18.0", "typescript": "^3.7.3", "webpack": "^4.41.2", "webpack-cli": "^3.3.10" diff --git a/src/DeclarativeLayers.ts b/src/DeclarativeLayers.ts index 5e19318..16ff00f 100644 --- a/src/DeclarativeLayers.ts +++ b/src/DeclarativeLayers.ts @@ -1,89 +1,135 @@ -import * as dataTypes from './dataTypes'; +import * as dataTypes from './dataTypes' // TODO karma complains if import from 'geoJson'. Figure out more elegant solution. -import * as geoJson from '../node_modules/@types/geojson/index'; -import * as leafletTypes from '../node_modules/@types/leaflet/index'; -import {defaultBooleanToTrue} from './utilities'; +import * as geoJson from '../node_modules/@types/geojson/index' +import * as leafletTypes from '../node_modules/@types/leaflet/index' +import { defaultBooleanToTrue } from './utilities' export interface ILayerReference { - [state: string]: dataTypes.ILeafletLayer; + [state: string]: dataTypes.ILeafletLayer } -type leafletTypesCopy = typeof leafletTypes; +type leafletTypesCopy = typeof leafletTypes export interface ILeafletWithLDL extends leafletTypesCopy { - DeclarativeLayers?: any; - + DeclarativeLayers?: any } export class DeclarativeLayers { - private layerReferences: ILayerReference = {}; // reference for removal from map + private layerReferences: ILayerReference = {} // reference for removal from map - constructor( - private suppliedLeafletReference: ILeafletWithLDL, - private map: leafletTypes.Map, - layersMetadata?: dataTypes.ILayersMetadata, - ) { - if (layersMetadata) { - layersMetadata.forEach((layerMetadata) => { - this.initializeLayer(layerMetadata); - }); - } + constructor( + private suppliedLeafletReference: ILeafletWithLDL, + private map: leafletTypes.Map, + layersMetadata?: dataTypes.ILayersMetadata, + ) { + if (layersMetadata) { + layersMetadata.forEach(layerMetadata => { + this.initializeLayer(layerMetadata) + }) } - public getLayerReferences = () => { - return this.layerReferences; + } + public getLayerReferences = () => { + return this.layerReferences + } + public addLayer = ( + layerMetadata: dataTypes.ILayerMetadata, + ): dataTypes.ILeafletLayer => { + this.initializeLayer(layerMetadata) + return this.layerReferences[layerMetadata.id] + } + public removeLayer = (layer: dataTypes.ILeafletLayer): void => { + this.map.removeLayer(layer) + } + public toggleLayer = (layer: dataTypes.ILeafletLayer): void => { + if (this.map.hasLayer(layer)) { + this.removeLayer(layer) + } else { + this.map.addLayer(layer) } - - public addLayer = (layerMetadata: dataTypes.ILayerMetadata): dataTypes.ILeafletLayer => { - this.initializeLayer(layerMetadata); - return this.layerReferences[layerMetadata.id]; + } + private initializeLayer = (layerMetadata: dataTypes.ILayerMetadata): void => { + const layer: dataTypes.ILeafletLayer = this.createLeafletLayer( + layerMetadata, + ) + this.addLayerToReferences(layerMetadata.id, layer) + if (this.shouldBeVisibleInitially(layerMetadata)) { + this.map.addLayer(this.layerReferences[layerMetadata.id]) } - public removeLayer = (layer: dataTypes.ILeafletLayer): void => { - this.map.removeLayer(layer); + } + private createLeafletLayer = ( + layerMetadata: dataTypes.ILayerMetadata, + ): dataTypes.ILeafletLayer => { + if (dataTypes.isTilesType(layerMetadata)) { + return this.initializeTileLayer(layerMetadata as dataTypes.ITilesMetadata) + } else if (dataTypes.isGeoJsonType(layerMetadata)) { + return this.initializeGeoJsonLayer( + layerMetadata as dataTypes.IGeoJsonMetadata, + ) + } else if (dataTypes.isImageOverlayType(layerMetadata)) { + return this.initializeImageOverlayLayer( + layerMetadata as dataTypes.IImageOverlayMetadata, + ) + } else { + throw new Error( + `the data type for ${layerMetadata!.id} isnt currently supported`, + ) } - private initializeLayer = (layerMetadata: dataTypes.ILayerMetadata): void => { - const layer: dataTypes.ILeafletLayer = this.createLeafletLayer(layerMetadata); - this.addLayerToReferences(layerMetadata.id, layer); - if (this.shouldBeVisibleInitially(layerMetadata)) { - this.map.addLayer(this.layerReferences[layerMetadata.id]); + } + private addLayerToReferences = ( + id: string, + layer: dataTypes.ILeafletLayer, + ) => { + this.layerReferences[id] = layer + } + private shouldBeVisibleInitially = ({ + visibleInitially, + id, + }: dataTypes.ILayerMetadata): boolean => { + // if tagged as visible AND initialized + return defaultBooleanToTrue(visibleInitially) && !!this.layerReferences[id] + } + private initializeTileLayer = (layerMetadata: dataTypes.ITilesMetadata) => { + return new this.suppliedLeafletReference.TileLayer( + layerMetadata.url, + layerMetadata.options, + ) + } + private initializeImageOverlayLayer = ( + layerMetadata: dataTypes.IImageOverlayMetadata, + ) => { + return new this.suppliedLeafletReference.ImageOverlay( + layerMetadata.url, + layerMetadata.bounds, + layerMetadata.options, + ) + } + private initializeGeoJsonLayer = ( + layerMetadata: dataTypes.IGeoJsonMetadata, + ) => { + const options: leafletTypes.GeoJSONOptions = layerMetadata.options + ? layerMetadata.options + : {} + const onEachFeatureOptions: leafletTypes.GeoJSONOptions = { + onEachFeature: ( + feature: geoJson.Feature, + layer: leafletTypes.GeoJSON, + ): void => { + if (options.onEachFeature) { + options.onEachFeature(feature, layer) } - } - private createLeafletLayer = (layerMetadata: dataTypes.ILayerMetadata): dataTypes.ILeafletLayer => { - if (dataTypes.isTilesType(layerMetadata)) { - return this.initializeTileLayer(layerMetadata as dataTypes.ITilesMetadata); - } else if (dataTypes.isGeoJsonType(layerMetadata)) { - return this.initializeGeoJsonLayer(layerMetadata as dataTypes.IGeoJsonMetadata); - } else if (dataTypes.isImageOverlayType(layerMetadata)) { - return this.initializeImageOverlayLayer(layerMetadata as dataTypes.IImageOverlayMetadata); - } else { - throw new Error(`the data type for ${layerMetadata!.id} isnt currently supported`); + if (layerMetadata.generateFeaturePopupContent) { + const popupContent: leafletTypes.Content = layerMetadata.generateFeaturePopupContent( + feature, + ) + layer.bindPopup(popupContent) } + }, } - private addLayerToReferences = (id: string, layer: dataTypes.ILeafletLayer) => { - this.layerReferences[id] = layer; - } - private shouldBeVisibleInitially = ({visibleInitially, id}: dataTypes.ILayerMetadata): boolean => { - // if tagged as visible AND initialized - return defaultBooleanToTrue(visibleInitially) && !!this.layerReferences[id]; - } - private initializeTileLayer = (layerMetadata: dataTypes.ITilesMetadata) => { - return new this.suppliedLeafletReference.TileLayer(layerMetadata.url, layerMetadata.options); - } - private initializeImageOverlayLayer = (layerMetadata: dataTypes.IImageOverlayMetadata) => { - return new this.suppliedLeafletReference.ImageOverlay - (layerMetadata.url, layerMetadata.bounds, layerMetadata.options); - } - private initializeGeoJsonLayer = (layerMetadata: dataTypes.IGeoJsonMetadata) => { - const options: leafletTypes.GeoJSONOptions = layerMetadata.options ? layerMetadata.options : {}; - const onEachFeatureOptions: leafletTypes.GeoJSONOptions = { - onEachFeature: (feature: geoJson.Feature, layer: leafletTypes.GeoJSON): void => { - if (options.onEachFeature) { - options.onEachFeature(feature, layer); - } - if (layerMetadata.generateFeaturePopupContent) { - const popupContent: leafletTypes.Content = layerMetadata.generateFeaturePopupContent(feature); - layer.bindPopup(popupContent); - } - }, - }; - const mergedOptions: leafletTypes.GeoJSONOptions = {...options, ...onEachFeatureOptions}; - return new this.suppliedLeafletReference.GeoJSON(layerMetadata.data, mergedOptions); + const mergedOptions: leafletTypes.GeoJSONOptions = { + ...options, + ...onEachFeatureOptions, } + return new this.suppliedLeafletReference.GeoJSON( + layerMetadata.data, + mergedOptions, + ) + } } diff --git a/src/dataTypes.ts b/src/dataTypes.ts index 6ff9229..d4a5ca1 100644 --- a/src/dataTypes.ts +++ b/src/dataTypes.ts @@ -1,44 +1,52 @@ -import * as leaflet from 'leaflet'; +import * as leaflet from 'leaflet' // TODO karma complains if import from 'geoJson'. Figure out more elegant solution. -import * as geojson from '../node_modules/@types/geojson/index'; +import * as geojson from '../node_modules/@types/geojson/index' export interface IBasicMetadata { - label: string; - visibleInitially?: boolean; - id: string; - legend?: string; // path to legend image + label: string + visibleInitially?: boolean + id: string + legend?: string // path to legend image } export interface IImageOverlayMetadata extends IBasicMetadata { - url: string; - bounds: leaflet.LatLngBoundsExpression; - options?: leaflet.ImageOverlayOptions; + url: string + bounds: leaflet.LatLngBoundsExpression + options?: leaflet.ImageOverlayOptions } -export interface IGeoJsonMetadata extends IBasicMetadata { - data: geojson.GeoJsonObject; - options?: leaflet.GeoJSONOptions; - generateFeaturePopupContent?(feature: geojson.Feature): leaflet.Content; +export interface IGeoJsonMetadata extends IBasicMetadata { + data: geojson.GeoJsonObject + options?: leaflet.GeoJSONOptions + generateFeaturePopupContent?(feature: geojson.Feature): leaflet.Content } -export interface ITilesMetadata extends IBasicMetadata { - url: string; - options?: leaflet.TileLayerOptions; +export interface ITilesMetadata extends IBasicMetadata { + url: string + options?: leaflet.TileLayerOptions } -export type ILayerMetadata = ITilesMetadata | IGeoJsonMetadata | IImageOverlayMetadata; +export type ILayerMetadata = + | ITilesMetadata + | IGeoJsonMetadata + | IImageOverlayMetadata export interface ILayersMetadata extends Array {} -export type ILeafletLayer = leaflet.TileLayer | leaflet.GeoJSON | leaflet.ImageOverlay; +export type ILeafletLayer = + | leaflet.TileLayer + | leaflet.GeoJSON + | leaflet.ImageOverlay // Type Guards export const isTilesType = (layer: any): layer is ITilesMetadata => { - return (layer.url !== undefined && layer.bounds === undefined); -}; + return layer.url !== undefined && layer.bounds === undefined +} export const isGeoJsonType = (layer: any): layer is IGeoJsonMetadata => { - return layer.data !== undefined; -}; -export const isImageOverlayType = (layer: any): layer is IImageOverlayMetadata => { - return (layer.bounds !== undefined && layer.url !== undefined); -}; + return layer.data !== undefined +} +export const isImageOverlayType = ( + layer: any, +): layer is IImageOverlayMetadata => { + return layer.bounds !== undefined && layer.url !== undefined +} diff --git a/src/index.ts b/src/index.ts index 8d44273..ad0275b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,45 +1,47 @@ -import {ILayersMetadata, ILeafletLayer, ILayerMetadata} from './dataTypes'; +import { ILayersMetadata, ILeafletLayer, ILayerMetadata } from './dataTypes' // TODO karma complains if import from '@types/leaflet'. Figure out more elegant solution. -import {Map as ILeafletMap} from '../node_modules/@types/leaflet/index'; -import {ILeafletWithLDL, DeclarativeLayers} from './DeclarativeLayers'; +import { Map as ILeafletMap } from '../node_modules/@types/leaflet/index' +import { ILeafletWithLDL, DeclarativeLayers } from './DeclarativeLayers' -declare const L: ILeafletWithLDL; -declare const define: any; -declare const exports: any; -declare const module: any; -declare const require: any; +declare const L: ILeafletWithLDL +declare const define: any +declare const exports: any +declare const module: any +declare const require: any // UMD pattern to support module sustems like AMD and CommonJS as reccommended by Leaflet -(((factory, window) => { - - // define an AMD module that relies on 'leaflet' - if (typeof define === 'function' && define.amd) { - define(['leaflet'], factory); +;((factory, window) => { + // define an AMD module that relies on 'leaflet' + if (typeof define === 'function' && define.amd) { + define(['leaflet'], factory) // define a Common JS module that relies on 'leaflet' - } else if (typeof exports === 'object') { - module.exports = factory(require('leaflet')); - } + } else if (typeof exports === 'object') { + module.exports = factory(require('leaflet')) + } - // attach your leaflet-declarative-layers to the global 'L' variable - if (typeof window !== 'undefined' && window.L) { - const leafletInstance = window.L as ILeafletWithLDL; - leafletInstance.DeclarativeLayers = leafletInstance.Class.extend(factory(L)); - } else { - const message: string = - `The Leaflet reference is not available for the\ - Leaflet Environmental Layers plugin. Try reordering your script tags.`; - throw new Error(message); - } + // attach your leaflet-declarative-layers to the global 'L' variable + if (typeof window !== 'undefined' && window.L) { + const leafletInstance = window.L as ILeafletWithLDL + leafletInstance.DeclarativeLayers = leafletInstance.Class.extend(factory(L)) + } else { + const message: string = `The Leaflet reference is not available for the\ + Leaflet Environmental Layers plugin. Try reordering your script tags.` + throw new Error(message) + } })((leaflet: ILeafletWithLDL) => { - let declarativeLayersInstance: DeclarativeLayers; - const leafletDeclarativeLayersPlugin = { - initialize: (map: ILeafletMap, layersMetadata: ILayersMetadata) => { - declarativeLayersInstance = new DeclarativeLayers(L, map, layersMetadata); - }, - getLayerReferences: () => declarativeLayersInstance.getLayerReferences(), - addLayer: (layerMetadata: ILayerMetadata) => declarativeLayersInstance.addLayer(layerMetadata), - removeLayer: (layer: ILeafletLayer) => declarativeLayersInstance.removeLayer(layer), - }; - return leafletDeclarativeLayersPlugin; -}, window)); + let declarativeLayersInstance: DeclarativeLayers + const leafletDeclarativeLayersPlugin = { + initialize: (map: ILeafletMap, layersMetadata: ILayersMetadata) => { + declarativeLayersInstance = new DeclarativeLayers(L, map, layersMetadata) + }, + getLayerReferences: () => declarativeLayersInstance.getLayerReferences(), + addLayer: (layerMetadata: ILayerMetadata) => + declarativeLayersInstance.addLayer(layerMetadata), + removeLayer: (layer: ILeafletLayer) => + declarativeLayersInstance.removeLayer(layer), + toggleLayer: (layer: ILeafletLayer) => + declarativeLayersInstance.toggleLayer(layer), + } + return leafletDeclarativeLayersPlugin +}, window) diff --git a/src/utilities.ts b/src/utilities.ts index e691ed3..d42e66a 100644 --- a/src/utilities.ts +++ b/src/utilities.ts @@ -1,4 +1,7 @@ -export const defaultBooleanToTrue = (value: boolean | undefined | null): boolean => { - // reminder: null == undefined - return value == undefined ? true : value; -}; +export const defaultBooleanToTrue = ( + value: boolean | undefined | null, +): boolean => { + // reminder: null == undefined + // tslint:disable-next-line: triple-equals + return value == undefined ? true : value +} diff --git a/test/e2e/togglingLayers.spec.js b/test/e2e/togglingLayers.spec.js new file mode 100644 index 0000000..417fea8 --- /dev/null +++ b/test/e2e/togglingLayers.spec.js @@ -0,0 +1,66 @@ +describe('adding layers after initializing LDL', () => { + beforeEach(() => { + cy.visit('/demo/togglingLayers.html') + }) + describe('basic setup', () => { + it('contains a map element', () => { + cy.get('#map'); + }); + }) + describe('toggling layers with button clicks', () => { + it('adds the test tile layer on first click', ()=> { + cy.get('#toggleTile').click(); + cy.get('.test-tile-layer'); + }); + it('removes the test tile layer on second click', ()=> { + cy.get('#toggleTile').click(); + cy.get('#toggleTile').click(); + cy.get('.test-tile-layer').should('not.exist'); + }); + it('adds the test tile layer on third click', ()=> { + cy.get('#toggleTile').click(); + cy.get('#toggleTile').click(); + cy.get('#toggleTile').click(); + + cy.get('.test-tile-layer'); + }); + + it('adds the testGeoJSON layer on first click', () => { + cy.get('#toggleGeoJson').click(); + cy.get('.test-geojson-icon'); + }) + it('removes the testGeoJSON layer on second click', ()=> { + cy.get('#toggleGeoJson').click(); + cy.get('#toggleGeoJson').click(); + + cy.get('.test-geojson-icon').should('not.exist'); + }); + it('adds the testGeoJSON on third click', ()=> { + cy.get('#toggleGeoJson').click(); + cy.get('#toggleGeoJson').click(); + cy.get('#toggleGeoJson').click(); + + cy.get('.test-geojson-icon'); + }); + + + it('adds the image overlay layer on the first click', () => { + cy.get('#toggleImageOverlay').click(); + cy.get('.test-image-overlay'); + }); + it('removes the image overlay layer on second click', ()=> { + cy.get('#toggleImageOverlay').click(); + cy.get('#toggleImageOverlay').click(); + + cy.get('.test-image-overlay').should('not.exist'); + }); + it('adds the image overlay layer on third click', ()=> { + cy.get('#toggleImageOverlay').click(); + cy.get('#toggleImageOverlay').click(); + cy.get('#toggleImageOverlay').click(); + + cy.get('.test-image-overlay'); + }); + + }); +}); diff --git a/test/unitAndIntegration/DeclarativeLayers.spec.ts b/test/unitAndIntegration/DeclarativeLayers.spec.ts index 66961dc..9c3ecbd 100644 --- a/test/unitAndIntegration/DeclarativeLayers.spec.ts +++ b/test/unitAndIntegration/DeclarativeLayers.spec.ts @@ -1,283 +1,349 @@ -import { Mock } from 'ts-mocks'; -import * as leaflet from 'leaflet'; -import * as dataTypes from '../../src/dataTypes'; -import { DeclarativeLayers, ILayerReference } from '../../src/DeclarativeLayers'; -import {_} from 'lodash'; +import { Mock } from 'ts-mocks' +import * as leaflet from 'leaflet' +import * as dataTypes from '../../src/dataTypes' +import { DeclarativeLayers, ILayerReference } from '../../src/DeclarativeLayers' +import { _ } from 'lodash' import { - FeatureCollection as geoJsonFeatureCollection, - Feature as geoJsonFeature, -} from '../../node_modules/@types/geojson/index'; -let testingOnEach: number; + FeatureCollection as geoJsonFeatureCollection, + Feature as geoJsonFeature, +} from '../../node_modules/@types/geojson/index' +let testingOnEach: number const fakeFeatureClick = (e: leaflet.LeafletEvent) => { - map.flyTo(new leaflet.LatLng(-104.98999178409576, 39.74683938093904)); -}; + map.flyTo(new leaflet.LatLng(-104.98999178409576, 39.74683938093904)) +} const geojsonFeatureCollection: geoJsonFeatureCollection = { - type: 'FeatureCollection', - features: [ - { - type: 'Feature', - properties: { - popupContent: '18th & California Light Rail Stop', - }, - geometry: { - type: 'Point', - coordinates: [-104.98999178409576, 39.74683938093904], - }, - }, { - type: 'Feature', - properties: { - popupContent: '20th & Welton Light Rail Stop', - }, - geometry: { - type: 'Point', - coordinates: [-104.98689115047453, 39.747924136466565], - }, - }, - ], -}; -const layers: dataTypes.ILayersMetadata = [{ + type: 'FeatureCollection', + features: [ + { + type: 'Feature', + properties: { + popupContent: '18th & California Light Rail Stop', + }, + geometry: { + type: 'Point', + coordinates: [-104.98999178409576, 39.74683938093904], + }, + }, + { + type: 'Feature', + properties: { + popupContent: '20th & Welton Light Rail Stop', + }, + geometry: { + type: 'Point', + coordinates: [-104.98689115047453, 39.747924136466565], + }, + }, + ], +} +const layers: dataTypes.ILayersMetadata = [ + { id: 'testTileLayer1', label: 'testTileLayer1', url: 'www.testTileLayer1url.com', visibleInitially: true, options: { - zIndex: 3, + zIndex: 3, }, -}, -{ + }, + { id: 'testTileLayer2', label: 'testTileLayer2', url: 'www.testTileLayer1Url.com', visibleInitially: false, options: { - maxZoom: 2, + maxZoom: 2, }, -}, -{ + }, + { id: 'testGeoJsonLayer1', label: 'testGeoJsonLayer1', data: geojsonFeatureCollection, - options: {onEachFeature: (feature, layer) => { - testingOnEach += 1; - }}, + options: { + onEachFeature: (feature, layer) => { + testingOnEach += 1 + }, + }, generateFeaturePopupContent: (feature) => { - return feature.properties.popupContent; + return feature.properties.popupContent }, -}, -{ + }, + { id: 'testImageOverlay1', label: 'testImageOverlay1', visibleInitially: true, url: 'url', - bounds: [[40.712216, -74.22655], [40.773941, -74.12544]], - options: {attribution: 'I\'m a test image overlay!'} -}]; -let map: leaflet.Map; -let MockMap: Mock; -let declarativeLayers: DeclarativeLayers; -let testTileLayer1: leaflet.TileLayer; -let testTileLayer2: leaflet.TileLayer; -let testGeoJsonLayer1: leaflet.GeoJSON; + bounds: [ + [40.712216, -74.22655], + [40.773941, -74.12544], + ], + options: { attribution: "I'm a test image overlay!" }, + }, +] +let map: leaflet.Map +let MockMap: Mock +let declarativeLayers: DeclarativeLayers +let testTileLayer1: leaflet.TileLayer +let testTileLayer2: leaflet.TileLayer +let testGeoJsonLayer1: leaflet.GeoJSON const initializateDeclarativeLayers = () => { - MockMap = new Mock({ - addLayer: Mock.ANY_FUNC, - removeLayer: Mock.ANY_FUNC, - flyTo: Mock.ANY_FUNC, - }); - map = MockMap.Object; - declarativeLayers = new DeclarativeLayers(leaflet, map, layers); - testTileLayer1 = declarativeLayers.getLayerReferences().testTileLayer1 as leaflet.TileLayer; - testTileLayer2 = declarativeLayers.getLayerReferences().testTileLayer2 as leaflet.TileLayer; - testGeoJsonLayer1 = declarativeLayers.getLayerReferences().testGeoJsonLayer1 as leaflet.GeoJSON; -}; + MockMap = new Mock({ + addLayer: Mock.ANY_FUNC, + removeLayer: Mock.ANY_FUNC, + flyTo: Mock.ANY_FUNC, + }) + map = MockMap.Object + declarativeLayers = new DeclarativeLayers(leaflet, map, layers) + testTileLayer1 = declarativeLayers.getLayerReferences() + .testTileLayer1 as leaflet.TileLayer + testTileLayer2 = declarativeLayers.getLayerReferences() + .testTileLayer2 as leaflet.TileLayer + testGeoJsonLayer1 = declarativeLayers.getLayerReferences() + .testGeoJsonLayer1 as leaflet.GeoJSON +} describe('declarative layers', () => { - beforeEach((done) => { - testingOnEach = 0; - spyOn(leaflet.Layer.prototype, 'bindPopup'); - initializateDeclarativeLayers(); - done(); - }); - describe('initialization', () => { - describe('visibleInitially property', () => { - it('adds visibleIntially=true to the map', () => { - expect(map.addLayer).toHaveBeenCalledWith(testTileLayer1); - }); - it('doesnt add visibleIntially=false to the map', () => { - expect(map.addLayer).not.toHaveBeenCalledWith(testTileLayer2); - }); - it('adds layers with no visibleInitially property set to the map by default', () => { - expect(map.addLayer).toHaveBeenCalledWith(testGeoJsonLayer1); - }); - }); - }); - describe('access to layers refrences', () => { - it('exposes references to added layers (visible or not)', () => { - expect( Object.keys(declarativeLayers.getLayerReferences()).length).toEqual(layers.length); - expect(declarativeLayers.getLayerReferences().testTileLayer1).toBeDefined(); - expect(declarativeLayers.getLayerReferences().testTileLayer2).toBeDefined(); - expect(declarativeLayers.getLayerReferences().testGeoJsonLayer1).toBeDefined(); - expect(declarativeLayers.getLayerReferences().testImageOverlay1).toBeDefined(); - }); - }); - describe('adding layers initially', () => { - it('shouldnt be called with undefined values', () => { - expect(map.addLayer).not.toHaveBeenCalledWith(undefined); - }); - describe('tile layers', () => { - it('loads tile layers', () => { - expect(map.addLayer).toHaveBeenCalledWith(testTileLayer1); - }); - it('passes the tile layer options', () => { - expect(testTileLayer1.options.zIndex).toEqual((layers[0] as dataTypes.ITilesMetadata).options.zIndex); - expect(testTileLayer2.options.maxZoom).toBe((layers[1] as dataTypes.ITilesMetadata).options.maxZoom); - }); - }); - describe('GeoJson layers', () => { - it('should load GeoJson Layers', () => { - expect(map.addLayer).toHaveBeenCalledWith(declarativeLayers.getLayerReferences().testGeoJsonLayer1); - }); - // TODO add test for options - describe('popups', () => { - const geoJsonMetadataWithPopup = layers[2] as dataTypes.IGeoJsonMetadata; - it('should bind popups to a layer', () => { - expect(testGeoJsonLayer1.bindPopup) - .toHaveBeenCalledWith(geojsonFeatureCollection.features[0].properties.popupContent); - }); - it('shouldnt interfere with other options using onEachFeature', () => { - expect(testingOnEach).toEqual(2); - }); - }); - }); - describe('ImageOverlay Layers', () => { - it ('should load image overlays', () => { - expect(map.addLayer).toHaveBeenCalledWith(declarativeLayers.getLayerReferences().testImageOverlay1); - }); - it ('should pass image overlay options to Leaflet', () => { - expect(declarativeLayers.getLayerReferences().testImageOverlay1.options.attribution) - .toEqual(layers[3].options.attribution); - }); - }); - }); - describe('adding and removing layers after initialization', () => { - let newGeoJsonMetadataVisible: dataTypes.ILayerMetadata; - let newGeoJsonMetadataInvisible: dataTypes.ILayerMetadata; - let newTileLayerVisible: dataTypes.ILayerMetadata; - let newTileLayerInvisible: dataTypes.ILayerMetadata; - let newImageOverlay: dataTypes.ILayerMetadata; - const newGeojsonFeatureVisible: geoJsonFeature = { - type: 'Feature', - properties: {}, - geometry: { - type: 'Point', - coordinates: [-104.99404, 39.75621], - }, - }; - const newGeojsonFeatureInvisible: geoJsonFeature = { - type: 'Feature', - properties: {}, - geometry: { - type: 'Point', - coordinates: [-104.99404, 39.1], - }, - }; - let layerReferences: ILayerReference; - let testAddLayerReference: dataTypes.ILeafletLayer; - beforeEach(() => { - newGeoJsonMetadataVisible = { - id: 'testNewGeoJsonLayerVisible', - label: 'testNewGeoJsonLayerVisible', - data: newGeojsonFeatureVisible, - options: { attribution: 'fjdskl' }, - }; - newGeoJsonMetadataInvisible = { - id: 'testNewGeoJsonLayerInvisible', - label: 'testNewGeoJsonLayerInvisible', - visibleInitially: false, - data: newGeojsonFeatureInvisible, - }; - newTileLayerVisible = { - id: 'testNewTileLayerVisible', - label: 'testNewTileLayerVisible', - url: 'www.testNewTileLayerVisibleUrl.com', - visibleInitially: true, - options: { - zIndex: 9, - }, - }; - newTileLayerInvisible = { - id: 'testNewTileLayerInvisible', - label: 'testNewTileLayerInvisible', - url: 'www.testNewTileLayerInvisibleUrl.com', - visibleInitially: false, - options: { maxZoom: 3}, - }; - newImageOverlay = { - id: 'testNewImageOverlay1', - label: 'testNewImageOverlay1', - visibleInitially: true, - url: 'url', - bounds: [[40.712216, -74.22655], [40.773941, -74.12544]], - options: {attribution: 'I\'m a test image overlay!'}, - }; - testAddLayerReference = declarativeLayers.addLayer(newGeoJsonMetadataVisible); - declarativeLayers.addLayer(newGeoJsonMetadataInvisible); - declarativeLayers.addLayer(newTileLayerVisible); - declarativeLayers.addLayer(newTileLayerInvisible); - declarativeLayers.addLayer(newImageOverlay); - layerReferences = declarativeLayers.getLayerReferences(); - }); - describe('adding layers to the map and references post inititialization', () => { - it('should add a new layer to the references regardless of if it tagged as visible', () => { - expect(layerReferences.testNewGeoJsonLayerVisible).toBeDefined(); - expect(layerReferences.testNewGeoJsonLayerInvisible).toBeDefined(); - expect(layerReferences.testNewTileLayerVisible).toBeDefined(); - expect(layerReferences.testNewTileLayerInvisible).toBeDefined(); - expect(layerReferences.testNewImageOverlay1).toBeDefined(); - }); - it('should add the new visibleInitially=true layers to the existing layers on the map', () => { - expect(map.addLayer).toHaveBeenCalledWith(layerReferences.testNewTileLayerVisible); - expect(map.addLayer).toHaveBeenCalledWith(layerReferences.testNewImageOverlay1); - }); - it('should add undefined visibleInitially layers to the existing layers on the map', () => { - expect(map.addLayer).toHaveBeenCalledWith(layerReferences.testNewGeoJsonLayerVisible); - }); - it('should NOT add a new layer with a false visible property to the map', () => { - expect(map.addLayer).not.toHaveBeenCalledWith(layerReferences.testNewGeoJsonLayerInvisible); - expect(map.addLayer).not.toHaveBeenCalledWith(layerReferences.testNewTileLayerInvisible); - }); - it('the addLayer function should return a reference to the added layer', () => { - expect(_.isEqual(testAddLayerReference, layerReferences.testNewGeoJsonLayerVisible)).toBeTruthy(); - }); - describe('including layer options', () => { - it('should pass on tileLayer options to the Leaflet layer', () => { - expect((layerReferences.testNewTileLayerVisible as leaflet.TileLayer).options.zIndex) - .toEqual((newTileLayerVisible as dataTypes.ITilesMetadata).options.zIndex); - expect((layerReferences.testNewTileLayerInvisible as leaflet.TileLayer).options.maxZoom) - .toEqual((newTileLayerInvisible as dataTypes.ITilesMetadata).options.maxZoom); - }); - it('should pass on GeoJSON options to the Leaflet layer', () => { - expect(layerReferences.testNewGeoJsonLayerVisible.options.attribution) - .toEqual(newGeoJsonMetadataVisible.options.attribution); - }); - // TODO explicit test for info win not conflicting with options - it ('should pass image overlay options to Leaflet', () => { - expect(declarativeLayers.getLayerReferences().testImageOverlay1.options.attribution) - .toEqual(layers[3].options.attribution); - }); - }); - }); - describe('removing layers from the map post inititialization', () => { - beforeEach(() => { - declarativeLayers.removeLayer(layerReferences.testNewGeoJsonLayerVisible); - - }); - it('should remove a layer from the map', () => { - expect(map.removeLayer).toHaveBeenCalledWith(layerReferences.testNewGeoJsonLayerVisible); - }); - it('the layer should still be available in the layer references', () => { - expect(layerReferences.testNewGeoJsonLayerVisible).toBeDefined(); - }); - }); - }); -}); + beforeEach((done) => { + testingOnEach = 0 + spyOn(leaflet.Layer.prototype, 'bindPopup') + initializateDeclarativeLayers() + done() + }) + describe('initialization', () => { + describe('visibleInitially property', () => { + it('adds visibleIntially=true to the map', () => { + expect(map.addLayer).toHaveBeenCalledWith(testTileLayer1) + }) + it('doesnt add visibleIntially=false to the map', () => { + expect(map.addLayer).not.toHaveBeenCalledWith(testTileLayer2) + }) + it('adds layers with no visibleInitially property set to the map by default', () => { + expect(map.addLayer).toHaveBeenCalledWith(testGeoJsonLayer1) + }) + }) + }) + describe('access to layers refrences', () => { + it('exposes references to added layers (visible or not)', () => { + expect( + Object.keys(declarativeLayers.getLayerReferences()).length, + ).toEqual(layers.length) + expect( + declarativeLayers.getLayerReferences().testTileLayer1, + ).toBeDefined() + expect( + declarativeLayers.getLayerReferences().testTileLayer2, + ).toBeDefined() + expect( + declarativeLayers.getLayerReferences().testGeoJsonLayer1, + ).toBeDefined() + expect( + declarativeLayers.getLayerReferences().testImageOverlay1, + ).toBeDefined() + }) + }) + describe('adding layers initially', () => { + it('shouldnt be called with undefined values', () => { + expect(map.addLayer).not.toHaveBeenCalledWith(undefined) + }) + describe('tile layers', () => { + it('loads tile layers', () => { + expect(map.addLayer).toHaveBeenCalledWith(testTileLayer1) + }) + it('passes the tile layer options', () => { + expect(testTileLayer1.options.zIndex).toEqual( + (layers[0] as dataTypes.ITilesMetadata).options.zIndex, + ) + expect(testTileLayer2.options.maxZoom).toBe( + (layers[1] as dataTypes.ITilesMetadata).options.maxZoom, + ) + }) + }) + describe('GeoJson layers', () => { + it('should load GeoJson Layers', () => { + expect(map.addLayer).toHaveBeenCalledWith( + declarativeLayers.getLayerReferences().testGeoJsonLayer1, + ) + }) + // TODO add test for options + describe('popups', () => { + const geoJsonMetadataWithPopup = layers[2] as dataTypes.IGeoJsonMetadata + it('should bind popups to a layer', () => { + expect(testGeoJsonLayer1.bindPopup).toHaveBeenCalledWith( + geojsonFeatureCollection.features[0].properties.popupContent, + ) + }) + it('shouldnt interfere with other options using onEachFeature', () => { + expect(testingOnEach).toEqual(2) + }) + }) + }) + describe('ImageOverlay Layers', () => { + it('should load image overlays', () => { + expect(map.addLayer).toHaveBeenCalledWith( + declarativeLayers.getLayerReferences().testImageOverlay1, + ) + }) + it('should pass image overlay options to Leaflet', () => { + expect( + declarativeLayers.getLayerReferences().testImageOverlay1.options + .attribution, + ).toEqual(layers[3].options.attribution) + }) + }) + }) + describe('adding and removing layers after initialization', () => { + let newGeoJsonMetadataVisible: dataTypes.ILayerMetadata + let newGeoJsonMetadataInvisible: dataTypes.ILayerMetadata + let newTileLayerVisible: dataTypes.ILayerMetadata + let newTileLayerInvisible: dataTypes.ILayerMetadata + let newImageOverlay: dataTypes.ILayerMetadata + const newGeojsonFeatureVisible: geoJsonFeature = { + type: 'Feature', + properties: {}, + geometry: { + type: 'Point', + coordinates: [-104.99404, 39.75621], + }, + } + const newGeojsonFeatureInvisible: geoJsonFeature = { + type: 'Feature', + properties: {}, + geometry: { + type: 'Point', + coordinates: [-104.99404, 39.1], + }, + } + let layerReferences: ILayerReference + let testAddLayerReference: dataTypes.ILeafletLayer + beforeEach(() => { + newGeoJsonMetadataVisible = { + id: 'testNewGeoJsonLayerVisible', + label: 'testNewGeoJsonLayerVisible', + data: newGeojsonFeatureVisible, + options: { attribution: 'fjdskl' }, + } + newGeoJsonMetadataInvisible = { + id: 'testNewGeoJsonLayerInvisible', + label: 'testNewGeoJsonLayerInvisible', + visibleInitially: false, + data: newGeojsonFeatureInvisible, + } + newTileLayerVisible = { + id: 'testNewTileLayerVisible', + label: 'testNewTileLayerVisible', + url: 'www.testNewTileLayerVisibleUrl.com', + visibleInitially: true, + options: { + zIndex: 9, + }, + } + newTileLayerInvisible = { + id: 'testNewTileLayerInvisible', + label: 'testNewTileLayerInvisible', + url: 'www.testNewTileLayerInvisibleUrl.com', + visibleInitially: false, + options: { maxZoom: 3 }, + } + newImageOverlay = { + id: 'testNewImageOverlay1', + label: 'testNewImageOverlay1', + visibleInitially: true, + url: 'url', + bounds: [ + [40.712216, -74.22655], + [40.773941, -74.12544], + ], + options: { attribution: "I'm a test image overlay!" }, + } + testAddLayerReference = declarativeLayers.addLayer( + newGeoJsonMetadataVisible, + ) + declarativeLayers.addLayer(newGeoJsonMetadataInvisible) + declarativeLayers.addLayer(newTileLayerVisible) + declarativeLayers.addLayer(newTileLayerInvisible) + declarativeLayers.addLayer(newImageOverlay) + layerReferences = declarativeLayers.getLayerReferences() + }) + describe('adding layers to the map and references post inititialization', () => { + it('should add a new layer to the references regardless of if it tagged as visible', () => { + expect(layerReferences.testNewGeoJsonLayerVisible).toBeDefined() + expect(layerReferences.testNewGeoJsonLayerInvisible).toBeDefined() + expect(layerReferences.testNewTileLayerVisible).toBeDefined() + expect(layerReferences.testNewTileLayerInvisible).toBeDefined() + expect(layerReferences.testNewImageOverlay1).toBeDefined() + }) + it('should add the new visibleInitially=true layers to the existing layers on the map', () => { + expect(map.addLayer).toHaveBeenCalledWith( + layerReferences.testNewTileLayerVisible, + ) + expect(map.addLayer).toHaveBeenCalledWith( + layerReferences.testNewImageOverlay1, + ) + }) + it('should add undefined visibleInitially layers to the existing layers on the map', () => { + expect(map.addLayer).toHaveBeenCalledWith( + layerReferences.testNewGeoJsonLayerVisible, + ) + }) + it('should NOT add a new layer with a false visible property to the map', () => { + expect(map.addLayer).not.toHaveBeenCalledWith( + layerReferences.testNewGeoJsonLayerInvisible, + ) + expect(map.addLayer).not.toHaveBeenCalledWith( + layerReferences.testNewTileLayerInvisible, + ) + }) + it('the addLayer function should return a reference to the added layer', () => { + expect( + _.isEqual( + testAddLayerReference, + layerReferences.testNewGeoJsonLayerVisible, + ), + ).toBeTruthy() + }) + describe('including layer options', () => { + it('should pass on tileLayer options to the Leaflet layer', () => { + expect( + (layerReferences.testNewTileLayerVisible as leaflet.TileLayer) + .options.zIndex, + ).toEqual( + (newTileLayerVisible as dataTypes.ITilesMetadata).options.zIndex, + ) + expect( + (layerReferences.testNewTileLayerInvisible as leaflet.TileLayer) + .options.maxZoom, + ).toEqual( + (newTileLayerInvisible as dataTypes.ITilesMetadata).options.maxZoom, + ) + }) + it('should pass on GeoJSON options to the Leaflet layer', () => { + expect( + layerReferences.testNewGeoJsonLayerVisible.options.attribution, + ).toEqual(newGeoJsonMetadataVisible.options.attribution) + }) + // TODO explicit test for info win not conflicting with options + it('should pass image overlay options to Leaflet', () => { + expect( + declarativeLayers.getLayerReferences().testImageOverlay1.options + .attribution, + ).toEqual(layers[3].options.attribution) + }) + }) + }) + describe('removing layers from the map post inititialization', () => { + beforeEach(() => { + declarativeLayers.removeLayer( + layerReferences.testNewGeoJsonLayerVisible, + ) + }) + it('should remove a layer from the map', () => { + expect(map.removeLayer).toHaveBeenCalledWith( + layerReferences.testNewGeoJsonLayerVisible, + ) + }) + it('the layer should still be available in the layer references', () => { + expect(layerReferences.testNewGeoJsonLayerVisible).toBeDefined() + }) + }) + }) +}) diff --git a/test/unitAndIntegration/toggleDeclarativeLayers.spec.ts b/test/unitAndIntegration/toggleDeclarativeLayers.spec.ts new file mode 100644 index 0000000..8dff406 --- /dev/null +++ b/test/unitAndIntegration/toggleDeclarativeLayers.spec.ts @@ -0,0 +1,123 @@ +import { Mock } from 'ts-mocks' +import * as leaflet from 'leaflet' +import * as dataTypes from '../../src/dataTypes' +import { DeclarativeLayers, ILayerReference } from '../../src/DeclarativeLayers' +import { + FeatureCollection as geoJsonFeatureCollection, + Feature as geoJsonFeature, +} from '../../node_modules/@types/geojson/index' +const geojsonFeatureCollection: geoJsonFeatureCollection = { + type: 'FeatureCollection', + features: [ + { + type: 'Feature', + properties: { + popupContent: '18th & California Light Rail Stop', + }, + geometry: { + type: 'Point', + coordinates: [-104.98999178409576, 39.74683938093904], + }, + }, + { + type: 'Feature', + properties: { + popupContent: '20th & Welton Light Rail Stop', + }, + geometry: { + type: 'Point', + coordinates: [-104.98689115047453, 39.747924136466565], + }, + }, + ], +} +const layers: dataTypes.ILayersMetadata = [ + { + id: 'testTileLayer1', + label: 'testTileLayer1', + url: 'www.testTileLayer1url.com', + visibleInitially: false, + }, + { + id: 'testGeoJsonLayer1', + label: 'testGeoJsonLayer1', + data: geojsonFeatureCollection, + visibleInitially: false, + }, + { + id: 'testImageOverlay1', + label: 'testImageOverlay1', + visibleInitially: false, + url: 'url', + bounds: [ + [40.712216, -74.22655], + [40.773941, -74.12544], + ], + }, +] + +let declarativeLayers: DeclarativeLayers +let testTileLayer1: leaflet.TileLayer +let testGeoJsonLayer1: leaflet.GeoJSON +let testImageOverlay: leaflet.ImageOverlay + +const initializateDeclarativeLayers = (mockMap) => { + declarativeLayers = new DeclarativeLayers(leaflet, mockMap, layers) + testTileLayer1 = declarativeLayers.getLayerReferences() + .testTileLayer1 as leaflet.TileLayer + testGeoJsonLayer1 = declarativeLayers.getLayerReferences() + .testGeoJsonLayer1 as leaflet.GeoJSON + testImageOverlay = declarativeLayers.getLayerReferences() + .testImageOverlay1 as leaflet.ImageOverlay +} +describe('toggling layers on and off with toggleLayer function', () => { + let layersForToggling: dataTypes.ILeafletLayer[] + + it('toggles layers on', () => { + const MockMap = new Mock({ + addLayer: Mock.ANY_FUNC, + removeLayer: Mock.ANY_FUNC, + hasLayer: () => { + return false + }, + }) + const map = MockMap.Object + + initializateDeclarativeLayers(map) + layersForToggling = [testTileLayer1, testGeoJsonLayer1, testImageOverlay] + expect(map.addLayer).toHaveBeenCalledTimes(0) // because visibleInitially set to false + + layersForToggling.forEach((layer) => { + declarativeLayers.toggleLayer(layer) + }) + + expect(map.addLayer).toHaveBeenCalledTimes(3) + expect(map.addLayer).toHaveBeenCalledWith(layersForToggling[0]) + expect(map.addLayer).toHaveBeenCalledWith(layersForToggling[1]) + expect(map.addLayer).toHaveBeenCalledWith(layersForToggling[2]) + }) + it('foodfsps', () => { + const MockMap = new Mock({ + addLayer: Mock.ANY_FUNC, + removeLayer: Mock.ANY_FUNC, + hasLayer: () => { + return true // the map pretends the layer exists already (Prob a less fragile way to do this, but I picked this WIP test up after 6 months and just want to get it done) + }, + }) + const map = MockMap.Object + + initializateDeclarativeLayers(map) + layersForToggling = [testTileLayer1, testGeoJsonLayer1, testImageOverlay] + expect(map.removeLayer).toHaveBeenCalledTimes(0) + + layersForToggling.forEach((layer) => { + declarativeLayers.toggleLayer(layer) + }) + + expect(map.removeLayer).toHaveBeenCalledTimes(3) + + expect(map.removeLayer).toHaveBeenCalledWith(layersForToggling[0]) + expect(map.removeLayer).toHaveBeenCalledWith(layersForToggling[1]) + expect(map.removeLayer).toHaveBeenCalledWith(layersForToggling[2]) + }) +}) diff --git a/test/unitAndIntegration/utilities.spec.ts b/test/unitAndIntegration/utilities.spec.ts index 338bce0..187ab62 100644 --- a/test/unitAndIntegration/utilities.spec.ts +++ b/test/unitAndIntegration/utilities.spec.ts @@ -1,15 +1,14 @@ -import {defaultBooleanToTrue} from '../../src/utilities' +import { defaultBooleanToTrue } from '../../src/utilities' describe('utilities module', () => { - describe('defaultToTrue fucntion', () => { - it('converts undefined to true', () => { - expect(defaultBooleanToTrue(undefined)).toEqual(true); - }) - it('retains false as false', () => { - expect(defaultBooleanToTrue(false)).toEqual(false); - }) - it('converts null to true', () => { - expect(defaultBooleanToTrue(null)).toEqual(true); - }) - + describe('defaultToTrue fucntion', () => { + it('converts undefined to true', () => { + expect(defaultBooleanToTrue(undefined)).toEqual(true) }) + it('retains false as false', () => { + expect(defaultBooleanToTrue(false)).toEqual(false) + }) + it('converts null to true', () => { + expect(defaultBooleanToTrue(null)).toEqual(true) + }) + }) }) diff --git a/tslint.json b/tslint.json index 8d1b7bd..7074f61 100644 --- a/tslint.json +++ b/tslint.json @@ -1,14 +1,8 @@ { - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": { - "ordered-imports": false, - "quotemark": [true, "single", "avoid-escape", "avoid-template"], - "object-literal-sort-keys": false, - "triple-equals": [true, "allow-undefined-check", "allow-null-check"] - }, - "rulesDirectory": [] -} \ No newline at end of file + "defaultSeverity": "error", + "extends": ["tslint:recommended", "tslint-config-prettier"], + "rules": { + "ordered-imports": false, + "object-literal-sort-keys": false + } +}