bdd: new step variant 'result contains in field'

This replaces the + notation for recursing into result dictionaries.
This commit is contained in:
Sarah Hoffmann
2023-03-09 19:31:21 +01:00
parent 556bb2386d
commit e42c1c9c7a
3 changed files with 23 additions and 36 deletions

View File

@@ -7,9 +7,9 @@ Feature: Object details
Then the result is valid json Then the result is valid json
And result has attributes geometry And result has attributes geometry
And result has not attributes keywords,address,linked_places,parentof And result has not attributes keywords,address,linked_places,parentof
And results contain And results contain in field geometry
| geometry+type | | type |
| Point | | Point |
Scenario: JSON Details with pretty printing Scenario: JSON Details with pretty printing
When sending json details query for W297699560 When sending json details query for W297699560
@@ -75,9 +75,9 @@ Feature: Object details
| 1 | | 1 |
Then the result is valid json Then the result is valid json
And result has attributes geometry And result has attributes geometry
And results contain And results contain in field geometry
| geometry+type | | type |
| <geometry> | | <geometry> |
Examples: Examples:
| osmid | geometry | | osmid | geometry |

View File

@@ -87,25 +87,6 @@ class GenericResponse:
r |= r.pop('geocoding') r |= r.pop('geocoding')
def assert_subfield(self, idx, path, value):
assert path
field = self.result[idx]
for p in path:
assert isinstance(field, dict)
assert p in field
field = field[p]
if isinstance(value, float):
assert Almost(value) == float(field)
elif value.startswith("^"):
assert re.fullmatch(value, field)
elif isinstance(field, dict):
assert field, eval('{' + value + '}')
else:
assert str(field) == str(value)
def assert_address_field(self, idx, field, value): def assert_address_field(self, idx, field, value):
""" Check that result rows`idx` has a field `field` with value `value` """ Check that result rows`idx` has a field `field` with value `value`
in its address. If idx is None, then all results are checked. in its address. If idx is None, then all results are checked.
@@ -122,7 +103,7 @@ class GenericResponse:
self.check_row_field(idx, field, value, base=address) self.check_row_field(idx, field, value, base=address)
def match_row(self, row, context=None): def match_row(self, row, context=None, field=None):
""" Match the result fields against the given behave table row. """ Match the result fields against the given behave table row.
""" """
if 'ID' in row.headings: if 'ID' in row.headings:
@@ -131,12 +112,20 @@ class GenericResponse:
todo = range(len(self.result)) todo = range(len(self.result))
for i in todo: for i in todo:
subdict = self.result[i]
if field is not None:
for key in field.split('.'):
self.check_row(i, key in subdict, f"Missing subfield {key}")
subdict = subdict[key]
self.check_row(i, isinstance(subdict, dict),
f"Subfield {key} not a dict")
for name, value in zip(row.headings, row.cells): for name, value in zip(row.headings, row.cells):
if name == 'ID': if name == 'ID':
pass pass
elif name == 'osm': elif name == 'osm':
self.check_row_field(i, 'osm_type', OsmType(value[0])) self.check_row_field(i, 'osm_type', OsmType(value[0]), base=subdict)
self.check_row_field(i, 'osm_id', Field(value[1:])) self.check_row_field(i, 'osm_id', Field(value[1:]), base=subdict)
elif name == 'centroid': elif name == 'centroid':
if ' ' in value: if ' ' in value:
lon, lat = value.split(' ') lon, lat = value.split(' ')
@@ -144,12 +133,10 @@ class GenericResponse:
lon, lat = context.osm.grid_node(int(value)) lon, lat = context.osm.grid_node(int(value))
else: else:
raise RuntimeError("Context needed when using grid coordinates") raise RuntimeError("Context needed when using grid coordinates")
self.check_row_field(i, 'lat', Field(float(lat))) self.check_row_field(i, 'lat', Field(float(lat)), base=subdict)
self.check_row_field(i, 'lon', Field(float(lon))) self.check_row_field(i, 'lon', Field(float(lon)), base=subdict)
elif '+' in name:
self.assert_subfield(i, name.split('+'), value)
else: else:
self.check_row_field(i, name, Field(value)) self.check_row_field(i, name, Field(value), base=subdict)
def check_row(self, idx, check, msg): def check_row(self, idx, check, msg):

View File

@@ -264,12 +264,12 @@ def check_header_no_attr(context, neg, attrs):
'absent' if neg else 'present') 'absent' if neg else 'present')
@then(u'results contain') @then(u'results contain(?: in field (?P<field>.*))?')
def step_impl(context): def step_impl(context, field):
context.execute_steps("then at least 1 result is returned") context.execute_steps("then at least 1 result is returned")
for line in context.table: for line in context.table:
context.response.match_row(line, context=context) context.response.match_row(line, context=context, field=field)
@then(u'result (?P<lid>\d+ )?has (?P<neg>not )?attributes (?P<attrs>.*)') @then(u'result (?P<lid>\d+ )?has (?P<neg>not )?attributes (?P<attrs>.*)')