Skip to content
Permalink
Browse files
Split ProviderTestCase into provider/source tests
There's now a FeatureSourceTestCase base class which handles
testing QgsFeatureSources for conformance. These tests
consist mostly of tests which where previously in
ProviderTestCase. ProviderTestCase now subclasses
FeatureSourceTestCase + adds tests which are specific
to QgsVectorDataProviders.
  • Loading branch information
nyalldawson committed May 25, 2017
1 parent df3a43f commit aa376c2a1f941b070e57d242f6a4dc9d95577ddc

Large diffs are not rendered by default.

Large diffs are not rendered by default.

@@ -39,7 +39,7 @@ def setUpClass(cls):
# Create test layer
cls.vl = QgsVectorLayer(cls.dbconn + ' srid=4326 type=Point table="QGIS_TEST"."SOMEDATA" (GEOM) sql=', 'test', 'DB2')
assert(cls.vl.isValid())
cls.provider = cls.vl.dataProvider()
cls.source = cls.vl.dataProvider()
cls.poly_vl = QgsVectorLayer(
cls.dbconn + ' srid=4326 type=POLYGON table="QGIS_TEST"."SOME_POLY_DATA" (geom) sql=', 'test', 'DB2')
assert(cls.poly_vl.isValid())
@@ -83,7 +83,7 @@ def setUpClass(cls):
# Create test layer
cls.vl = cls.createLayer()
assert (cls.vl.isValid())
cls.provider = cls.vl.dataProvider()
cls.source = cls.vl.dataProvider()

# poly layer
cls.poly_vl = QgsVectorLayer('Polygon?crs=epsg:4326&field=pk:integer&key=pk',
@@ -415,7 +415,7 @@ def setUpClass(cls):
cls.vl = QgsVectorLayer('Point?crs=epsg:4326&index=yes&field=pk:integer&field=cnt:int8&field=name:string(0)&field=name2:string(0)&field=num_char:string&key=pk',
'test', 'memory')
assert (cls.vl.isValid())
cls.provider = cls.vl.dataProvider()
cls.source = cls.vl.dataProvider()

f1 = QgsFeature()
f1.setAttributes([5, -200, NULL, 'NuLl', '5'])
@@ -436,7 +436,7 @@ def setUpClass(cls):
f5.setAttributes([4, 400, 'Honey', 'Honey', '4'])
f5.setGeometry(QgsGeometry.fromWkt('Point (-65.32 78.3)'))

cls.provider.addFeatures([f1, f2, f3, f4, f5])
cls.source.addFeatures([f1, f2, f3, f4, f5])

# poly layer
cls.poly_vl = QgsVectorLayer('Polygon?crs=epsg:4326&index=yes&field=pk:integer&key=pk',
@@ -40,7 +40,7 @@ def setUpClass(cls):
cls.vl = QgsVectorLayer(
cls.dbconn + ' sslmode=disable key=\'pk\' srid=4326 type=POINT table="qgis_test"."someData" (geom) sql=', 'test', 'mssql')
assert(cls.vl.isValid())
cls.provider = cls.vl.dataProvider()
cls.source = cls.vl.dataProvider()
cls.poly_vl = QgsVectorLayer(
cls.dbconn + ' sslmode=disable key=\'pk\' srid=4326 type=POLYGON table="qgis_test"."some_poly_data" (geom) sql=', 'test', 'mssql')
assert(cls.poly_vl.isValid())
@@ -40,7 +40,7 @@ def setUpClass(cls):
cls.vl = QgsVectorLayer(
cls.dbconn + ' sslmode=disable key=\'pk\' srid=4326 type=POINT table="QGIS"."SOME_DATA" (GEOM) sql=', 'test', 'oracle')
assert(cls.vl.isValid())
cls.provider = cls.vl.dataProvider()
cls.source = cls.vl.dataProvider()
cls.poly_vl = QgsVectorLayer(
cls.dbconn + ' sslmode=disable key=\'pk\' srid=4326 type=POLYGON table="QGIS"."SOME_POLY_DATA" (GEOM) sql=', 'test', 'oracle')
assert(cls.poly_vl.isValid())
@@ -151,8 +151,8 @@ def testDateTimeTypes(self):
QDate(2004, 3, 4), QTime(13, 41, 52)))

def testDefaultValue(self):
self.assertEqual(self.provider.defaultValue(1), NULL)
self.assertEqual(self.provider.defaultValue(2), "'qgis'")
self.assertEqual(self.source.defaultValue(1), NULL)
self.assertEqual(self.source.defaultValue(2), "'qgis'")


if __name__ == '__main__':
@@ -51,7 +51,7 @@ def setUpClass(cls):
# Create test layers
cls.vl = QgsVectorLayer(cls.dbconn + ' sslmode=disable key=\'pk\' srid=4326 type=POINT table="qgis_test"."someData" (geom) sql=', 'test', 'postgres')
assert cls.vl.isValid()
cls.provider = cls.vl.dataProvider()
cls.source = cls.vl.dataProvider()
cls.poly_vl = QgsVectorLayer(cls.dbconn + ' sslmode=disable key=\'pk\' srid=4326 type=POLYGON table="qgis_test"."some_poly_data" (geom) sql=', 'test', 'postgres')
assert cls.poly_vl.isValid()
cls.poly_provider = cls.poly_vl.dataProvider()
@@ -70,7 +70,7 @@ def execSQLCommand(self, sql):
cur.close()
self.con.commit()

def getEditableLayer(self):
def getSource(self):
# create temporary table for edit tests
self.execSQLCommand('DROP TABLE IF EXISTS qgis_test."editData" CASCADE')
self.execSQLCommand('CREATE TABLE qgis_test."editData" ( pk SERIAL NOT NULL PRIMARY KEY, cnt integer, name text, name2 text, num_char text, geom public.geometry(Point, 4326))')
@@ -85,6 +85,9 @@ def getEditableLayer(self):
'test', 'postgres')
return vl

def getEditableLayer(self):
return self.getSource()

def enableCompiler(self):
QgsSettings().setValue('/qgis/compileExpressions', True)

@@ -99,17 +102,17 @@ def partiallyCompiledFilters(self):

# HERE GO THE PROVIDER SPECIFIC TESTS
def testDefaultValue(self):
self.provider.setProviderProperty(QgsDataProvider.EvaluateDefaultValues, True)
self.assertIsInstance(self.provider.defaultValue(0), int)
self.assertEqual(self.provider.defaultValue(1), NULL)
self.assertEqual(self.provider.defaultValue(2), 'qgis')
self.provider.setProviderProperty(QgsDataProvider.EvaluateDefaultValues, False)
self.source.setProviderProperty(QgsDataProvider.EvaluateDefaultValues, True)
self.assertIsInstance(self.source.defaultValue(0), int)
self.assertEqual(self.source.defaultValue(1), NULL)
self.assertEqual(self.source.defaultValue(2), 'qgis')
self.source.setProviderProperty(QgsDataProvider.EvaluateDefaultValues, False)

def testDefaultValueClause(self):
self.provider.setProviderProperty(QgsDataProvider.EvaluateDefaultValues, False)
self.assertEqual(self.provider.defaultValueClause(0), 'nextval(\'qgis_test."someData_pk_seq"\'::regclass)')
self.assertFalse(self.provider.defaultValueClause(1))
self.assertEqual(self.provider.defaultValueClause(2), '\'qgis\'::text')
self.source.setProviderProperty(QgsDataProvider.EvaluateDefaultValues, False)
self.assertEqual(self.source.defaultValueClause(0), 'nextval(\'qgis_test."someData_pk_seq"\'::regclass)')
self.assertFalse(self.source.defaultValueClause(1))
self.assertEqual(self.source.defaultValueClause(2), '\'qgis\'::text')

def testDateTimeTypes(self):
vl = QgsVectorLayer('%s table="qgis_test"."date_times" sql=' % (self.dbconn), "testdatetimes", "postgres")
@@ -727,7 +730,7 @@ def setUpClass(cls):
# Create test layers
cls.vl = QgsVectorLayer(cls.dbconn + ' sslmode=disable key=\'"key1","key2"\' srid=4326 type=POINT table="qgis_test"."someDataCompound" (geom) sql=', 'test', 'postgres')
assert cls.vl.isValid()
cls.provider = cls.vl.dataProvider()
cls.source = cls.vl.dataProvider()

@classmethod
def tearDownClass(cls):
@@ -63,7 +63,7 @@ def setUpClass(cls):
cls.basetestpolyfile = os.path.join(cls.basetestpath, 'shapefile_poly.shp')
cls.vl = QgsVectorLayer('{}|layerid=0'.format(cls.basetestfile), 'test', 'ogr')
assert(cls.vl.isValid())
cls.provider = cls.vl.dataProvider()
cls.source = cls.vl.dataProvider()
cls.vl_poly = QgsVectorLayer('{}|layerid=0'.format(cls.basetestpolyfile), 'test', 'ogr')
assert (cls.vl_poly.isValid())
cls.poly_provider = cls.vl_poly.dataProvider()
@@ -76,7 +76,7 @@ def tearDownClass(cls):
for dirname in cls.dirs_to_cleanup:
shutil.rmtree(dirname, True)

def getEditableLayer(self):
def getSource(self):
tmpdir = tempfile.mkdtemp()
self.dirs_to_cleanup.append(tmpdir)
srcpath = os.path.join(TEST_DATA_DIR, 'provider')
@@ -87,6 +87,9 @@ def getEditableLayer(self):
vl = QgsVectorLayer('{}|layerid=0'.format(datasource), 'test', 'ogr')
return vl

def getEditableLayer(self):
return self.getSource()

def enableCompiler(self):
QgsSettings().setValue('/qgis/compileExpressions', True)

@@ -64,7 +64,7 @@ def setUpClass(cls):
# setup provider for base tests
cls.vl = QgsVectorLayer('dbname=\'{}/provider/spatialite.db\' table="somedata" (geom) sql='.format(TEST_DATA_DIR), 'test', 'spatialite')
assert(cls.vl.isValid())
cls.provider = cls.vl.dataProvider()
cls.source = cls.vl.dataProvider()

cls.vl_poly = QgsVectorLayer('dbname=\'{}/provider/spatialite.db\' table="somepolydata" (geom) sql='.format(TEST_DATA_DIR), 'test', 'spatialite')
assert(cls.vl_poly.isValid())
@@ -165,7 +165,7 @@ def tearDownClass(cls):
for dirname in cls.dirs_to_cleanup:
shutil.rmtree(dirname, True)

def getEditableLayer(self):
def getSource(self):
tmpdir = tempfile.mkdtemp()
self.dirs_to_cleanup.append(tmpdir)
srcpath = os.path.join(TEST_DATA_DIR, 'provider')
@@ -177,6 +177,9 @@ def getEditableLayer(self):
'spatialite')
return vl

def getEditableLayer(self):
return self.getSource()

def setUp(self):
"""Run before each test."""
pass
@@ -58,7 +58,7 @@ def setUpClass(cls):
d.setUid("pk")
cls.vl = QgsVectorLayer(d.toString(), 'test', 'virtual')
assert (cls.vl.isValid())
cls.provider = cls.vl.dataProvider()
cls.source = cls.vl.dataProvider()

shp_poly = os.path.join(TEST_DATA_DIR, 'provider/shapefile_poly.shp')
d = QgsVirtualLayerDefinition()
@@ -130,7 +130,7 @@ def setUpClass(cls):
# Create test layer
cls.vl = QgsVectorLayer("url='http://" + endpoint + "' typename='my:typename'", 'test', 'WFS')
assert (cls.vl.isValid())
cls.provider = cls.vl.dataProvider()
cls.source = cls.vl.dataProvider()

with open(sanitize(endpoint, '?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=my:typename&SRSNAME=urn:ogc:def:crs:EPSG::4326'), 'wb') as f:
f.write("""
@@ -149,7 +149,7 @@ def setUpClass(cls):

cls.vl = QgsVectorLayer(url.toString(), 'test', 'delimitedtext')
assert cls.vl.isValid(), "{} is invalid".format(cls.basetestfile)
cls.provider = cls.vl.dataProvider()
cls.source = cls.vl.dataProvider()

@classmethod
def tearDownClass(cls):
@@ -175,7 +175,7 @@ def setUpClass(cls):

cls.vl = QgsVectorLayer(url.toString(), 'test', 'delimitedtext')
assert cls.vl.isValid(), "{} is invalid".format(cls.basetestfile)
cls.provider = cls.vl.dataProvider()
cls.source = cls.vl.dataProvider()

cls.basetestpolyfile = os.path.join(srcpath, 'delimited_wkt_poly.csv')

@@ -51,8 +51,10 @@
QgsVectorLayerSimpleLabeling,
QgsSingleCategoryDiagramRenderer,
QgsDiagramLayerSettings,
QgsTextFormat)
QgsTextFormat,
NULL)
from qgis.testing import start_app, unittest
from featuresourcetestbase import FeatureSourceTestCase
from utilities import unitTestDataPath
start_app()

@@ -172,7 +174,54 @@ def dumpEditBuffer(layer):
print(("%d | %s" % (f.id(), f.geometry().exportToWkt())))


class TestQgsVectorLayer(unittest.TestCase):
class TestQgsVectorLayer(unittest.TestCase, FeatureSourceTestCase):

@classmethod
def getSource(cls):
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

@classmethod
def setUpClass(cls):
"""Run before all tests"""
# Create test layer for FeatureSourceTestCase
cls.source = cls.getSource()

def testGetFeaturesSubsetAttributes2(self):
""" Override and skip this QgsFeatureSource test. We are using a memory provider, and it's actually more efficient for the memory provider to return
its features as direct copies (due to implicit sharing of QgsFeature)
"""
pass

def testGetFeaturesNoGeometry(self):
""" Override and skip this QgsFeatureSource test. We are using a memory provider, and it's actually more efficient for the memory provider to return
its features as direct copies (due to implicit sharing of QgsFeature)
"""
pass

def test_FeatureCount(self):
myPath = os.path.join(unitTestDataPath(), 'lines.shp')

0 comments on commit aa376c2

Please sign in to comment.