Skip to content

Commit

Permalink
Allow specifying a 'primary key' field when comparing layers for
Browse files Browse the repository at this point in the history
processing tests

Some algorithms will return results in different orders, e.g.
due to the use of dicts or other methods which do not guarantee
a fixed return order.

Using a primary key to do the feature match allows us to flexibly
handle these situations and provide tests for these algorithms.
  • Loading branch information
nyalldawson committed Aug 5, 2017
1 parent 6aa672d commit d4ad063
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 4 deletions.
5 changes: 3 additions & 2 deletions python/plugins/processing/tests/AlgorithmsTestBase.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,13 +287,14 @@ def check_results(self, results, context, params, expected):
self.assertTrue(result_lyr, results[id])

compare = expected_result.get('compare', {})
pk = expected_result.get('pk', None)

if len(expected_lyrs) == 1:
self.assertLayersEqual(expected_lyrs[0], result_lyr, compare=compare)
self.assertLayersEqual(expected_lyrs[0], result_lyr, compare=compare, pk=pk)
else:
res = False
for l in expected_lyrs:
if self.checkLayersEqual(l, result_lyr, compare=compare):
if self.checkLayersEqual(l, result_lyr, compare=compare, pk=pk):
res = True
break
self.assertTrue(res, 'Could not find matching layer in expected results')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2501,6 +2501,10 @@ tests:
OUTPUT:
name: expected/stats_by_category.gml
type: vector
pk: id2
compare:
fields:
fid: skip

# - algorithm: qgis:zonalstatistics
# name: simple zonal statistics
Expand Down
18 changes: 16 additions & 2 deletions python/testing/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ def assertLayersEqual(self, layer_expected, layer_result, **kwargs):
:keyword compare: A map of comparison options. e.g.
{ fields: { a: skip, b: { precision: 2 }, geometry: { precision: 5 } }
{ fields: { __all__: cast( str ) } }
:keyword pk: "Primary key" type field - used to match features
from the expected table to their corresponding features in the result table. If not specified
features are compared by their order in the layer (e.g. first feature compared with first feature,
etc)
"""
self.checkLayersEqual(layer_expected, layer_result, True, **kwargs)

Expand All @@ -69,6 +73,10 @@ def checkLayersEqual(self, layer_expected, layer_result, use_asserts=False, **kw
:keyword compare: A map of comparison options. e.g.
{ fields: { a: skip, b: { precision: 2 }, geometry: { precision: 5 } }
{ fields: { __all__: cast( str ) } }
:keyword pk: "Primary key" type field - used to match features
from the expected table to their corresponding features in the result table. If not specified
features are compared by their order in the layer (e.g. first feature compared with first feature,
etc)
"""

try:
Expand Down Expand Up @@ -98,8 +106,14 @@ def checkLayersEqual(self, layer_expected, layer_result, use_asserts=False, **kw
except KeyError:
precision = 14

expected_features = sorted(layer_expected.getFeatures(request), key=lambda f: f.id())
result_features = sorted(layer_result.getFeatures(request), key=lambda f: f.id())
def sort_by_pk_or_fid(f):
if 'pk' in kwargs and kwargs['pk'] is not None:
return f[kwargs['pk']]
else:
return f.id()

expected_features = sorted(layer_expected.getFeatures(request), key=sort_by_pk_or_fid)
result_features = sorted(layer_result.getFeatures(request), key=sort_by_pk_or_fid)

for feats in zip(expected_features, result_features):
if feats[0].hasGeometry():
Expand Down

0 comments on commit d4ad063

Please sign in to comment.