diff --git a/Logic/BBox.ts b/Logic/BBox.ts index aa8e69935..19e0bb876 100644 --- a/Logic/BBox.ts +++ b/Logic/BBox.ts @@ -64,6 +64,15 @@ export class BBox { return new BBox([[maxLon, maxLat], [minLon, minLat]]) } + /** + * Calculates the BBox based on a slippy map tile number + * + * const bbox = BBox.fromTile(16, 32754, 21785) + * bbox.minLon // => -0.076904296875 + * bbox.maxLon // => -0.0714111328125 + * bbox.minLat // => 51.5292513551899 + * bbox.maxLat // => 51.53266860674158 + */ static fromTile(z: number, x: number, y: number): BBox { return new BBox(Tiles.tile_bounds_lon_lat(z, x, y)) } diff --git a/Logic/GeoOperations.ts b/Logic/GeoOperations.ts index 9c0bad52c..8daf7fe37 100644 --- a/Logic/GeoOperations.ts +++ b/Logic/GeoOperations.ts @@ -50,6 +50,19 @@ export class GeoOperations { * * If 'feature' is a point, it will return every feature the point is embedded in. Overlap will be undefined * + * const polygon = {"type": "Feature","properties": {},"geometry": {"type": "Polygon","coordinates": [[[1.8017578124999998,50.401515322782366],[-3.1640625,46.255846818480315],[5.185546875,44.74673324024678],[1.8017578124999998,50.401515322782366]]]}}; + * const point = {"type": "Feature", "properties": {}, "geometry": { "type": "Point", "coordinates": [2.274169921875, 46.76244305208004]}}; + * const overlap = GeoOperations.calculateOverlap(point, [polygon]); + * overlap.length // => 1 + * overlap[0].feat == polygon // => true + * const line = {"type": "Feature","properties": {},"geometry": {"type": "LineString","coordinates": [[3.779296875,48.777912755501845],[1.23046875,47.60616304386874]]}}; + * const lineOverlap = GeoOperations.calculateOverlap(line, [polygon]); + * lineOverlap.length // => 1 + * lineOverlap[0].overlap // => 156745.3293320278 + * lineOverlap[0].feat == polygon // => true + * const line0 = {"type": "Feature","properties": {},"geometry": {"type": "LineString","coordinates": [[0.0439453125,47.31648293428332],[0.6591796875,46.77749276376827]]}}; + * const overlap0 = GeoOperations.calculateOverlap(line0, [polygon]); + * overlap.length // => 1 */ static calculateOverlap(feature: any, otherFeatures: any[]): { feat: any, overlap: number }[] { @@ -138,6 +151,28 @@ export class GeoOperations { return true; } + /** + * Detect wether or not the given point is located in the feature + * + * // Should work with a normal polygon + * const polygon = {"type": "Feature","properties": {},"geometry": {"type": "Polygon","coordinates": [[[1.8017578124999998,50.401515322782366],[-3.1640625,46.255846818480315],[5.185546875,44.74673324024678],[1.8017578124999998,50.401515322782366]]]}}; + * GeoOperations.inside([3.779296875, 48.777912755501845], polygon) // => false + * GeoOperations.inside([1.23046875, 47.60616304386874], polygon) // => true + * + * // should work with a multipolygon and detect holes + * const multiPolygon = {"type": "Feature", "properties": {}, + * "geometry": { + * "type": "MultiPolygon", + * "coordinates": [[ + * [[1.8017578124999998,50.401515322782366],[-3.1640625,46.255846818480315],[5.185546875,44.74673324024678],[1.8017578124999998,50.401515322782366]], + * [[1.0107421875,48.821332549646634],[1.329345703125,48.25394114463431],[1.988525390625,48.71271258145237],[0.999755859375,48.86471476180277],[1.0107421875,48.821332549646634]] + * ]] + * } + * }; + * GeoOperations.inside([2.515869140625, 47.37603463349758], multiPolygon) // => true + * GeoOperations.inside([1.42822265625, 48.61838518688487], multiPolygon) // => false + * GeoOperations.inside([4.02099609375, 47.81315451752768], multiPolygon) // => false + */ public static inside(pointCoordinate, feature): boolean { // ray-casting algorithm based on // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html diff --git a/Logic/UIEventSource.ts b/Logic/UIEventSource.ts index fad6e0737..31c9585b0 100644 --- a/Logic/UIEventSource.ts +++ b/Logic/UIEventSource.ts @@ -158,10 +158,11 @@ export class UIEventSource { ) } - public AsPromise(): Promise { + public AsPromise(condition?: ((t: T )=> boolean)): Promise { const self = this; + condition = condition ?? (t => t !== undefined) return new Promise((resolve, reject) => { - if (self.data !== undefined) { + if (condition(self.data)) { resolve(self.data) } else { self.addCallbackD(data => { diff --git a/Models/ThemeConfig/Conversion/FixImages.ts b/Models/ThemeConfig/Conversion/FixImages.ts index 4a3e70e63..191de56e6 100644 --- a/Models/ThemeConfig/Conversion/FixImages.ts +++ b/Models/ThemeConfig/Conversion/FixImages.ts @@ -28,6 +28,9 @@ export class ExtractImages extends Conversion { t["$ref"] == "#/definitions/TagRenderingConfigJson" || t["$ref"] == "#/definitions/QuestionableTagRenderingConfigJson") } + /** + * + */ convert(json: LayoutConfigJson, context: string): { result: string[], errors: string[], warnings: string[] } { const allFoundImages : string[] = [] const errors = [] @@ -116,6 +119,40 @@ export class FixImages extends DesugaringStep { this._knownImages = knownImages; } + /** + * If the id is an URL to a json file, replaces "./" in images with the path to the json file + * + * const theme = { + * "id": "https://raw.githubusercontent.com/seppesantens/MapComplete-Themes/main/VerkeerdeBordenDatabank/verkeerdeborden.json" + * "layers": [ + * { + * "mapRendering": [ + * { + * "icon": "./TS_bolt.svg", + * iconBadges: [{ + * if: "id=yes", + * then: { + * mappings: [ + * { + * if: "id=yes", + * then: "./Something.svg" + * } + * ] + * } + * }], + * "location": [ + * "point", + * "centroid" + * ] + * } + * ] + * } + * ], + * } + * const fixed = new FixImages(new Set()).convert( theme, "test").result + * fixed.layers[0]["mapRendering"][0].icon // => "https://raw.githubusercontent.com/seppesantens/MapComplete-Themes/main/VerkeerdeBordenDatabank/TS_bolt.svg" + * fixed.layers[0]["mapRendering"][0].iconBadges[0].then.mappings[0].then // => "https://raw.githubusercontent.com/seppesantens/MapComplete-Themes/main/VerkeerdeBordenDatabank/Something.svg" + */ convert(json: LayoutConfigJson, context: string): { result: LayoutConfigJson, warnings?: string[] } { let url: URL; try { diff --git a/Models/ThemeConfig/Conversion/PrepareTheme.ts b/Models/ThemeConfig/Conversion/PrepareTheme.ts index fb6f72be4..7d2025db0 100644 --- a/Models/ThemeConfig/Conversion/PrepareTheme.ts +++ b/Models/ThemeConfig/Conversion/PrepareTheme.ts @@ -230,6 +230,16 @@ export class AddMiniMap extends DesugaringStep { /** * Returns true if this tag rendering has a minimap in some language. * Note: this minimap can be hidden by conditions + * + * AddMiniMap.hasMinimap({render: "{minimap()}"}) // => true + * AddMiniMap.hasMinimap({render: {en: "{minimap()}"}}) // => true + * AddMiniMap.hasMinimap({render: {en: "{minimap()}", nl: "{minimap()}"}}) // => true + * AddMiniMap.hasMinimap({render: {en: "{minimap()}", nl: "No map for the dutch!"}}) // => true + * AddMiniMap.hasMinimap({render: "{minimap()}"}) // => true + * AddMiniMap.hasMinimap({render: "{minimap(18,featurelist)}"}) // => true + * AddMiniMap.hasMinimap({mappings: [{if: "xyz=abc",then: "{minimap(18,featurelist)}"}]}) // => true + * AddMiniMap.hasMinimap({render: "Some random value {key}"}) // => false + * AddMiniMap.hasMinimap({render: "Some random value {minimap}"}) // => false */ static hasMinimap(renderingConfig: TagRenderingConfigJson): boolean { const translations: any[] = Utils.NoNull([renderingConfig.render, ...(renderingConfig.mappings ?? []).map(m => m.then)]); diff --git a/Models/ThemeConfig/Conversion/Validation.ts b/Models/ThemeConfig/Conversion/Validation.ts index ef02ba211..d0e19329b 100644 --- a/Models/ThemeConfig/Conversion/Validation.ts +++ b/Models/ThemeConfig/Conversion/Validation.ts @@ -250,7 +250,8 @@ export class DetectShadowedMappings extends DesugaringStep ["_abc"] * DetectShadowedMappings.extractCalculatedTagNames({calculatedTags: ["_abc=js()"]}) // => ["_abc"] */ - private static extractCalculatedTagNames(layerConfig?: LayerConfigJson){ + public static extractCalculatedTagNames(layerConfig?: LayerConfigJson | {calculatedTags : string []}){ + // TODO make private again when doctests support this return layerConfig?.calculatedTags?.map(ct => { if(ct.indexOf(':=') >= 0){ return ct.split(':=')[0] @@ -260,6 +261,39 @@ export class DetectShadowedMappings extends DesugaringStep 1 + * r.errors[0].indexOf("The mapping key=value is fully matched by a previous mapping (namely 0)") >= 0 // => true + * + * const tr = {mappings: [ + * { + * if: {or: ["key=value", "x=y"]}, + * then: "Case A" + * }, + * { + * if: {and: ["key=value", "x=y"]}, + * then: "Shadowed" + * } + * ] + * } + * const r = new DetectShadowedMappings().convert(tr, "test"); + * r.errors.length // => 1 + * r.errors[0].indexOf("The mapping key=value&x=y is fully matched by a previous mapping (namely 0)") >= 0 // => true + */ convert(json: QuestionableTagRenderingConfigJson, context: string): { result: QuestionableTagRenderingConfigJson; errors?: string[]; warnings?: string[] } { const errors = [] const warnings = [] @@ -324,6 +358,26 @@ export class DetectMappingsWithImages extends DesugaringStep", + * "nl": "Nietjes ", + * "fr": "Arceaux ", + * "gl": "De roda (Stands) ", + * "de": "Fahrradbügel ", + * "hu": "Korlát ", + * "it": "Archetti ", + * "zh_Hant": "單車架 " + * } + * }] + * }, "test"); + * r.errors.length > 0 // => true + * r.errors.some(msg => msg.indexOf("./assets/layers/bike_parking/staple.svg") >= 0) // => true + */ convert(json: TagRenderingConfigJson, context: string): { result: TagRenderingConfigJson; errors?: string[]; warnings?: string[], information?: string[] } { const errors = [] const warnings = [] diff --git a/Utils.ts b/Utils.ts index 29d9e9f3e..43f891c0e 100644 --- a/Utils.ts +++ b/Utils.ts @@ -883,7 +883,15 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be b: parseInt(hex.substr(5, 2), 16), } } + + public static asDict(tags: {key: string, value: string | number}[]) : Map{ + const d= new Map() + for (const tag of tags) { + d.set(tag.key, tag.value) + } + return d + } } diff --git a/package.json b/package.json index de03a8c58..bba387370 100644 --- a/package.json +++ b/package.json @@ -12,8 +12,9 @@ "strttest": "export NODE_OPTIONS=--max_old_space_size=8364 && parcel serve test.html", "watch:css": "tailwindcss -i index.css -o css/index-tailwind-output.css --watch", "generate:css": "tailwindcss -i index.css -o css/index-tailwind-output.css", - "generate:doctests": "doctest-ts --mocha Logic/**/*.ts && doctest-ts --mocha UI/**/*.ts && doctest-ts --mocha *.ts && doctest-ts --mocha Models/**/*.ts", - "test": "(npm run generate:doctests 2>&1 | grep -v \"No doctests found in\") && mocha --require ts-node/register \"./**/*.doctest.ts\" \"tests/*\" \"tests/**/*.ts\"", + "generate:doctests": "doctest-ts --mocha Logic/**/*.ts && doctest-ts --mocha Logic/*.ts && doctest-ts --mocha UI/**/*.ts && doctest-ts --mocha UI/*.ts && doctest-ts --mocha *.ts && doctest-ts --mocha Models/**/*.ts && doctest-ts --mocha Models/ThemeConfig/**/*.ts && doctest-ts --mocha Models/*.ts", + "test:run-only": "mocha --require ts-node/register --require tests/testhooks.ts \"./**/*.doctest.ts\" \"tests/*\" \"tests/**/*.ts\"", + "test": "(npm run generate:doctests 2>&1 | grep -v \"No doctests found in\") && npm run test:run-only", "init": "npm ci && npm run generate && npm run generate:editor-layer-index && npm run generate:layouts && npm run clean", "add-weblate-upstream": "git remote add weblate-layers https://hosted.weblate.org/git/mapcomplete/layer-translations/ ; git remote add weblate-core https://hosted.weblate.org/git/mapcomplete/layer-core/; git remote add weblate-themes https://hosted.weblate.org/git/mapcomplete/layer-themes/; git remote add weblate-github git@github.com:weblate/MapComplete.git", "fix-weblate": "git remote update weblate-layers; git merge weblate-layers/master", diff --git a/testLegacy/ChangesetHandler.spec.ts b/testLegacy/ChangesetHandler.spec.ts deleted file mode 100644 index 8e0ee713b..000000000 --- a/testLegacy/ChangesetHandler.spec.ts +++ /dev/null @@ -1,181 +0,0 @@ -import T from "./TestHelper"; -import {ChangesetHandler, ChangesetTag} from "../Logic/Osm/ChangesetHandler"; -import {UIEventSource} from "../Logic/UIEventSource"; -import {OsmConnection} from "../Logic/Osm/OsmConnection"; -import {ElementStorage} from "../Logic/ElementStorage"; -import {Changes} from "../Logic/Osm/Changes"; - -export default class ChangesetHandlerSpec extends T { - - private static asDict(tags: {key: string, value: string | number}[]) : Map{ - const d= new Map() - - for (const tag of tags) { - d.set(tag.key, tag.value) - } - - return d - } - - constructor() { - super([ - [ - "Test rewrite tags", () => { - const cs = new ChangesetHandler(new UIEventSource(true), - new OsmConnection({}), - new ElementStorage(), - new Changes(), - new UIEventSource(undefined) - ); - - - const oldChangesetMeta = { - "type": "changeset", - "id": 118443748, - "created_at": "2022-03-13T19:52:10Z", - "closed_at": "2022-03-13T20:54:35Z", - "open": false, - "user": "Pieter Vander Vennet", - "uid": 3818858, - "minlat": 51.0361902, - "minlon": 3.7092939, - "maxlat": 51.0364194, - "maxlon": 3.7099520, - "comments_count": 0, - "changes_count": 3, - "tags": { - "answer": "5", - "comment": "Adding data with #MapComplete for theme #toerisme_vlaanderen", - "created_by": "MapComplete 0.16.6", - "host": "https://mapcomplete.osm.be/toerisme_vlaanderen.html", - "imagery": "osm", - "locale": "nl", - "source": "survey", - "source:node/-1":"note/1234", - "theme": "toerisme_vlaanderen", - } - } - let rewritten = cs.RewriteTagsOf( - [{ - key: "newTag", - value: "newValue", - aggregate: false - }], - new Map(), - oldChangesetMeta) - let d = ChangesetHandlerSpec.asDict(rewritten) - T.equals(10, d.size) - T.equals("5", d.get("answer")) - T.equals("Adding data with #MapComplete for theme #toerisme_vlaanderen", d.get("comment")) - T.equals("MapComplete 0.16.6", d.get("created_by")) - T.equals("https://mapcomplete.osm.be/toerisme_vlaanderen.html", d.get("host")) - T.equals("osm", d.get("imagery")) - T.equals("survey", d.get("source")) - T.equals("note/1234", d.get("source:node/-1")) - T.equals("toerisme_vlaanderen", d.get("theme")) - - T.equals("newValue", d.get("newTag")) - - - - - rewritten = cs.RewriteTagsOf( - [{ - key: "answer", - value: "37", - aggregate: true - }], - new Map(), - oldChangesetMeta) - d = ChangesetHandlerSpec.asDict(rewritten) - - T.equals(9, d.size) - T.equals("42", d.get("answer")) - T.equals("Adding data with #MapComplete for theme #toerisme_vlaanderen", d.get("comment")) - T.equals("MapComplete 0.16.6", d.get("created_by")) - T.equals("https://mapcomplete.osm.be/toerisme_vlaanderen.html", d.get("host")) - T.equals("osm", d.get("imagery")) - T.equals("survey", d.get("source")) - T.equals("note/1234", d.get("source:node/-1")) - T.equals("toerisme_vlaanderen", d.get("theme")) - - rewritten = cs.RewriteTagsOf( - [], - new Map([["node/-1", "node/42"]]), - oldChangesetMeta) - d = ChangesetHandlerSpec.asDict(rewritten) - - T.equals(9, d.size) - T.equals("5", d.get("answer")) - T.equals("Adding data with #MapComplete for theme #toerisme_vlaanderen", d.get("comment")) - T.equals("MapComplete 0.16.6", d.get("created_by")) - T.equals("https://mapcomplete.osm.be/toerisme_vlaanderen.html", d.get("host")) - T.equals("osm", d.get("imagery")) - T.equals("survey", d.get("source")) - T.equals("note/1234", d.get("source:node/42")) - T.equals("toerisme_vlaanderen", d.get("theme")) - - }, - ],[ - "Test rewrite on special motivation", () => { - - - const cs = new ChangesetHandler(new UIEventSource(true), - new OsmConnection({}), - new ElementStorage(), - new Changes(), - new UIEventSource(undefined) - ); - - - const oldChangesetMeta = { - "type": "changeset", - "id": 118443748, - "created_at": "2022-03-13T19:52:10Z", - "closed_at": "2022-03-13T20:54:35Z", - "open": false, - "user": "Pieter Vander Vennet", - "uid": 3818858, - "minlat": 51.0361902, - "minlon": 3.7092939, - "maxlat": 51.0364194, - "maxlon": 3.7099520, - "comments_count": 0, - "changes_count": 3, - "tags": { - "answer": "5", - "comment": "Adding data with #MapComplete for theme #toerisme_vlaanderen", - "created_by": "MapComplete 0.16.6", - "host": "https://mapcomplete.osm.be/toerisme_vlaanderen.html", - "imagery": "osm", - "locale": "nl", - "source": "survey", - "source:-1":"note/1234", - "theme": "toerisme_vlaanderen", - } - } - - const extraMetaTags : ChangesetTag[] = [ - { - key: "created_by", - value:"mapcomplete" - }, - { - key: "source:node/-1", - value:"note/1234" - } - ] - const changes = new Map([["node/-1","node/42"]]) - const hasSpecialMotivationChanges = ChangesetHandler.rewriteMetaTags(extraMetaTags, changes) - T.isTrue(hasSpecialMotivationChanges, "Special rewrite did not trigger") - // Rewritten inline by rewriteMetaTags - T.equals("source:node/42", extraMetaTags[1].key) - T.equals("note/1234", extraMetaTags[1].value) - T.equals("created_by", extraMetaTags[0].key) - T.equals("mapcomplete", extraMetaTags[0].value) - } - - ] - ]); - } -} \ No newline at end of file diff --git a/testLegacy/CreateCache.spec.ts b/testLegacy/CreateCache.spec.ts index 2eaeceb7a..6d54f3bec 100644 --- a/testLegacy/CreateCache.spec.ts +++ b/testLegacy/CreateCache.spec.ts @@ -3,6 +3,7 @@ import {main} from "../scripts/generateCache" import {existsSync, mkdirSync, readFileSync, rmdirSync, unlinkSync} from "fs"; import ScriptUtils from "../scripts/ScriptUtils"; import {Utils} from "../Utils"; +import {expect} from "chai"; export default class CreateCacheSpec extends T { @@ -26,8 +27,8 @@ export default class CreateCacheSpec extends T { ]) await ScriptUtils.sleep(100) const birdhides = JSON.parse(readFileSync("/tmp/np-cache/natuurpunt_birdhide_12_2085_1368.geojson","UTF8")) - T.equals(5, birdhides.features.length, "Got "+birdhides.features.length+" birdhidse") - T.isTrue(birdhides.features.some(f => f.properties.id === "node/5158056232"), "Didn't find birdhide node/5158056232 ") + expect(birdhides.features.length).deep.equal(5) + expect(birdhides.features.some(f => f.properties.id === "node/5158056232"), "Didn't find birdhide node/5158056232 ").true } ] ] diff --git a/testLegacy/CreateNoteImportLayer.spec.ts b/testLegacy/CreateNoteImportLayer.spec.ts deleted file mode 100644 index 8eed04159..000000000 --- a/testLegacy/CreateNoteImportLayer.spec.ts +++ /dev/null @@ -1,35 +0,0 @@ -import T from "./TestHelper"; -import CreateNoteImportLayer from "../Models/ThemeConfig/Conversion/CreateNoteImportLayer"; -import * as bookcases from "../assets/layers/public_bookcase/public_bookcase.json" -import {DesugaringContext} from "../Models/ThemeConfig/Conversion/Conversion"; -import {LayerConfigJson} from "../Models/ThemeConfig/Json/LayerConfigJson"; -import {TagRenderingConfigJson} from "../Models/ThemeConfig/Json/TagRenderingConfigJson"; -import {PrepareLayer} from "../Models/ThemeConfig/Conversion/PrepareLayer"; -import {Utils} from "../Utils"; - -export default class CreateNoteImportLayerSpec extends T { - - constructor() { - super([ - ["Bookcase", () => { - const desugaringState: DesugaringContext = { - sharedLayers: new Map(), - tagRenderings: new Map() - - } - const layerPrepare = new PrepareLayer(desugaringState) - const layer = layerPrepare.convertStrict(bookcases, "ImportLayerGeneratorTest:Parse bookcases") - const generator = new CreateNoteImportLayer() - const generatedLayer: LayerConfigJson = generator.convertStrict(layer, "ImportLayerGeneratorTest: convert") - T.equals("_tags~(^|.*;)amenity=public_bookcase($|;.*)", generatedLayer.isShown.mappings[1].if["and"][1].or[0].and[0]) - T.isTrue(generatedLayer.minzoom <= layer.minzoom, "Zoomlevel is to high") - let renderings = Utils.NoNull(Utils.NoNull(generatedLayer.tagRenderings - .map(tr => (tr).render)) - .map(render => render["en"])) - T.isTrue(renderings.some(r => r.indexOf("import_button") > 0), "no import button found") - }] - ]); - } - - -} \ No newline at end of file diff --git a/testLegacy/GeoOperations.spec.ts b/testLegacy/GeoOperations.spec.ts index 5eb64fa0e..9d8c1ff9d 100644 --- a/testLegacy/GeoOperations.spec.ts +++ b/testLegacy/GeoOperations.spec.ts @@ -1,190 +1,13 @@ import * as Assert from "assert"; -import {equal} from "assert"; import T from "./TestHelper"; import {GeoOperations} from "../Logic/GeoOperations"; -import {BBox} from "../Logic/BBox"; import * as turf from "@turf/turf" +import {expect} from "chai"; export default class GeoOperationsSpec extends T { - private static polygon = { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 1.8017578124999998, - 50.401515322782366 - ], - [ - -3.1640625, - 46.255846818480315 - ], - [ - 5.185546875, - 44.74673324024678 - ], - [ - 1.8017578124999998, - 50.401515322782366 - ] - ] - ] - } - }; - private static multiPolygon = { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "MultiPolygon", - "coordinates": [[ - [ - [ - 1.8017578124999998, - 50.401515322782366 - ], - [ - -3.1640625, - 46.255846818480315 - ], - [ - 5.185546875, - 44.74673324024678 - ], - [ - 1.8017578124999998, - 50.401515322782366 - ] - ], - [ - [ - 1.0107421875, - 48.821332549646634 - ], - [ - 1.329345703125, - 48.25394114463431 - ], - [ - 1.988525390625, - 48.71271258145237 - ], - [ - 0.999755859375, - 48.86471476180277 - ], - [ - 1.0107421875, - 48.821332549646634 - ] - ] - ]] - } - }; - - private static inHole = [1.42822265625, 48.61838518688487] - private static inMultiPolygon = [2.515869140625, 47.37603463349758] - private static outsidePolygon = [4.02099609375, 47.81315451752768] - constructor() { super([ - ["Point out of polygon", () => { - GeoOperationsSpec.isFalse(GeoOperations.inside([ - 3.779296875, - 48.777912755501845 - ], GeoOperationsSpec.polygon), "Point is outside of the polygon"); - } - - ], - ["Point inside of polygon", () => { - - GeoOperationsSpec.isTrue(GeoOperations.inside([ - 1.23046875, - 47.60616304386874 - ], GeoOperationsSpec.polygon), "Point is inside of the polygon"); - } - ], - ["MultiPolygonTest", () => { - - const isTrue = GeoOperationsSpec.isTrue; - const isFalse = GeoOperationsSpec.isFalse; - - isFalse(GeoOperations.inside(GeoOperationsSpec.inHole, GeoOperationsSpec.multiPolygon), "InHole was detected as true"); - isTrue(GeoOperations.inside(GeoOperationsSpec.inMultiPolygon, GeoOperationsSpec.multiPolygon), "InMultiPolgyon was not detected as true"); - isFalse(GeoOperations.inside(GeoOperationsSpec.outsidePolygon, GeoOperationsSpec.multiPolygon), "OutsideOfPolygon was detected as true"); - - }], - ["Intersection between a line and a polygon", () => { - const line = { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "LineString", - "coordinates": [ - [ - 3.779296875, - 48.777912755501845 - ], - [ - 1.23046875, - 47.60616304386874 - ] - ] - } - }; - - const overlap = GeoOperations.calculateOverlap(line, [GeoOperationsSpec.polygon]); - Assert.equal(1, overlap.length) - }], - ["Fully enclosed", () => { - const line = { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "LineString", - "coordinates": [ - [ - 0.0439453125, - 47.31648293428332 - ], - [ - 0.6591796875, - 46.77749276376827 - ] - ] - } - }; - - const overlap = GeoOperations.calculateOverlap(line, [GeoOperationsSpec.polygon]); - Assert.equal(1, overlap.length) - }], - ["overlapWith matches points too", () => { - const point = { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Point", - "coordinates": [ - 2.274169921875, - 46.76244305208004 - ] - } - }; - - const overlap = GeoOperations.calculateOverlap(point, [GeoOperationsSpec.polygon]); - Assert.equal(1, overlap.length) - }], - ["bbox bounds test", - () => { - const bbox = BBox.fromTile(16, 32754, 21785) - equal(-0.076904296875, bbox.minLon) - equal(-0.0714111328125, bbox.maxLon) - equal(51.5292513551899, bbox.minLat) - equal(51.53266860674158, bbox.maxLat) - } - ], ["Regression test: intersection/overlap", () => { const polyGrb = { @@ -412,7 +235,7 @@ export default class GeoOperationsSpec extends T { const copy = GeoOperations.removeOvernoding(feature) Assert.equal(copy.geometry.coordinates[0].length, 7) - T.listIdentical([ + expect(copy.geometry.coordinates[0]).deep.equal([ [ 4.477944199999975, 51.02783550000022 @@ -441,7 +264,7 @@ export default class GeoOperationsSpec extends T { 4.477944199999975, 51.02783550000022 ] - ], copy.geometry.coordinates[0]) + ]) }] ] ) diff --git a/testLegacy/ImageProvider.spec.ts b/testLegacy/ImageProvider.spec.ts deleted file mode 100644 index 1020a4732..000000000 --- a/testLegacy/ImageProvider.spec.ts +++ /dev/null @@ -1,83 +0,0 @@ -import T from "./TestHelper"; -import AllImageProviders from "../Logic/ImageProviders/AllImageProviders"; -import {UIEventSource} from "../Logic/UIEventSource"; -import {Utils} from "../Utils"; - -export default class ImageProviderSpec extends T { - - constructor() { - super([ - ["Search images", () => { - - let i = 0 - - function expects(url, tags, providerName = undefined) { - tags.id = "test/" + i - i++ - AllImageProviders.LoadImagesFor(new UIEventSource(tags)).addCallbackD(images => { - console.log("ImageProvider test", tags.id, "for", tags) - const img = images[0] - if (img === undefined) { - throw "No image found" - } - T.equals(url, img.url, tags.id) - if (providerName) { - T.equals(img.provider.constructor.name, providerName) - } - console.log("OK") - }) - } - - const muntpoort_expected = "https://commons.wikimedia.org/wiki/Special:FilePath/File%3ABr%C3%BCgge-Muntpoort_6-29510-58192.jpg?width=500&height=400" - expects( - muntpoort_expected, - { - "wikimedia_commons": "File:Brügge-Muntpoort_6-29510-58192.jpg" - }, "WikimediaImageProvider") - - - expects(muntpoort_expected, - { - "wikimedia_commons": "https://upload.wikimedia.org/wikipedia/commons/c/cd/Br%C3%BCgge-Muntpoort_6-29510-58192.jpg" - }, "WikimediaImageProvider") - - expects(muntpoort_expected, { - "image": "https://upload.wikimedia.org/wikipedia/commons/c/cd/Br%C3%BCgge-Muntpoort_6-29510-58192.jpg" - }, "WikimediaImageProvider") - - - expects("https://commons.wikimedia.org/wiki/Special:FilePath/File%3ABelgium-5955_-_Simon_Stevin_(13746657193).jpg?width=500&height=400", { - "image": "File:Belgium-5955_-_Simon_Stevin_(13746657193).jpg" - }, "WikimediaImageProvider") - - expects("https://commons.wikimedia.org/wiki/Special:FilePath/File%3ABelgium-5955_-_Simon_Stevin_(13746657193).jpg?width=500&height=400", { - "wikimedia_commons": "File:Belgium-5955_-_Simon_Stevin_(13746657193).jpg" - }, "WikimediaImageProvider") - - - expects("https://commons.wikimedia.org/wiki/Special:FilePath/File%3ABrugge_Leeuwstraat_zonder_nummer_Leeuwbrug_-_119334_-_onroerenderfgoed.jpg?width=500&height=400", { - image: "File:Brugge_Leeuwstraat_zonder_nummer_Leeuwbrug_-_119334_-_onroerenderfgoed.jpg" - }, "WikimediaImageProvider") - - expects("https://commons.wikimedia.org/wiki/Special:FilePath/File%3APapageno_Jef_Claerhout.jpg?width=500&height=400", { - "wikimedia_commons": "File:Papageno_Jef_Claerhout.jpg" - }, "WikimediaImageProvider") - - Utils.injectJsonDownloadForTests( - "https://graph.mapillary.com/196804715753265?fields=thumb_1024_url&&access_token=MLY|4441509239301885|b40ad2d3ea105435bd40c7e76993ae85", - { - "thumb_1024_url": "https://scontent-bru2-1.xx.fbcdn.net/m1/v/t6/An8HQ3DrfU76tWMC602spvM_e_rqOHyiUcYUTetXM7K52DDBEY5J4FWg4WKQqVUlMsWJn4nLXk0pxlBLx31146FqZ2Kg65z7lJUfR6wpW6WPSR5_y7RKdv4YEuzPjwIN0lagBnQONV3UjmXnEGpMouU?stp=s1024x768&ccb=10-5&oh=d460b401c505714ee1cb8bd6baf8ae5d&oe=61731FC3&_nc_sid=122ab1", - "id": "196804715753265" - } - ) - - expects("https://scontent-bru2-1.xx.fbcdn.net/m1/v/t6/An8HQ3DrfU76tWMC602spvM_e_rqOHyiUcYUTetXM7K52DDBEY5J4FWg4WKQqVUlMsWJn4nLXk0pxlBLx31146FqZ2Kg65z7lJUfR6wpW6WPSR5_y7RKdv4YEuzPjwIN0lagBnQONV3UjmXnEGpMouU?stp=s1024x768&ccb=10-5&oh=d460b401c505714ee1cb8bd6baf8ae5d&oe=61731FC3&_nc_sid=122ab1", { - "mapillary": "https://www.mapillary.com/app/?pKey=196804715753265" - }) - - - }] - ]); - } - -} \ No newline at end of file diff --git a/testLegacy/ImportMultiPolygon.spec.ts b/testLegacy/ImportMultiPolygon.spec.ts index e4b480f92..11f40af70 100644 --- a/testLegacy/ImportMultiPolygon.spec.ts +++ b/testLegacy/ImportMultiPolygon.spec.ts @@ -1,10 +1,8 @@ import T from "./TestHelper"; import CreateMultiPolygonWithPointReuseAction from "../Logic/Osm/Actions/CreateMultiPolygonWithPointReuseAction"; -import { Tag } from "../Logic/Tags/Tag"; -import FeaturePipelineState from "../Logic/State/FeaturePipelineState"; -import { Changes } from "../Logic/Osm/Changes"; -import {ChangesetHandler} from "../Logic/Osm/ChangesetHandler"; -import * as Assert from "assert"; +import {Tag} from "../Logic/Tags/Tag"; +import {Changes} from "../Logic/Osm/Changes"; +import {expect} from "chai"; export default class ImportMultiPolygonSpec extends T { @@ -197,21 +195,21 @@ export default class ImportMultiPolygonSpec extends T { } const ways= descriptions.filter(d => d.type === "way") - T.isTrue(ways[0].id == -18, "unexpected id") - T.isTrue(ways[1].id == -27, "unexpected id") + expect(ways[0].id == -18, "unexpected id").true + expect(ways[1].id == -27, "unexpected id").true const outer = ways[0].changes["coordinates"] const outerExpected = [[5.262684300000043,50.84624409999995],[5.262777500000024,50.84620759999988],[5.262798899999998,50.84621390000019],[5.262999799999994,50.84619519999999],[5.263107500000007,50.84618920000014],[5.263115,50.84620990000026],[5.26310279999998,50.84623050000014],[5.263117999999977,50.846247400000166],[5.263174599999989,50.84631019999971],[5.263166999999989,50.84631459999995],[5.263243999999979,50.84640239999989],[5.2631607000000065,50.84643459999996],[5.26313309999997,50.84640089999985],[5.262907499999996,50.84647790000018],[5.2628939999999576,50.846463699999774],[5.262872100000033,50.846440700000294],[5.262784699999991,50.846348899999924],[5.262684300000043,50.84624409999995]] - T.listIdentical(feature.geometry.coordinates[0], outer) + expect(outer).deep.equal(feature.geometry.coordinates[0]) const inner = ways[1].changes["coordinates"] - T.listIdentical(feature.geometry.coordinates[1], inner) + expect(inner).deep.equal(feature.geometry.coordinates[1]) const members = <{type: string, role: string, ref: number}[]> descriptions.find(d => d.type === "relation").changes["members"] - T.isTrue(members[0].role == "outer", "incorrect role") - T.isTrue(members[1].role == "inner", "incorrect role") - T.isTrue(members[0].type == "way", "incorrect type") - T.isTrue(members[1].type == "way", "incorrect type") - T.isTrue(members[0].ref == -18, "incorrect id") - T.isTrue(members[1].ref == -27, "incorrect id") - }] + expect(members[0].role == "outer", "incorrect role").true + expect(members[1].role == "inner", "incorrect role").true + expect(members[0].type == "way", "incorrect type").true + expect(members[1].type == "way", "incorrect type").true + expect(members[0].ref == -18, "incorrect id").true + expect(members[1].ref == -27, "incorrect id").true + }] ]); } diff --git a/testLegacy/LegacyThemeLoader.spec.ts b/testLegacy/LegacyThemeLoader.spec.ts index 9053e8014..402e88ecc 100644 --- a/testLegacy/LegacyThemeLoader.spec.ts +++ b/testLegacy/LegacyThemeLoader.spec.ts @@ -2,13 +2,11 @@ import T from "./TestHelper"; import {FixLegacyTheme} from "../Models/ThemeConfig/Conversion/LegacyJsonConvert"; import LayoutConfig from "../Models/ThemeConfig/LayoutConfig"; import {TagRenderingConfigJson} from "../Models/ThemeConfig/Json/TagRenderingConfigJson"; -import {AddMiniMap} from "../Models/ThemeConfig/Conversion/PrepareTheme"; -import {DetectMappingsWithImages, DetectShadowedMappings} from "../Models/ThemeConfig/Conversion/Validation"; -import * as Assert from "assert"; -import {ExtractImages, FixImages} from "../Models/ThemeConfig/Conversion/FixImages"; +import {ExtractImages} from "../Models/ThemeConfig/Conversion/FixImages"; import {PrepareLayer} from "../Models/ThemeConfig/Conversion/PrepareLayer"; import {LayerConfigJson} from "../Models/ThemeConfig/Json/LayerConfigJson"; import LineRenderingConfigJson from "../Models/ThemeConfig/Json/LineRenderingConfigJson"; +import {expect} from "chai"; export default class LegacyThemeLoaderSpec extends T { @@ -147,332 +145,21 @@ export default class LegacyThemeLoaderSpec extends T { ] } - private static readonly verkeerde_borden = { - "id": "https://raw.githubusercontent.com/seppesantens/MapComplete-Themes/main/VerkeerdeBordenDatabank/VerkeerdeBordenDatabank.json", - "title": { - "nl": "VerkeerdeBordenDatabank", - "en": "Erratic Signs Database" - }, - "maintainer": "Seppe Santens", - "icon": "https://upload.wikimedia.org/wikipedia/commons/b/bc/Belgian_traffic_sign_A51.svg", - "description": { - "nl": "Een kaart om verkeerde of ontbrekende verkeersborden te tonen en te editeren.", - "en": "A map to show and edit incorrect or missing traffic signs." - }, - "version": "2021-09-16", - "startLat": 51.08881, - "startLon": 3.447282, - "startZoom": 15, - "clustering": { - "maxZoom": 8 - }, - "layers": [ - { - "id": "trafficsign", - "name": { - "nl": "verkeersbord", - "en": "traffic sign" - }, - "source": { - "osmTags": { - "and": [ - "traffic_sign~*", - "traffic_sign:issue~*" - ] - } - }, - "minzoom": 10, - "title": { - "render": { - "nl": "verkeersbord", - "en": "traffic sign" - } - }, - "tagRenderings": [ - "images", - { - "render": { - "nl": "ID verkeersbord: {traffic_sign}", - "en": "traffic sign ID: {traffic_sign}" - }, - "question": { - "nl": "Wat is het ID voor dit verkeersbord?", - "en": "What is ID for this traffic sign?" - }, - "freeform": { - "key": "traffic_sign" - }, - "id": "trafficsign-traffic_sign" - }, - { - "render": { - "nl": "Probleem bij dit verkeersbord: {traffic_sign:issue}", - "en": "Issue with this traffic sign: {traffic_sign:issue}" - }, - "question": { - "nl": "Wat is het probleem met dit verkeersbord?", - "en": "What is the issue with this traffic sign?" - }, - "freeform": { - "key": "traffic_sign:issue" - }, - "id": "trafficsign-traffic_sign:issue" - }, - { - "question": { - "nl": "Wanneer werd dit verkeersbord laatst gesurveyed?", - "en": "When was this traffic sign last surveyed?" - }, - "render": { - "nl": "Dit verkeersbord werd laatst gesurveyed op {survey:date}", - "en": "This traffic sign was last surveyed on {survey:date}" - }, - "freeform": { - "key": "survey:date", - "type": "date" - }, - "mappings": [ - { - "if": "survey:date:={_now:date}", - "then": "Vandaag gesurveyed!" - } - ], - "id": "trafficsign-survey:date" - } - ], - "mapRendering": [ - { - "icon": "./TS_bolt.svg", - iconBadges: [{ - if: "id=yes", - then: { - mappings: [ - { - if: "id=yes", - then: "./Something.svg" - } - ] - } - }], - "location": [ - "point", - "centroid" - ] - } - ] - }, - { - "id": "notrafficsign", - "name": { - "nl": "geen verkeersbord", - "en": "no traffic sign" - }, - "source": { - "osmTags": { - "and": [ - { - "or": [ - "no:traffic_sign~*", - "not:traffic_sign~*" - ] - }, - "traffic_sign:issue~*" - ] - } - }, - "minzoom": 10, - "title": { - "render": { - "nl": "ontbrekend verkeersbord", - "en": "missing traffic sign" - } - }, - "tagRenderings": [ - "images", - { - "render": { - "nl": "ID ontbrekend verkeersbord: {no:traffic_sign}", - "en": "missing traffic sign ID: {no:traffic_sign}" - }, - "question": { - "nl": "Wat is het ID voor het ontbrekende verkeersbord?", - "en": "What is ID for the missing traffic sign?" - }, - "freeform": { - "key": "no:traffic_sign" - }, - "id": "notrafficsign-no:traffic_sign" - }, - { - "render": { - "nl": "Probleem bij deze situatie: {traffic_sign:issue}", - "en": "Issue with this situation: {traffic_sign:issue}" - }, - "question": { - "nl": "Wat is er mis met deze situatie?", - "en": "What is the issue with this situation?" - }, - "freeform": { - "key": "traffic_sign:issue" - }, - "id": "notrafficsign-traffic_sign:issue" - }, - { - "question": { - "nl": "Wanneer werd deze situatie laatst gesurveyed?", - "en": "When was this situation last surveyed?" - }, - "render": { - "nl": "Deze situatie werd laatst gesurveyed op {survey:date}", - "en": "This situation was last surveyed on {survey:date}" - }, - "freeform": { - "key": "survey:date", - "type": "date" - }, - "mappings": [ - { - "if": "survey:date:={_now:date}", - "then": "Vandaag gesurveyed!" - } - ], - "id": "notrafficsign-survey:date" - } - ], - "mapRendering": [ - { - "icon": "./TS_questionmark.svg", - "location": [ - "point", - "centroid" - ] - } - ] - } - ], - "defaultBackgroundId": "Stamen.TonerLite" - } constructor() { super([ - ["Walking_node_theme", () => { + ["should load the Walking_node_theme", () => { const config = LegacyThemeLoaderSpec.walking_node_theme const fixed = new FixLegacyTheme().convert( // @ts-ignore config, "While testing") - T.isTrue(fixed.errors.length === 0, "Could not fix the legacy theme") + expect(fixed.errors.length === 0, "Could not fix the legacy theme").true const theme = new LayoutConfig(fixed.result) }], - ["Detect minimaps", () => { - function shouldHave(config: TagRenderingConfigJson) { - T.equals(AddMiniMap.hasMinimap(config), true, "Did _not_ dected a minimap, even though there is one in " + JSON.stringify(config)) - } - - function shouldNot(config: TagRenderingConfigJson) { - T.equals(AddMiniMap.hasMinimap(config), false, "Did erronously dected a minimap, even though there is none in " + JSON.stringify(config)) - } - - shouldHave({ - render: "{minimap()}" - }); - shouldHave({ - render: {en: "{minimap()}"} - }); - shouldHave({ - render: {en: "{minimap()}", nl: "{minimap()}"} - }); - shouldHave({ - render: {en: "{minimap()}", nl: "No map for the dutch!"} - }); - - shouldHave({ - render: "{minimap()}" - }) - shouldHave({ - render: "{minimap(18,featurelist)}" - }) - shouldHave({ - mappings: [ - { - if: "xyz=abc", - then: "{minimap(18,featurelist)}" - } - ] - }) - shouldNot({ - render: "Some random value {key}" - }) - shouldNot({ - render: "Some random value {minimap}" - }) - - }], - ["Shadowed mappings are detected", - () => { - const r = new DetectShadowedMappings().convert({ - mappings: [ - { - if: {or: ["key=value", "x=y"]}, - then: "Case A" - }, - { - if: "key=value", - then: "Shadowed" - } - ] - }, "test"); - T.isTrue(r.warnings.length > 0, "Failing case 0 is not detected") - T.isTrue(r.warnings[0].indexOf("The mapping key=value is fully matched by a previous mapping (namely 0)") >= 0, "Error message does not contain tag and indices") - const r0 = new DetectShadowedMappings().convert({ - mappings: [ - { - if: {or: ["key=value", "x=y"]}, - then: "Case A" - }, - { - if: {and: ["key=value", "x=y"]}, - then: "Shadowed" - } - ] - }, "test"); - T.isTrue(r0.warnings.length > 0, "Failing case 1 is not detected") - } - ], - ["Images are rewritten", () => { - const fixed = new FixImages(new Set()).convertStrict(LegacyThemeLoaderSpec.verkeerde_borden, "test") - const fixedValue = fixed.layers[0]["mapRendering"][0].icon - Assert.equal("https://raw.githubusercontent.com/seppesantens/MapComplete-Themes/main/VerkeerdeBordenDatabank/TS_bolt.svg", - fixedValue) - - const fixedMapping = fixed.layers[0]["mapRendering"][0].iconBadges[0].then.mappings[0].then - Assert.equal("https://raw.githubusercontent.com/seppesantens/MapComplete-Themes/main/VerkeerdeBordenDatabank/Something.svg", - fixedMapping) - }], - ["Images in simple mappings are detected", () => { - const r = new DetectMappingsWithImages().convert({ - "mappings": [ - { - "if": "bicycle_parking=stands", - "then": { - "en": "Staple racks ", - "nl": "Nietjes ", - "fr": "Arceaux ", - "gl": "De roda (Stands) ", - "de": "Fahrradbügel ", - "hu": "Korlát ", - "it": "Archetti ", - "zh_Hant": "單車架 " - } - }] - }, "test"); - const errors = r.errors; - T.isTrue(errors.length > 0, "No images found"); - T.isTrue(errors.some(msg => msg.indexOf("./assets/layers/bike_parking/staple.svg") >= 0), "staple.svg not mentioned"); - }], ["Images in 'thens' are detected in QuestionableTagRenderings", () => { const r = new ExtractImages(true, new Map()).convert({ "layers": [ @@ -504,9 +191,9 @@ export default class LegacyThemeLoaderSpec extends T { ] }, "test"); const images = r.result - T.isTrue(images.length > 0, "No images found"); - T.isTrue(images.findIndex(img => img == "./assets/layers/bike_parking/staple.svg") >= 0, "staple.svg not mentioned"); - T.isTrue(images.findIndex(img => img == "./assets/layers/bike_parking/bollard.svg") >= 0, "bollard.svg not mentioned"); + images.length // => 2 + expect(images.findIndex(img => img == "./assets/layers/bike_parking/staple.svg") >= 0, "staple.svg not mentioned").true + expect(images.findIndex(img => img == "./assets/layers/bike_parking/bollard.svg") >= 0, "bollard.svg not mentioned").true }], ["Rotation and colours is not detected as image", () => { const r = new ExtractImages(true, new Map()).convert({ @@ -524,9 +211,9 @@ export default class LegacyThemeLoaderSpec extends T { ] }, "test"); const images = r.result - T.isTrue(images.length > 0, "No images found"); - T.isTrue(images.length < 2, "To much images found: " + images.join(", ")); - T.isTrue(images[0] === "pin", "pin not mentioned"); + expect(images.length > 0, "No images found").true + expect(images.length < 2, "To much images found: " + images.join(", ")).true + expect(images[0] === "pin", "pin not mentioned").true }], ["Test expansion in map renderings", () => { const exampleLayer: LayerConfigJson = { @@ -598,59 +285,10 @@ export default class LegacyThemeLoaderSpec extends T { } - Assert.equal(JSON.stringify(result), JSON.stringify(expected)) + expect(result).deep.eq(expected) } ], - ["Advanced rewriting of the mapRendering",() => { - const source = {"mapRendering": [ - { - "rewrite": { - "sourceString": ["left|right", "lr_offset"], - "into": [ - ["left", "right"], - [-6, 6] - ] - }, - "renderings": [ - { - "color": { - "render": "#888", - "mappings": [ - { - "if": "parking:condition:left|right=free", - "then": "#299921" - }, - { - "if": "parking:condition:left|right=ticket", - "then": "#219991" - } - ] - }, - "width": { - "render": 6, - "mappings": [ - { - "if": { - "or": [ - "parking:lane:left|right=no", - "parking:lane:left|right=separate" - ] - }, - "then": 0 - } - ] - }, - "offset": "lr_offset", - "lineCap": "butt" - } - ] - } - ] - }} - - - ] ] ); } diff --git a/testLegacy/OsmConnection.spec.ts b/testLegacy/OsmConnection.spec.ts deleted file mode 100644 index 1b8116213..000000000 --- a/testLegacy/OsmConnection.spec.ts +++ /dev/null @@ -1,45 +0,0 @@ -import T from "./TestHelper"; -import UserDetails, {OsmConnection} from "../Logic/Osm/OsmConnection"; -import {UIEventSource} from "../Logic/UIEventSource"; -import ScriptUtils from "../scripts/ScriptUtils"; - - -export default class OsmConnectionSpec extends T { - - /* - This token gives access to the TESTING-instance of OSM. No real harm can be done with it, so it can be commited to the repo - */ - private static _osm_token = "LJFmv2nUicSNmBNsFeyCHx5KKx6Aiesx8pXPbX4n" - - constructor() { - super([ - ["login on dev", - () => { - const osmConn = new OsmConnection({ - osmConfiguration: "osm-test", - oauth_token: new UIEventSource(OsmConnectionSpec._osm_token) - } - ); - - osmConn.userDetails.map((userdetails: UserDetails) => { - if (userdetails.loggedIn) { - console.log("Logged in with the testing account. Writing some random data to test preferences") - const data = Math.random().toString() - osmConn.GetPreference("test").setData(data) - - osmConn.GetPreference("https://raw.githubusercontent.com/AgusQui/MapCompleteRailway/main/railway") - .setData(data) - - } - }); - - ScriptUtils.sleep(1000) - - } - ] - - - ]); - } - -} \ No newline at end of file diff --git a/testLegacy/OsmObject.spec.ts b/testLegacy/OsmObject.spec.ts deleted file mode 100644 index 1e0cd3707..000000000 --- a/testLegacy/OsmObject.spec.ts +++ /dev/null @@ -1,28 +0,0 @@ -import T from "./TestHelper"; -import {OsmObject} from "../Logic/Osm/OsmObject"; - -export default class OsmObjectSpec extends T { - constructor() { - super([ - [ - "Download referencing ways", - () => { - OsmObjectSpec.runTest().then(_ => console.log("Referencing ways test is done (async)")) - } - - ] - - - ]); - } - - private static async runTest() { - const ways = await OsmObject.DownloadReferencingWays("node/1124134958") - if (ways === undefined) { - throw "Did not get the ways" - } - if (ways.length !== 4) { - throw "Expected 4 ways but got " + ways.length - } - } -} \ No newline at end of file diff --git a/testLegacy/RelationSplitHandler.spec.ts b/testLegacy/RelationSplitHandler.spec.ts deleted file mode 100644 index 7f42577a2..000000000 --- a/testLegacy/RelationSplitHandler.spec.ts +++ /dev/null @@ -1,690 +0,0 @@ -import T from "./TestHelper"; -import {InPlaceReplacedmentRTSH, TurnRestrictionRSH} from "../Logic/Osm/Actions/RelationSplitHandler"; -import {OsmObject, OsmRelation} from "../Logic/Osm/OsmObject"; -import {Changes} from "../Logic/Osm/Changes"; -import {Utils} from "../Utils"; - -export default class RelationSplitHandlerSpec extends T { - constructor() { - - Utils.injectJsonDownloadForTests( - "https://www.openstreetmap.org/api/0.6/node/1124134958/ways", - { - "version": "0.6", - "generator": "CGImap 0.8.5 (2937646 spike-07.openstreetmap.org)", - "copyright": "OpenStreetMap and contributors", - "attribution": "http://www.openstreetmap.org/copyright", - "license": "http://opendatacommons.org/licenses/odbl/1-0/", - "elements": [{ - "type": "way", - "id": 97038428, - "timestamp": "2019-06-19T12:26:24Z", - "version": 6, - "changeset": 71399984, - "user": "Pieter Vander Vennet", - "uid": 3818858, - "nodes": [1124134958, 323729212, 323729351, 2542460408, 187073405], - "tags": { - "highway": "residential", - "name": "Brugs-Kerkhofstraat", - "sett:pattern": "arc", - "surface": "sett" - } - }, { - "type": "way", - "id": 97038434, - "timestamp": "2019-06-19T12:26:24Z", - "version": 5, - "changeset": 71399984, - "user": "Pieter Vander Vennet", - "uid": 3818858, - "nodes": [1124134958, 1124135024, 187058607], - "tags": { - "bicycle": "use_sidepath", - "highway": "residential", - "name": "Kerkhofblommenstraat", - "sett:pattern": "arc", - "surface": "sett" - } - }, { - "type": "way", - "id": 97038435, - "timestamp": "2017-12-21T21:41:08Z", - "version": 4, - "changeset": 54826837, - "user": "Jakka", - "uid": 2403313, - "nodes": [1124134958, 2576628889, 1124135035, 5298371485, 5298371495], - "tags": {"bicycle": "use_sidepath", "highway": "residential", "name": "Kerkhofblommenstraat"} - }, { - "type": "way", - "id": 251446313, - "timestamp": "2019-01-07T19:22:47Z", - "version": 4, - "changeset": 66106872, - "user": "M!dgard", - "uid": 763799, - "nodes": [1124134958, 5243143198, 4555715455], - "tags": {"foot": "yes", "highway": "service"} - }] - } - ) - - Utils.injectJsonDownloadForTests( - "https://www.openstreetmap.org/api/0.6/relation/9572808", - { - "version": "0.6", - "generator": "CGImap 0.8.5 (3128319 spike-07.openstreetmap.org)", - "copyright": "OpenStreetMap and contributors", - "attribution": "http://www.openstreetmap.org/copyright", - "license": "http://opendatacommons.org/licenses/odbl/1-0/", - "elements": [{ - "type": "relation", - "id": 9572808, - "timestamp": "2021-08-12T12:44:06Z", - "version": 11, - "changeset": 109573204, - "user": "A67-A67", - "uid": 553736, - "members": [{"type": "way", "ref": 173662702, "role": ""}, { - "type": "way", - "ref": 467606230, - "role": "" - }, {"type": "way", "ref": 126267167, "role": ""}, { - "type": "way", - "ref": 301897426, - "role": "" - }, {"type": "way", "ref": 687866206, "role": ""}, { - "type": "way", - "ref": 295132739, - "role": "" - }, {"type": "way", "ref": 690497698, "role": ""}, { - "type": "way", - "ref": 627893684, - "role": "" - }, {"type": "way", "ref": 295132741, "role": ""}, { - "type": "way", - "ref": 301903120, - "role": "" - }, {"type": "way", "ref": 672541156, "role": ""}, { - "type": "way", - "ref": 126264330, - "role": "" - }, {"type": "way", "ref": 280440853, "role": ""}, { - "type": "way", - "ref": 838499667, - "role": "" - }, {"type": "way", "ref": 838499663, "role": ""}, { - "type": "way", - "ref": 690497623, - "role": "" - }, {"type": "way", "ref": 301902946, "role": ""}, { - "type": "way", - "ref": 280460715, - "role": "" - }, {"type": "way", "ref": 972534369, "role": ""}, { - "type": "way", - "ref": 695680702, - "role": "" - }, {"type": "way", "ref": 690497860, "role": ""}, { - "type": "way", - "ref": 295410363, - "role": "" - }, {"type": "way", "ref": 823864063, "role": ""}, { - "type": "way", - "ref": 663172088, - "role": "" - }, {"type": "way", "ref": 659950322, "role": ""}, { - "type": "way", - "ref": 659950323, - "role": "" - }, {"type": "way", "ref": 230180094, "role": ""}, { - "type": "way", - "ref": 690497912, - "role": "" - }, {"type": "way", "ref": 39588765, "role": ""}], - "tags": { - "distance": "13 km", - "name": "Abdijenroute", - "network": "lcn", - "old_name": "Spoorlijn 58", - "operator": "Toerisme West-Vlaanderen", - "railway": "abandoned", - "route": "bicycle", - "type": "route", - "wikipedia": "nl:Spoorlijn 58" - } - }] - } - ) - - Utils.injectJsonDownloadForTests( - "https://www.openstreetmap.org/api/0.6/way/687866206/full", - { - "version": "0.6", - "generator": "CGImap 0.8.5 (2601512 spike-07.openstreetmap.org)", - "copyright": "OpenStreetMap and contributors", - "attribution": "http://www.openstreetmap.org/copyright", - "license": "http://opendatacommons.org/licenses/odbl/1-0/", - "elements": [{ - "type": "node", - "id": 5273988959, - "lat": 51.1811406, - "lon": 3.2427712, - "timestamp": "2021-07-29T21:14:53Z", - "version": 6, - "changeset": 108847202, - "user": "kaart_fietser", - "uid": 11022240, - "tags": {"network:type": "node_network", "rwn_ref": "32"} - }, { - "type": "node", - "id": 6448669326, - "lat": 51.1811346, - "lon": 3.242891, - "timestamp": "2019-05-04T22:44:12Z", - "version": 1, - "changeset": 69891295, - "user": "Pieter Vander Vennet", - "uid": 3818858, - "tags": {"barrier": "bollard"} - }, { - "type": "way", - "id": 687866206, - "timestamp": "2019-05-06T20:52:20Z", - "version": 2, - "changeset": 69951497, - "user": "noelbov", - "uid": 8054928, - "nodes": [6448669326, 5273988959], - "tags": { - "highway": "cycleway", - "name": "Abdijenroute", - "railway": "abandoned", - "surface": "asphalt" - } - }] - } - ) - - Utils.injectJsonDownloadForTests( - "https://www.openstreetmap.org/api/0.6/way/690497698/full", - { - "version": "0.6", - "generator": "CGImap 0.8.5 (3023311 spike-07.openstreetmap.org)", - "copyright": "OpenStreetMap and contributors", - "attribution": "http://www.openstreetmap.org/copyright", - "license": "http://opendatacommons.org/licenses/odbl/1-0/", - "elements": [{ - "type": "node", - "id": 170497152, - "lat": 51.1832353, - "lon": 3.2498759, - "timestamp": "2018-04-24T00:29:37Z", - "version": 7, - "changeset": 58357376, - "user": "Pieter Vander Vennet", - "uid": 3818858 - }, { - "type": "node", - "id": 2988218625, - "lat": 51.1835053, - "lon": 3.2503067, - "timestamp": "2018-09-24T21:48:46Z", - "version": 2, - "changeset": 62895918, - "user": "A67-A67", - "uid": 553736 - }, { - "type": "node", - "id": 5273988967, - "lat": 51.182659, - "lon": 3.249004, - "timestamp": "2017-12-09T18:40:21Z", - "version": 1, - "changeset": 54493533, - "user": "CacherB", - "uid": 1999108 - }, { - "type": "way", - "id": 690497698, - "timestamp": "2021-07-29T21:14:53Z", - "version": 3, - "changeset": 108847202, - "user": "kaart_fietser", - "uid": 11022240, - "nodes": [2988218625, 170497152, 5273988967], - "tags": { - "highway": "cycleway", - "lit": "no", - "name": "Abdijenroute", - "oneway": "no", - "railway": "abandoned", - "surface": "compacted" - } - }] - } - ) - Utils.injectJsonDownloadForTests( - "https://www.openstreetmap.org/api/0.6/relation/4374576", - { - "version": "0.6", - "generator": "CGImap 0.8.5 (1266692 spike-06.openstreetmap.org)", - "copyright": "OpenStreetMap and contributors", - "attribution": "http://www.openstreetmap.org/copyright", - "license": "http://opendatacommons.org/licenses/odbl/1-0/", - "elements": [{ - "type": "relation", - "id": 4374576, - "timestamp": "2014-12-23T21:42:27Z", - "version": 2, - "changeset": 27660623, - "user": "escada", - "uid": 436365, - "members": [{"type": "way", "ref": 318616190, "role": "from"}, { - "type": "node", - "ref": 1407529979, - "role": "via" - }, {"type": "way", "ref": 143298912, "role": "to"}], - "tags": {"restriction": "no_right_turn", "type": "restriction"} - }] - } - ) - - Utils.injectJsonDownloadForTests( - "https://www.openstreetmap.org/api/0.6/way/143298912/full", - { - "version": "0.6", - "generator": "CGImap 0.8.5 (4046166 spike-07.openstreetmap.org)", - "copyright": "OpenStreetMap and contributors", - "attribution": "http://www.openstreetmap.org/copyright", - "license": "http://opendatacommons.org/licenses/odbl/1-0/", - "elements": [{ - "type": "node", - "id": 26343912, - "lat": 51.2146847, - "lon": 3.2397007, - "timestamp": "2015-04-11T10:40:56Z", - "version": 5, - "changeset": 30139621, - "user": "M!dgard", - "uid": 763799 - }, { - "type": "node", - "id": 26343913, - "lat": 51.2161912, - "lon": 3.2386907, - "timestamp": "2015-04-11T10:40:56Z", - "version": 6, - "changeset": 30139621, - "user": "M!dgard", - "uid": 763799 - }, { - "type": "node", - "id": 26343914, - "lat": 51.2193456, - "lon": 3.2360696, - "timestamp": "2015-04-11T10:40:56Z", - "version": 5, - "changeset": 30139621, - "user": "M!dgard", - "uid": 763799 - }, { - "type": "node", - "id": 26343915, - "lat": 51.2202816, - "lon": 3.2352429, - "timestamp": "2015-04-11T10:40:56Z", - "version": 5, - "changeset": 30139621, - "user": "M!dgard", - "uid": 763799 - }, { - "type": "node", - "id": 875668688, - "lat": 51.2131868, - "lon": 3.2406009, - "timestamp": "2015-04-11T10:40:56Z", - "version": 4, - "changeset": 30139621, - "user": "M!dgard", - "uid": 763799 - }, { - "type": "node", - "id": 1109632153, - "lat": 51.2207068, - "lon": 3.234882, - "timestamp": "2015-04-11T10:40:55Z", - "version": 3, - "changeset": 30139621, - "user": "M!dgard", - "uid": 763799 - }, { - "type": "node", - "id": 1109632154, - "lat": 51.220784, - "lon": 3.2348394, - "timestamp": "2021-05-30T08:01:17Z", - "version": 4, - "changeset": 105557550, - "user": "albertino", - "uid": 499281 - }, { - "type": "node", - "id": 1109632177, - "lat": 51.2205082, - "lon": 3.2350441, - "timestamp": "2015-04-11T10:40:55Z", - "version": 3, - "changeset": 30139621, - "user": "M!dgard", - "uid": 763799 - }, { - "type": "node", - "id": 1407529961, - "lat": 51.2168476, - "lon": 3.2381772, - "timestamp": "2015-04-11T10:40:55Z", - "version": 2, - "changeset": 30139621, - "user": "M!dgard", - "uid": 763799 - }, { - "type": "node", - "id": 1407529969, - "lat": 51.2155155, - "lon": 3.23917, - "timestamp": "2011-08-21T20:08:27Z", - "version": 1, - "changeset": 9088257, - "user": "toeklk", - "uid": 219908 - }, { - "type": "node", - "id": 1407529979, - "lat": 51.212694, - "lon": 3.2409595, - "timestamp": "2015-04-11T10:40:55Z", - "version": 6, - "changeset": 30139621, - "user": "M!dgard", - "uid": 763799, - "tags": {"highway": "traffic_signals"} - }, { - "type": "node", - "id": 1634435395, - "lat": 51.2129189, - "lon": 3.2408257, - "timestamp": "2012-02-15T19:37:51Z", - "version": 1, - "changeset": 10695640, - "user": "Eimai", - "uid": 6072 - }, { - "type": "node", - "id": 1634435396, - "lat": 51.2132508, - "lon": 3.2405417, - "timestamp": "2012-02-15T19:37:51Z", - "version": 1, - "changeset": 10695640, - "user": "Eimai", - "uid": 6072 - }, { - "type": "node", - "id": 1634435397, - "lat": 51.2133918, - "lon": 3.2404416, - "timestamp": "2015-04-11T10:40:55Z", - "version": 2, - "changeset": 30139621, - "user": "M!dgard", - "uid": 763799 - }, { - "type": "node", - "id": 1974988033, - "lat": 51.2127459, - "lon": 3.240928, - "timestamp": "2012-10-20T12:24:13Z", - "version": 1, - "changeset": 13566903, - "user": "skyman81", - "uid": 955688 - }, { - "type": "node", - "id": 3250129361, - "lat": 51.2127906, - "lon": 3.2409016, - "timestamp": "2018-12-19T00:00:33Z", - "version": 2, - "changeset": 65596519, - "user": "beardhatcode", - "uid": 5439560, - "tags": {"crossing": "traffic_signals", "highway": "crossing"} - }, { - "type": "node", - "id": 3250129363, - "lat": 51.2149189, - "lon": 3.2395571, - "timestamp": "2015-04-11T10:40:56Z", - "version": 2, - "changeset": 30139621, - "user": "M!dgard", - "uid": 763799 - }, { - "type": "node", - "id": 3450326133, - "lat": 51.2139571, - "lon": 3.2401205, - "timestamp": "2015-04-11T10:40:26Z", - "version": 1, - "changeset": 30139621, - "user": "M!dgard", - "uid": 763799 - }, { - "type": "node", - "id": 3450326135, - "lat": 51.2181385, - "lon": 3.2370893, - "timestamp": "2015-04-11T10:40:26Z", - "version": 1, - "changeset": 30139621, - "user": "M!dgard", - "uid": 763799 - }, { - "type": "node", - "id": 4794847239, - "lat": 51.2191224, - "lon": 3.2362584, - "timestamp": "2019-08-27T23:07:05Z", - "version": 2, - "changeset": 73816461, - "user": "Pieter Vander Vennet", - "uid": 3818858 - }, { - "type": "node", - "id": 8493044168, - "lat": 51.2130348, - "lon": 3.2407284, - "timestamp": "2021-03-06T21:52:51Z", - "version": 1, - "changeset": 100555232, - "user": "kaart_fietser", - "uid": 11022240, - "tags": {"highway": "traffic_signals", "traffic_signals": "traffic_lights"} - }, { - "type": "node", - "id": 8792687918, - "lat": 51.2207505, - "lon": 3.2348579, - "timestamp": "2021-06-02T18:27:15Z", - "version": 1, - "changeset": 105735092, - "user": "albertino", - "uid": 499281 - }, { - "type": "way", - "id": 143298912, - "timestamp": "2021-06-02T18:27:15Z", - "version": 15, - "changeset": 105735092, - "user": "albertino", - "uid": 499281, - "nodes": [1407529979, 1974988033, 3250129361, 1634435395, 8493044168, 875668688, 1634435396, 1634435397, 3450326133, 26343912, 3250129363, 1407529969, 26343913, 1407529961, 3450326135, 4794847239, 26343914, 26343915, 1109632177, 1109632153, 8792687918, 1109632154], - "tags": { - "cycleway:right": "track", - "highway": "primary", - "lanes": "2", - "lit": "yes", - "maxspeed": "70", - "name": "Buiten Kruisvest", - "oneway": "yes", - "ref": "R30", - "surface": "asphalt", - "wikipedia": "nl:Buiten Kruisvest" - } - }] - } - ) - - - super([ - ["split 295132739", - async () => { - // Lets mimick a split action of https://www.openstreetmap.org/way/295132739 - - const relation: OsmRelation = await OsmObject.DownloadObjectAsync("relation/9572808") - const originalNodeIds = [5273988967, - 170497153, - 1507524582, - 4524321710, - 170497155, - 170497157, - 170497158, - 3208166179, - 1507524610, - 170497160, - 3208166178, - 1507524573, - 1575932830, - 6448669326] - - const withSplit = [[5273988967, - 170497153, - 1507524582, - 4524321710, - 170497155, - 170497157, - 170497158], - [ - 3208166179, - 1507524610, - 170497160, - 3208166178, - 1507524573, - 1575932830, - 6448669326]] - - const splitter = new InPlaceReplacedmentRTSH( - { - relation: relation, - originalWayId: 295132739, - allWayIdsInOrder: [295132739, -1], - originalNodes: originalNodeIds, - allWaysNodesInOrder: withSplit - }, "no-theme") - const changeDescription = await splitter.CreateChangeDescriptions(new Changes()) - const allIds = changeDescription[0].changes["members"].map(m => m.ref).join(",") - const expected = "687866206,295132739,-1,690497698" - T.isTrue(allIds.indexOf(expected) >= 0, "didn't find the expected order of ids in the relation to test") - }], - ["split https://www.openstreetmap.org/way/143298912 (turn restriction relation)", - async () => { - - - const relation: OsmRelation = await OsmObject.DownloadObjectAsync("relation/4374576") - const originalNodeIds = - [ - 1407529979, - 1974988033, - 3250129361, - 1634435395, - 8493044168, - 875668688, - 1634435396, - 1634435397, - 3450326133, - 26343912, - 3250129363, - 1407529969, - 26343913, - 1407529961, - 3450326135, - 4794847239, - 26343914, - 26343915, - 1109632177, - 1109632153, - 8792687918, - 1109632154 - - ] - - const withSplit = [[ - 1407529979, // The via point - 1974988033, - 3250129361, - 1634435395, - 8493044168, - 875668688, - 1634435396, - 1634435397, - 3450326133, - 26343912, - 3250129363, - 1407529969, - 26343913], - [ - 1407529961, - 3450326135, - 4794847239, - 26343914, - 26343915, - 1109632177, - 1109632153, - 8792687918, - 1109632154 - - ]] - - const splitter = new TurnRestrictionRSH( - { - relation: relation, - originalWayId: 143298912, - allWayIdsInOrder: [-1, 143298912], - originalNodes: originalNodeIds, - allWaysNodesInOrder: withSplit - }, "no-theme") - const changeDescription = await splitter.CreateChangeDescriptions(new Changes()) - const allIds = changeDescription[0].changes["members"].map(m => m.type + "/" + m.ref + "-->" + m.role).join(",") - const expected = "way/318616190-->from,node/1407529979-->via,way/-1-->to" - T.equals(expected, allIds) - - - // Reversing the ids has no effect - const splitterReverse = new TurnRestrictionRSH( - { - relation: relation, - originalWayId: 143298912, - allWayIdsInOrder: [143298912, -1], - originalNodes: originalNodeIds, - allWaysNodesInOrder: withSplit - }, "no-theme") - const changesReverse = await splitterReverse.CreateChangeDescriptions(new Changes()) - T.equals(0, changesReverse.length, "Reverse turn restriction split did generate a changedescription, should not be needed") - - } - ] - ]); - } -} \ No newline at end of file diff --git a/testLegacy/ReplaceGeometry.spec.ts b/testLegacy/ReplaceGeometry.spec.ts deleted file mode 100644 index 96b49d945..000000000 --- a/testLegacy/ReplaceGeometry.spec.ts +++ /dev/null @@ -1,932 +0,0 @@ -import T from "./TestHelper"; -import {Utils} from "../Utils"; -import ReplaceGeometryAction from "../Logic/Osm/Actions/ReplaceGeometryAction"; -import * as grb from "../assets/themes/grb_import/grb.json" -import LayoutConfig from "../Models/ThemeConfig/LayoutConfig"; -import State from "../State"; -import {BBox} from "../Logic/BBox"; -import Minimap from "../UI/Base/Minimap"; - -export default class ReplaceGeometrySpec extends T { - - private static readonly grbStripped = { - "id": "grb", - "title": { - "nl": "GRB import helper" - }, - "description": "Smaller version of the GRB theme", - "language": [ - "nl", - "en" - ], - socialImage: "img.jpg", - "version": "0", - "startLat": 51.0249, - "startLon": 4.026489, - "startZoom": 9, - "clustering": false, - "overrideAll": { - "minzoom": 19 - }, - "layers": [ - { - "id": "type_node", - source: { - osmTags: "type=node" - }, - mapRendering: null, - "override": { - "calculatedTags": [ - "_is_part_of_building=feat.get('parent_ways')?.some(p => p.building !== undefined && p.building !== '') ?? false", - "_is_part_of_grb_building=feat.get('parent_ways')?.some(p => p['source:geometry:ref'] !== undefined) ?? false", - "_is_part_of_building_passage=feat.get('parent_ways')?.some(p => p.tunnel === 'building_passage') ?? false", - "_is_part_of_highway=!feat.get('is_part_of_building_passage') && (feat.get('parent_ways')?.some(p => p.highway !== undefined && p.highway !== '') ?? false)", - "_is_part_of_landuse=feat.get('parent_ways')?.some(p => (p.landuse !== undefined && p.landuse !== '') || (p.natural !== undefined && p.natural !== '')) ?? false", - "_moveable=feat.get('_is_part_of_building') && !feat.get('_is_part_of_grb_building')" - ], - "mapRendering": [ - { - "icon": "square:#cc0", - "iconSize": "5,5,center", - "location": [ - "point" - ] - } - ], - "passAllFeatures": true - } - }, - { - "id": "osm-buildings", - "name": "All OSM-buildings", - "source": { - "osmTags": "building~*", - "maxCacheAge": 0 - }, - "calculatedTags": [ - "_surface:strict:=feat.get('_surface')" - ], - "mapRendering": [ - { - "width": { - "render": "2", - "mappings": [ - { - "if": "fixme~*", - "then": "5" - } - ] - }, - "color": { - "render": "#00c", - "mappings": [ - { - "if": "fixme~*", - "then": "#ff00ff" - }, - { - "if": "building=house", - "then": "#a00" - }, - { - "if": "building=shed", - "then": "#563e02" - }, - { - "if": { - "or": [ - "building=garage", - "building=garages" - ] - }, - "then": "#f9bfbb" - }, - { - "if": "building=yes", - "then": "#0774f2" - } - ] - } - } - ], - "title": "OSM-gebouw", - "tagRenderings": [ - { - "id": "building type", - "freeform": { - "key": "building" - }, - "render": "The building type is {building}", - "question": { - "en": "What kind of building is this?" - }, - "mappings": [ - { - "if": "building=house", - "then": "A normal house" - }, - { - "if": "building=detached", - "then": "A house detached from other building" - }, - { - "if": "building=semidetached_house", - "then": "A house sharing only one wall with another house" - }, - { - "if": "building=apartments", - "then": "An apartment building - highrise for living" - }, - { - "if": "building=office", - "then": "An office building - highrise for work" - }, - { - "if": "building=apartments", - "then": "An apartment building" - }, - { - "if": "building=shed", - "then": "A small shed, e.g. in a garden" - }, - { - "if": "building=garage", - "then": "A single garage to park a car" - }, - { - "if": "building=garages", - "then": "A building containing only garages; typically they are all identical" - }, - { - "if": "building=yes", - "then": "A building - no specification" - } - ] - }, - { - "id": "grb-housenumber", - "render": { - "nl": "Het huisnummer is {addr:housenumber}" - }, - "question": { - "nl": "Wat is het huisnummer?" - }, - "freeform": { - "key": "addr:housenumber" - }, - "mappings": [ - { - "if": { - "and": [ - "not:addr:housenumber=yes", - "addr:housenumber=" - ] - }, - "then": { - "nl": "Geen huisnummer" - } - } - ] - }, - { - "id": "grb-unit", - "question": "Wat is de wooneenheid-aanduiding?", - "render": { - "nl": "De wooneenheid-aanduiding is {addr:unit} " - }, - "freeform": { - "key": "addr:unit" - }, - "mappings": [ - { - "if": "addr:unit=", - "then": "Geen wooneenheid-nummer" - } - ] - }, - { - "id": "grb-street", - "render": { - "nl": "De straat is {addr:street}" - }, - "freeform": { - "key": "addr:street" - }, - "question": { - "nl": "Wat is de straat?" - } - }, - { - "id": "grb-fixme", - "render": { - "nl": "De fixme is {fixme}" - }, - "question": { - "nl": "Wat zegt de fixme?" - }, - "freeform": { - "key": "fixme" - }, - "mappings": [ - { - "if": { - "and": [ - "fixme=" - ] - }, - "then": { - "nl": "Geen fixme" - } - } - ] - }, - { - "id": "grb-min-level", - "render": { - "nl": "Dit gebouw begint maar op de {building:min_level} verdieping" - }, - "question": { - "nl": "Hoeveel verdiepingen ontbreken?" - }, - "freeform": { - "key": "building:min_level", - "type": "pnat" - } - }, - "all_tags" - ], - "filter": [ - { - "id": "has-fixme", - "options": [ - { - "osmTags": "fixme~*", - "question": "Heeft een FIXME" - } - ] - } - ] - }, - { - "id": "grb", - "description": "Geometry which comes from GRB with tools to import them", - "source": { - "osmTags": { - "and": [ - "HUISNR~*", - "man_made!=mast" - ] - }, - "geoJson": "https://betadata.grbosm.site/grb?bbox={x_min},{y_min},{x_max},{y_max}", - "geoJsonZoomLevel": 18, - "mercatorCrs": true, - "maxCacheAge": 0 - }, - "name": "GRB geometries", - "title": "GRB outline", - "calculatedTags": [ - "_overlaps_with_buildings=feat.overlapWith('osm-buildings').filter(f => f.feat.properties.id.indexOf('-') < 0)", - "_overlaps_with=feat.get('_overlaps_with_buildings').filter(f => f.overlap > 1 /* square meter */ )[0] ?? ''", - "_osm_obj:source:ref=feat.get('_overlaps_with')?.feat?.properties['source:geometry:ref']", - "_osm_obj:id=feat.get('_overlaps_with')?.feat?.properties?.id", - "_osm_obj:source:date=feat.get('_overlaps_with')?.feat?.properties['source:geometry:date'].replace(/\\//g, '-')", - "_osm_obj:building=feat.get('_overlaps_with')?.feat?.properties?.building", - "_osm_obj:addr:street=(feat.get('_overlaps_with')?.feat?.properties ?? {})['addr:street']", - "_osm_obj:addr:housenumber=(feat.get('_overlaps_with')?.feat?.properties ?? {})['addr:housenumber']", - "_osm_obj:surface=(feat.get('_overlaps_with')?.feat?.properties ?? {})['_surface:strict']", - - "_overlap_absolute=feat.get('_overlaps_with')?.overlap", - "_reverse_overlap_percentage=Math.round(100 * feat.get('_overlap_absolute') / feat.get('_surface'))", - "_overlap_percentage=Math.round(100 * feat.get('_overlap_absolute') / feat.get('_osm_obj:surface'))", - "_grb_ref=feat.properties['source:geometry:entity'] + '/' + feat.properties['source:geometry:oidn']", - "_imported_osm_object_found= feat.properties['_osm_obj:source:ref'] == feat.properties._grb_ref", - "_grb_date=feat.properties['source:geometry:date'].replace(/\\//g,'-')", - "_imported_osm_still_fresh= feat.properties['_osm_obj:source:date'] == feat.properties._grb_date", - "_target_building_type=feat.properties['_osm_obj:building'] === 'yes' ? feat.properties.building : (feat.properties['_osm_obj:building'] ?? feat.properties.building)", - "_building:min_level= feat.properties['fixme']?.startsWith('verdieping, correct the building tag, add building:level and building:min_level before upload in JOSM!') ? '1' : ''", - "_intersects_with_other_features=feat.intersectionsWith('generic_osm_object').map(f => \"\" + f.feat.properties.id + \"\").join(', ')" - ], - "tagRenderings": [], - "mapRendering": [ - { - "iconSize": "50,50,center", - "icon": "./assets/themes/grb_import/housenumber_blank.svg", - "location": [ - "point", - "centroid" - ] - } - ] - } - ] - } - - - constructor() { - super([ - ["House replacement with connected node", async () => { - - Minimap.createMiniMap = () => undefined; - - const coordinates = <[number, number][]>[ - [ - 3.216690793633461, - 51.21474084112525 - ], - [ - 3.2167256623506546, - 51.214696737309964 - ], - [ - 3.2169999182224274, - 51.214768983537674 - ], - [ - 3.2169650495052338, - 51.21480720678671 - ], - [ - 3.2169368863105774, - 51.21480090625335 - ], - [ - 3.2169489562511444, - 51.21478074454077 - ], - [ - 3.216886594891548, - 51.214765203214625 - ], - [ - 3.2168812304735184, - 51.21477192378873 - ], - [ - 3.2168644666671753, - 51.214768983537674 - ], - [ - 3.2168537378311157, - 51.21478746511261 - ], - [ - 3.216690793633461, - 51.21474084112525 - ] - ] - - const targetFeature = { - type: "Feature", - properties: {}, - geometry: { - type: "Polygon", - coordinates: [coordinates] - } - } - - const wayId = "way/160909312" - - Utils.injectJsonDownloadForTests( - "https://www.openstreetmap.org/api/0.6/map.json?bbox=3.2166673243045807,51.21467321525788,3.217007964849472,51.21482442824023", - { - "version": "0.6", - "generator": "CGImap 0.8.6 (1549677 spike-06.openstreetmap.org)", - "copyright": "OpenStreetMap and contributors", - "attribution": "http://www.openstreetmap.org/copyright", - "license": "http://opendatacommons.org/licenses/odbl/1-0/", - "bounds": {"minlat": 51.2146732, "minlon": 3.2166673, "maxlat": 51.2148244, "maxlon": 3.217008}, - "elements": [{ - "type": "node", - "id": 1612385157, - "lat": 51.2148016, - "lon": 3.2168453, - "timestamp": "2018-04-30T12:26:00Z", - "version": 3, - "changeset": 58553478, - "user": "Pieter Vander Vennet", - "uid": 3818858 - }, { - "type": "node", - "id": 1728816256, - "lat": 51.2147111, - "lon": 3.2170233, - "timestamp": "2017-07-18T22:52:44Z", - "version": 2, - "changeset": 50391526, - "user": "catweazle67", - "uid": 1976209 - }, { - "type": "node", - "id": 1728816287, - "lat": 51.2146408, - "lon": 3.2167601, - "timestamp": "2021-10-29T16:24:43Z", - "version": 3, - "changeset": 113131915, - "user": "Pieter Vander Vennet", - "uid": 3818858 - }, { - "type": "node", - "id": 1728823481, - "lat": 51.2146968, - "lon": 3.2167242, - "timestamp": "2021-11-02T23:37:11Z", - "version": 5, - "changeset": 113305401, - "user": "Pieter Vander Vennet", - "uid": 3818858 - }, { - "type": "node", - "id": 1728823499, - "lat": 51.2147127, - "lon": 3.2170302, - "timestamp": "2017-07-18T22:52:45Z", - "version": 2, - "changeset": 50391526, - "user": "catweazle67", - "uid": 1976209 - }, { - "type": "node", - "id": 1728823501, - "lat": 51.2148696, - "lon": 3.2168941, - "timestamp": "2017-07-18T22:52:45Z", - "version": 2, - "changeset": 50391526, - "user": "catweazle67", - "uid": 1976209 - }, { - "type": "node", - "id": 1728823514, - "lat": 51.2147863, - "lon": 3.2168551, - "timestamp": "2021-11-02T23:37:11Z", - "version": 5, - "changeset": 113305401, - "user": "Pieter Vander Vennet", - "uid": 3818858 - }, { - "type": "node", - "id": 1728823522, - "lat": 51.2148489, - "lon": 3.2169012, - "timestamp": "2017-07-18T22:52:45Z", - "version": 2, - "changeset": 50391526, - "user": "catweazle67", - "uid": 1976209 - }, { - "type": "node", - "id": 1728823523, - "lat": 51.2147578, - "lon": 3.2169995, - "timestamp": "2017-07-18T22:52:45Z", - "version": 2, - "changeset": 50391526, - "user": "catweazle67", - "uid": 1976209 - }, { - "type": "node", - "id": 1728823543, - "lat": 51.2148075, - "lon": 3.2166445, - "timestamp": "2017-07-18T22:52:46Z", - "version": 3, - "changeset": 50391526, - "user": "catweazle67", - "uid": 1976209 - }, { - "type": "node", - "id": 1728823544, - "lat": 51.2148553, - "lon": 3.2169315, - "timestamp": "2017-07-18T22:52:46Z", - "version": 2, - "changeset": 50391526, - "user": "catweazle67", - "uid": 1976209 - }, { - "type": "node", - "id": 1728823549, - "lat": 51.2147401, - "lon": 3.2168877, - "timestamp": "2021-11-02T23:37:11Z", - "version": 5, - "changeset": 113305401, - "user": "Pieter Vander Vennet", - "uid": 3818858 - }, { - "type": "node", - "id": 4978288376, - "lat": 51.2147306, - "lon": 3.2168928, - "timestamp": "2017-07-18T22:52:21Z", - "version": 1, - "changeset": 50391526, - "user": "catweazle67", - "uid": 1976209 - }, { - "type": "node", - "id": 4978288381, - "lat": 51.2147638, - "lon": 3.2168856, - "timestamp": "2021-11-02T23:37:11Z", - "version": 4, - "changeset": 113305401, - "user": "Pieter Vander Vennet", - "uid": 3818858 - }, { - "type": "node", - "id": 4978288382, - "lat": 51.2148189, - "lon": 3.216912, - "timestamp": "2017-07-18T22:52:21Z", - "version": 1, - "changeset": 50391526, - "user": "catweazle67", - "uid": 1976209 - }, { - "type": "node", - "id": 4978288385, - "lat": 51.2148835, - "lon": 3.2170623, - "timestamp": "2017-07-18T22:52:21Z", - "version": 1, - "changeset": 50391526, - "user": "catweazle67", - "uid": 1976209 - }, { - "type": "node", - "id": 4978288387, - "lat": 51.2148904, - "lon": 3.2171037, - "timestamp": "2017-07-18T22:52:21Z", - "version": 1, - "changeset": 50391526, - "user": "catweazle67", - "uid": 1976209 - }, { - "type": "node", - "id": 4978289383, - "lat": 51.2147678, - "lon": 3.2169969, - "timestamp": "2021-11-02T23:37:11Z", - "version": 4, - "changeset": 113305401, - "user": "Pieter Vander Vennet", - "uid": 3818858 - }, { - "type": "node", - "id": 4978289384, - "lat": 51.2147684, - "lon": 3.2168674, - "timestamp": "2021-11-02T23:37:11Z", - "version": 4, - "changeset": 113305401, - "user": "Pieter Vander Vennet", - "uid": 3818858 - }, { - "type": "node", - "id": 4978289386, - "lat": 51.2147716, - "lon": 3.2168811, - "timestamp": "2021-11-02T23:37:11Z", - "version": 4, - "changeset": 113305401, - "user": "Pieter Vander Vennet", - "uid": 3818858 - }, { - "type": "node", - "id": 4978289388, - "lat": 51.2148115, - "lon": 3.216966, - "timestamp": "2021-11-02T23:38:13Z", - "version": 7, - "changeset": 113306325, - "user": "Pieter Vander Vennet", - "uid": 3818858 - }, { - "type": "node", - "id": 4978289391, - "lat": 51.2148019, - "lon": 3.2169194, - "timestamp": "2017-07-18T22:52:21Z", - "version": 1, - "changeset": 50391526, - "user": "catweazle67", - "uid": 1976209 - }, { - "type": "node", - "id": 9219974337, - "lat": 51.2148449, - "lon": 3.2171278, - "timestamp": "2021-11-02T23:40:52Z", - "version": 1, - "changeset": 113305401, - "user": "Pieter Vander Vennet", - "uid": 3818858 - }, { - "type": "node", - "id": 9219979643, - "lat": 51.2147405, - "lon": 3.216693, - "timestamp": "2021-11-02T23:37:11Z", - "version": 1, - "changeset": 113305401, - "user": "Pieter Vander Vennet", - "uid": 3818858 - }, { - "type": "node", - "id": 9219979646, - "lat": 51.2148043, - "lon": 3.2169312, - "timestamp": "2021-11-02T23:38:13Z", - "version": 2, - "changeset": 113306325, - "user": "Pieter Vander Vennet", - "uid": 3818858 - }, { - "type": "node", - "id": 9219979647, - "lat": 51.2147792, - "lon": 3.2169466, - "timestamp": "2021-11-02T23:37:11Z", - "version": 1, - "changeset": 113305401, - "user": "Pieter Vander Vennet", - "uid": 3818858 - }, { - "type": "way", - "id": 160909311, - "timestamp": "2021-12-23T12:03:37Z", - "version": 6, - "changeset": 115295690, - "user": "s8evq", - "uid": 3710738, - "nodes": [1728823481, 1728823549, 4978288376, 1728823523, 1728823499, 1728816256, 1728816287, 1728823481], - "tags": { - "addr:city": "Brugge", - "addr:country": "BE", - "addr:housenumber": "106", - "addr:postcode": "8000", - "addr:street": "Ezelstraat", - "building": "house", - "source:geometry:date": "2015-07-09", - "source:geometry:ref": "Gbg/2391617" - } - }, { - "type": "way", - "id": 160909312, - "timestamp": "2021-11-02T23:38:13Z", - "version": 4, - "changeset": 113306325, - "user": "Pieter Vander Vennet", - "uid": 3818858, - "nodes": [9219979643, 1728823481, 1728823549, 4978289383, 4978289388, 9219979646, 9219979647, 4978288381, 4978289386, 4978289384, 1728823514, 9219979643], - "tags": { - "addr:city": "Brugge", - "addr:country": "BE", - "addr:housenumber": "108", - "addr:postcode": "8000", - "addr:street": "Ezelstraat", - "building": "house", - "source:geometry:date": "2018-10-02", - "source:geometry:ref": "Gbg/5926383" - } - }, { - "type": "way", - "id": 160909315, - "timestamp": "2021-12-23T12:03:37Z", - "version": 8, - "changeset": 115295690, - "user": "s8evq", - "uid": 3710738, - "nodes": [1728823543, 1728823501, 1728823522, 4978288382, 1612385157, 1728823514, 9219979643, 1728823543], - "tags": { - "addr:city": "Brugge", - "addr:country": "BE", - "addr:housenumber": "110", - "addr:postcode": "8000", - "addr:street": "Ezelstraat", - "building": "house", - "name": "La Style", - "shop": "hairdresser", - "source:geometry:date": "2015-07-09", - "source:geometry:ref": "Gbg/5260837" - } - }, { - "type": "way", - "id": 508533816, - "timestamp": "2021-12-23T12:03:37Z", - "version": 7, - "changeset": 115295690, - "user": "s8evq", - "uid": 3710738, - "nodes": [4978288387, 4978288385, 1728823544, 1728823522, 4978288382, 4978289391, 9219979646, 4978289388, 9219974337, 4978288387], - "tags": { - "building": "yes", - "source:geometry:date": "2015-07-09", - "source:geometry:ref": "Gbg/5260790" - } - }] - } - ) - - Utils.injectJsonDownloadForTests( - "https://www.openstreetmap.org/api/0.6/way/160909312/full", - { - "version": "0.6", - "generator": "CGImap 0.8.6 (2407324 spike-06.openstreetmap.org)", - "copyright": "OpenStreetMap and contributors", - "attribution": "http://www.openstreetmap.org/copyright", - "license": "http://opendatacommons.org/licenses/odbl/1-0/", - "elements": [{ - "type": "node", - "id": 1728823481, - "lat": 51.2146968, - "lon": 3.2167242, - "timestamp": "2021-11-02T23:37:11Z", - "version": 5, - "changeset": 113305401, - "user": "Pieter Vander Vennet", - "uid": 3818858 - }, { - "type": "node", - "id": 1728823514, - "lat": 51.2147863, - "lon": 3.2168551, - "timestamp": "2021-11-02T23:37:11Z", - "version": 5, - "changeset": 113305401, - "user": "Pieter Vander Vennet", - "uid": 3818858 - }, { - "type": "node", - "id": 1728823549, - "lat": 51.2147401, - "lon": 3.2168877, - "timestamp": "2021-11-02T23:37:11Z", - "version": 5, - "changeset": 113305401, - "user": "Pieter Vander Vennet", - "uid": 3818858 - }, { - "type": "node", - "id": 4978288381, - "lat": 51.2147638, - "lon": 3.2168856, - "timestamp": "2021-11-02T23:37:11Z", - "version": 4, - "changeset": 113305401, - "user": "Pieter Vander Vennet", - "uid": 3818858 - }, { - "type": "node", - "id": 4978289383, - "lat": 51.2147678, - "lon": 3.2169969, - "timestamp": "2021-11-02T23:37:11Z", - "version": 4, - "changeset": 113305401, - "user": "Pieter Vander Vennet", - "uid": 3818858 - }, { - "type": "node", - "id": 4978289384, - "lat": 51.2147684, - "lon": 3.2168674, - "timestamp": "2021-11-02T23:37:11Z", - "version": 4, - "changeset": 113305401, - "user": "Pieter Vander Vennet", - "uid": 3818858 - }, { - "type": "node", - "id": 4978289386, - "lat": 51.2147716, - "lon": 3.2168811, - "timestamp": "2021-11-02T23:37:11Z", - "version": 4, - "changeset": 113305401, - "user": "Pieter Vander Vennet", - "uid": 3818858 - }, { - "type": "node", - "id": 4978289388, - "lat": 51.2148115, - "lon": 3.216966, - "timestamp": "2021-11-02T23:38:13Z", - "version": 7, - "changeset": 113306325, - "user": "Pieter Vander Vennet", - "uid": 3818858 - }, { - "type": "node", - "id": 9219979643, - "lat": 51.2147405, - "lon": 3.216693, - "timestamp": "2021-11-02T23:37:11Z", - "version": 1, - "changeset": 113305401, - "user": "Pieter Vander Vennet", - "uid": 3818858 - }, { - "type": "node", - "id": 9219979646, - "lat": 51.2148043, - "lon": 3.2169312, - "timestamp": "2021-11-02T23:38:13Z", - "version": 2, - "changeset": 113306325, - "user": "Pieter Vander Vennet", - "uid": 3818858 - }, { - "type": "node", - "id": 9219979647, - "lat": 51.2147792, - "lon": 3.2169466, - "timestamp": "2021-11-02T23:37:11Z", - "version": 1, - "changeset": 113305401, - "user": "Pieter Vander Vennet", - "uid": 3818858 - }, { - "type": "way", - "id": 160909312, - "timestamp": "2021-11-02T23:38:13Z", - "version": 4, - "changeset": 113306325, - "user": "Pieter Vander Vennet", - "uid": 3818858, - "nodes": [9219979643, 1728823481, 1728823549, 4978289383, 4978289388, 9219979646, 9219979647, 4978288381, 4978289386, 4978289384, 1728823514, 9219979643], - "tags": { - "addr:city": "Brugge", - "addr:country": "BE", - "addr:housenumber": "108", - "addr:postcode": "8000", - "addr:street": "Ezelstraat", - "building": "house", - "source:geometry:date": "2018-10-02", - "source:geometry:ref": "Gbg/5926383" - } - }] - } - ) - Utils.injectJsonDownloadForTests("https://raw.githubusercontent.com/pietervdvn/MapComplete-data/main/latlon2country/0.0.0.json", "be") - - const layout = new LayoutConfig(ReplaceGeometrySpec.grbStripped) - - - const state = new State(layout) - State.state = state; - const bbox = new BBox( - [[ - 3.2166673243045807, - 51.21467321525788 - ], - [ - 3.217007964849472, - 51.21482442824023 - ] - ]) - const url = `https://www.openstreetmap.org/api/0.6/map.json?bbox=${bbox.minLon},${bbox.minLat},${bbox.maxLon},${bbox.maxLat}` - const data = await Utils.downloadJson(url) - - state.featurePipeline.fullNodeDatabase.handleOsmJson(data, 0) - - - const action = new ReplaceGeometryAction(state, targetFeature, wayId, { - theme: "test" - } - ) - - const closestIds = await action.GetClosestIds() - T.listIdentical( - [9219979643, - 1728823481, - 4978289383, - 4978289388, - 9219979646, - 9219979647, - 4978288381, - 4978289386, - 4978289384, - 1728823514, - undefined], - closestIds.closestIds - ); - - T.equals(1, closestIds.reprojectedNodes.size, "Expected only a single reprojected node"); - const reproj = closestIds.reprojectedNodes.get(1728823549) - T.equals(1, reproj.projectAfterIndex) - T.equals(3.2168880864669203, reproj.newLon); - T.equals(51.214739524104694, reproj.newLat); - T.equals(0, closestIds.detachedNodes.size) - const changes = await action.Perform(state.changes) - T.listIdentical([[3.216690793633461, 51.21474084112525], [3.2167256623506546, 51.214696737309964], [3.2168880864669203, 51.214739524104694], [3.2169999182224274, 51.214768983537674], [3.2169650495052338, 51.21480720678671], [3.2169368863105774, 51.21480090625335], [3.2169489562511444, 51.21478074454077], [3.216886594891548, 51.214765203214625], [3.2168812304735184, 51.21477192378873], [3.2168644666671753, 51.214768983537674], [3.2168537378311157, 51.21478746511261], [3.216690793633461, 51.21474084112525]], - changes[11].changes["coordinates"]) - - }], - ]); - } -} \ No newline at end of file diff --git a/testLegacy/TestAll.ts b/testLegacy/TestAll.ts index 36c9e7e61..19dab17f9 100644 --- a/testLegacy/TestAll.ts +++ b/testLegacy/TestAll.ts @@ -1,45 +1,19 @@ import GeoOperationsSpec from "./GeoOperations.spec"; -import OsmObjectSpec from "./OsmObject.spec"; -import ScriptUtils from "../scripts/ScriptUtils"; -import RelationSplitHandlerSpec from "./RelationSplitHandler.spec"; -import SplitActionSpec from "./SplitAction.spec"; -import {Utils} from "../Utils"; -import ImageProviderSpec from "./ImageProvider.spec"; -import ReplaceGeometrySpec from "./ReplaceGeometry.spec"; import LegacyThemeLoaderSpec from "./LegacyThemeLoader.spec"; import T from "./TestHelper"; -import CreateNoteImportLayerSpec from "./CreateNoteImportLayer.spec"; import CreateCacheSpec from "./CreateCache.spec"; import ImportMultiPolygonSpec from "./ImportMultiPolygon.spec"; -import ChangesetHandlerSpec from "./ChangesetHandler.spec"; async function main() { const allTests: T[] = [ - new ChangesetHandlerSpec(), - new OsmObjectSpec(), new GeoOperationsSpec(), - new RelationSplitHandlerSpec(), - new SplitActionSpec(), - new ImageProviderSpec(), - new ReplaceGeometrySpec(), new LegacyThemeLoaderSpec(), - new CreateNoteImportLayerSpec(), new CreateCacheSpec(), new ImportMultiPolygonSpec(), ] - ScriptUtils.fixUtils(); - const realDownloadFunc = Utils.externalDownloadFunction; - Utils.externalDownloadFunction = async (url) => { - console.error("Fetching ", url, "blocked in tests, use Utils.injectJsonDownloadForTests") - const data = await realDownloadFunc(url) - console.log("\n\n ----------- \nBLOCKED DATA\n Utils.injectJsonDownloadForTests(\n" + - " ", JSON.stringify(url), ", \n", - " ", JSON.stringify(data), "\n )\n------------------\n\n") - throw "Detected internet access for URL " + url + ", please inject it with Utils.injectJsonDownloadForTests" - } let args = [...process.argv] args.splice(0, 2) diff --git a/testLegacy/TestHelper.ts b/testLegacy/TestHelper.ts index 0c56d4150..01a40dcbf 100644 --- a/testLegacy/TestHelper.ts +++ b/testLegacy/TestHelper.ts @@ -1,3 +1,5 @@ +import {expect} from "chai" + export default class T { public readonly name: string; @@ -7,46 +9,6 @@ export default class T { this.name = this.constructor.name; this._tests = tests; } - - static isTrue(b: boolean, msg: string) { - if (!b) { - throw "Expected true, but got false: " + msg - } - } - - static equals(expected, got, msg?) { - if (expected !== got) { - throw "Not the same: " + (msg ?? "") + "\n" + - "Expected: " + expected + "\n" + - "Got : " + got - } - } - - static isFalse(b: boolean, msg: string) { - if (b) { - throw "Expected false, but got true: " + msg - } - } - - static listIdentical(expected: T[], actual: T[]): void { - if (expected === undefined) { - throw "ListIdentical failed: expected list is undefined" - } - if (actual === undefined) { - throw "ListIdentical failed: actual list is undefined" - } - if (expected.length !== actual.length) { - throw `ListIdentical failed: expected a list of length ${expected.length} but got a list of length ${actual.length}` - } - for (let i = 0; i < expected.length; i++) { - if (Array.isArray(expected[i])) { - T.listIdentical(expected[i], actual[i]) - } else if (expected[i] !== actual[i]) { - throw `ListIdentical failed at index ${i}: expected ${expected[i]} but got ${actual[i]}` - } - } - } - /** * RUns the test, returns the error messages. * Returns an empty list if successful diff --git a/tests/Chai.spec.ts b/tests/Chai.spec.ts index 36edff7f5..cc11fcb7f 100644 --- a/tests/Chai.spec.ts +++ b/tests/Chai.spec.ts @@ -1,5 +1,6 @@ import {describe} from 'mocha' import {expect} from 'chai' +import {Utils} from "../Utils"; describe("TestSuite", () => { @@ -10,6 +11,7 @@ describe("TestSuite", () => { }) }) -it("global test", () => { +it("global test", async() => { expect("abc").eq("abc") + expect(() => {throw "hi"}).throws(/hi/) }) \ No newline at end of file diff --git a/tests/Logic/Actors/Actors.spec.ts b/tests/Logic/Actors/Actors.spec.ts index cb3faf9eb..334647c56 100644 --- a/tests/Logic/Actors/Actors.spec.ts +++ b/tests/Logic/Actors/Actors.spec.ts @@ -1,10 +1,8 @@ -import {describe} from 'mocha' import {expect} from 'chai' import {Utils} from "../../../Utils"; import UserRelatedState from "../../../Logic/State/UserRelatedState"; import LayoutConfig from "../../../Models/ThemeConfig/LayoutConfig"; import SelectedElementTagsUpdater from "../../../Logic/Actors/SelectedElementTagsUpdater"; -import T from "../../../testLegacy/TestHelper"; import * as bookcaseJson from "../../../assets/generated/themes/bookcases.json" import {UIEventSource} from "../../../Logic/UIEventSource"; @@ -95,9 +93,9 @@ it("should download the latest version", () => { SelectedElementTagsUpdater.applyUpdate(state, latestTags, feature.properties.id) // The name should be updated - T.equals("Stubbekwartier-buurtbibliotheek", feature.properties.name) + expect(feature.properties.name).deep.equal("Stubbekwartier-buurtbibliotheek") // The fixme should be removed - T.equals(undefined, feature.properties.fixme) + expect(feature.properties.fixme).deep.equal(undefined) }) it("Hash without selected element should download geojson from OSM-API", async () => { @@ -111,9 +109,9 @@ it("Hash without selected element should download geojson from OSM-API", async ( loc.addCallback(_ => { - T.equals("node/5568693115", selected.data.properties.id) - T.equals(14, loc.data.zoom) - T.equals(51.2179199, loc.data.lat) + expect(selected.data.properties.id).deep.equal("node/5568693115") + expect(loc.data.zoom).deep.equal(14) + expect(loc.data.lat).deep.equal(51.2179199) }) new SelectedFeatureHandler(hash, { diff --git a/tests/Logic/ImageProviders/ImageProviders.spec.ts b/tests/Logic/ImageProviders/ImageProviders.spec.ts new file mode 100644 index 000000000..0000633b1 --- /dev/null +++ b/tests/Logic/ImageProviders/ImageProviders.spec.ts @@ -0,0 +1,77 @@ +import {describe} from 'mocha' +import {expect} from 'chai' +import AllImageProviders from "../../../Logic/ImageProviders/AllImageProviders"; +import {UIEventSource} from "../../../Logic/UIEventSource"; +import {Utils} from "../../../Utils"; + +describe("ImageProviders", () => { + + it("should work on a variaty of inputs", () => { + let i = 0 + function expects(url, tags, providerName = undefined) { + tags.id = "test/" + i + i++ + AllImageProviders.LoadImagesFor(new UIEventSource(tags)).addCallbackD(images => { + console.log("ImageProvider test", tags.id, "for", tags) + const img = images[0] + if (img === undefined) { + throw "No image found" + } + expect(img.url).deep.equal(url) + if (providerName) { + expect(providerName).deep.equal(img.provider.constructor.name) + } + console.log("OK") + }) + } + + const muntpoort_expected = "https://commons.wikimedia.org/wiki/Special:FilePath/File%3ABr%C3%BCgge-Muntpoort_6-29510-58192.jpg?width=500&height=400" + expects( + muntpoort_expected, + { + "wikimedia_commons": "File:Brügge-Muntpoort_6-29510-58192.jpg" + }, "WikimediaImageProvider") + + + expects(muntpoort_expected, + { + "wikimedia_commons": "https://upload.wikimedia.org/wikipedia/commons/c/cd/Br%C3%BCgge-Muntpoort_6-29510-58192.jpg" + }, "WikimediaImageProvider") + + expects(muntpoort_expected, { + "image": "https://upload.wikimedia.org/wikipedia/commons/c/cd/Br%C3%BCgge-Muntpoort_6-29510-58192.jpg" + }, "WikimediaImageProvider") + + + expects("https://commons.wikimedia.org/wiki/Special:FilePath/File%3ABelgium-5955_-_Simon_Stevin_(13746657193).jpg?width=500&height=400", { + "image": "File:Belgium-5955_-_Simon_Stevin_(13746657193).jpg" + }, "WikimediaImageProvider") + + expects("https://commons.wikimedia.org/wiki/Special:FilePath/File%3ABelgium-5955_-_Simon_Stevin_(13746657193).jpg?width=500&height=400", { + "wikimedia_commons": "File:Belgium-5955_-_Simon_Stevin_(13746657193).jpg" + }, "WikimediaImageProvider") + + + expects("https://commons.wikimedia.org/wiki/Special:FilePath/File%3ABrugge_Leeuwstraat_zonder_nummer_Leeuwbrug_-_119334_-_onroerenderfgoed.jpg?width=500&height=400", { + image: "File:Brugge_Leeuwstraat_zonder_nummer_Leeuwbrug_-_119334_-_onroerenderfgoed.jpg" + }, "WikimediaImageProvider") + + expects("https://commons.wikimedia.org/wiki/Special:FilePath/File%3APapageno_Jef_Claerhout.jpg?width=500&height=400", { + "wikimedia_commons": "File:Papageno_Jef_Claerhout.jpg" + }, "WikimediaImageProvider") + + Utils.injectJsonDownloadForTests( + "https://graph.mapillary.com/196804715753265?fields=thumb_1024_url&&access_token=MLY|4441509239301885|b40ad2d3ea105435bd40c7e76993ae85", + { + "thumb_1024_url": "https://scontent-bru2-1.xx.fbcdn.net/m1/v/t6/An8HQ3DrfU76tWMC602spvM_e_rqOHyiUcYUTetXM7K52DDBEY5J4FWg4WKQqVUlMsWJn4nLXk0pxlBLx31146FqZ2Kg65z7lJUfR6wpW6WPSR5_y7RKdv4YEuzPjwIN0lagBnQONV3UjmXnEGpMouU?stp=s1024x768&ccb=10-5&oh=d460b401c505714ee1cb8bd6baf8ae5d&oe=61731FC3&_nc_sid=122ab1", + "id": "196804715753265" + } + ) + + expects("https://scontent-bru2-1.xx.fbcdn.net/m1/v/t6/An8HQ3DrfU76tWMC602spvM_e_rqOHyiUcYUTetXM7K52DDBEY5J4FWg4WKQqVUlMsWJn4nLXk0pxlBLx31146FqZ2Kg65z7lJUfR6wpW6WPSR5_y7RKdv4YEuzPjwIN0lagBnQONV3UjmXnEGpMouU?stp=s1024x768&ccb=10-5&oh=d460b401c505714ee1cb8bd6baf8ae5d&oe=61731FC3&_nc_sid=122ab1", { + "mapillary": "https://www.mapillary.com/app/?pKey=196804715753265" + }) + + + }) +}) \ No newline at end of file diff --git a/tests/Logic/OSM/Actions/RelationSplitHandler.spec.ts b/tests/Logic/OSM/Actions/RelationSplitHandler.spec.ts new file mode 100644 index 000000000..86cf5e23b --- /dev/null +++ b/tests/Logic/OSM/Actions/RelationSplitHandler.spec.ts @@ -0,0 +1,690 @@ +import {describe} from 'mocha' +import {expect} from 'chai' +import {Utils} from "../../../../Utils"; +import {OsmObject, OsmRelation} from "../../../../Logic/Osm/OsmObject"; +import {InPlaceReplacedmentRTSH, TurnRestrictionRSH} from "../../../../Logic/Osm/Actions/RelationSplitHandler"; +import {Changes} from "../../../../Logic/Osm/Changes"; + +describe("RelationSplitHandler", () => { + + Utils.injectJsonDownloadForTests( + "https://www.openstreetmap.org/api/0.6/node/1124134958/ways", + { + "version": "0.6", + "generator": "CGImap 0.8.5 (2937646 spike-07.openstreetmap.org)", + "copyright": "OpenStreetMap and contributors", + "attribution": "http://www.openstreetmap.org/copyright", + "license": "http://opendatacommons.org/licenses/odbl/1-0/", + "elements": [{ + "type": "way", + "id": 97038428, + "timestamp": "2019-06-19T12:26:24Z", + "version": 6, + "changeset": 71399984, + "user": "Pieter Vander Vennet", + "uid": 3818858, + "nodes": [1124134958, 323729212, 323729351, 2542460408, 187073405], + "tags": { + "highway": "residential", + "name": "Brugs-Kerkhofstraat", + "sett:pattern": "arc", + "surface": "sett" + } + }, { + "type": "way", + "id": 97038434, + "timestamp": "2019-06-19T12:26:24Z", + "version": 5, + "changeset": 71399984, + "user": "Pieter Vander Vennet", + "uid": 3818858, + "nodes": [1124134958, 1124135024, 187058607], + "tags": { + "bicycle": "use_sidepath", + "highway": "residential", + "name": "Kerkhofblommenstraat", + "sett:pattern": "arc", + "surface": "sett" + } + }, { + "type": "way", + "id": 97038435, + "timestamp": "2017-12-21T21:41:08Z", + "version": 4, + "changeset": 54826837, + "user": "Jakka", + "uid": 2403313, + "nodes": [1124134958, 2576628889, 1124135035, 5298371485, 5298371495], + "tags": {"bicycle": "use_sidepath", "highway": "residential", "name": "Kerkhofblommenstraat"} + }, { + "type": "way", + "id": 251446313, + "timestamp": "2019-01-07T19:22:47Z", + "version": 4, + "changeset": 66106872, + "user": "M!dgard", + "uid": 763799, + "nodes": [1124134958, 5243143198, 4555715455], + "tags": {"foot": "yes", "highway": "service"} + }] + } + ) + + Utils.injectJsonDownloadForTests( + "https://www.openstreetmap.org/api/0.6/relation/9572808", + { + "version": "0.6", + "generator": "CGImap 0.8.5 (3128319 spike-07.openstreetmap.org)", + "copyright": "OpenStreetMap and contributors", + "attribution": "http://www.openstreetmap.org/copyright", + "license": "http://opendatacommons.org/licenses/odbl/1-0/", + "elements": [{ + "type": "relation", + "id": 9572808, + "timestamp": "2021-08-12T12:44:06Z", + "version": 11, + "changeset": 109573204, + "user": "A67-A67", + "uid": 553736, + "members": [{"type": "way", "ref": 173662702, "role": ""}, { + "type": "way", + "ref": 467606230, + "role": "" + }, {"type": "way", "ref": 126267167, "role": ""}, { + "type": "way", + "ref": 301897426, + "role": "" + }, {"type": "way", "ref": 687866206, "role": ""}, { + "type": "way", + "ref": 295132739, + "role": "" + }, {"type": "way", "ref": 690497698, "role": ""}, { + "type": "way", + "ref": 627893684, + "role": "" + }, {"type": "way", "ref": 295132741, "role": ""}, { + "type": "way", + "ref": 301903120, + "role": "" + }, {"type": "way", "ref": 672541156, "role": ""}, { + "type": "way", + "ref": 126264330, + "role": "" + }, {"type": "way", "ref": 280440853, "role": ""}, { + "type": "way", + "ref": 838499667, + "role": "" + }, {"type": "way", "ref": 838499663, "role": ""}, { + "type": "way", + "ref": 690497623, + "role": "" + }, {"type": "way", "ref": 301902946, "role": ""}, { + "type": "way", + "ref": 280460715, + "role": "" + }, {"type": "way", "ref": 972534369, "role": ""}, { + "type": "way", + "ref": 695680702, + "role": "" + }, {"type": "way", "ref": 690497860, "role": ""}, { + "type": "way", + "ref": 295410363, + "role": "" + }, {"type": "way", "ref": 823864063, "role": ""}, { + "type": "way", + "ref": 663172088, + "role": "" + }, {"type": "way", "ref": 659950322, "role": ""}, { + "type": "way", + "ref": 659950323, + "role": "" + }, {"type": "way", "ref": 230180094, "role": ""}, { + "type": "way", + "ref": 690497912, + "role": "" + }, {"type": "way", "ref": 39588765, "role": ""}], + "tags": { + "distance": "13 km", + "name": "Abdijenroute", + "network": "lcn", + "old_name": "Spoorlijn 58", + "operator": "Toerisme West-Vlaanderen", + "railway": "abandoned", + "route": "bicycle", + "type": "route", + "wikipedia": "nl:Spoorlijn 58" + } + }] + } + ) + + Utils.injectJsonDownloadForTests( + "https://www.openstreetmap.org/api/0.6/way/687866206/full", + { + "version": "0.6", + "generator": "CGImap 0.8.5 (2601512 spike-07.openstreetmap.org)", + "copyright": "OpenStreetMap and contributors", + "attribution": "http://www.openstreetmap.org/copyright", + "license": "http://opendatacommons.org/licenses/odbl/1-0/", + "elements": [{ + "type": "node", + "id": 5273988959, + "lat": 51.1811406, + "lon": 3.2427712, + "timestamp": "2021-07-29T21:14:53Z", + "version": 6, + "changeset": 108847202, + "user": "kaart_fietser", + "uid": 11022240, + "tags": {"network:type": "node_network", "rwn_ref": "32"} + }, { + "type": "node", + "id": 6448669326, + "lat": 51.1811346, + "lon": 3.242891, + "timestamp": "2019-05-04T22:44:12Z", + "version": 1, + "changeset": 69891295, + "user": "Pieter Vander Vennet", + "uid": 3818858, + "tags": {"barrier": "bollard"} + }, { + "type": "way", + "id": 687866206, + "timestamp": "2019-05-06T20:52:20Z", + "version": 2, + "changeset": 69951497, + "user": "noelbov", + "uid": 8054928, + "nodes": [6448669326, 5273988959], + "tags": { + "highway": "cycleway", + "name": "Abdijenroute", + "railway": "abandoned", + "surface": "asphalt" + } + }] + } + ) + + Utils.injectJsonDownloadForTests( + "https://www.openstreetmap.org/api/0.6/way/690497698/full", + { + "version": "0.6", + "generator": "CGImap 0.8.5 (3023311 spike-07.openstreetmap.org)", + "copyright": "OpenStreetMap and contributors", + "attribution": "http://www.openstreetmap.org/copyright", + "license": "http://opendatacommons.org/licenses/odbl/1-0/", + "elements": [{ + "type": "node", + "id": 170497152, + "lat": 51.1832353, + "lon": 3.2498759, + "timestamp": "2018-04-24T00:29:37Z", + "version": 7, + "changeset": 58357376, + "user": "Pieter Vander Vennet", + "uid": 3818858 + }, { + "type": "node", + "id": 2988218625, + "lat": 51.1835053, + "lon": 3.2503067, + "timestamp": "2018-09-24T21:48:46Z", + "version": 2, + "changeset": 62895918, + "user": "A67-A67", + "uid": 553736 + }, { + "type": "node", + "id": 5273988967, + "lat": 51.182659, + "lon": 3.249004, + "timestamp": "2017-12-09T18:40:21Z", + "version": 1, + "changeset": 54493533, + "user": "CacherB", + "uid": 1999108 + }, { + "type": "way", + "id": 690497698, + "timestamp": "2021-07-29T21:14:53Z", + "version": 3, + "changeset": 108847202, + "user": "kaart_fietser", + "uid": 11022240, + "nodes": [2988218625, 170497152, 5273988967], + "tags": { + "highway": "cycleway", + "lit": "no", + "name": "Abdijenroute", + "oneway": "no", + "railway": "abandoned", + "surface": "compacted" + } + }] + } + ) + Utils.injectJsonDownloadForTests( + "https://www.openstreetmap.org/api/0.6/relation/4374576", + { + "version": "0.6", + "generator": "CGImap 0.8.5 (1266692 spike-06.openstreetmap.org)", + "copyright": "OpenStreetMap and contributors", + "attribution": "http://www.openstreetmap.org/copyright", + "license": "http://opendatacommons.org/licenses/odbl/1-0/", + "elements": [{ + "type": "relation", + "id": 4374576, + "timestamp": "2014-12-23T21:42:27Z", + "version": 2, + "changeset": 27660623, + "user": "escada", + "uid": 436365, + "members": [{"type": "way", "ref": 318616190, "role": "from"}, { + "type": "node", + "ref": 1407529979, + "role": "via" + }, {"type": "way", "ref": 143298912, "role": "to"}], + "tags": {"restriction": "no_right_turn", "type": "restriction"} + }] + } + ) + + Utils.injectJsonDownloadForTests( + "https://www.openstreetmap.org/api/0.6/way/143298912/full", + { + "version": "0.6", + "generator": "CGImap 0.8.5 (4046166 spike-07.openstreetmap.org)", + "copyright": "OpenStreetMap and contributors", + "attribution": "http://www.openstreetmap.org/copyright", + "license": "http://opendatacommons.org/licenses/odbl/1-0/", + "elements": [{ + "type": "node", + "id": 26343912, + "lat": 51.2146847, + "lon": 3.2397007, + "timestamp": "2015-04-11T10:40:56Z", + "version": 5, + "changeset": 30139621, + "user": "M!dgard", + "uid": 763799 + }, { + "type": "node", + "id": 26343913, + "lat": 51.2161912, + "lon": 3.2386907, + "timestamp": "2015-04-11T10:40:56Z", + "version": 6, + "changeset": 30139621, + "user": "M!dgard", + "uid": 763799 + }, { + "type": "node", + "id": 26343914, + "lat": 51.2193456, + "lon": 3.2360696, + "timestamp": "2015-04-11T10:40:56Z", + "version": 5, + "changeset": 30139621, + "user": "M!dgard", + "uid": 763799 + }, { + "type": "node", + "id": 26343915, + "lat": 51.2202816, + "lon": 3.2352429, + "timestamp": "2015-04-11T10:40:56Z", + "version": 5, + "changeset": 30139621, + "user": "M!dgard", + "uid": 763799 + }, { + "type": "node", + "id": 875668688, + "lat": 51.2131868, + "lon": 3.2406009, + "timestamp": "2015-04-11T10:40:56Z", + "version": 4, + "changeset": 30139621, + "user": "M!dgard", + "uid": 763799 + }, { + "type": "node", + "id": 1109632153, + "lat": 51.2207068, + "lon": 3.234882, + "timestamp": "2015-04-11T10:40:55Z", + "version": 3, + "changeset": 30139621, + "user": "M!dgard", + "uid": 763799 + }, { + "type": "node", + "id": 1109632154, + "lat": 51.220784, + "lon": 3.2348394, + "timestamp": "2021-05-30T08:01:17Z", + "version": 4, + "changeset": 105557550, + "user": "albertino", + "uid": 499281 + }, { + "type": "node", + "id": 1109632177, + "lat": 51.2205082, + "lon": 3.2350441, + "timestamp": "2015-04-11T10:40:55Z", + "version": 3, + "changeset": 30139621, + "user": "M!dgard", + "uid": 763799 + }, { + "type": "node", + "id": 1407529961, + "lat": 51.2168476, + "lon": 3.2381772, + "timestamp": "2015-04-11T10:40:55Z", + "version": 2, + "changeset": 30139621, + "user": "M!dgard", + "uid": 763799 + }, { + "type": "node", + "id": 1407529969, + "lat": 51.2155155, + "lon": 3.23917, + "timestamp": "2011-08-21T20:08:27Z", + "version": 1, + "changeset": 9088257, + "user": "toeklk", + "uid": 219908 + }, { + "type": "node", + "id": 1407529979, + "lat": 51.212694, + "lon": 3.2409595, + "timestamp": "2015-04-11T10:40:55Z", + "version": 6, + "changeset": 30139621, + "user": "M!dgard", + "uid": 763799, + "tags": {"highway": "traffic_signals"} + }, { + "type": "node", + "id": 1634435395, + "lat": 51.2129189, + "lon": 3.2408257, + "timestamp": "2012-02-15T19:37:51Z", + "version": 1, + "changeset": 10695640, + "user": "Eimai", + "uid": 6072 + }, { + "type": "node", + "id": 1634435396, + "lat": 51.2132508, + "lon": 3.2405417, + "timestamp": "2012-02-15T19:37:51Z", + "version": 1, + "changeset": 10695640, + "user": "Eimai", + "uid": 6072 + }, { + "type": "node", + "id": 1634435397, + "lat": 51.2133918, + "lon": 3.2404416, + "timestamp": "2015-04-11T10:40:55Z", + "version": 2, + "changeset": 30139621, + "user": "M!dgard", + "uid": 763799 + }, { + "type": "node", + "id": 1974988033, + "lat": 51.2127459, + "lon": 3.240928, + "timestamp": "2012-10-20T12:24:13Z", + "version": 1, + "changeset": 13566903, + "user": "skyman81", + "uid": 955688 + }, { + "type": "node", + "id": 3250129361, + "lat": 51.2127906, + "lon": 3.2409016, + "timestamp": "2018-12-19T00:00:33Z", + "version": 2, + "changeset": 65596519, + "user": "beardhatcode", + "uid": 5439560, + "tags": {"crossing": "traffic_signals", "highway": "crossing"} + }, { + "type": "node", + "id": 3250129363, + "lat": 51.2149189, + "lon": 3.2395571, + "timestamp": "2015-04-11T10:40:56Z", + "version": 2, + "changeset": 30139621, + "user": "M!dgard", + "uid": 763799 + }, { + "type": "node", + "id": 3450326133, + "lat": 51.2139571, + "lon": 3.2401205, + "timestamp": "2015-04-11T10:40:26Z", + "version": 1, + "changeset": 30139621, + "user": "M!dgard", + "uid": 763799 + }, { + "type": "node", + "id": 3450326135, + "lat": 51.2181385, + "lon": 3.2370893, + "timestamp": "2015-04-11T10:40:26Z", + "version": 1, + "changeset": 30139621, + "user": "M!dgard", + "uid": 763799 + }, { + "type": "node", + "id": 4794847239, + "lat": 51.2191224, + "lon": 3.2362584, + "timestamp": "2019-08-27T23:07:05Z", + "version": 2, + "changeset": 73816461, + "user": "Pieter Vander Vennet", + "uid": 3818858 + }, { + "type": "node", + "id": 8493044168, + "lat": 51.2130348, + "lon": 3.2407284, + "timestamp": "2021-03-06T21:52:51Z", + "version": 1, + "changeset": 100555232, + "user": "kaart_fietser", + "uid": 11022240, + "tags": {"highway": "traffic_signals", "traffic_signals": "traffic_lights"} + }, { + "type": "node", + "id": 8792687918, + "lat": 51.2207505, + "lon": 3.2348579, + "timestamp": "2021-06-02T18:27:15Z", + "version": 1, + "changeset": 105735092, + "user": "albertino", + "uid": 499281 + }, { + "type": "way", + "id": 143298912, + "timestamp": "2021-06-02T18:27:15Z", + "version": 15, + "changeset": 105735092, + "user": "albertino", + "uid": 499281, + "nodes": [1407529979, 1974988033, 3250129361, 1634435395, 8493044168, 875668688, 1634435396, 1634435397, 3450326133, 26343912, 3250129363, 1407529969, 26343913, 1407529961, 3450326135, 4794847239, 26343914, 26343915, 1109632177, 1109632153, 8792687918, 1109632154], + "tags": { + "cycleway:right": "track", + "highway": "primary", + "lanes": "2", + "lit": "yes", + "maxspeed": "70", + "name": "Buiten Kruisvest", + "oneway": "yes", + "ref": "R30", + "surface": "asphalt", + "wikipedia": "nl:Buiten Kruisvest" + } + }] + } + ) + + + + + it("should split all cycling relation (split 295132739)", + async () => { + // Lets mimick a split action of https://www.openstreetmap.org/way/295132739 + + const relation: OsmRelation = await OsmObject.DownloadObjectAsync("relation/9572808") + const originalNodeIds = [5273988967, + 170497153, + 1507524582, + 4524321710, + 170497155, + 170497157, + 170497158, + 3208166179, + 1507524610, + 170497160, + 3208166178, + 1507524573, + 1575932830, + 6448669326] + + const withSplit = [[5273988967, + 170497153, + 1507524582, + 4524321710, + 170497155, + 170497157, + 170497158], + [ + 3208166179, + 1507524610, + 170497160, + 3208166178, + 1507524573, + 1575932830, + 6448669326]] + + const splitter = new InPlaceReplacedmentRTSH( + { + relation: relation, + originalWayId: 295132739, + allWayIdsInOrder: [295132739, -1], + originalNodes: originalNodeIds, + allWaysNodesInOrder: withSplit + }, "no-theme") + const changeDescription = await splitter.CreateChangeDescriptions(new Changes()) + const allIds = changeDescription[0].changes["members"].map(m => m.ref).join(",") + const expected = "687866206,295132739,-1,690497698" + expect(allIds.indexOf(expected) >= 0, "didn't find the expected order of ids in the relation to test").true + }) + + it( + "should split turn restrictions (split of https://www.openstreetmap.org/way/143298912)", + async () => { + + const relation: OsmRelation = await OsmObject.DownloadObjectAsync("relation/4374576") + const originalNodeIds = + [ + 1407529979, + 1974988033, + 3250129361, + 1634435395, + 8493044168, + 875668688, + 1634435396, + 1634435397, + 3450326133, + 26343912, + 3250129363, + 1407529969, + 26343913, + 1407529961, + 3450326135, + 4794847239, + 26343914, + 26343915, + 1109632177, + 1109632153, + 8792687918, + 1109632154 + + ] + + const withSplit = [[ + 1407529979, // The via point + 1974988033, + 3250129361, + 1634435395, + 8493044168, + 875668688, + 1634435396, + 1634435397, + 3450326133, + 26343912, + 3250129363, + 1407529969, + 26343913], + [ + 1407529961, + 3450326135, + 4794847239, + 26343914, + 26343915, + 1109632177, + 1109632153, + 8792687918, + 1109632154 + + ]] + + const splitter = new TurnRestrictionRSH( + { + relation: relation, + originalWayId: 143298912, + allWayIdsInOrder: [-1, 143298912], + originalNodes: originalNodeIds, + allWaysNodesInOrder: withSplit + }, "no-theme") + const changeDescription = await splitter.CreateChangeDescriptions(new Changes()) + const allIds = changeDescription[0].changes["members"].map(m => m.type + "/" + m.ref + "-->" + m.role).join(",") + const expected = "way/318616190-->from,node/1407529979-->via,way/-1-->to" + expect(allIds).deep.equal(expected) + + + // Reversing the ids has no effect + const splitterReverse = new TurnRestrictionRSH( + { + relation: relation, + originalWayId: 143298912, + allWayIdsInOrder: [143298912, -1], + originalNodes: originalNodeIds, + allWaysNodesInOrder: withSplit + }, "no-theme") + const changesReverse = await splitterReverse.CreateChangeDescriptions(new Changes()) + expect(changesReverse.length).deep.equal(0) + + } + ) +}) diff --git a/tests/Logic/OSM/Actions/ReplaceGeometryAction.spec.ts b/tests/Logic/OSM/Actions/ReplaceGeometryAction.spec.ts new file mode 100644 index 000000000..3e4cd31e6 --- /dev/null +++ b/tests/Logic/OSM/Actions/ReplaceGeometryAction.spec.ts @@ -0,0 +1,927 @@ +import {describe} from 'mocha' +import {expect} from 'chai' +import Minimap from "../../../../UI/Base/Minimap"; +import {Utils} from "../../../../Utils"; +import LayoutConfig from "../../../../Models/ThemeConfig/LayoutConfig"; +import State from "../../../../State"; +import {BBox} from "../../../../Logic/BBox"; +import ReplaceGeometryAction from "../../../../Logic/Osm/Actions/ReplaceGeometryAction"; + +describe("ReplaceGeometryAction", () => { + + const grbStripped = { + "id": "grb", + "title": { + "nl": "GRB import helper" + }, + "description": "Smaller version of the GRB theme", + "language": [ + "nl", + "en" + ], + socialImage: "img.jpg", + "version": "0", + "startLat": 51.0249, + "startLon": 4.026489, + "startZoom": 9, + "clustering": false, + "overrideAll": { + "minzoom": 19 + }, + "layers": [ + { + "id": "type_node", + source: { + osmTags: "type=node" + }, + mapRendering: null, + "override": { + "calculatedTags": [ + "_is_part_of_building=feat.get('parent_ways')?.some(p => p.building !== undefined && p.building !== '') ?? false", + "_is_part_of_grb_building=feat.get('parent_ways')?.some(p => p['source:geometry:ref'] !== undefined) ?? false", + "_is_part_of_building_passage=feat.get('parent_ways')?.some(p => p.tunnel === 'building_passage') ?? false", + "_is_part_of_highway=!feat.get('is_part_of_building_passage') && (feat.get('parent_ways')?.some(p => p.highway !== undefined && p.highway !== '') ?? false)", + "_is_part_of_landuse=feat.get('parent_ways')?.some(p => (p.landuse !== undefined && p.landuse !== '') || (p.natural !== undefined && p.natural !== '')) ?? false", + "_moveable=feat.get('_is_part_of_building') && !feat.get('_is_part_of_grb_building')" + ], + "mapRendering": [ + { + "icon": "square:#cc0", + "iconSize": "5,5,center", + "location": [ + "point" + ] + } + ], + "passAllFeatures": true + } + }, + { + "id": "osm-buildings", + "name": "All OSM-buildings", + "source": { + "osmTags": "building~*", + "maxCacheAge": 0 + }, + "calculatedTags": [ + "_surface:strict:=feat.get('_surface')" + ], + "mapRendering": [ + { + "width": { + "render": "2", + "mappings": [ + { + "if": "fixme~*", + "then": "5" + } + ] + }, + "color": { + "render": "#00c", + "mappings": [ + { + "if": "fixme~*", + "then": "#ff00ff" + }, + { + "if": "building=house", + "then": "#a00" + }, + { + "if": "building=shed", + "then": "#563e02" + }, + { + "if": { + "or": [ + "building=garage", + "building=garages" + ] + }, + "then": "#f9bfbb" + }, + { + "if": "building=yes", + "then": "#0774f2" + } + ] + } + } + ], + "title": "OSM-gebouw", + "tagRenderings": [ + { + "id": "building type", + "freeform": { + "key": "building" + }, + "render": "The building type is {building}", + "question": { + "en": "What kind of building is this?" + }, + "mappings": [ + { + "if": "building=house", + "then": "A normal house" + }, + { + "if": "building=detached", + "then": "A house detached from other building" + }, + { + "if": "building=semidetached_house", + "then": "A house sharing only one wall with another house" + }, + { + "if": "building=apartments", + "then": "An apartment building - highrise for living" + }, + { + "if": "building=office", + "then": "An office building - highrise for work" + }, + { + "if": "building=apartments", + "then": "An apartment building" + }, + { + "if": "building=shed", + "then": "A small shed, e.g. in a garden" + }, + { + "if": "building=garage", + "then": "A single garage to park a car" + }, + { + "if": "building=garages", + "then": "A building containing only garages; typically they are all identical" + }, + { + "if": "building=yes", + "then": "A building - no specification" + } + ] + }, + { + "id": "grb-housenumber", + "render": { + "nl": "Het huisnummer is {addr:housenumber}" + }, + "question": { + "nl": "Wat is het huisnummer?" + }, + "freeform": { + "key": "addr:housenumber" + }, + "mappings": [ + { + "if": { + "and": [ + "not:addr:housenumber=yes", + "addr:housenumber=" + ] + }, + "then": { + "nl": "Geen huisnummer" + } + } + ] + }, + { + "id": "grb-unit", + "question": "Wat is de wooneenheid-aanduiding?", + "render": { + "nl": "De wooneenheid-aanduiding is {addr:unit} " + }, + "freeform": { + "key": "addr:unit" + }, + "mappings": [ + { + "if": "addr:unit=", + "then": "Geen wooneenheid-nummer" + } + ] + }, + { + "id": "grb-street", + "render": { + "nl": "De straat is {addr:street}" + }, + "freeform": { + "key": "addr:street" + }, + "question": { + "nl": "Wat is de straat?" + } + }, + { + "id": "grb-fixme", + "render": { + "nl": "De fixme is {fixme}" + }, + "question": { + "nl": "Wat zegt de fixme?" + }, + "freeform": { + "key": "fixme" + }, + "mappings": [ + { + "if": { + "and": [ + "fixme=" + ] + }, + "then": { + "nl": "Geen fixme" + } + } + ] + }, + { + "id": "grb-min-level", + "render": { + "nl": "Dit gebouw begint maar op de {building:min_level} verdieping" + }, + "question": { + "nl": "Hoeveel verdiepingen ontbreken?" + }, + "freeform": { + "key": "building:min_level", + "type": "pnat" + } + }, + "all_tags" + ], + "filter": [ + { + "id": "has-fixme", + "options": [ + { + "osmTags": "fixme~*", + "question": "Heeft een FIXME" + } + ] + } + ] + }, + { + "id": "grb", + "description": "Geometry which comes from GRB with tools to import them", + "source": { + "osmTags": { + "and": [ + "HUISNR~*", + "man_made!=mast" + ] + }, + "geoJson": "https://betadata.grbosm.site/grb?bbox={x_min},{y_min},{x_max},{y_max}", + "geoJsonZoomLevel": 18, + "mercatorCrs": true, + "maxCacheAge": 0 + }, + "name": "GRB geometries", + "title": "GRB outline", + "calculatedTags": [ + "_overlaps_with_buildings=feat.overlapWith('osm-buildings').filter(f => f.feat.properties.id.indexOf('-') < 0)", + "_overlaps_with=feat.get('_overlaps_with_buildings').filter(f => f.overlap > 1 /* square meter */ )[0] ?? ''", + "_osm_obj:source:ref=feat.get('_overlaps_with')?.feat?.properties['source:geometry:ref']", + "_osm_obj:id=feat.get('_overlaps_with')?.feat?.properties?.id", + "_osm_obj:source:date=feat.get('_overlaps_with')?.feat?.properties['source:geometry:date'].replace(/\\//g, '-')", + "_osm_obj:building=feat.get('_overlaps_with')?.feat?.properties?.building", + "_osm_obj:addr:street=(feat.get('_overlaps_with')?.feat?.properties ?? {})['addr:street']", + "_osm_obj:addr:housenumber=(feat.get('_overlaps_with')?.feat?.properties ?? {})['addr:housenumber']", + "_osm_obj:surface=(feat.get('_overlaps_with')?.feat?.properties ?? {})['_surface:strict']", + + "_overlap_absolute=feat.get('_overlaps_with')?.overlap", + "_reverse_overlap_percentage=Math.round(100 * feat.get('_overlap_absolute') / feat.get('_surface'))", + "_overlap_percentage=Math.round(100 * feat.get('_overlap_absolute') / feat.get('_osm_obj:surface'))", + "_grb_ref=feat.properties['source:geometry:entity'] + '/' + feat.properties['source:geometry:oidn']", + "_imported_osm_object_found= feat.properties['_osm_obj:source:ref'] == feat.properties._grb_ref", + "_grb_date=feat.properties['source:geometry:date'].replace(/\\//g,'-')", + "_imported_osm_still_fresh= feat.properties['_osm_obj:source:date'] == feat.properties._grb_date", + "_target_building_type=feat.properties['_osm_obj:building'] === 'yes' ? feat.properties.building : (feat.properties['_osm_obj:building'] ?? feat.properties.building)", + "_building:min_level= feat.properties['fixme']?.startsWith('verdieping, correct the building tag, add building:level and building:min_level before upload in JOSM!') ? '1' : ''", + "_intersects_with_other_features=feat.intersectionsWith('generic_osm_object').map(f => \"\" + f.feat.properties.id + \"\").join(', ')" + ], + "tagRenderings": [], + "mapRendering": [ + { + "iconSize": "50,50,center", + "icon": "./assets/themes/grb_import/housenumber_blank.svg", + "location": [ + "point", + "centroid" + ] + } + ] + } + ] + } + + Minimap.createMiniMap = () => undefined; + + const coordinates = <[number, number][]>[ + [ + 3.216690793633461, + 51.21474084112525 + ], + [ + 3.2167256623506546, + 51.214696737309964 + ], + [ + 3.2169999182224274, + 51.214768983537674 + ], + [ + 3.2169650495052338, + 51.21480720678671 + ], + [ + 3.2169368863105774, + 51.21480090625335 + ], + [ + 3.2169489562511444, + 51.21478074454077 + ], + [ + 3.216886594891548, + 51.214765203214625 + ], + [ + 3.2168812304735184, + 51.21477192378873 + ], + [ + 3.2168644666671753, + 51.214768983537674 + ], + [ + 3.2168537378311157, + 51.21478746511261 + ], + [ + 3.216690793633461, + 51.21474084112525 + ] + ] + + const targetFeature = { + type: "Feature", + properties: {}, + geometry: { + type: "Polygon", + coordinates: [coordinates] + } + } + + const wayId = "way/160909312" + + Utils.injectJsonDownloadForTests( + "https://www.openstreetmap.org/api/0.6/map.json?bbox=3.2166673243045807,51.21467321525788,3.217007964849472,51.21482442824023", + { + "version": "0.6", + "generator": "CGImap 0.8.6 (1549677 spike-06.openstreetmap.org)", + "copyright": "OpenStreetMap and contributors", + "attribution": "http://www.openstreetmap.org/copyright", + "license": "http://opendatacommons.org/licenses/odbl/1-0/", + "bounds": {"minlat": 51.2146732, "minlon": 3.2166673, "maxlat": 51.2148244, "maxlon": 3.217008}, + "elements": [{ + "type": "node", + "id": 1612385157, + "lat": 51.2148016, + "lon": 3.2168453, + "timestamp": "2018-04-30T12:26:00Z", + "version": 3, + "changeset": 58553478, + "user": "Pieter Vander Vennet", + "uid": 3818858 + }, { + "type": "node", + "id": 1728816256, + "lat": 51.2147111, + "lon": 3.2170233, + "timestamp": "2017-07-18T22:52:44Z", + "version": 2, + "changeset": 50391526, + "user": "catweazle67", + "uid": 1976209 + }, { + "type": "node", + "id": 1728816287, + "lat": 51.2146408, + "lon": 3.2167601, + "timestamp": "2021-10-29T16:24:43Z", + "version": 3, + "changeset": 113131915, + "user": "Pieter Vander Vennet", + "uid": 3818858 + }, { + "type": "node", + "id": 1728823481, + "lat": 51.2146968, + "lon": 3.2167242, + "timestamp": "2021-11-02T23:37:11Z", + "version": 5, + "changeset": 113305401, + "user": "Pieter Vander Vennet", + "uid": 3818858 + }, { + "type": "node", + "id": 1728823499, + "lat": 51.2147127, + "lon": 3.2170302, + "timestamp": "2017-07-18T22:52:45Z", + "version": 2, + "changeset": 50391526, + "user": "catweazle67", + "uid": 1976209 + }, { + "type": "node", + "id": 1728823501, + "lat": 51.2148696, + "lon": 3.2168941, + "timestamp": "2017-07-18T22:52:45Z", + "version": 2, + "changeset": 50391526, + "user": "catweazle67", + "uid": 1976209 + }, { + "type": "node", + "id": 1728823514, + "lat": 51.2147863, + "lon": 3.2168551, + "timestamp": "2021-11-02T23:37:11Z", + "version": 5, + "changeset": 113305401, + "user": "Pieter Vander Vennet", + "uid": 3818858 + }, { + "type": "node", + "id": 1728823522, + "lat": 51.2148489, + "lon": 3.2169012, + "timestamp": "2017-07-18T22:52:45Z", + "version": 2, + "changeset": 50391526, + "user": "catweazle67", + "uid": 1976209 + }, { + "type": "node", + "id": 1728823523, + "lat": 51.2147578, + "lon": 3.2169995, + "timestamp": "2017-07-18T22:52:45Z", + "version": 2, + "changeset": 50391526, + "user": "catweazle67", + "uid": 1976209 + }, { + "type": "node", + "id": 1728823543, + "lat": 51.2148075, + "lon": 3.2166445, + "timestamp": "2017-07-18T22:52:46Z", + "version": 3, + "changeset": 50391526, + "user": "catweazle67", + "uid": 1976209 + }, { + "type": "node", + "id": 1728823544, + "lat": 51.2148553, + "lon": 3.2169315, + "timestamp": "2017-07-18T22:52:46Z", + "version": 2, + "changeset": 50391526, + "user": "catweazle67", + "uid": 1976209 + }, { + "type": "node", + "id": 1728823549, + "lat": 51.2147401, + "lon": 3.2168877, + "timestamp": "2021-11-02T23:37:11Z", + "version": 5, + "changeset": 113305401, + "user": "Pieter Vander Vennet", + "uid": 3818858 + }, { + "type": "node", + "id": 4978288376, + "lat": 51.2147306, + "lon": 3.2168928, + "timestamp": "2017-07-18T22:52:21Z", + "version": 1, + "changeset": 50391526, + "user": "catweazle67", + "uid": 1976209 + }, { + "type": "node", + "id": 4978288381, + "lat": 51.2147638, + "lon": 3.2168856, + "timestamp": "2021-11-02T23:37:11Z", + "version": 4, + "changeset": 113305401, + "user": "Pieter Vander Vennet", + "uid": 3818858 + }, { + "type": "node", + "id": 4978288382, + "lat": 51.2148189, + "lon": 3.216912, + "timestamp": "2017-07-18T22:52:21Z", + "version": 1, + "changeset": 50391526, + "user": "catweazle67", + "uid": 1976209 + }, { + "type": "node", + "id": 4978288385, + "lat": 51.2148835, + "lon": 3.2170623, + "timestamp": "2017-07-18T22:52:21Z", + "version": 1, + "changeset": 50391526, + "user": "catweazle67", + "uid": 1976209 + }, { + "type": "node", + "id": 4978288387, + "lat": 51.2148904, + "lon": 3.2171037, + "timestamp": "2017-07-18T22:52:21Z", + "version": 1, + "changeset": 50391526, + "user": "catweazle67", + "uid": 1976209 + }, { + "type": "node", + "id": 4978289383, + "lat": 51.2147678, + "lon": 3.2169969, + "timestamp": "2021-11-02T23:37:11Z", + "version": 4, + "changeset": 113305401, + "user": "Pieter Vander Vennet", + "uid": 3818858 + }, { + "type": "node", + "id": 4978289384, + "lat": 51.2147684, + "lon": 3.2168674, + "timestamp": "2021-11-02T23:37:11Z", + "version": 4, + "changeset": 113305401, + "user": "Pieter Vander Vennet", + "uid": 3818858 + }, { + "type": "node", + "id": 4978289386, + "lat": 51.2147716, + "lon": 3.2168811, + "timestamp": "2021-11-02T23:37:11Z", + "version": 4, + "changeset": 113305401, + "user": "Pieter Vander Vennet", + "uid": 3818858 + }, { + "type": "node", + "id": 4978289388, + "lat": 51.2148115, + "lon": 3.216966, + "timestamp": "2021-11-02T23:38:13Z", + "version": 7, + "changeset": 113306325, + "user": "Pieter Vander Vennet", + "uid": 3818858 + }, { + "type": "node", + "id": 4978289391, + "lat": 51.2148019, + "lon": 3.2169194, + "timestamp": "2017-07-18T22:52:21Z", + "version": 1, + "changeset": 50391526, + "user": "catweazle67", + "uid": 1976209 + }, { + "type": "node", + "id": 9219974337, + "lat": 51.2148449, + "lon": 3.2171278, + "timestamp": "2021-11-02T23:40:52Z", + "version": 1, + "changeset": 113305401, + "user": "Pieter Vander Vennet", + "uid": 3818858 + }, { + "type": "node", + "id": 9219979643, + "lat": 51.2147405, + "lon": 3.216693, + "timestamp": "2021-11-02T23:37:11Z", + "version": 1, + "changeset": 113305401, + "user": "Pieter Vander Vennet", + "uid": 3818858 + }, { + "type": "node", + "id": 9219979646, + "lat": 51.2148043, + "lon": 3.2169312, + "timestamp": "2021-11-02T23:38:13Z", + "version": 2, + "changeset": 113306325, + "user": "Pieter Vander Vennet", + "uid": 3818858 + }, { + "type": "node", + "id": 9219979647, + "lat": 51.2147792, + "lon": 3.2169466, + "timestamp": "2021-11-02T23:37:11Z", + "version": 1, + "changeset": 113305401, + "user": "Pieter Vander Vennet", + "uid": 3818858 + }, { + "type": "way", + "id": 160909311, + "timestamp": "2021-12-23T12:03:37Z", + "version": 6, + "changeset": 115295690, + "user": "s8evq", + "uid": 3710738, + "nodes": [1728823481, 1728823549, 4978288376, 1728823523, 1728823499, 1728816256, 1728816287, 1728823481], + "tags": { + "addr:city": "Brugge", + "addr:country": "BE", + "addr:housenumber": "106", + "addr:postcode": "8000", + "addr:street": "Ezelstraat", + "building": "house", + "source:geometry:date": "2015-07-09", + "source:geometry:ref": "Gbg/2391617" + } + }, { + "type": "way", + "id": 160909312, + "timestamp": "2021-11-02T23:38:13Z", + "version": 4, + "changeset": 113306325, + "user": "Pieter Vander Vennet", + "uid": 3818858, + "nodes": [9219979643, 1728823481, 1728823549, 4978289383, 4978289388, 9219979646, 9219979647, 4978288381, 4978289386, 4978289384, 1728823514, 9219979643], + "tags": { + "addr:city": "Brugge", + "addr:country": "BE", + "addr:housenumber": "108", + "addr:postcode": "8000", + "addr:street": "Ezelstraat", + "building": "house", + "source:geometry:date": "2018-10-02", + "source:geometry:ref": "Gbg/5926383" + } + }, { + "type": "way", + "id": 160909315, + "timestamp": "2021-12-23T12:03:37Z", + "version": 8, + "changeset": 115295690, + "user": "s8evq", + "uid": 3710738, + "nodes": [1728823543, 1728823501, 1728823522, 4978288382, 1612385157, 1728823514, 9219979643, 1728823543], + "tags": { + "addr:city": "Brugge", + "addr:country": "BE", + "addr:housenumber": "110", + "addr:postcode": "8000", + "addr:street": "Ezelstraat", + "building": "house", + "name": "La Style", + "shop": "hairdresser", + "source:geometry:date": "2015-07-09", + "source:geometry:ref": "Gbg/5260837" + } + }, { + "type": "way", + "id": 508533816, + "timestamp": "2021-12-23T12:03:37Z", + "version": 7, + "changeset": 115295690, + "user": "s8evq", + "uid": 3710738, + "nodes": [4978288387, 4978288385, 1728823544, 1728823522, 4978288382, 4978289391, 9219979646, 4978289388, 9219974337, 4978288387], + "tags": { + "building": "yes", + "source:geometry:date": "2015-07-09", + "source:geometry:ref": "Gbg/5260790" + } + }] + } + ) + + Utils.injectJsonDownloadForTests( + "https://www.openstreetmap.org/api/0.6/way/160909312/full", + { + "version": "0.6", + "generator": "CGImap 0.8.6 (2407324 spike-06.openstreetmap.org)", + "copyright": "OpenStreetMap and contributors", + "attribution": "http://www.openstreetmap.org/copyright", + "license": "http://opendatacommons.org/licenses/odbl/1-0/", + "elements": [{ + "type": "node", + "id": 1728823481, + "lat": 51.2146968, + "lon": 3.2167242, + "timestamp": "2021-11-02T23:37:11Z", + "version": 5, + "changeset": 113305401, + "user": "Pieter Vander Vennet", + "uid": 3818858 + }, { + "type": "node", + "id": 1728823514, + "lat": 51.2147863, + "lon": 3.2168551, + "timestamp": "2021-11-02T23:37:11Z", + "version": 5, + "changeset": 113305401, + "user": "Pieter Vander Vennet", + "uid": 3818858 + }, { + "type": "node", + "id": 1728823549, + "lat": 51.2147401, + "lon": 3.2168877, + "timestamp": "2021-11-02T23:37:11Z", + "version": 5, + "changeset": 113305401, + "user": "Pieter Vander Vennet", + "uid": 3818858 + }, { + "type": "node", + "id": 4978288381, + "lat": 51.2147638, + "lon": 3.2168856, + "timestamp": "2021-11-02T23:37:11Z", + "version": 4, + "changeset": 113305401, + "user": "Pieter Vander Vennet", + "uid": 3818858 + }, { + "type": "node", + "id": 4978289383, + "lat": 51.2147678, + "lon": 3.2169969, + "timestamp": "2021-11-02T23:37:11Z", + "version": 4, + "changeset": 113305401, + "user": "Pieter Vander Vennet", + "uid": 3818858 + }, { + "type": "node", + "id": 4978289384, + "lat": 51.2147684, + "lon": 3.2168674, + "timestamp": "2021-11-02T23:37:11Z", + "version": 4, + "changeset": 113305401, + "user": "Pieter Vander Vennet", + "uid": 3818858 + }, { + "type": "node", + "id": 4978289386, + "lat": 51.2147716, + "lon": 3.2168811, + "timestamp": "2021-11-02T23:37:11Z", + "version": 4, + "changeset": 113305401, + "user": "Pieter Vander Vennet", + "uid": 3818858 + }, { + "type": "node", + "id": 4978289388, + "lat": 51.2148115, + "lon": 3.216966, + "timestamp": "2021-11-02T23:38:13Z", + "version": 7, + "changeset": 113306325, + "user": "Pieter Vander Vennet", + "uid": 3818858 + }, { + "type": "node", + "id": 9219979643, + "lat": 51.2147405, + "lon": 3.216693, + "timestamp": "2021-11-02T23:37:11Z", + "version": 1, + "changeset": 113305401, + "user": "Pieter Vander Vennet", + "uid": 3818858 + }, { + "type": "node", + "id": 9219979646, + "lat": 51.2148043, + "lon": 3.2169312, + "timestamp": "2021-11-02T23:38:13Z", + "version": 2, + "changeset": 113306325, + "user": "Pieter Vander Vennet", + "uid": 3818858 + }, { + "type": "node", + "id": 9219979647, + "lat": 51.2147792, + "lon": 3.2169466, + "timestamp": "2021-11-02T23:37:11Z", + "version": 1, + "changeset": 113305401, + "user": "Pieter Vander Vennet", + "uid": 3818858 + }, { + "type": "way", + "id": 160909312, + "timestamp": "2021-11-02T23:38:13Z", + "version": 4, + "changeset": 113306325, + "user": "Pieter Vander Vennet", + "uid": 3818858, + "nodes": [9219979643, 1728823481, 1728823549, 4978289383, 4978289388, 9219979646, 9219979647, 4978288381, 4978289386, 4978289384, 1728823514, 9219979643], + "tags": { + "addr:city": "Brugge", + "addr:country": "BE", + "addr:housenumber": "108", + "addr:postcode": "8000", + "addr:street": "Ezelstraat", + "building": "house", + "source:geometry:date": "2018-10-02", + "source:geometry:ref": "Gbg/5926383" + } + }] + } + ) + Utils.injectJsonDownloadForTests("https://raw.githubusercontent.com/pietervdvn/MapComplete-data/main/latlon2country/0.0.0.json", "be") + + +it("should move nodes accordingly", async () => { + + + const layout = new LayoutConfig(grbStripped) + + + const state = new State(layout) + State.state = state; + const bbox = new BBox( + [[ + 3.2166673243045807, + 51.21467321525788 + ], + [ + 3.217007964849472, + 51.21482442824023 + ] + ]) + const url = `https://www.openstreetmap.org/api/0.6/map.json?bbox=${bbox.minLon},${bbox.minLat},${bbox.maxLon},${bbox.maxLat}` + const data = await Utils.downloadJson(url) + + state.featurePipeline.fullNodeDatabase.handleOsmJson(data, 0) + + + const action = new ReplaceGeometryAction(state, targetFeature, wayId, { + theme: "test" + } + ) + + const closestIds = await action.GetClosestIds() + expect(closestIds.closestIds).deep.equal([9219979643, + 1728823481, + 4978289383, + 4978289388, + 9219979646, + 9219979647, + 4978288381, + 4978289386, + 4978289384, + 1728823514, + undefined]) + + expect(closestIds.reprojectedNodes.size).deep.equal(1) + const reproj = closestIds.reprojectedNodes.get(1728823549) + expect(reproj.projectAfterIndex).deep.equal(1) + expect(reproj.newLon).deep.equal(3.2168880864669203) + expect(reproj.newLat).deep.equal(51.214739524104694) + expect(closestIds.detachedNodes.size).deep.equal(0) + const changes = await action.Perform(state.changes) + expect(changes[11].changes["coordinates"]).deep.equal([[3.216690793633461, 51.21474084112525], [3.2167256623506546, 51.214696737309964], [3.2168880864669203, 51.214739524104694], [3.2169999182224274, 51.214768983537674], [3.2169650495052338, 51.21480720678671], [3.2169368863105774, 51.21480090625335], [3.2169489562511444, 51.21478074454077], [3.216886594891548, 51.214765203214625], [3.2168812304735184, 51.21477192378873], [3.2168644666671753, 51.214768983537674], [3.2168537378311157, 51.21478746511261], [3.216690793633461, 51.21474084112525]]) + +}) + + +}) diff --git a/testLegacy/SplitAction.spec.ts b/tests/Logic/OSM/Actions/SplitAction.spec.ts similarity index 83% rename from testLegacy/SplitAction.spec.ts rename to tests/Logic/OSM/Actions/SplitAction.spec.ts index 4e9187f77..b2f5f9c58 100644 --- a/testLegacy/SplitAction.spec.ts +++ b/tests/Logic/OSM/Actions/SplitAction.spec.ts @@ -1,297 +1,199 @@ -import T from "./TestHelper"; -import {Changes} from "../Logic/Osm/Changes"; -import SplitAction from "../Logic/Osm/Actions/SplitAction"; -import {equal} from "assert"; -import {Utils} from "../Utils"; +import {describe} from 'mocha' +import {expect} from 'chai' +import {Utils} from "../../../../Utils"; +import SplitAction from "../../../../Logic/Osm/Actions/SplitAction"; +import {Changes} from "../../../../Logic/Osm/Changes"; -export default class SplitActionSpec extends T { - - - constructor() { - super([ - ["split 295132739", - () => SplitActionSpec.split().then(_ => console.log("OK"))], - ["split 295132739 on already existing node", - () => SplitActionSpec.splitWithPointReuse().then(_ => console.log("OK"))], - ["split 61435323 on already existing node", - () => SplitActionSpec.SplitHoutkaai().then(_ => console.log("OK"))], - ["Split test line", - async () => { - - Utils.injectJsonDownloadForTests( - "https://www.openstreetmap.org/api/0.6/way/941079939/full", - { - "version": "0.6", - "generator": "CGImap 0.8.5 (957273 spike-08.openstreetmap.org)", - "copyright": "OpenStreetMap and contributors", - "attribution": "http://www.openstreetmap.org/copyright", - "license": "http://opendatacommons.org/licenses/odbl/1-0/", - "elements": [{ - "type": "node", - "id": 6490126559, - "lat": 51.2332219, - "lon": 3.1429387, - "timestamp": "2021-05-09T19:04:53Z", - "version": 2, - "changeset": 104407928, - "user": "M!dgard", - "uid": 763799, - "tags": {"highway": "street_lamp", "power": "pole", "support": "pole"} - }, { - "type": "node", - "id": 8715440363, - "lat": 51.2324011, - "lon": 3.1367377, - "timestamp": "2021-05-09T19:04:53Z", - "version": 1, - "changeset": 104407928, - "user": "M!dgard", - "uid": 763799, - "tags": {"fixme": "continue"} - }, { - "type": "node", - "id": 8715440364, - "lat": 51.232455, - "lon": 3.1368759, - "timestamp": "2021-05-09T19:04:53Z", - "version": 1, - "changeset": 104407928, - "user": "M!dgard", - "uid": 763799, - "tags": {"power": "pole"} - }, { - "type": "node", - "id": 8715440365, - "lat": 51.2325883, - "lon": 3.1373986, - "timestamp": "2021-05-09T19:04:53Z", - "version": 1, - "changeset": 104407928, - "user": "M!dgard", - "uid": 763799, - "tags": {"power": "pole"} - }, { - "type": "node", - "id": 8715440366, - "lat": 51.232688, - "lon": 3.1379837, - "timestamp": "2021-05-09T19:04:53Z", - "version": 1, - "changeset": 104407928, - "user": "M!dgard", - "uid": 763799, - "tags": {"power": "pole"} - }, { - "type": "node", - "id": 8715440367, - "lat": 51.2327354, - "lon": 3.1385649, - "timestamp": "2021-05-09T19:04:53Z", - "version": 1, - "changeset": 104407928, - "user": "M!dgard", - "uid": 763799, - "tags": {"power": "pole"} - }, { - "type": "node", - "id": 8715440368, - "lat": 51.2327042, - "lon": 3.1392187, - "timestamp": "2021-05-09T19:04:53Z", - "version": 1, - "changeset": 104407928, - "user": "M!dgard", - "uid": 763799, - "tags": {"highway": "street_lamp", "power": "pole", "support": "pole"} - }, { - "type": "node", - "id": 8715440369, - "lat": 51.2323902, - "lon": 3.139353, - "timestamp": "2021-05-09T19:04:53Z", - "version": 1, - "changeset": 104407928, - "user": "M!dgard", - "uid": 763799, - "tags": {"power": "pole"} - }, { - "type": "node", - "id": 8715440370, - "lat": 51.2321027, - "lon": 3.139601, - "timestamp": "2021-05-09T19:04:53Z", - "version": 1, - "changeset": 104407928, - "user": "M!dgard", - "uid": 763799, - "tags": {"highway": "street_lamp", "power": "pole", "ref": "242", "support": "pole"} - }, { - "type": "node", - "id": 8715440371, - "lat": 51.2322614, - "lon": 3.1401564, - "timestamp": "2021-05-09T19:04:53Z", - "version": 1, - "changeset": 104407928, - "user": "M!dgard", - "uid": 763799, - "tags": {"power": "pole"} - }, { - "type": "node", - "id": 8715440372, - "lat": 51.232378, - "lon": 3.1407909, - "timestamp": "2021-05-09T19:04:53Z", - "version": 1, - "changeset": 104407928, - "user": "M!dgard", - "uid": 763799, - "tags": {"power": "pole"} - }, { - "type": "node", - "id": 8715440373, - "lat": 51.2325532, - "lon": 3.1413659, - "timestamp": "2021-05-09T19:04:53Z", - "version": 1, - "changeset": 104407928, - "user": "M!dgard", - "uid": 763799, - "tags": {"power": "pole"} - }, { - "type": "node", - "id": 8715440374, - "lat": 51.2327611, - "lon": 3.1418877, - "timestamp": "2021-05-09T19:04:53Z", - "version": 1, - "changeset": 104407928, - "user": "M!dgard", - "uid": 763799, - "tags": {"power": "pole"} - }, { - "type": "node", - "id": 8715440375, - "lat": 51.2330037, - "lon": 3.142418, - "timestamp": "2021-05-09T19:04:53Z", - "version": 1, - "changeset": 104407928, - "user": "M!dgard", - "uid": 763799, - "tags": {"power": "pole"} - }, { - "type": "way", - "id": 941079939, - "timestamp": "2021-05-09T19:04:53Z", - "version": 1, - "changeset": 104407928, - "user": "M!dgard", - "uid": 763799, - "nodes": [6490126559, 8715440375, 8715440374, 8715440373, 8715440372, 8715440371, 8715440370, 8715440369, 8715440368, 8715440367, 8715440366, 8715440365, 8715440364, 8715440363], - "tags": {"power": "minor_line"} - }] - } - ) - - Utils.injectJsonDownloadForTests( - "https://www.openstreetmap.org/api/0.6/way/941079939/relations", - { - "version": "0.6", - "generator": "CGImap 0.8.5 (2419440 spike-07.openstreetmap.org)", - "copyright": "OpenStreetMap and contributors", - "attribution": "http://www.openstreetmap.org/copyright", - "license": "http://opendatacommons.org/licenses/odbl/1-0/", - "elements": [] - } - ) - - // Split points are lon,lat - const splitPointAroundP3: [number, number] = [3.1392198801040645, 51.232701022376745] - const splitAction = new SplitAction("way/941079939", [splitPointAroundP3], {theme: "test"}) - const changes = await splitAction.Perform(new Changes()) - console.log(changes) - // 8715440368 is the expected point of the split - - /* Nodes are - 6490126559 (part of ways 941079941 and 941079940) - 8715440375 - 8715440374 - 8715440373 - 8715440372 - 8715440371 - 8715440370 - 8715440369 - 8715440368 <--- split here - 8715440367 - 8715440366 - 8715440365 - 8715440364 - 8715440363 - */ - - const nodeList0 = [6490126559, - 8715440375, - 8715440374, - 8715440373, - 8715440372, - 8715440371, - 8715440370, - 8715440369, - 8715440368] - - const nodeList1 = [ - 8715440368, - 8715440367, - 8715440366, - 8715440365, - 8715440364, - 8715440363 - ] - - T.listIdentical(nodeList0, changes[0].changes["nodes"]) - T.listIdentical(nodeList1, changes[1].changes["nodes"]) - } - ], - ["Split minor powerline halfway", async () => { - - - const splitPointHalfway: [number, number] = [3.1392842531204224, 51.23255322710106] - const splitAction = new SplitAction("way/941079939", [splitPointHalfway], {theme: "test"}, 1) - const changes = await splitAction.Perform(new Changes()) - - const nodeList0 = [6490126559, - 8715440375, - 8715440374, - 8715440373, - 8715440372, - 8715440371, - 8715440370, - 8715440369, - -1] - - const nodeList1 = [ - -1, - 8715440368, - 8715440367, - 8715440366, - 8715440365, - 8715440364, - 8715440363 - ] - // THe first change is the creation of the new node - T.equals("node", changes[0].type) - T.equals(-1, changes[0].id) - - T.listIdentical(nodeList0, changes[1].changes["nodes"]) - T.listIdentical(nodeList1, changes[2].changes["nodes"]) +describe("SplitAction", () => { + { // Setup of download + Utils.injectJsonDownloadForTests( + "https://www.openstreetmap.org/api/0.6/way/941079939/full", + { + "version": "0.6", + "generator": "CGImap 0.8.5 (957273 spike-08.openstreetmap.org)", + "copyright": "OpenStreetMap and contributors", + "attribution": "http://www.openstreetmap.org/copyright", + "license": "http://opendatacommons.org/licenses/odbl/1-0/", + "elements": [{ + "type": "node", + "id": 6490126559, + "lat": 51.2332219, + "lon": 3.1429387, + "timestamp": "2021-05-09T19:04:53Z", + "version": 2, + "changeset": 104407928, + "user": "M!dgard", + "uid": 763799, + "tags": {"highway": "street_lamp", "power": "pole", "support": "pole"} + }, { + "type": "node", + "id": 8715440363, + "lat": 51.2324011, + "lon": 3.1367377, + "timestamp": "2021-05-09T19:04:53Z", + "version": 1, + "changeset": 104407928, + "user": "M!dgard", + "uid": 763799, + "tags": {"fixme": "continue"} + }, { + "type": "node", + "id": 8715440364, + "lat": 51.232455, + "lon": 3.1368759, + "timestamp": "2021-05-09T19:04:53Z", + "version": 1, + "changeset": 104407928, + "user": "M!dgard", + "uid": 763799, + "tags": {"power": "pole"} + }, { + "type": "node", + "id": 8715440365, + "lat": 51.2325883, + "lon": 3.1373986, + "timestamp": "2021-05-09T19:04:53Z", + "version": 1, + "changeset": 104407928, + "user": "M!dgard", + "uid": 763799, + "tags": {"power": "pole"} + }, { + "type": "node", + "id": 8715440366, + "lat": 51.232688, + "lon": 3.1379837, + "timestamp": "2021-05-09T19:04:53Z", + "version": 1, + "changeset": 104407928, + "user": "M!dgard", + "uid": 763799, + "tags": {"power": "pole"} + }, { + "type": "node", + "id": 8715440367, + "lat": 51.2327354, + "lon": 3.1385649, + "timestamp": "2021-05-09T19:04:53Z", + "version": 1, + "changeset": 104407928, + "user": "M!dgard", + "uid": 763799, + "tags": {"power": "pole"} + }, { + "type": "node", + "id": 8715440368, + "lat": 51.2327042, + "lon": 3.1392187, + "timestamp": "2021-05-09T19:04:53Z", + "version": 1, + "changeset": 104407928, + "user": "M!dgard", + "uid": 763799, + "tags": {"highway": "street_lamp", "power": "pole", "support": "pole"} + }, { + "type": "node", + "id": 8715440369, + "lat": 51.2323902, + "lon": 3.139353, + "timestamp": "2021-05-09T19:04:53Z", + "version": 1, + "changeset": 104407928, + "user": "M!dgard", + "uid": 763799, + "tags": {"power": "pole"} + }, { + "type": "node", + "id": 8715440370, + "lat": 51.2321027, + "lon": 3.139601, + "timestamp": "2021-05-09T19:04:53Z", + "version": 1, + "changeset": 104407928, + "user": "M!dgard", + "uid": 763799, + "tags": {"highway": "street_lamp", "power": "pole", "ref": "242", "support": "pole"} + }, { + "type": "node", + "id": 8715440371, + "lat": 51.2322614, + "lon": 3.1401564, + "timestamp": "2021-05-09T19:04:53Z", + "version": 1, + "changeset": 104407928, + "user": "M!dgard", + "uid": 763799, + "tags": {"power": "pole"} + }, { + "type": "node", + "id": 8715440372, + "lat": 51.232378, + "lon": 3.1407909, + "timestamp": "2021-05-09T19:04:53Z", + "version": 1, + "changeset": 104407928, + "user": "M!dgard", + "uid": 763799, + "tags": {"power": "pole"} + }, { + "type": "node", + "id": 8715440373, + "lat": 51.2325532, + "lon": 3.1413659, + "timestamp": "2021-05-09T19:04:53Z", + "version": 1, + "changeset": 104407928, + "user": "M!dgard", + "uid": 763799, + "tags": {"power": "pole"} + }, { + "type": "node", + "id": 8715440374, + "lat": 51.2327611, + "lon": 3.1418877, + "timestamp": "2021-05-09T19:04:53Z", + "version": 1, + "changeset": 104407928, + "user": "M!dgard", + "uid": 763799, + "tags": {"power": "pole"} + }, { + "type": "node", + "id": 8715440375, + "lat": 51.2330037, + "lon": 3.142418, + "timestamp": "2021-05-09T19:04:53Z", + "version": 1, + "changeset": 104407928, + "user": "M!dgard", + "uid": 763799, + "tags": {"power": "pole"} + }, { + "type": "way", + "id": 941079939, + "timestamp": "2021-05-09T19:04:53Z", + "version": 1, + "changeset": 104407928, + "user": "M!dgard", + "uid": 763799, + "nodes": [6490126559, 8715440375, 8715440374, 8715440373, 8715440372, 8715440371, 8715440370, 8715440369, 8715440368, 8715440367, 8715440366, 8715440365, 8715440364, 8715440363], + "tags": {"power": "minor_line"} + }] } - ] - ]); - } + ) - private static async split(): Promise { + Utils.injectJsonDownloadForTests( + "https://www.openstreetmap.org/api/0.6/way/941079939/relations", + { + "version": "0.6", + "generator": "CGImap 0.8.5 (2419440 spike-07.openstreetmap.org)", + "copyright": "OpenStreetMap and contributors", + "attribution": "http://www.openstreetmap.org/copyright", + "license": "http://opendatacommons.org/licenses/odbl/1-0/", + "elements": [] + } + ) Utils.injectJsonDownloadForTests( "https://www.openstreetmap.org/api/0.6/way/295132739/full", @@ -472,34 +374,6 @@ export default class SplitActionSpec extends T { } ) - // Lets split road https://www.openstreetmap.org/way/295132739 - const id = "way/295132739" - const splitPoint: [number, number] = [3.246733546257019, 51.181710380278176] - const splitter = new SplitAction(id, [splitPoint], { - theme: "test" - }) - const changeDescription = await splitter.CreateChangeDescriptions(new Changes()) - - equal(changeDescription[0].type, "node") - equal(changeDescription[0].id, -1) - equal(changeDescription[0].changes["lat"], 51.181710380278176) - equal(changeDescription[0].changes["lon"], 3.246733546257019) - - equal(changeDescription[1].type, "way") - equal(changeDescription[1].id, -2) - equal(changeDescription[1].changes["coordinates"].length, 6) - equal(changeDescription[1].changes["coordinates"][5][0], splitPoint[0]) - equal(changeDescription[1].changes["coordinates"][5][1], splitPoint[1]) - - equal(changeDescription[2].type, "way") - equal(changeDescription[2].id, 295132739) - equal(changeDescription[2].changes["coordinates"].length, 10) - equal(changeDescription[2].changes["coordinates"][0][0], splitPoint[0]) - equal(changeDescription[2].changes["coordinates"][0][1], splitPoint[1]) - } - - private static async SplitHoutkaai(): Promise { - Utils.injectJsonDownloadForTests( "https://www.openstreetmap.org/api/0.6/way/61435323/full", { @@ -2074,37 +1948,144 @@ export default class SplitActionSpec extends T { }] } ) - - - const id = "way/61435323" - const splitPoint: [number, number] = [3.2021324336528774, 51.2170001600597] - const splitter = new SplitAction(id, [splitPoint], { - theme: "test" - }) - const changeDescription = await splitter.CreateChangeDescriptions(new Changes()) - - // Should be a new node - equal(changeDescription[0].type, "node") - equal(changeDescription[3].type, "relation") } + + it("split 295132739", + async () => { + // Lets split road https://www.openstreetmap.org/way/295132739 + const id = "way/295132739" + const splitPoint: [number, number] = [3.246733546257019, 51.181710380278176] + const splitter = new SplitAction(id, [splitPoint], { + theme: "test" + }) + const changeDescription = await splitter.CreateChangeDescriptions(new Changes()) - private static async splitWithPointReuse(): Promise { - // Lets split road near an already existing point https://www.openstreetmap.org/way/295132739 - const id = "way/295132739" - const splitPoint: [number, number] = [3.2451081275939937, 51.18116898253599] - const splitter = new SplitAction(id, [splitPoint], { - theme: "test" + expect(changeDescription[0].type).eq("node") + expect(changeDescription[0].id).eq( -1) + expect(changeDescription[0].changes["lat"]).eq( 51.181710380278176) + expect(changeDescription[0].changes["lon"]).eq( 3.246733546257019) + expect(changeDescription[1].type).eq( "way") + expect(changeDescription[1].id).eq( -2) + expect(changeDescription[1].changes["coordinates"].length).eq( 6) + expect(changeDescription[1].changes["coordinates"][5][0]).eq( splitPoint[0]) + expect(changeDescription[1].changes["coordinates"][5][1]).eq( splitPoint[1]) + expect(changeDescription[2].type).eq( "way") + expect(changeDescription[2].id,).eq(295132739) + expect(changeDescription[2].changes["coordinates"].length).eq( 10) + expect(changeDescription[2].changes["coordinates"][0][0]).eq( splitPoint[0]) + expect(changeDescription[2].changes["coordinates"][0][1]).eq( splitPoint[1]); }) - const changeDescription = await splitter.CreateChangeDescriptions(new Changes()) + + it("split 295132739 on already existing node", + async () => { + // Lets split road near an already existing point https://www.openstreetmap.org/way/295132739 + const id = "way/295132739" + const splitPoint: [number, number] = [3.2451081275939937, 51.18116898253599] + const splitter = new SplitAction(id, [splitPoint], { + theme: "test" + }) + const changeDescription = await splitter.CreateChangeDescriptions(new Changes()) + + expect(changeDescription.length).eq( 2) + expect(changeDescription[0].type).eq( "way") + expect(changeDescription[1].type).eq( "way") + expect(changeDescription[0].changes["nodes"][changeDescription[0].changes["nodes"].length - 1]).eq( changeDescription[1].changes["nodes"][0]) + expect(changeDescription[1].changes["nodes"][0]).eq( 1507524610); + }) + + it("split 61435323 on already existing node", + async () => { + const id = "way/61435323" + const splitPoint: [number, number] = [3.2021324336528774, 51.2170001600597] + const splitter = new SplitAction(id, [splitPoint], { + theme: "test" + }) + const changeDescription = await splitter.CreateChangeDescriptions(new Changes()) + + // Should be a new node + expect(changeDescription[0].type).eq( "node") + expect(changeDescription[3].type).eq( "relation"); + }) + + it("Split test line", + async () => { + // Split points are lon,lat + const splitPointAroundP3: [number, number] = [3.1392198801040645, 51.232701022376745] + const splitAction = new SplitAction("way/941079939", [splitPointAroundP3], {theme: "test"}) + const changes = await splitAction.Perform(new Changes()) + console.log(changes) + // 8715440368 is the expected point of the split + + /* Nodes are + 6490126559 (part of ways 941079941 and 941079940) + 8715440375 + 8715440374 + 8715440373 + 8715440372 + 8715440371 + 8715440370 + 8715440369 + 8715440368 <--- split here + 8715440367 + 8715440366 + 8715440365 + 8715440364 + 8715440363 + */ + + expect(changes[0].changes["nodes"]).deep.equal([6490126559, + 8715440375, + 8715440374, + 8715440373, + 8715440372, + 8715440371, + 8715440370, + 8715440369, + 8715440368]) + expect(changes[1].changes["nodes"]).deep.equal([ + 8715440368, + 8715440367, + 8715440366, + 8715440365, + 8715440364, + 8715440363 + ]) + + }) + + + + it("Split minor powerline halfway", async () => { + + + const splitPointHalfway: [number, number] = [3.1392842531204224, 51.23255322710106] + const splitAction = new SplitAction("way/941079939", [splitPointHalfway], {theme: "test"}, 1) + const changes = await splitAction.Perform(new Changes()) + + // THe first change is the creation of the new node + expect(changes[0].type).deep.equal("node") + expect(changes[0].id).deep.equal(-1) + + expect(changes[1].changes["nodes"]).deep.equal([6490126559, + 8715440375, + 8715440374, + 8715440373, + 8715440372, + 8715440371, + 8715440370, + 8715440369, + -1]) + expect(changes[2].changes["nodes"]).deep.equal([ + -1, + 8715440368, + 8715440367, + 8715440366, + 8715440365, + 8715440364, + 8715440363 + ]) + + + }) +}) - equal(2, changeDescription.length) - const ch0 = changeDescription[0] - const ch1 = changeDescription[1] - const nodes0: number[] = ch0.changes["nodes"] - const nodes1: number[] = ch1.changes["nodes"] - equal(ch0.type, "way") - equal(ch1.type, "way") - equal(nodes0[nodes0.length - 1], nodes1[0]) - equal(1507524610, nodes1[0]) - } -} \ No newline at end of file diff --git a/tests/Logic/OSM/ChangesetHandler.spec.ts b/tests/Logic/OSM/ChangesetHandler.spec.ts new file mode 100644 index 000000000..3d33bdcbe --- /dev/null +++ b/tests/Logic/OSM/ChangesetHandler.spec.ts @@ -0,0 +1,195 @@ +import {describe} from 'mocha' +import {expect} from 'chai' +import {Utils} from "../../../Utils"; +import {ChangesetHandler, ChangesetTag} from "../../../Logic/Osm/ChangesetHandler"; +import {UIEventSource} from "../../../Logic/UIEventSource"; +import {OsmConnection} from "../../../Logic/Osm/OsmConnection"; +import {ElementStorage} from "../../../Logic/ElementStorage"; +import {Changes} from "../../../Logic/Osm/Changes"; + +describe("ChangesetHanlder", () => { + + describe("RewriteTagsOf", () => { + it("should insert new tags", () => { + + const changesetHandler = new ChangesetHandler(new UIEventSource(true), + new OsmConnection({}), + new ElementStorage(), + new Changes(), + new UIEventSource(undefined) + ); + + const oldChangesetMeta = { + "type": "changeset", + "id": 118443748, + "created_at": "2022-03-13T19:52:10Z", + "closed_at": "2022-03-13T20:54:35Z", + "open": false, + "user": "Pieter Vander Vennet", + "uid": 3818858, + "minlat": 51.0361902, + "minlon": 3.7092939, + "maxlat": 51.0364194, + "maxlon": 3.7099520, + "comments_count": 0, + "changes_count": 3, + "tags": { + "answer": "5", + "comment": "Adding data with #MapComplete for theme #toerisme_vlaanderen", + "created_by": "MapComplete 0.16.6", + "host": "https://mapcomplete.osm.be/toerisme_vlaanderen.html", + "imagery": "osm", + "locale": "nl", + "source": "survey", + "source:node/-1": "note/1234", + "theme": "toerisme_vlaanderen", + } + } + const rewritten = changesetHandler.RewriteTagsOf( + [{ + key: "newTag", + value: "newValue", + aggregate: false + }], + new Map(), + oldChangesetMeta) + const d = Utils.asDict(rewritten) + expect(d.size).deep.equal(10) + expect(d.get("answer")).deep.equal("5") + expect(d.get("comment")).deep.equal("Adding data with #MapComplete for theme #toerisme_vlaanderen") + expect(d.get("created_by")).deep.equal("MapComplete 0.16.6") + expect(d.get("host")).deep.equal("https://mapcomplete.osm.be/toerisme_vlaanderen.html") + expect(d.get("imagery")).deep.equal("osm") + expect(d.get("source")).deep.equal("survey") + expect(d.get("source:node/-1")).deep.equal("note/1234") + expect(d.get("theme")).deep.equal("toerisme_vlaanderen") + expect(d.get("newTag")).deep.equal("newValue") + + }) + it("should aggregate numeric tags", () => { + const changesetHandler = new ChangesetHandler(new UIEventSource(true), + new OsmConnection({}), + new ElementStorage(), + new Changes(), + new UIEventSource(undefined) + ); + const oldChangesetMeta = { + "type": "changeset", + "id": 118443748, + "created_at": "2022-03-13T19:52:10Z", + "closed_at": "2022-03-13T20:54:35Z", + "open": false, + "user": "Pieter Vander Vennet", + "uid": 3818858, + "minlat": 51.0361902, + "minlon": 3.7092939, + "maxlat": 51.0364194, + "maxlon": 3.7099520, + "comments_count": 0, + "changes_count": 3, + "tags": { + "answer": "5", + "comment": "Adding data with #MapComplete for theme #toerisme_vlaanderen", + "created_by": "MapComplete 0.16.6", + "host": "https://mapcomplete.osm.be/toerisme_vlaanderen.html", + "imagery": "osm", + "locale": "nl", + "source": "survey", + "source:node/-1": "note/1234", + "theme": "toerisme_vlaanderen", + } + } + const rewritten = changesetHandler.RewriteTagsOf( + [{ + key: "answer", + value: "37", + aggregate: true + }], + new Map(), + oldChangesetMeta) + const d = Utils.asDict(rewritten) + + expect(d.size).deep.equal(9) + expect(d.get("answer")).deep.equal("42") + expect(d.get("comment")).deep.equal("Adding data with #MapComplete for theme #toerisme_vlaanderen") + expect(d.get("created_by")).deep.equal("MapComplete 0.16.6") + expect(d.get("host")).deep.equal("https://mapcomplete.osm.be/toerisme_vlaanderen.html") + expect(d.get("imagery")).deep.equal("osm") + expect(d.get("source")).deep.equal("survey") + expect(d.get("source:node/-1")).deep.equal("note/1234") + expect(d.get("theme")).deep.equal("toerisme_vlaanderen") + }) + it("should rewrite special reasons with the correct ID", () => { + const changesetHandler = new ChangesetHandler(new UIEventSource(true), + new OsmConnection({}), + new ElementStorage(), + new Changes(), + new UIEventSource(undefined) + ); + const oldChangesetMeta = { + "type": "changeset", + "id": 118443748, + "created_at": "2022-03-13T19:52:10Z", + "closed_at": "2022-03-13T20:54:35Z", + "open": false, + "user": "Pieter Vander Vennet", + "uid": 3818858, + "minlat": 51.0361902, + "minlon": 3.7092939, + "maxlat": 51.0364194, + "maxlon": 3.7099520, + "comments_count": 0, + "changes_count": 3, + "tags": { + "answer": "5", + "comment": "Adding data with #MapComplete for theme #toerisme_vlaanderen", + "created_by": "MapComplete 0.16.6", + "host": "https://mapcomplete.osm.be/toerisme_vlaanderen.html", + "imagery": "osm", + "locale": "nl", + "source": "survey", + "source:node/-1": "note/1234", + "theme": "toerisme_vlaanderen", + } + } + const rewritten = changesetHandler.RewriteTagsOf( + [], + new Map([["node/-1", "node/42"]]), + oldChangesetMeta) + const d = Utils.asDict(rewritten) + + expect(d.size).deep.equal(9) + expect(d.get("answer")).deep.equal("5") + expect(d.get("comment")).deep.equal("Adding data with #MapComplete for theme #toerisme_vlaanderen") + expect(d.get("created_by")).deep.equal("MapComplete 0.16.6") + expect(d.get("host")).deep.equal("https://mapcomplete.osm.be/toerisme_vlaanderen.html") + expect(d.get("imagery")).deep.equal("osm") + expect(d.get("source")).deep.equal("survey") + expect(d.get("source:node/42")).deep.equal("note/1234") + expect(d.get("theme")).deep.equal("toerisme_vlaanderen") + }) + }) + + describe("rewriteMetaTags" , () => { + it("should rewrite special reasons with the correct ID", () => { + const extraMetaTags : ChangesetTag[] = [ + { + key: "created_by", + value:"mapcomplete" + }, + { + key: "source:node/-1", + value:"note/1234" + } + ] + const changes = new Map([["node/-1","node/42"]]) + const hasSpecialMotivationChanges = ChangesetHandler.rewriteMetaTags(extraMetaTags, changes) + expect(hasSpecialMotivationChanges, "Special rewrite did not trigger").true + // Rewritten inline by rewriteMetaTags + expect(extraMetaTags[1].key).deep.equal("source:node/42") + expect(extraMetaTags[1].value).deep.equal("note/1234") + expect(extraMetaTags[0].key).deep.equal("created_by") + expect(extraMetaTags[0].value).deep.equal("mapcomplete") + }) +}) +}) diff --git a/tests/Logic/OSM/OsmObject.spec.ts b/tests/Logic/OSM/OsmObject.spec.ts new file mode 100644 index 000000000..7ddc8aaef --- /dev/null +++ b/tests/Logic/OSM/OsmObject.spec.ts @@ -0,0 +1,23 @@ +import {describe} from 'mocha' +import {expect} from 'chai' +import {OsmObject} from "../../../Logic/Osm/OsmObject"; +import {Utils} from "../../../Utils"; + +describe("OsmObject", () => { + + describe("download referencing ways", () => { + + Utils.injectJsonDownloadForTests( + "https://www.openstreetmap.org/api/0.6/node/1124134958/ways", {"version":"0.6","generator":"CGImap 0.8.6 (49805 spike-06.openstreetmap.org)","copyright":"OpenStreetMap and contributors","attribution":"http://www.openstreetmap.org/copyright","license":"http://opendatacommons.org/licenses/odbl/1-0/","elements":[{"type":"way","id":97038428,"timestamp":"2019-06-19T12:26:24Z","version":6,"changeset":71399984,"user":"Pieter Vander Vennet","uid":3818858,"nodes":[1124134958,323729212,323729351,2542460408,187073405],"tags":{"highway":"residential","name":"Brugs-Kerkhofstraat","sett:pattern":"arc","surface":"sett"}},{"type":"way","id":97038434,"timestamp":"2019-06-19T12:26:24Z","version":5,"changeset":71399984,"user":"Pieter Vander Vennet","uid":3818858,"nodes":[1124134958,1124135024,187058607],"tags":{"bicycle":"use_sidepath","highway":"residential","name":"Kerkhofblommenstraat","sett:pattern":"arc","surface":"sett"}},{"type":"way","id":97038435,"timestamp":"2017-12-21T21:41:08Z","version":4,"changeset":54826837,"user":"Jakka","uid":2403313,"nodes":[1124134958,2576628889,1124135035,5298371485,5298371495],"tags":{"bicycle":"use_sidepath","highway":"residential","name":"Kerkhofblommenstraat"}},{"type":"way","id":251446313,"timestamp":"2019-01-07T19:22:47Z","version":4,"changeset":66106872,"user":"M!dgard","uid":763799,"nodes":[1124134958,5243143198,4555715455],"tags":{"foot":"yes","highway":"service"}}]}) + + + it("should download referencing ways", + async () => { + + + const ways = await OsmObject.DownloadReferencingWays("node/1124134958") + expect(ways).not.undefined + expect(ways).length(4) + }) + }) +}) diff --git a/tests/Models/ThemeConfig/Conversion/CreateNoteImportLayer.spec.ts b/tests/Models/ThemeConfig/Conversion/CreateNoteImportLayer.spec.ts new file mode 100644 index 000000000..be13f28bf --- /dev/null +++ b/tests/Models/ThemeConfig/Conversion/CreateNoteImportLayer.spec.ts @@ -0,0 +1,32 @@ +import {describe} from 'mocha' +import {expect} from 'chai' +import {Utils} from "../../../../Utils"; +import {DesugaringContext} from "../../../../Models/ThemeConfig/Conversion/Conversion"; +import {LayerConfigJson} from "../../../../Models/ThemeConfig/Json/LayerConfigJson"; +import {TagRenderingConfigJson} from "../../../../Models/ThemeConfig/Json/TagRenderingConfigJson"; +import {PrepareLayer} from "../../../../Models/ThemeConfig/Conversion/PrepareLayer"; +import * as bookcases from "../../../../assets/layers/public_bookcase/public_bookcase.json"; +import CreateNoteImportLayer from "../../../../Models/ThemeConfig/Conversion/CreateNoteImportLayer"; + +describe("CreateNoteImportLayer", () => { + + it("should generate a layerconfig", () => { + const desugaringState: DesugaringContext = { + sharedLayers: new Map(), + tagRenderings: new Map() + + } + const layerPrepare = new PrepareLayer(desugaringState) + const layer = layerPrepare.convertStrict(bookcases, "ImportLayerGeneratorTest:Parse bookcases") + const generator = new CreateNoteImportLayer() + const generatedLayer: LayerConfigJson = generator.convertStrict(layer, "ImportLayerGeneratorTest: convert") + expect(generatedLayer.isShown.mappings[1].if["and"][1].or[0].and[0]).deep.equal("_tags~(^|.*;)amenity=public_bookcase($|;.*)") + expect(generatedLayer.minzoom <= layer.minzoom, "Zoomlevel is to high").true + let renderings = Utils.NoNull(Utils.NoNull(generatedLayer.tagRenderings + .map(tr => (tr).render)) + .map(render => render["en"])) + expect(renderings.some(r => r.indexOf("import_button") > 0), "no import button found").true + + + }) +}) diff --git a/tests/testhooks.ts b/tests/testhooks.ts new file mode 100644 index 000000000..f5100dd08 --- /dev/null +++ b/tests/testhooks.ts @@ -0,0 +1,24 @@ +import ScriptUtils from "../scripts/ScriptUtils"; +import {Utils} from "../Utils"; + +export const mochaHooks = { + + beforeEach(done) { + ScriptUtils.fixUtils(); + + // Block internet access + const realDownloadFunc = Utils.externalDownloadFunction; + Utils.externalDownloadFunction = async (url) => { + console.error("Fetching ", url, "blocked in tests, use Utils.injectJsonDownloadForTests") + const data = await realDownloadFunc(url) + console.log("\n\n ----------- \nBLOCKED DATA\n Utils.injectJsonDownloadForTests(\n" + + " ", JSON.stringify(url), ", \n", + " ", JSON.stringify(data), "\n )\n------------------\n\n") + throw new Error("Detected internet access for URL " + url + ", please inject it with Utils.injectJsonDownloadForTests") + } + + done(); + } + + +} \ No newline at end of file