Merge develop

This commit is contained in:
Pieter Vander Vennet 2023-05-16 03:30:00 +02:00
commit 5904142402
13 changed files with 80 additions and 40 deletions

View file

@ -243,7 +243,9 @@ export class And extends TagsFilter {
properties[opt.key] = opt.value
}
}
for (const opt of optimized) {
for (let i = 0; i < optimized.length; i++){
const opt = optimized[i];
if (opt instanceof Tag) {
const k = opt.key
const v = properties[k]
@ -264,7 +266,23 @@ export class And extends TagsFilter {
if (v === undefined) {
continue
}
if (v !== opt.value) {
if(opt.invert){
// We should _not_ match this value
// If 'v' is given, we already know what value it should be
// If 'v' is the not-expected value, we have a conflict and return false
// Otherwise, we can safely drop this value
const doesMatch = (typeof opt.value === "string" && v === opt.value) ||
(v.match(<RegExp> opt.value) !== null)
if(doesMatch){
// We have a conflict as 'opt' is inverted
return false
}else{
optimized.splice(i, 1)
i--
}
}else if (v !== opt.value) {
// detected an internal conflict
return false
}

View file

@ -55,7 +55,9 @@ export default class SourceConfig {
throw (
"Error at " +
context +
": the specified tags are conflicting with each other: they will never match anything at all"
": the specified tags are conflicting with each other: they will never match anything at all.\n" +
"\tThe offending tags are: "+params.osmTags.asHumanString(false, false, {})+
"\tThey optmize into 'false' "
)
}
if (optimized === true) {

View file

@ -233,7 +233,7 @@
{
"if": "amenity=cafe",
"then": {
"en": "A <b>cafe</b> to drink tea, coffee or an alcoholical bevarage in a quiet environment",
"en": "A <b>cafe</b> to drink tea, coffee or an alcoholic beverage in a quiet environment",
"nl": "Dit is een <b>cafe</b> - een plaats waar men rustig kan zitten om een thee, koffie of alcoholische drank te nuttigen.",
"de": "Ein <b>Café</b>, um in ruhiger Umgebung Tee, Kaffee oder ein alkoholisches Getränk zu trinken",
"da": "En <b>café</b> til at drikke te, kaffe eller en alkoholisk drik i rolige omgivelser",
@ -245,7 +245,7 @@
{
"if": "amenity=restaurant",
"then": {
"en": "A <b>restuarant</b> where one can get a proper meal",
"en": "A <b>restaurant</b> where one can get a proper meal",
"nl": "Dit is een <b>restaurant</b> waar men een maaltijd geserveerd krijgt",
"de": "Ein <b>Restaurant</b>, in dem man ordentlich essen kann",
"da": "En <b>restaurant</b>, hvor man kan få et ordentligt måltid",
@ -369,4 +369,4 @@
"fr": "Une couche montrants les cafés et pubs où lon peut prendre un verre. Cette couche pose des questions y afférentes.",
"ca": "Una capa que mostra cafeteries i bars on un es pot reunir amb una beguda. La capa demana algunes preguntes rellevants"
}
}
}

View file

@ -4699,12 +4699,12 @@
"socket:typee=1"
],
"title": {
"en": "a charging station for electrical bikes with a normal european wall plug <img src='./assets/layers/charging_station/typee.svg' style='width: 2rem; height: 2rem; float: left; background: white; border-radius: 1rem; margin-right: 0.5rem'/> (meant to charge electrical bikes)",
"nl": "een oplaadpunt voor elektrische fietsen met een gewoon Europees stopcontact <img src='./assets/layers/charging_station/typee.svg' style='width: 2rem; height: 2rem; float: left; background: white; border-radius: 1rem; margin-right: 0.5rem'/> (speciaal bedoeld voor fietsen)",
"ca": "una estació de càrrega per a bicicletes elèctriques amb un endoll de paret europeu normal<img src='./assets/layers/charging_station/typee.svg' style='width: 2rem; height: 2rem; float: left; background: white; border-radius: 1rem; margin-right: 0.5rem'/> (destinat a carregar bicicletes elèctriques)",
"da": "en ladestation til elektriske cykler med et normalt europæisk vægstik <img src='./assets/layers/charging_station/typee.svg' style='width: 2rem; height: 2rem; float: left; background: white; border-radius: 1rem; margin-right: 0.5rem'/> (beregnet til opladning af elektriske cykler)",
"de": "eine Ladestation für Elektrofahrräder mit einer normalen europäischen Steckdose <img src='./assets/layers/charging_station/typee.svg' style='width: 2rem; height: 2rem; float: left; background: white; border-radius: 1rem; margin-right: 0.5rem'/> (zum Laden von Elektrofahrrädern)",
"es": "una estación de carga para bicicletas eléctricas con un enchufe de pared europeo normal <img src='./assets/layers/charging_station/typee.svg' style='width: 2rem; height: 2rem; float: left; background: white; border-radius: 1rem; margin-right: 0.5rem'/> (pensado para cargar bicicletas eléctricas)"
"en": "a charging station for electrical bikes with a normal european wall plug <img src='./assets/layers/charging_station/TypeE.svg' class=\"w-6 h-6 mx-1 bg-white rounded-full \" style='display: inline-block'/>",
"nl": "een oplaadpunt voor elektrische fietsen met een gewoon Europees stopcontact <img src='./assets/layers/charging_station/TypeE.svg' class=\"w-6 h-6 mx-1 bg-white rounded-full\" style='display: inline-block'/>",
"ca": "una estació de càrrega per a bicicletes elèctriques amb un endoll de paret europeu normal <img src='./assets/layers/charging_station/TypeE.svg' class=\"w-6 h-6 mx-1 bg-white rounded-full\" style='display: inline-block'/>",
"da": "en ladestation til elektriske cykler med et normalt europæisk vægstik <img src='./assets/layers/charging_station/TypeE.svg' class=\"w-6 h-6 mx-1 bg-white rounded-full\" style='display: inline-block'/>",
"de": "eine Ladestation für Elektrofahrräder mit einer normalen europäischen Steckdose <img src='./assets/layers/charging_station/TypeE.svg' class=\"w-6 h-6 mx-1 bg-white rounded-full\" style='display: inline-block'/>",
"es": "una estación de carga para bicicletas eléctricas con un enchufe de pared europeo normal <img src='./assets/layers/charging_station/TypeE.svg' class=\"w-6 h-6 mx-1 bg-white rounded-full\" style='display: inline-block'/>"
},
"preciseInput": {
"preferredBackground": "map"

View file

@ -800,8 +800,8 @@
"socket:typee=1"
],
"title": {
"en": "charging station for electrical bikes with a normal european wall plug <img src='./assets/layers/charging_station/TypeE.svg' style='width: 2rem; height: 2rem; float: left; background: white; border-radius: 1rem; margin-right: 0.5rem'/> (meant to charge electrical bikes)",
"nl": "oplaadpunt voor elektrische fietsen"
"en": "charging station for electrical bikes with a normal european wall plug <img src='./assets/layers/charging_station/TypeE.svg' class="w-4 h-4 mx-1 bg-white rounded-full"/>",
"nl": "oplaadpunt voor elektrische fietsen met een gewone, europese stekker <img src='./assets/layers/charging_station/TypeE.svg' class="w-4 h-4 mx-1 bg-white rounded-full"/>"
},
"preciseInput": {
"preferredBackground": "map"

View file

@ -16,7 +16,8 @@
"source": {
"osmTags": {
"and": [
"shop~*"
"shop~*",
"shop!=mall"
]
}
},

View file

@ -460,7 +460,8 @@
"fr": "Méthode de montage : {camera:mount}",
"it": "Metodo di montaggio: {camera:mount}",
"de": "Montageart: {camera:mount}",
"da": "Monteringsmetode: {camera:mount}"
"da": "Monteringsmetode: {camera:mount}",
"ca": "Mètode de muntatge: {camera:mount}"
},
"freeform": {
"key": "camera:mount"

View file

@ -4964,7 +4964,8 @@
"then": "Aquesta càmera està posicionada a un arbre"
}
},
"question": "Com està posicionada aquesta càmera?"
"question": "Com està posicionada aquesta càmera?",
"render": "Mètode de muntatge: {camera:mount}"
},
"camera_direction": {
"question": "En quina direcció geogràfica apunta aquesta càmera?",

View file

@ -1,6 +1,6 @@
{
"name": "mapcomplete",
"version": "0.30.5",
"version": "0.30.6",
"repository": "https://github.com/pietervdvn/MapComplete",
"description": "A small website to edit OSM easily",
"bugs": "https://github.com/pietervdvn/MapComplete/issues",

View file

@ -1117,10 +1117,6 @@ video {
width: 2.75rem;
}
.w-24 {
width: 6rem;
}
.w-1\/2 {
width: 50%;
}
@ -1134,6 +1130,10 @@ video {
width: 24rem;
}
.w-24 {
width: 6rem;
}
.w-10 {
width: 2.5rem;
}

View file

@ -7,8 +7,8 @@ import { describe, it } from "vitest"
* @param reason
* @private
*/
function detectInCode(forbidden: string, reason: string): (done: () => void) => void {
return (done: () => void) => {
function detectInCode(forbidden: string, reason: string): Promise<void> {
return new Promise<void>((done) => {
const excludedDirs = [
".git",
"node_modules",
@ -49,14 +49,23 @@ function detectInCode(forbidden: string, reason: string): (done: () => void) =>
console.error(found.length, "issues found")
throw msg
}
done()
}
)
}
})
}
function wrap(promise: Promise<void>): ((done: () => void) => void) {
return (done => {
promise.then(done)
})
}
function itAsync(name: string, promise: Promise<void>){
it(name, wrap(promise))
}
describe("Code quality", () => {
it(
itAsync(
"should not contain reverse",
detectInCode(
"reverse()",
@ -64,12 +73,12 @@ describe("Code quality", () => {
)
)
it(
itAsync(
"should not contain 'constructor.name'",
detectInCode("constructor\\.name", "This is not allowed, as minification does erase names.")
)
it(
itAsync(
"should not contain 'innerText'",
detectInCode(
"innerText",
@ -77,7 +86,7 @@ describe("Code quality", () => {
)
)
it(
itAsync(
"should not contain 'import * as name from \"xyz.json\"'",
detectInCode(
'import \\* as [a-zA-Z0-9_]\\+ from \\"[.-_/a-zA-Z0-9]\\+\\.json\\"',
@ -85,7 +94,7 @@ describe("Code quality", () => {
)
)
it(
itAsync(
"should not contain '[\"default\"]'",
detectInCode('\\[\\"default\\"\\]', "Possible leftover of faulty default import")
)

View file

@ -1,10 +1,10 @@
import { TagsFilter } from "../../../Logic/Tags/TagsFilter"
import { And } from "../../../Logic/Tags/And"
import { Tag } from "../../../Logic/Tags/Tag"
import { TagUtils } from "../../../Logic/Tags/TagUtils"
import { Or } from "../../../Logic/Tags/Or"
import { RegexTag } from "../../../Logic/Tags/RegexTag"
import { describe, expect, it } from "vitest"
import {TagsFilter} from "../../../Logic/Tags/TagsFilter"
import {And} from "../../../Logic/Tags/And"
import {Tag} from "../../../Logic/Tags/Tag"
import {TagUtils} from "../../../Logic/Tags/TagUtils"
import {Or} from "../../../Logic/Tags/Or"
import {RegexTag} from "../../../Logic/Tags/RegexTag"
import {describe, expect, it} from "vitest"
describe("Tag optimalization", () => {
describe("And", () => {
@ -71,6 +71,14 @@ describe("Tag optimalization", () => {
expect(TagUtils.toString(opt)).toBe("amenity=binoculars&bicycle=yes")
})
it("should correctly optimize key=A&key!=B into key=A", () => {
const t = new And([new Tag("shop", "sports"), new RegexTag("shop", "mall", true)])
const opt = t.optimize()
expect(typeof opt !== "boolean").true
expect(TagUtils.toString(<TagsFilter>opt)).toBe("shop=sports")
})
it("should optimize nested ORs", () => {
const filter = TagUtils.Tag({
or: [
@ -263,7 +271,7 @@ describe("Tag optimalization", () => {
or: [
"club=climbing",
{
and: ["sport=climbing", { or: ["club~*", "office~*"] }],
and: ["sport=climbing", {or: ["club~*", "office~*"]}],
},
{
and: [

View file

@ -6,6 +6,6 @@ export default defineConfig({
test: {
globals: true,
setupFiles: ["./test/testhooks.ts"],
include: ["./test", "./*.doctest.ts", "./**/*.doctest.ts"],
include: ["./test/*.spec.ts","./test/**/*.spec.ts", "./*.doctest.ts", "./**/*.doctest.ts"],
},
})