Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[processing] Allow tests for algs which modify layers in place
Add test for Create Attribute Index algorithm
  • Loading branch information
nyalldawson committed Jan 5, 2017
1 parent 7b17751 commit 7a7f119
Show file tree
Hide file tree
Showing 15 changed files with 55 additions and 14 deletions.
49 changes: 35 additions & 14 deletions python/plugins/processing/tests/AlgorithmsTestBase.py
Expand Up @@ -36,6 +36,8 @@
import yaml
import nose2
import gdal
import shutil
import glob
import hashlib
import tempfile

Expand Down Expand Up @@ -69,6 +71,8 @@ def processingTestDataPath():

class AlgorithmsTest(object):

in_place_layers = {}

def test_algorithms(self):
"""
This is the main test function. All others will be executed based on the definitions in testdata/algorithm_tests.yaml
Expand Down Expand Up @@ -110,14 +114,14 @@ def check_algorithm(self, name, defs):
if expectFailure:
try:
alg.execute()
self.check_results(alg.getOutputValuesAsDictionary(), defs['results'])
self.check_results(alg.getOutputValuesAsDictionary(), defs['params'], defs['results'])
except Exception:
pass
else:
raise _UnexpectedSuccess
else:
alg.execute()
self.check_results(alg.getOutputValuesAsDictionary(), defs['results'])
self.check_results(alg.getOutputValuesAsDictionary(), defs['params'], defs['results'])

def load_params(self, params):
"""
Expand All @@ -126,18 +130,18 @@ def load_params(self, params):
if isinstance(params, list):
return [self.load_param(p) for p in params]
elif isinstance(params, dict):
return {key: self.load_param(p) for key, p in list(params.items())}
return {key: self.load_param(p, key) for key, p in list(params.items())}
else:
return params

def load_param(self, param):
def load_param(self, param, id=None):
"""
Loads a parameter. If it's not a map, the parameter will be returned as-is. If it is a map, it will process the
parameter based on its key `type` and return the appropriate parameter to pass to the algorithm.
"""
try:
if param['type'] in ('vector', 'raster', 'table'):
return self.load_layer(param)
return self.load_layer(id, param)
elif param['type'] == 'multi':
return [self.load_param(p) for p in param['params']]
elif param['type'] == 'file':
Expand Down Expand Up @@ -176,12 +180,26 @@ def load_result_param(self, param):

raise KeyError("Unknown type '{}' specified for parameter".format(param['type']))

def load_layer(self, param):
def load_layer(self, id, param):
"""
Loads a layer which was specified as parameter.
"""
filepath = self.filepath_from_param(param)

try:
# check if alg modifies layer in place
if param['in_place']:
tmpdir = tempfile.mkdtemp()
self.cleanup_paths.append(tmpdir)
path, file_name = os.path.split(filepath)
base, ext = os.path.splitext(file_name)
for file in glob.glob(os.path.join(path, '{}.*'.format(base))):
shutil.copy(os.path.join(path, file), tmpdir)
filepath = os.path.join(tmpdir, file_name)
self.in_place_layers[id] = filepath
except:
pass

if param['type'] in ('vector', 'table'):
lyr = QgsVectorLayer(filepath, param['name'], 'ogr')
elif param['type'] == 'raster':
Expand All @@ -201,19 +219,22 @@ def filepath_from_param(self, param):

return os.path.join(prefix, param['name'])

def check_results(self, results, expected):
def check_results(self, results, params, expected):
"""
Checks if result produced by an algorithm matches with the expected specification.
"""
for id, expected_result in list(expected.items()):
if expected_result['type'] in ('vector', 'table'):
expected_lyr = self.load_layer(expected_result)
try:
results[id]
except KeyError as e:
raise KeyError('Expected result {} does not exist in {}'.format(str(e), list(results.keys())))

result_lyr = QgsVectorLayer(results[id], id, 'ogr')
expected_lyr = self.load_layer(id, expected_result)
if 'in_place_result' in expected_result:
result_lyr = QgsVectorLayer(self.in_place_layers[id], id, 'ogr')
else:
try:
results[id]
except KeyError as e:
raise KeyError('Expected result {} does not exist in {}'.format(str(e), list(results.keys())))

result_lyr = QgsVectorLayer(results[id], id, 'ogr')

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

Expand Down
1 change: 1 addition & 0 deletions python/plugins/processing/tests/testdata/custom/points.cpg
@@ -0,0 +1 @@
UTF-8
Binary file not shown.
1 change: 1 addition & 0 deletions python/plugins/processing/tests/testdata/custom/points.prj
@@ -0,0 +1 @@
GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
1 change: 1 addition & 0 deletions python/plugins/processing/tests/testdata/custom/points.qpj
@@ -0,0 +1 @@
GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
UTF-8
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
@@ -0,0 +1 @@
GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]
Binary file not shown.
Binary file not shown.
14 changes: 14 additions & 0 deletions python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml
Expand Up @@ -2090,3 +2090,17 @@ tests:
# OUTPUT_POLYGON:
# name: expected/servicearea_bounds.gml
# type: vector

- algorithm: qgis:createattributeindex
name: Create attribute index
params:
FIELD: id
INPUT:
name: custom/points.shp
type: vector
in_place: true
results:
INPUT:
name: expected/create_attr_index_points.shp
type: vector
in_place_result: true

0 comments on commit 7a7f119

Please sign in to comment.