Add tests for tags, add check for duplicate names as layer ids, fix #393

This commit is contained in:
Pieter Vander Vennet 2021-07-12 11:44:55 +02:00
parent fa9313a3b7
commit 33e2dca7e4
7 changed files with 95 additions and 60 deletions

View file

@ -56,7 +56,6 @@ export class InitUiElements {
console.log("Using layout: ", layoutToUse.id, "LayoutFromBase64 is ", layoutFromBase64); console.log("Using layout: ", layoutToUse.id, "LayoutFromBase64 is ", layoutFromBase64);
State.state = new State(layoutToUse); State.state = new State(layoutToUse);
// This 'leaks' the global state via the window object, useful for debugging // This 'leaks' the global state via the window object, useful for debugging

View file

@ -23,9 +23,7 @@ export class Or extends TagsFilter {
const choices = []; const choices = [];
for (const tagsFilter of this.or) { for (const tagsFilter of this.or) {
const subChoices = tagsFilter.asOverpass(); const subChoices = tagsFilter.asOverpass();
for (const subChoice of subChoices) { choices.push(...subChoices)
choices.push(subChoice)
}
} }
return choices; return choices;
} }

View file

@ -34,9 +34,9 @@ export class RegexTag extends TagsFilter {
asOverpass(): string[] { asOverpass(): string[] {
if (typeof this.key === "string") { if (typeof this.key === "string") {
return [`['${this.key}'${this.invert ? "!" : ""}~'${RegexTag.source(this.value)}']`]; return [`["${this.key}"${this.invert ? "!" : ""}~"${RegexTag.source(this.value)}"]`];
} }
return [`[~'${this.key.source}'${this.invert ? "!" : ""}~'${RegexTag.source(this.value)}']`]; return [`[~"${this.key.source}"${this.invert ? "!" : ""}~"${RegexTag.source(this.value)}"]`];
} }
isUsableAsAnswer(): boolean { isUsableAsAnswer(): boolean {

View file

@ -10,11 +10,16 @@
{ {
"or": [ "or": [
"leisure=nature_reserve", "leisure=nature_reserve",
{
"and": [
"protect_class!=98",
"boundary=protected_area" "boundary=protected_area"
] ]
} }
] ]
} }
]
}
}, },
"title": { "title": {
"render": { "render": {

View file

@ -29,7 +29,7 @@
"socialImage": "./assets/themes/buurtnatuur/social_image.jpg", "socialImage": "./assets/themes/buurtnatuur/social_image.jpg",
"layers": [ "layers": [
{ {
"id": "nature_reserve", "id": "nature_reserve_buurtnatuur",
"name": { "name": {
"nl": "Natuurgebied" "nl": "Natuurgebied"
}, },
@ -141,7 +141,7 @@
} }
}, },
"calculatedTags": [ "calculatedTags": [
"_overlapWithUpperLayers=Math.max(...feat.overlapWith('nature_reserve').map(o => o.overlap))/feat.area", "_overlapWithUpperLayers=Math.max(...feat.overlapWith('nature_reserve_buurtnatuur').map(o => o.overlap))/feat.area",
"_tooMuchOverlap=Number(feat.properties._overlapWithUpperLayers) > 0.1 ? 'yes' :'no'" "_tooMuchOverlap=Number(feat.properties._overlapWithUpperLayers) > 0.1 ? 'yes' :'no'"
], ],
"isShown": { "isShown": {
@ -240,7 +240,7 @@
} }
}, },
"calculatedTags": [ "calculatedTags": [
"_overlapWithUpperLayers=Math.max(...feat.overlapWith('parks','nature_reserve').map(o => o.overlap))/feat.area", "_overlapWithUpperLayers=Math.max(...feat.overlapWith('parks','nature_reserve_buurtnatuur').map(o => o.overlap))/feat.area",
"_tooMuchOverlap=Number(feat.properties._overlapWithUpperLayers) > 0.1 ? 'yes' : 'no'" "_tooMuchOverlap=Number(feat.properties._overlapWithUpperLayers) > 0.1 ? 'yes' : 'no'"
], ],
"isShown": { "isShown": {

View file

@ -140,6 +140,7 @@ class LayerOverviewUtils {
const layerFiles = lt.layers; const layerFiles = lt.layers;
const themeFiles = lt.themes; const themeFiles = lt.themes;
console.log(" ---------- VALIDATING ---------") console.log(" ---------- VALIDATING ---------")
const licensePaths = [] const licensePaths = []
for (const i in licenses) { for (const i in licenses) {
@ -151,6 +152,9 @@ class LayerOverviewUtils {
const knownLayerIds = new Map<string, LayerConfig>(); const knownLayerIds = new Map<string, LayerConfig>();
for (const layerFile of layerFiles) { for (const layerFile of layerFiles) {
if (knownLayerIds.has(layerFile.parsed.id)) {
throw "Duplicate identifier: " + layerFile.parsed.id + " in file " + layerFile.path
}
layerErrorCount.push(...this.validateLayer(layerFile.parsed, layerFile.path, knownPaths)) layerErrorCount.push(...this.validateLayer(layerFile.parsed, layerFile.path, knownPaths))
knownLayerIds.set(layerFile.parsed.id, new LayerConfig(layerFile.parsed, AllKnownLayers.sharedUnits)) knownLayerIds.set(layerFile.parsed.id, new LayerConfig(layerFile.parsed, AllKnownLayers.sharedUnits))
} }
@ -170,9 +174,8 @@ class LayerOverviewUtils {
missingTranslations.push(...this.validateTranslationCompletenessOfObject(layerConfig, themeFile.language, "Layer " + layer)) missingTranslations.push(...this.validateTranslationCompletenessOfObject(layerConfig, themeFile.language, "Layer " + layer))
} }
} else { } else if (layer.builtin !== undefined) {
let names = layer.builtin; let names = layer.builtin;
if (names !== undefined) {
if (typeof names === "string") { if (typeof names === "string") {
names = [names] names = [names]
} }
@ -183,8 +186,9 @@ class LayerOverviewUtils {
return return
}) })
} else { } else {
// layer.builtin contains layer overrides - we can skip those
layerErrorCount.push(...this.validateLayer(layer, undefined, knownPaths, themeFile.id)) layerErrorCount.push(...this.validateLayer(layer, undefined, knownPaths, themeFile.id))
if (knownLayerIds.has(layer.id)) {
throw `The theme ${themeFile.id} defines a layer with id ${layer.id}, which is the same as an already existing layer`
} }
} }
} }

View file

@ -4,15 +4,12 @@ import T from "./TestHelper";
import {FromJSON} from "../Customizations/JSON/FromJSON"; import {FromJSON} from "../Customizations/JSON/FromJSON";
import Locale from "../UI/i18n/Locale"; import Locale from "../UI/i18n/Locale";
import Translations from "../UI/i18n/Translations"; import Translations from "../UI/i18n/Translations";
import {UIEventSource} from "../Logic/UIEventSource";
import TagRenderingConfig from "../Customizations/JSON/TagRenderingConfig"; import TagRenderingConfig from "../Customizations/JSON/TagRenderingConfig";
import EditableTagRendering from "../UI/Popup/EditableTagRendering";
import {Translation} from "../UI/i18n/Translation"; import {Translation} from "../UI/i18n/Translation";
import {OH, OpeningHour} from "../UI/OpeningHours/OpeningHours"; import {OH, OpeningHour} from "../UI/OpeningHours/OpeningHours";
import PublicHolidayInput from "../UI/OpeningHours/PublicHolidayInput";
import {SubstitutedTranslation} from "../UI/SubstitutedTranslation";
import {Tag} from "../Logic/Tags/Tag"; import {Tag} from "../Logic/Tags/Tag";
import {And} from "../Logic/Tags/And"; import {And} from "../Logic/Tags/And";
import {Overpass} from "../Logic/Osm/Overpass";
Utils.runningFromConsole = true; Utils.runningFromConsole = true;
@ -161,6 +158,38 @@ export default class TagSpec extends T{
equal(false, t.matchesProperties({"key": "somevalue"})) equal(false, t.matchesProperties({"key": "somevalue"}))
} }
], ],
[
"Test not with overpass",
() => {
const t = {
and: [
"boundary=protected_area",
"protect_class!=98"
]
}
const filter = FromJSON.Tag(t)
const overpass = filter.asOverpass();
console.log(overpass)
equal(overpass[0], "[\"boundary\"=\"protected_area\"][\"protect_class\"!~\"^98$\"]")
const or = {
or: [
"leisure=nature_reserve",
t
]
}
const overpassOr = FromJSON.Tag(or).asOverpass()
equal(2, overpassOr.length)
equal(overpassOr[1], "[\"boundary\"=\"protected_area\"][\"protect_class\"!~\"^98$\"]")
const orInOr = {or:[
"amenity=drinking_water",
or
]}
const overpassOrInor = FromJSON.Tag(orInOr).asOverpass()
equal(3, overpassOrInor.length)
}
],
[ [
"Tagrendering test", "Tagrendering test",
() => { () => {