nakarte

Source code of https://map.sikmir.ru (fork)
git clone git://git.sikmir.ru/nakarte
Log | Files | Refs | LICENSE

commit 792c7d4702b7ac6b28f4b9ccd7a447130fef62f4
parent b861dfa0585a1542102273ce62120adf297ce78b
Author: Sergej Orlov <wladimirych@gmail.com>
Date:   Sat, 21 Dec 2019 21:04:12 +0300

tests: create tests for layers, remove checks from layers.js

Diffstat:
Msrc/App.js | 2+-
Msrc/layers.js | 90++++++-------------------------------------------------------------------------
Atest/test_layers.js | 125+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 132 insertions(+), 85 deletions(-)

diff --git a/src/App.js b/src/App.js @@ -20,7 +20,7 @@ import enableLayersControlAdaptiveHeight from '~/lib/leaflet.control.layers.adap import enableLayersMinimize from '~/lib/leaflet.control.layers.minimize'; import enableLayersConfig from '~/lib/leaflet.control.layers.configure'; import raiseControlsOnFocus from '~/lib/leaflet.controls.raise-on-focus'; -import getLayers from './layers'; +import {getLayers} from './layers'; import '~/lib/leaflet.control.layers.events'; import '~/lib/leaflet.control.jnx'; import '~/lib/leaflet.control.jnx/hash-state'; diff --git a/src/layers.js b/src/layers.js @@ -10,8 +10,7 @@ import '~/lib/leaflet.layer.wikimapia'; import {GeocachingSu} from '~/lib/leaflet.layer.geocaching-su'; import {StravaHeatmap} from '~/lib/leaflet.layer.strava-heatmap'; -export default function getLayers() { - const layers = [ + const layersDefs = [ { title: 'OpenStreetMap', description: 'OSM default style', @@ -1112,8 +1111,9 @@ export default function getLayers() { 'geocaching.su', ]; +function getLayers() { // set metadata - for (let layer of layers) { + for (let layer of layersDefs) { layer.layer.meta = {title: layer.title}; } @@ -1124,7 +1124,7 @@ export default function getLayers() { orderByTitle[title] = i + 1; } - for (let layer of layers) { + for (let layer of layersDefs) { const title = layer.title; layer.order = orderByTitle[title]; if (!layer.order) { @@ -1135,7 +1135,7 @@ export default function getLayers() { // divide layers by groups const grouppedLayers = []; const layersByTitle = {}; - for (let layer of layers) { + for (let layer of layersDefs) { layersByTitle[layer.title] = layer; } for (let groupDef of groupsDefs) { @@ -1143,89 +1143,10 @@ export default function getLayers() { grouppedLayers.push(group); for (let title of groupDef.layers) { let layer = layersByTitle[title]; - if (!layer) { - throw new Error(`Unknown layer in groups definitions: ${title}`); - } group.layers.push(layer); } } - // TODO: move it to tests - const codes = new Set(); - const titles = new Set(); - const shortNames = new Set(); - for (let layer of layers) { - const {title, layer: {options}} = layer; - if (!options) { - throw new Error(`Layer without options: ${layer.title}`); - } - if (titles.has(title)) { - throw new Error(`Duplicate layer title "${title}"`); - } - titles.add(title); - const { - code, - shortName, - print, - isOverlay, - isOverlayTransparent - } = options; - if (!code) { - throw new Error('Layer without code: ' + layer.title); - } - if (codes.has(code)) { - throw new Error(`Duplicate layer code "${code}"`); - } - codes.add(code); - - if (print) { - if (isOverlay && (isOverlayTransparent === undefined)) { - throw new Error('Overlay layer without isOverlayTransparent: ' + layer.title); - } - if (!shortName) { - throw new Error('Layer without shortName: ' + layer.title); - } - if (shortNames.has(shortName)) { - throw new Error(`Duplicate layer shortName: "${shortName}"`); - } - shortNames.add(shortName); - } - } - - // check order definition - let seenOverlay = false; - for (let title of titlesByOrder) { - if (title[0] !== '#') { - if (!titles.has(title)) { - throw new Error(`Unknown layer title in order list: ${title}`); - } - let isOverlay = layersByTitle[title]; - if (isOverlay) { - seenOverlay = true; - } else { - if (seenOverlay) { - throw new Error(`Base layer after overlays: ${title}`); - } - } - } - } - // check groups definitions - const seenLayerTitles = new Set(); - for (let group of groupsDefs) { - for (let title of group.layers) { - if (seenLayerTitles.has(title)) { - throw new Error(`Duplicate layer in groups definition: ${title}`); - } - seenLayerTitles.add(title); - } - } - // unknown layers in groupsDefs already checked, check only that all layers assigned to groups - for (let title of titles) { - if (!seenLayerTitles.has(title)) { - throw new Error(`Layer not assigned to any group: ${title}`); - } - } - return { layers: grouppedLayers, customLayersOrder: { @@ -1235,3 +1156,4 @@ export default function getLayers() { }}; } +export {getLayers, layersDefs, groupsDefs, titlesByOrder}; diff --git a/test/test_layers.js b/test/test_layers.js @@ -0,0 +1,125 @@ +import {layersDefs, groupsDefs, titlesByOrder} from '~/layers'; + +suite('layers definitions'); + +layersDefs.forEach(function(layerDef) { + test(`layer properties ${layerDef.title}`, function() { + assert.isString(layerDef.title, 'title defined'); + assert.isNotEmpty(layerDef.title, 'title not empty'); + assert.oneOf(typeof layerDef.description, ['undefined', 'string'], 'description undefined or string'); + if (typeof layerDef.description == 'string') { + assert.isNotEmpty(layerDef.description); + } + assert.oneOf(layerDef.isDefault, [true, false], 'isDefault'); + assert.isObject(layerDef.layer, 'layer'); + + const options = layerDef.layer.options; + assert.isObject(layerDef.layer.options, 'options'); + assert.isString(options.code, 'options.code'); + assert.isNotEmpty(options.code, 'options.code'); + assert.oneOf(options.isOverlay, [true, false], 'isOverlay'); + if (options.isOverlay && options.print) { + assert.oneOf(options.isOverlayTransparent, [true, false], 'isOverlayTransparent'); + } + assert.oneOf(options.print, [true, false], 'print'); + if (options.print) { + assert.oneOf(options.scaleDependent, [true, false], 'scaleDependent'); + assert.isString(options.shortName, 'shortName'); + assert.isNotEmpty(options.shortName, 'shortName'); + } + assert.oneOf(options.jnx, [true, false], 'jnx'); + assert.oneOf(options.noCors, [true, false, undefined], 'noCors'); + }); +}); + +test('Layers titles unique', function() { + const seen = new Set(); + const duplicates = new Set(); + for (let layerDef of layersDefs) { + const name = layerDef.title; + if (seen.has(name)) { + duplicates.add(name); + } + seen.add(name); + } + assert.isEmpty(Array.from(duplicates), 'duplicate layers'); +}); + +test('Layers codes unique', function() { + const seen = new Set(); + const duplicates = new Set(); + for (let layerDef of layersDefs) { + const code = layerDef.layer.options.code; + if (seen.has(code)) { + duplicates.add(code); + } + seen.add(code); + } + assert.isEmpty(Array.from(duplicates), 'duplicate codes'); +}); + +test('Layers short names unique', function() { + const seen = new Set(); + const duplicates = new Set(); + for (let layerDef of layersDefs) { + if (!layerDef.layer.options.print) { + continue; + } + const shortName = layerDef.layer.options.shortName; + if (seen.has(shortName)) { + duplicates.add(shortName); + } + seen.add(shortName); + } + assert.isEmpty(Array.from(duplicates), 'duplicate short names'); +}); + +suite('Layers groups definitions'); + +test('Groups valid', function() { + for (let groupDef of groupsDefs) { + assert.isString(groupDef.title); + assert.isNotEmpty(groupDef.title); + assert.isNotEmpty(groupDef.layers); + } +}); + +test('groupsDefs contains same layers as layersDefs', function() { + const layersInLayersDefs = layersDefs.map((layerDef) => layerDef.title); + const layersInGroupsDefs = groupsDefs.map((groupDef) => groupDef.layers).flat(); + assert.deepEqual(layersInGroupsDefs.sort(), layersInLayersDefs.sort()); +}); + +suite('Layers order definitions'); + +test('titlesByOrder has same layers as layersDef', function() { + const layersInLayersDefs = layersDefs.map((layerDef) => layerDef.title); + const layersInTitlesByOrder = titlesByOrder.filter((layerName) => layerName[0] !== '#'); + assert.deepEqual(layersInLayersDefs.sort(), layersInTitlesByOrder.sort()); +}); + +test('All baselayers ordered before overlays', function() { + let seenOverlay = false; + let outOfOrder = []; + for (let layerName of titlesByOrder) { + if (layerName[0] === '#') { + continue; + } + let layerDef = layersDefs.filter((layerDef) => layerDef.title === layerName)[0]; + let isOverlay = layerDef.layer.options.isOverlay; + if (seenOverlay && !isOverlay) { + outOfOrder.push(layerName); + } + seenOverlay |= isOverlay; + } + assert.isEmpty(outOfOrder); +}); + +test('Order contains markers for custom layers in right order', function() { + assert.include(titlesByOrder, '#custom-top'); + assert.include(titlesByOrder, '#custom-bottom'); + const customTopOrder = titlesByOrder.indexOf('#custom-top'); + const customBottomOrder = titlesByOrder.indexOf('#custom-bottom'); + assert.isAbove(customTopOrder, customBottomOrder); + +});