mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-15 00:04:00 -04:00
Add tests
This commit is contained in:
parent
3f8ae8b225
commit
3d7ac65764
@ -186,6 +186,7 @@ ADD_PYTHON_TEST(PyQgsZipUtils test_qgsziputils.py)
|
||||
ADD_PYTHON_TEST(PyQgsSourceSelectProvider test_qgssourceselectprovider.py)
|
||||
ADD_PYTHON_TEST(PyQgsAuthManagerProxy test_authmanager_proxy.py)
|
||||
ADD_PYTHON_TEST(PyQgsAuthSettingsWidget test_authsettingswidget.py)
|
||||
ADD_PYTHON_TEST(PyQgsAuxiliaryStorage test_qgsauxiliarystorage.py)
|
||||
|
||||
IF (NOT WIN32)
|
||||
ADD_PYTHON_TEST(PyQgsLogger test_qgslogger.py)
|
||||
|
390
tests/src/python/test_qgsauxiliarystorage.py
Normal file
390
tests/src/python/test_qgsauxiliarystorage.py
Normal file
@ -0,0 +1,390 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""QGIS Unit tests for Auxiliary Storage.
|
||||
|
||||
.. note:: This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
"""
|
||||
__author__ = 'Paul Blottiere'
|
||||
__date__ = '06/09/2017'
|
||||
__copyright__ = 'Copyright 2017, The QGIS Project'
|
||||
# This will get replaced with a git SHA1 when you do a git archive
|
||||
__revision__ = '$Format:%H$'
|
||||
|
||||
import qgis # NOQA
|
||||
|
||||
import os
|
||||
|
||||
from qgis.PyQt.QtCore import QTemporaryFile
|
||||
from qgis.core import (QgsAuxiliaryStorage,
|
||||
QgsAuxiliaryLayer,
|
||||
QgsVectorLayer,
|
||||
QgsFeature,
|
||||
QgsGeometry,
|
||||
QgsPropertyDefinition,
|
||||
QgsProject,
|
||||
QgsFeatureRequest,
|
||||
QgsPalLayerSettings,
|
||||
QgsSymbolLayer,
|
||||
QgsVectorLayerSimpleLabeling,
|
||||
NULL)
|
||||
from qgis.testing import start_app, unittest
|
||||
from utilities import unitTestDataPath, writeShape
|
||||
start_app()
|
||||
|
||||
|
||||
def tmpPath():
|
||||
f = QTemporaryFile()
|
||||
f.open()
|
||||
f.close()
|
||||
os.remove(f.fileName())
|
||||
|
||||
return f.fileName()
|
||||
|
||||
|
||||
def createLayer():
|
||||
vl = QgsVectorLayer(
|
||||
'Point?crs=epsg:4326&field=pk:integer&field=cnt:integer&field=name:string(0)&field=name2:string(0)&field=num_char:string&key=pk', 'test', 'memory')
|
||||
assert (vl.isValid())
|
||||
|
||||
f1 = QgsFeature()
|
||||
f1.setAttributes([5, -200, NULL, 'NuLl', '5'])
|
||||
f1.setGeometry(QgsGeometry.fromWkt('Point (-71.123 78.23)'))
|
||||
|
||||
f2 = QgsFeature()
|
||||
f2.setAttributes([3, 300, 'Pear', 'PEaR', '3'])
|
||||
|
||||
f3 = QgsFeature()
|
||||
f3.setAttributes([1, 100, 'Orange', 'oranGe', '1'])
|
||||
f3.setGeometry(QgsGeometry.fromWkt('Point (-70.332 66.33)'))
|
||||
|
||||
f4 = QgsFeature()
|
||||
f4.setAttributes([2, 200, 'Apple', 'Apple', '2'])
|
||||
f4.setGeometry(QgsGeometry.fromWkt('Point (-68.2 70.8)'))
|
||||
|
||||
f5 = QgsFeature()
|
||||
f5.setAttributes([4, 400, 'Honey', 'Honey', '4'])
|
||||
f5.setGeometry(QgsGeometry.fromWkt('Point (-65.32 78.3)'))
|
||||
|
||||
vl.dataProvider().addFeatures([f1, f2, f3, f4, f5])
|
||||
return vl
|
||||
|
||||
|
||||
class TestQgsAuxiliaryStorage(unittest.TestCase):
|
||||
|
||||
def testCreateSaveOpenStorageWithString(self):
|
||||
# Empty string in copy mode. A new database is created in a temporary
|
||||
# file.
|
||||
s0 = QgsAuxiliaryStorage()
|
||||
self.assertTrue(s0.isValid())
|
||||
|
||||
# saveAs should be used instead of save in case of an empty string
|
||||
# given to the constructor of QgsAuxiliaryStorage
|
||||
self.assertEqual(s0.fileName(), "")
|
||||
self.assertFalse(s0.save())
|
||||
|
||||
# Create a new auxiliary layer with 'pk' as key
|
||||
vl0 = createLayer()
|
||||
pkf = vl0.fields().field(vl0.fields().indexOf('pk'))
|
||||
al0 = s0.createAuxiliaryLayer(pkf, vl0)
|
||||
self.assertTrue(al0.isValid())
|
||||
|
||||
# Test the auxiliary key
|
||||
key = al0.joinInfo().targetFieldName()
|
||||
self.assertEqual(key, 'pk')
|
||||
|
||||
# Add a field in auxiliary layer
|
||||
p = QgsPropertyDefinition('propName', QgsPropertyDefinition.DataTypeNumeric, '', '', 'user')
|
||||
self.assertTrue(al0.addAuxiliaryField(p))
|
||||
|
||||
# saveAs without saving the auxiliary layer, the auxiliary field is lost
|
||||
f = tmpPath()
|
||||
self.assertTrue(s0.saveAs(f))
|
||||
|
||||
# Open the previous database.
|
||||
s1 = QgsAuxiliaryStorage(f)
|
||||
self.assertTrue(s1.isValid())
|
||||
|
||||
# Load the auxiliary layer from auxiliary storage
|
||||
self.assertTrue(vl0.loadAuxiliaryLayer(s1, key))
|
||||
|
||||
# As the vl0 has not been saved before saving the storage, there
|
||||
# shouldn't have auxiliary fields
|
||||
self.assertEqual(len(vl0.auxiliaryLayer().auxiliaryFields()), 0)
|
||||
|
||||
# Save the layer before saving the storage
|
||||
self.assertTrue(al0.save())
|
||||
self.assertTrue(s0.saveAs(f))
|
||||
|
||||
# Open the previous database.
|
||||
s2 = QgsAuxiliaryStorage(f)
|
||||
self.assertTrue(s2.isValid())
|
||||
|
||||
# Load the auxiliary layer from auxiliary storage
|
||||
self.assertTrue(vl0.loadAuxiliaryLayer(s2, key))
|
||||
|
||||
# As the vl0 has been saved before saving the storage, there
|
||||
# should have 1 auxiliary field
|
||||
self.assertEqual(len(vl0.auxiliaryLayer().auxiliaryFields()), 1)
|
||||
|
||||
# save is available on s2
|
||||
self.assertTrue(s2.save())
|
||||
|
||||
def testCreateSaveOpenStorageWithProject(self):
|
||||
# New project without fileName
|
||||
p = QgsProject()
|
||||
|
||||
# Create storage
|
||||
s0 = QgsAuxiliaryStorage(p)
|
||||
self.assertTrue(s0.isValid())
|
||||
|
||||
# saveAs should be used instead of save in case of an empty string
|
||||
# given to the constructor of QgsAuxiliaryStorage
|
||||
self.assertEqual(s0.fileName(), "")
|
||||
self.assertFalse(s0.save())
|
||||
|
||||
# saveAs
|
||||
f = tmpPath()
|
||||
self.assertTrue(s0.saveAs(f))
|
||||
|
||||
def testProjectStorage(self):
|
||||
# New project without fileName
|
||||
p0 = QgsProject()
|
||||
self.assertTrue(p0.auxiliaryStorage().isValid())
|
||||
|
||||
# Create new layers with key otherwise auxiliary layers are not
|
||||
# automacially created when added in project
|
||||
vl0 = createLayer()
|
||||
vl0Shp = writeShape(vl0, 'vl0.shp')
|
||||
|
||||
vl1 = createLayer()
|
||||
vl1Shp = writeShape(vl1, 'vl1.shp')
|
||||
|
||||
vl0 = QgsVectorLayer(vl0Shp, 'points', 'ogr')
|
||||
self.assertTrue(vl0.isValid())
|
||||
|
||||
vl1 = QgsVectorLayer(vl1Shp, 'points', 'ogr')
|
||||
self.assertTrue(vl1.isValid())
|
||||
|
||||
# Add layers to project and check underlying auxiliary layers
|
||||
p0.addMapLayers([vl0, vl1])
|
||||
|
||||
self.assertTrue(vl0.loadAuxiliaryLayer(p0.auxiliaryStorage(), 'pk'))
|
||||
self.assertTrue(vl1.loadAuxiliaryLayer(p0.auxiliaryStorage(), 'num_char'))
|
||||
|
||||
al0 = vl0.auxiliaryLayer()
|
||||
al1 = vl1.auxiliaryLayer()
|
||||
|
||||
self.assertEqual(al0.joinInfo().targetFieldName(), 'pk')
|
||||
self.assertEqual(al1.joinInfo().targetFieldName(), 'num_char')
|
||||
|
||||
# Add a field in auxiliary layers
|
||||
pdef0 = QgsPropertyDefinition('propname', QgsPropertyDefinition.DataTypeNumeric, '', '', 'ut')
|
||||
self.assertTrue(al0.addAuxiliaryField(pdef0))
|
||||
|
||||
pdef1 = QgsPropertyDefinition('propname1', QgsPropertyDefinition.DataTypeString, '', '', 'ut')
|
||||
self.assertTrue(al1.addAuxiliaryField(pdef1))
|
||||
|
||||
# Check auxiliary fields names
|
||||
af0Name = QgsAuxiliaryLayer.nameFromProperty(pdef0, False)
|
||||
self.assertEqual(af0Name, 'ut_propname')
|
||||
af1Name = QgsAuxiliaryLayer.nameFromProperty(pdef1, False)
|
||||
self.assertEqual(af1Name, 'ut_propname1')
|
||||
|
||||
# Set value for auxiliary fields
|
||||
req = QgsFeatureRequest().setFilterExpression("name = 'Honey'")
|
||||
f = QgsFeature()
|
||||
vl0.getFeatures(req).nextFeature(f)
|
||||
self.assertTrue(f.isValid())
|
||||
af0Name = QgsAuxiliaryLayer.nameFromProperty(pdef0, True)
|
||||
index0 = vl0.fields().indexOf(af0Name)
|
||||
vl0.changeAttributeValue(f.id(), index0, 333)
|
||||
|
||||
req = QgsFeatureRequest().setFilterExpression("name = 'Apple'")
|
||||
f = QgsFeature()
|
||||
vl1.getFeatures(req).nextFeature(f)
|
||||
self.assertTrue(f.isValid())
|
||||
af1Name = QgsAuxiliaryLayer.nameFromProperty(pdef1, True)
|
||||
index1 = vl1.fields().indexOf(af1Name)
|
||||
vl1.changeAttributeValue(f.id(), index0, 'myvalue')
|
||||
|
||||
req = QgsFeatureRequest().setFilterExpression("name = 'Orange'")
|
||||
f = QgsFeature()
|
||||
vl1.getFeatures(req).nextFeature(f)
|
||||
self.assertTrue(f.isValid())
|
||||
vl1.changeAttributeValue(f.id(), index0, 'myvalue1')
|
||||
|
||||
# Save the project in a zip file
|
||||
f = tmpPath() + '.qgz'
|
||||
p0.write(f)
|
||||
|
||||
# Open the zip file with embedded auxiliary storage
|
||||
p1 = QgsProject()
|
||||
p1.read(f)
|
||||
|
||||
# Check that auxiliary fields are well loaded in layers
|
||||
self.assertEqual(len(p1.mapLayers().values()), 2)
|
||||
|
||||
for vl in p1.mapLayers().values():
|
||||
al = vl.auxiliaryLayer()
|
||||
self.assertEqual(len(al.auxiliaryFields()), 1)
|
||||
|
||||
af = al.auxiliaryFields()[0]
|
||||
afPropDef = QgsAuxiliaryLayer.propertyDefinitionFromField(af)
|
||||
self.assertEqual(afPropDef.origin(), 'ut')
|
||||
|
||||
if vl.auxiliaryLayer().joinInfo().targetFieldName() == 'pk':
|
||||
self.assertEqual(afPropDef.name(), 'propname')
|
||||
self.assertEqual(al.featureCount(), 1)
|
||||
|
||||
req = QgsFeatureRequest().setFilterExpression("name = 'Honey'")
|
||||
f = QgsFeature()
|
||||
vl.getFeatures(req).nextFeature(f)
|
||||
self.assertTrue(f.isValid())
|
||||
self.assertEqual(f.attributes()[index0], 333.0)
|
||||
else: # num_char
|
||||
self.assertEqual(al.featureCount(), 2)
|
||||
self.assertEqual(afPropDef.name(), 'propname1')
|
||||
|
||||
req = QgsFeatureRequest().setFilterExpression("name = 'Apple'")
|
||||
f = QgsFeature()
|
||||
vl.getFeatures(req).nextFeature(f)
|
||||
self.assertTrue(f.isValid())
|
||||
self.assertEqual(f.attributes()[index1], 'myvalue')
|
||||
|
||||
req = QgsFeatureRequest().setFilterExpression("name = 'Orange'")
|
||||
f = QgsFeature()
|
||||
vl.getFeatures(req).nextFeature(f)
|
||||
self.assertTrue(f.isValid())
|
||||
self.assertEqual(f.attributes()[index1], 'myvalue1')
|
||||
|
||||
def testAuxiliaryFieldWidgets(self):
|
||||
# Init storage
|
||||
s = QgsAuxiliaryStorage()
|
||||
self.assertTrue(s.isValid())
|
||||
|
||||
# Create a new auxiliary layer with 'pk' as key
|
||||
vl = createLayer()
|
||||
pkf = vl.fields().field(vl.fields().indexOf('pk'))
|
||||
al = s.createAuxiliaryLayer(pkf, vl)
|
||||
self.assertTrue(al.isValid())
|
||||
|
||||
# Set the auxiliary layer to the vector layer
|
||||
vl.setAuxiliaryLayer(al)
|
||||
|
||||
# Add a visible property
|
||||
p = QgsPropertyDefinition('propName', QgsPropertyDefinition.DataTypeNumeric, '', '', 'user')
|
||||
self.assertTrue(al.addAuxiliaryField(p))
|
||||
|
||||
index = al.indexOfPropertyDefinition(p)
|
||||
self.assertFalse(al.isHiddenProperty(index))
|
||||
|
||||
afName = QgsAuxiliaryLayer.nameFromProperty(p, True)
|
||||
index = vl.fields().indexOf(afName)
|
||||
setup = vl.editorWidgetSetup(index)
|
||||
self.assertEqual(setup.type(), '')
|
||||
|
||||
tested = False
|
||||
for c in vl.attributeTableConfig().columns():
|
||||
if c.name == afName:
|
||||
self.assertFalse(c.hidden)
|
||||
tested = True
|
||||
break
|
||||
self.assertTrue(tested)
|
||||
|
||||
# Add a hidden property
|
||||
p = QgsPalLayerSettings.propertyDefinitions()[QgsPalLayerSettings.PositionX]
|
||||
self.assertTrue(al.addAuxiliaryField(p))
|
||||
|
||||
index = al.indexOfPropertyDefinition(p)
|
||||
self.assertTrue(al.isHiddenProperty(index))
|
||||
|
||||
afName = QgsAuxiliaryLayer.nameFromProperty(p, True)
|
||||
index = vl.fields().indexOf(afName)
|
||||
setup = vl.editorWidgetSetup(index)
|
||||
self.assertEqual(setup.type(), 'Hidden')
|
||||
|
||||
tested = False
|
||||
for c in vl.attributeTableConfig().columns():
|
||||
if c.name == afName:
|
||||
self.assertTrue(c.hidden)
|
||||
tested = True
|
||||
break
|
||||
self.assertTrue(tested)
|
||||
|
||||
# Add a color property
|
||||
p = QgsSymbolLayer.propertyDefinitions()[QgsSymbolLayer.PropertyFillColor]
|
||||
self.assertTrue(al.addAuxiliaryField(p))
|
||||
|
||||
index = al.indexOfPropertyDefinition(p)
|
||||
self.assertFalse(al.isHiddenProperty(index))
|
||||
|
||||
afName = QgsAuxiliaryLayer.nameFromProperty(p, True)
|
||||
index = vl.fields().indexOf(afName)
|
||||
setup = vl.editorWidgetSetup(index)
|
||||
self.assertEqual(setup.type(), 'Color')
|
||||
|
||||
def testClear(self):
|
||||
s = QgsAuxiliaryStorage()
|
||||
self.assertTrue(s.isValid())
|
||||
|
||||
# Create a new auxiliary layer with 'pk' as key
|
||||
vl = createLayer()
|
||||
pkf = vl.fields().field(vl.fields().indexOf('pk'))
|
||||
al = s.createAuxiliaryLayer(pkf, vl)
|
||||
self.assertTrue(al.isValid())
|
||||
vl.setAuxiliaryLayer(al)
|
||||
|
||||
# Add a field in auxiliary layer
|
||||
p = QgsPropertyDefinition('myprop', QgsPropertyDefinition.DataTypeNumeric, '', '', 'me')
|
||||
self.assertFalse(al.exists(p))
|
||||
self.assertTrue(al.addAuxiliaryField(p))
|
||||
self.assertTrue(al.exists(p))
|
||||
|
||||
# Count auxiliary features
|
||||
self.assertEqual(al.featureCount(), 0)
|
||||
|
||||
# Set value for auxiliary fields
|
||||
req = QgsFeatureRequest().setFilterExpression("name = 'Honey'")
|
||||
f = QgsFeature()
|
||||
vl.getFeatures(req).nextFeature(f)
|
||||
self.assertTrue(f.isValid())
|
||||
afName = QgsAuxiliaryLayer.nameFromProperty(p, True)
|
||||
index = vl.fields().indexOf(afName)
|
||||
vl.changeAttributeValue(f.id(), index, 333)
|
||||
|
||||
# Count auxiliary features
|
||||
self.assertEqual(al.featureCount(), 1)
|
||||
|
||||
# Clear and count
|
||||
al.clear()
|
||||
self.assertEqual(al.featureCount(), 0)
|
||||
|
||||
def testCreateProperty(self):
|
||||
s = QgsAuxiliaryStorage()
|
||||
self.assertTrue(s.isValid())
|
||||
|
||||
# Create a new auxiliary layer with 'pk' as key
|
||||
vl = createLayer()
|
||||
pkf = vl.fields().field(vl.fields().indexOf('pk'))
|
||||
al = s.createAuxiliaryLayer(pkf, vl)
|
||||
self.assertTrue(al.isValid())
|
||||
vl.setAuxiliaryLayer(al)
|
||||
|
||||
# Create a new labeling property on layer without labels
|
||||
key = QgsPalLayerSettings.PositionX
|
||||
index = QgsAuxiliaryLayer.createProperty(key, vl)
|
||||
self.assertEqual(index, -1)
|
||||
|
||||
vl.setLabeling(QgsVectorLayerSimpleLabeling(QgsPalLayerSettings()))
|
||||
index = QgsAuxiliaryLayer.createProperty(key, vl)
|
||||
|
||||
p = QgsPalLayerSettings.propertyDefinitions()[key]
|
||||
afName = QgsAuxiliaryLayer.nameFromProperty(p, True)
|
||||
afIndex = vl.fields().indexOf(afName)
|
||||
self.assertEqual(index, afIndex)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
@ -123,6 +123,8 @@ def writeShape(theMemoryLayer, theFileName):
|
||||
mySkipAttributesFlag)
|
||||
assert myResult == QgsVectorFileWriter.NoError, 'Writing shape failed, Error {} ({})'.format(myResult, myErrorMessage)
|
||||
|
||||
return myFileName
|
||||
|
||||
|
||||
def doubleNear(a, b, tol=0.0000000001):
|
||||
"""
|
||||
|
Loading…
x
Reference in New Issue
Block a user