Skip to content

Commit e0bcc7e

Browse files
committedAug 13, 2020
Add tests for virtual layers subset strings
Fixes #26189
1 parent fb02ab9 commit e0bcc7e

File tree

1 file changed

+102
-5
lines changed

1 file changed

+102
-5
lines changed
 

‎tests/src/python/test_provider_virtual.py

Lines changed: 102 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,16 @@
2323
QgsVirtualLayerDefinitionUtils,
2424
QgsWkbTypes,
2525
QgsProject,
26-
QgsVectorLayerJoinInfo
26+
QgsVectorLayerJoinInfo,
27+
QgsVectorFileWriter,
28+
QgsVirtualLayerDefinitionUtils
2729
)
2830

2931
from qgis.testing import start_app, unittest
3032
from utilities import unitTestDataPath
3133

3234
from providertestbase import ProviderTestCase
33-
from qgis.PyQt.QtCore import QUrl, QVariant
35+
from qgis.PyQt.QtCore import QUrl, QVariant, QTemporaryDir
3436

3537
from qgis.utils import spatialite_connect
3638

@@ -833,15 +835,13 @@ def test_relative_paths(self):
833835
QgsProject.instance().setFileName(temp)
834836
QgsProject.instance().write()
835837

836-
QgsProject.instance().removeAllMapLayers()
837838
QgsProject.instance().clear()
838839
self.assertEqual(len(QgsProject.instance().mapLayers()), 0)
839840

840841
# Check that virtual layer source is stored with relative path
841842
percent_path_relative = toPercent("./france_parts.shp")
842843
with open(temp, 'r') as f:
843844
content = ''.join(f.readlines())
844-
print(content)
845845
self.assertTrue('<datasource>?layer=ogr:{}'.format(percent_path_relative) in content)
846846

847847
# Check that project is correctly re-read with all layers
@@ -854,7 +854,6 @@ def test_relative_paths(self):
854854
QgsProject.instance().writeEntryBool('Paths', '/Absolute', True)
855855
QgsProject.instance().write()
856856

857-
QgsProject.instance().removeAllMapLayers()
858857
QgsProject.instance().clear()
859858
self.assertEqual(len(QgsProject.instance().mapLayers()), 0)
860859

@@ -1164,6 +1163,104 @@ def test_filter_rect_precise(self):
11641163

11651164
QgsProject.instance().removeMapLayer(pl)
11661165

1166+
def test_subset_string(self):
1167+
"""Test that subset strings are stored and restored correctly from the project
1168+
See: GH #26189
1169+
"""
1170+
1171+
project = QgsProject.instance()
1172+
project.clear()
1173+
data_layer = QgsVectorLayer('Point?crs=epsg:4326&field=fid:integer&field=value:integer&field=join_pk:integer', 'data', 'memory')
1174+
join_layer = QgsVectorLayer('NoGeometry?field=fid:integer&field=value:string', 'join', 'memory')
1175+
tempdir = QTemporaryDir()
1176+
gpkg_path = os.path.join(tempdir.path(), 'test_subset.gpkg')
1177+
project_path = os.path.join(tempdir.path(), 'test_subset.qgs')
1178+
self.assertTrue(data_layer.isValid())
1179+
self.assertTrue(join_layer.isValid())
1180+
self.assertFalse(join_layer.isSpatial())
1181+
1182+
f = QgsFeature(data_layer.fields())
1183+
f.setAttributes([1, 20, 2])
1184+
f.setGeometry(QgsGeometry.fromWkt('point(9 45'))
1185+
self.assertTrue(data_layer.dataProvider().addFeature(f))
1186+
1187+
f = QgsFeature(data_layer.fields())
1188+
f.setAttributes([2, 10, 1])
1189+
f.setGeometry(QgsGeometry.fromWkt('point(9 45'))
1190+
self.assertTrue(data_layer.dataProvider().addFeature(f))
1191+
1192+
options = QgsVectorFileWriter.SaveVectorOptions()
1193+
options.driverName = 'GPKG'
1194+
options.actionOnExistingFile = QgsVectorFileWriter.CreateOrOverwriteFile
1195+
options.layerName = 'data'
1196+
1197+
_, _ = QgsVectorFileWriter.writeAsVectorFormatV2(
1198+
data_layer,
1199+
gpkg_path,
1200+
data_layer.transformContext(),
1201+
options
1202+
)
1203+
1204+
f = QgsFeature(join_layer.fields())
1205+
f.setAttributes([1, "ten"])
1206+
self.assertTrue(join_layer.dataProvider().addFeature(f))
1207+
f.setAttributes([2, "twenty"])
1208+
self.assertTrue(join_layer.dataProvider().addFeature(f))
1209+
1210+
options.layerName = 'join'
1211+
options.actionOnExistingFile = QgsVectorFileWriter.CreateOrOverwriteLayer
1212+
1213+
_, _ = QgsVectorFileWriter.writeAsVectorFormatV2(
1214+
join_layer,
1215+
gpkg_path,
1216+
join_layer.transformContext(),
1217+
options
1218+
)
1219+
1220+
gpkg_join_layer = QgsVectorLayer(gpkg_path + '|layername=join', 'join', 'ogr')
1221+
gpkg_data_layer = QgsVectorLayer(gpkg_path + '|layername=data', 'data', 'ogr')
1222+
1223+
self.assertTrue(gpkg_join_layer.isValid())
1224+
self.assertTrue(gpkg_data_layer.isValid())
1225+
self.assertEqual(gpkg_data_layer.featureCount(), 2)
1226+
self.assertEqual(gpkg_join_layer.featureCount(), 2)
1227+
1228+
self.assertTrue(project.addMapLayers([gpkg_data_layer, gpkg_join_layer]))
1229+
1230+
joinInfo = QgsVectorLayerJoinInfo()
1231+
joinInfo.setTargetFieldName("join_pk")
1232+
joinInfo.setJoinLayer(gpkg_join_layer)
1233+
joinInfo.setJoinFieldName("fid")
1234+
gpkg_data_layer.addJoin(joinInfo)
1235+
self.assertEqual(len(gpkg_data_layer.fields()), 4)
1236+
1237+
self.assertTrue(project.write(project_path))
1238+
1239+
# Reload project
1240+
self.assertTrue(project.read(project_path))
1241+
gpkg_data_layer = project.mapLayersByName('data')[0]
1242+
gpkg_join_layer = project.mapLayersByName('join')[0]
1243+
1244+
self.assertEqual(gpkg_data_layer.vectorJoins()[0], joinInfo)
1245+
1246+
# Now set a subset filter -> virtual layer
1247+
virtual_def = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(gpkg_data_layer)
1248+
virtual = QgsVectorLayer(virtual_def.toString(), "virtual_data", "virtual")
1249+
self.assertTrue(virtual.isValid())
1250+
project.addMapLayers([virtual])
1251+
1252+
self.assertEqual(virtual.featureCount(), 2)
1253+
self.assertTrue(virtual.setSubsetString('"join_value" = \'twenty\''))
1254+
self.assertEqual(virtual.featureCount(), 1)
1255+
self.assertEqual([f.attributes() for f in virtual.getFeatures()], [[1, 20, 2, 'twenty']])
1256+
1257+
# Store and reload the project
1258+
self.assertTrue(project.write(project_path))
1259+
self.assertTrue(project.read(project_path))
1260+
gpkg_virtual_layer = project.mapLayersByName('virtual_data')[0]
1261+
self.assertEqual(gpkg_virtual_layer.featureCount(), 1)
1262+
self.assertEqual(gpkg_virtual_layer.subsetString(), '"join_value" = \'twenty\'')
1263+
11671264

11681265
if __name__ == '__main__':
11691266
unittest.main()

0 commit comments

Comments
 (0)
Please sign in to comment.