]> git.openstreetmap.org Git - nominatim.git/commitdiff
bdd: new step variant 'result contains in field'
authorSarah Hoffmann <lonvia@denofr.de>
Thu, 9 Mar 2023 18:31:21 +0000 (19:31 +0100)
committerSarah Hoffmann <lonvia@denofr.de>
Thu, 9 Mar 2023 18:31:21 +0000 (19:31 +0100)
This replaces the + notation for recursing into result dictionaries.

test/bdd/api/details/params.feature
test/bdd/steps/http_responses.py
test/bdd/steps/steps_api_queries.py

index 3bb5bf7cbbb987de7492eba341063fff4f629cf4..3d5635de126c6136c575a2f7e860e6f7492d7234 100644 (file)
@@ -7,9 +7,9 @@ Feature: Object details
         Then the result is valid json
         And result has attributes geometry
         And result has not attributes keywords,address,linked_places,parentof
-        And results contain
-            | geometry+type |
-            | Point         |
+        And results contain in field geometry
+            | type  |
+            | Point |
 
     Scenario: JSON Details with pretty printing
         When sending json details query for W297699560
@@ -75,9 +75,9 @@ Feature: Object details
             | 1 |
         Then the result is valid json
         And result has attributes geometry
-        And results contain
-            | geometry+type |
-            | <geometry>    |
+        And results contain in field geometry
+            | type       |
+            | <geometry> |
 
     Examples:
             | osmid      | geometry   |
index ccf247a91de86c0dd7cda64a8fd1b1cc0c597b3d..ff78754670fa0d4c90a7ba8c6549a6fbd6650db0 100644 (file)
@@ -87,25 +87,6 @@ class GenericResponse:
                 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):
         """ Check that result rows`idx` has a field `field` with value `value`
             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)
 
 
-    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.
         """
         if 'ID' in row.headings:
@@ -131,12 +112,20 @@ class GenericResponse:
             todo = range(len(self.result))
 
         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):
                 if name == 'ID':
                     pass
                 elif name == 'osm':
-                    self.check_row_field(i, 'osm_type', OsmType(value[0]))
-                    self.check_row_field(i, 'osm_id', Field(value[1:]))
+                    self.check_row_field(i, 'osm_type', OsmType(value[0]), base=subdict)
+                    self.check_row_field(i, 'osm_id', Field(value[1:]), base=subdict)
                 elif name == 'centroid':
                     if ' ' in value:
                         lon, lat = value.split(' ')
@@ -144,12 +133,10 @@ class GenericResponse:
                         lon, lat = context.osm.grid_node(int(value))
                     else:
                         raise RuntimeError("Context needed when using grid coordinates")
-                    self.check_row_field(i, 'lat', Field(float(lat)))
-                    self.check_row_field(i, 'lon', Field(float(lon)))
-                elif '+' in name:
-                    self.assert_subfield(i, name.split('+'), value)
+                    self.check_row_field(i, 'lat', Field(float(lat)), base=subdict)
+                    self.check_row_field(i, 'lon', Field(float(lon)), base=subdict)
                 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):
index b15e296f7d426f40e811740093ae4eb2a03cab6d..7d8b1928fdf94208666abd45a1fd1486b8aacfc2 100644 (file)
@@ -264,12 +264,12 @@ def check_header_no_attr(context, neg, attrs):
                          'absent' if neg else 'present')
 
 
-@then(u'results contain')
-def step_impl(context):
+@then(u'results contain(?: in field (?P<field>.*))?')
+def step_impl(context, field):
     context.execute_steps("then at least 1 result is returned")
 
     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>.*)')