forked from hans/Nominatim
bdd: fully check correctness of geojson and geocodejson
Parse code now checks presence of all required fields and exports all fields for inspection.
This commit is contained in:
@@ -7,6 +7,7 @@
|
|||||||
"""
|
"""
|
||||||
Collection of assertion functions used for the steps.
|
Collection of assertion functions used for the steps.
|
||||||
"""
|
"""
|
||||||
|
import json
|
||||||
|
|
||||||
class Almost:
|
class Almost:
|
||||||
""" Compares a float value with a certain jitter.
|
""" Compares a float value with a certain jitter.
|
||||||
@@ -41,3 +42,24 @@ class Bbox:
|
|||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.coord)
|
return str(self.coord)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def check_for_attributes(obj, attrs, presence='present'):
|
||||||
|
""" Check that the object has the given attributes. 'attrs' is a
|
||||||
|
string with a comma-separated list of attributes. If 'presence'
|
||||||
|
is set to 'absent' then the function checks that the attributes do
|
||||||
|
not exist for the object
|
||||||
|
"""
|
||||||
|
def _dump_json():
|
||||||
|
return json.dumps(obj, sort_keys=True, indent=2, ensure_ascii=False)
|
||||||
|
|
||||||
|
for attr in attrs.split(','):
|
||||||
|
attr = attr.strip()
|
||||||
|
if presence == 'absent':
|
||||||
|
assert attr not in obj, \
|
||||||
|
f"Unexpected attribute {attr}. Full response:\n{_dump_json()}"
|
||||||
|
else:
|
||||||
|
assert attr in obj, \
|
||||||
|
f"No attribute '{attr}'. Full response:\n{_dump_json()}"
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import re
|
|||||||
import json
|
import json
|
||||||
import xml.etree.ElementTree as ET
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
from check_functions import Almost
|
from check_functions import Almost, check_for_attributes
|
||||||
|
|
||||||
OSM_TYPE = {'N' : 'node', 'W' : 'way', 'R' : 'relation',
|
OSM_TYPE = {'N' : 'node', 'W' : 'way', 'R' : 'relation',
|
||||||
'n' : 'node', 'w' : 'way', 'r' : 'relation',
|
'n' : 'node', 'w' : 'way', 'r' : 'relation',
|
||||||
@@ -76,15 +76,47 @@ class GenericResponse:
|
|||||||
else:
|
else:
|
||||||
self.result = [self.result]
|
self.result = [self.result]
|
||||||
|
|
||||||
|
|
||||||
def _parse_geojson(self):
|
def _parse_geojson(self):
|
||||||
self._parse_json()
|
self._parse_json()
|
||||||
if self.result:
|
if self.result:
|
||||||
self.result = list(map(_geojson_result_to_json_result, self.result[0]['features']))
|
geojson = self.result[0]
|
||||||
|
# check for valid geojson
|
||||||
|
check_for_attributes(geojson, 'type,features')
|
||||||
|
assert geojson['type'] == 'FeatureCollection'
|
||||||
|
assert isinstance(geojson['features'], list)
|
||||||
|
|
||||||
|
self.result = []
|
||||||
|
for result in geojson['features']:
|
||||||
|
check_for_attributes(result, 'type,properties,geometry')
|
||||||
|
assert result['type'] == 'Feature'
|
||||||
|
new = result['properties']
|
||||||
|
check_for_attributes(new, 'geojson', 'absent')
|
||||||
|
new['geojson'] = result['geometry']
|
||||||
|
if 'bbox' in result:
|
||||||
|
check_for_attributes(new, 'boundingbox', 'absent')
|
||||||
|
# bbox is minlon, minlat, maxlon, maxlat
|
||||||
|
# boundingbox is minlat, maxlat, minlon, maxlon
|
||||||
|
new['boundingbox'] = [result['bbox'][1],
|
||||||
|
result['bbox'][3],
|
||||||
|
result['bbox'][0],
|
||||||
|
result['bbox'][2]]
|
||||||
|
for k, v in geojson.items():
|
||||||
|
if k not in ('type', 'features'):
|
||||||
|
check_for_attributes(new, '__' + k, 'absent')
|
||||||
|
new['__' + k] = v
|
||||||
|
self.result.append(new)
|
||||||
|
|
||||||
|
|
||||||
def _parse_geocodejson(self):
|
def _parse_geocodejson(self):
|
||||||
self._parse_geojson()
|
self._parse_geojson()
|
||||||
if self.result is not None:
|
if self.result:
|
||||||
self.result = [r['geocoding'] for r in self.result]
|
for r in self.result:
|
||||||
|
assert set(r.keys()) == {'geocoding', 'geojson', '__geocoding'}, \
|
||||||
|
f"Unexpected keys in result: {r.keys()}"
|
||||||
|
check_for_attributes(r['geocoding'], 'geojson', 'absent')
|
||||||
|
r |= r.pop('geocoding')
|
||||||
|
|
||||||
|
|
||||||
def assert_field(self, idx, field, value):
|
def assert_field(self, idx, field, value):
|
||||||
""" Check that result row `idx` has a field `field` with value `value`.
|
""" Check that result row `idx` has a field `field` with value `value`.
|
||||||
|
|||||||
Reference in New Issue
Block a user