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:
M | src/App.js | | | 2 | +- |
M | src/layers.js | | | 90 | ++++++------------------------------------------------------------------------- |
A | test/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);
+
+});