From 3bdb5e987dfcaf47695de7f3b13c905c102d8da5 Mon Sep 17 00:00:00 2001 From: Roman Deev Date: Tue, 6 May 2025 22:08:13 +0300 Subject: [PATCH 1/2] show validation errors + tests --- src/building.js | 54 +++++++++++++++++++++---------------------- test/building.test.js | 34 +++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 28 deletions(-) diff --git a/src/building.js b/src/building.js index 7c3806b..ed0b9ef 100644 --- a/src/building.js +++ b/src/building.js @@ -75,29 +75,30 @@ class Building { } else { this.type = 'relation'; } - if (this.isValidData(outerElementXml)) { - this.nodelist = Building.buildNodeList(this.fullXmlData); - this.setHome(); - this.repositionNodes(); - if (this.type === 'way') { + try { + this.validateData(outerElementXml); + } catch (e) { + throw new Error(`Rendering of ${outerElementXml.tagName.toLowerCase()} ${id} is not is not possible. ${e}`); + } + + this.nodelist = Building.buildNodeList(this.fullXmlData); + this.setHome(); + this.repositionNodes(); + if (this.type === 'way') { + this.outerElement = new BuildingPart(id, this.fullXmlData, this.nodelist); + } else if (this.type === 'multipolygon') { + this.outerElement = new MultiBuildingPart(id, this.fullXmlData, this.nodelist); + } else { + const outlineRef = outerElementXml.querySelector('member[role="outline"]').getAttribute('ref'); + const outline = this.fullXmlData.getElementById(outlineRef); + const outlineType = outline.tagName.toLowerCase(); + if (outlineType === 'way') { this.outerElement = new BuildingPart(id, this.fullXmlData, this.nodelist); - } else if (this.type === 'multipolygon') { - this.outerElement = new MultiBuildingPart(id, this.fullXmlData, this.nodelist); } else { - const outlineRef = outerElementXml.querySelector('member[role="outline"]').getAttribute('ref'); - const outline = this.fullXmlData.getElementById(outlineRef); - const outlineType = outline.tagName.toLowerCase(); - if (outlineType === 'way') { - this.outerElement = new BuildingPart(id, this.fullXmlData, this.nodelist); - } else { - this.outerElement = new MultiBuildingPart(outlineRef, this.fullXmlData, this.nodelist); - } + this.outerElement = new MultiBuildingPart(outlineRef, this.fullXmlData, this.nodelist); } - this.addParts(); - } else { - window.printError('XML Not Valid'); - throw new Error('invalid XML'); } + this.addParts(); } /** @@ -248,7 +249,7 @@ class Building { /** * validate that we have the ID of a building way. */ - isValidData(xmlData) { + validateData(xmlData) { // Check that it is a building ( exists) const buildingType = xmlData.querySelector('[k="building"]'); const ways = []; @@ -256,7 +257,7 @@ class Building { // get all building relation parts // todo: multipolygon inner and outer roles. let parts = xmlData.querySelectorAll('member[role="part"]'); - var ref = 0; + let ref = 0; for (let i = 0; i < parts.length; i++) { ref = parts[i].getAttribute('ref'); const part = this.fullXmlData.getElementById(ref); @@ -268,8 +269,7 @@ class Building { } } else { if (!buildingType) { - window.printError('Outer way is not a building'); - return false; + throw new Error('Outer way is not a building'); } ways.push(xmlData); } @@ -282,16 +282,14 @@ class Building { const firstRef = nodes[0].getAttribute('ref'); const lastRef = nodes[nodes.length - 1].getAttribute('ref'); if (firstRef !== lastRef) { - window.printError('Way ' + way.getAttribute('id') + ' is not a closed way. ' + firstRef + ' !== ' + lastRef + '.'); - return false; + throw new Error('Way ' + way.getAttribute('id') + ' is not a closed way. ' + firstRef + ' !== ' + lastRef + '.'); } } else { - window.printError('Way ' + way.getAttribute('id') + ' has no nodes.'); - return false; + throw new Error('Way ' + way.getAttribute('id') + ' has no nodes.'); } } else { let parts = way.querySelectorAll('member[role="part"]'); - var ref = 0; + let ref = 0; for (let i = 0; i < parts.length; i++) { ref = parts[i].getAttribute('ref'); const part = this.fullXmlData.getElementById(ref); diff --git a/test/building.test.js b/test/building.test.js index 542f0e0..6dea886 100644 --- a/test/building.test.js +++ b/test/building.test.js @@ -60,6 +60,40 @@ describe.each([ }); }); +test('Test data validation open outline', () => { + const data = ` + + + + + + `; + expect(() => new Building('1', data)) + .toThrow(new Error('Rendering of way 1 is not is not possible. Error: Way 1 is not a closed way. 2 !== 4.')); +}); + +test('Test data validation with not building', () => { + const data = ` + + + + + + + `; + expect(() => new Building('1', data)) + .toThrow(new Error('Rendering of way 1 is not is not possible. Error: Outer way is not a building')); +}); + +test('Test data validation with empty way', () => { + const data = ` + + + `; + expect(() => new Building('1', data)) + .toThrow(new Error('Rendering of way 1 is not is not possible. Error: Way 1 has no nodes.')); +}); + test('Test Constructor', async() => { const bldg = new Building('31361386', data); expect(bldg.home).toBeDeepCloseTo([11.015512, 49.5833659], 10); From 2a0ab6d7913fa5b912a074a7ee77c53312b8550d Mon Sep 17 00:00:00 2001 From: Roman Deev Date: Wed, 7 May 2025 02:40:51 +0300 Subject: [PATCH 2/2] fix typo --- src/building.js | 2 +- test/building.test.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/building.js b/src/building.js index ed0b9ef..7f0374c 100644 --- a/src/building.js +++ b/src/building.js @@ -78,7 +78,7 @@ class Building { try { this.validateData(outerElementXml); } catch (e) { - throw new Error(`Rendering of ${outerElementXml.tagName.toLowerCase()} ${id} is not is not possible. ${e}`); + throw new Error(`Rendering of ${outerElementXml.tagName.toLowerCase()} ${id} is not possible. ${e}`); } this.nodelist = Building.buildNodeList(this.fullXmlData); diff --git a/test/building.test.js b/test/building.test.js index 6dea886..b076afe 100644 --- a/test/building.test.js +++ b/test/building.test.js @@ -69,7 +69,7 @@ test('Test data validation open outline', () => { `; expect(() => new Building('1', data)) - .toThrow(new Error('Rendering of way 1 is not is not possible. Error: Way 1 is not a closed way. 2 !== 4.')); + .toThrow(new Error('Rendering of way 1 is not possible. Error: Way 1 is not a closed way. 2 !== 4.')); }); test('Test data validation with not building', () => { @@ -82,7 +82,7 @@ test('Test data validation with not building', () => { `; expect(() => new Building('1', data)) - .toThrow(new Error('Rendering of way 1 is not is not possible. Error: Outer way is not a building')); + .toThrow(new Error('Rendering of way 1 is not possible. Error: Outer way is not a building')); }); test('Test data validation with empty way', () => { @@ -91,7 +91,7 @@ test('Test data validation with empty way', () => { `; expect(() => new Building('1', data)) - .toThrow(new Error('Rendering of way 1 is not is not possible. Error: Way 1 has no nodes.')); + .toThrow(new Error('Rendering of way 1 is not possible. Error: Way 1 has no nodes.')); }); test('Test Constructor', async() => {