Skip to content
Permalink
Browse files

Processing tests: allow topological geometry tests instead of exact t…

…ests

This is useful with geometry algorithms when the order of the coordinates of produced
geometries does not need to be exactly the same every time, but the output is still
topologically equivalent.
  • Loading branch information
wonder-sk committed May 9, 2018
1 parent 64b8c72 commit 73d10afe31849f44513dfeb47404c6518329d64e
Showing with 44 additions and 23 deletions.
  1. +4 −2 python/plugins/processing/tests/AlgorithmsTestBase.py
  2. +40 −21 python/testing/__init__.py
@@ -283,13 +283,14 @@ def check_results(self, results, context, params, expected):

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

if len(expected_lyrs) == 1:
self.assertLayersEqual(expected_lyrs[0], result_lyr, compare=compare, pk=pk)
self.assertLayersEqual(expected_lyrs[0], result_lyr, compare=compare, pk=pk, geometry={'topo_equal_check': topo_equal_check})
else:
res = False
for l in expected_lyrs:
if self.checkLayersEqual(l, result_lyr, compare=compare, pk=pk):
if self.checkLayersEqual(l, result_lyr, compare=compare, pk=pk, geometry={'topo_equal_check': topo_equal_check}):
res = True
break
self.assertTrue(res, 'Could not find matching layer in expected results')
@@ -319,6 +320,7 @@ def check_results(self, results, context, params, expected):


class GenericAlgorithmsTest(unittest.TestCase):

"""
General (non-provider specific) algorithm tests
"""
@@ -104,6 +104,11 @@ def checkLayersEqual(self, layer_expected, layer_result, use_asserts=False, **kw
except KeyError:
precision = 14

try:
topo_equal_check = compare['geometry']['topo_equal_check']
except KeyError:
topo_equal_check = False

def sort_by_pk_or_fid(f):
if 'pk' in kwargs and kwargs['pk'] is not None:
key = kwargs['pk']
@@ -118,27 +123,13 @@ def sort_by_pk_or_fid(f):
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():
geom0 = feats[0].geometry().constGet().asWkt(precision)
else:
geom0 = None
if feats[1].hasGeometry():
geom1 = feats[1].geometry().constGet().asWkt(precision)
else:
geom1 = None
if use_asserts:
_TestCase.assertEqual(
self,
geom0,
geom1,
'Features (Expected fid: {}, Result fid: {}) differ in geometry: \n\n Expected geometry:\n {}\n\n Result geometry:\n {}'.format(
feats[0].id(),
feats[1].id(),
geom0,
geom1
)
)
elif geom0 != geom1:

eq = self.checkGeometriesEqual(feats[0].geometry(),
feats[1].geometry(),
feats[0].id(),
feats[1].id(),
use_asserts, precision, topo_equal_check)
if not eq and use_asserts:
return False

for attr_expected, field_expected in zip(feats[0].attributes(), layer_expected.fields().toList()):
@@ -215,6 +206,34 @@ def assertFilesEqual(self, filepath_expected, filepath_result):
diff = list(diff)
self.assertEqual(0, len(diff), ''.join(diff))

def checkGeometriesEqual(self, geom0, geom1, geom0_id, geom1_id, use_asserts=False, precision=14, topo_equal_check=False):
""" Checks whether two geometries are the same - using either a strict check of coordinates (up to given precision)
or by using topological equality (where e.g. a polygon with clockwise is equal to a polygon with counter-clockwise
order of vertices) """
if not geom0.isNull() and not geom1.isNull():
if topo_equal_check:
equal = geom0.isGeosEqual(geom1)
else:
equal = geom0.constGet().asWkt(precision) == geom1.constGet().asWkt(precision)
elif geom0.isNull() and geom1.isNull():
equal = True
else:
equal = False

if use_asserts:
_TestCase.assertTrue(
self,
equal,
'Features (Expected fid: {}, Result fid: {}) differ in geometry: \n\n Expected geometry:\n {}\n\n Result geometry:\n {}'.format(
geom0_id,
geom1_id,
geom0.constGet().asWkt(precision) if geom0 is not None else 'NULL',
geom1.constGet().asWkt(precision) if geom1 is not None else 'NULL'
)
)
else:
return equal


class _UnexpectedSuccess(Exception):

0 comments on commit 73d10af

Please sign in to comment.
You can’t perform that action at this time.