Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Add tests for virtual layers subset strings
Fixes #26189
  • Loading branch information
elpaso committed Aug 13, 2020
1 parent fb02ab9 commit e0bcc7e
Showing 1 changed file with 102 additions and 5 deletions.
107 changes: 102 additions & 5 deletions tests/src/python/test_provider_virtual.py
Expand Up @@ -23,14 +23,16 @@
QgsVirtualLayerDefinitionUtils,
QgsWkbTypes,
QgsProject,
QgsVectorLayerJoinInfo
QgsVectorLayerJoinInfo,
QgsVectorFileWriter,
QgsVirtualLayerDefinitionUtils
)

from qgis.testing import start_app, unittest
from utilities import unitTestDataPath

from providertestbase import ProviderTestCase
from qgis.PyQt.QtCore import QUrl, QVariant
from qgis.PyQt.QtCore import QUrl, QVariant, QTemporaryDir

from qgis.utils import spatialite_connect

Expand Down Expand Up @@ -833,15 +835,13 @@ def test_relative_paths(self):
QgsProject.instance().setFileName(temp)
QgsProject.instance().write()

QgsProject.instance().removeAllMapLayers()
QgsProject.instance().clear()
self.assertEqual(len(QgsProject.instance().mapLayers()), 0)

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

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

QgsProject.instance().removeAllMapLayers()
QgsProject.instance().clear()
self.assertEqual(len(QgsProject.instance().mapLayers()), 0)

Expand Down Expand Up @@ -1164,6 +1163,104 @@ def test_filter_rect_precise(self):

QgsProject.instance().removeMapLayer(pl)

def test_subset_string(self):
"""Test that subset strings are stored and restored correctly from the project
See: GH #26189
"""

project = QgsProject.instance()
project.clear()
data_layer = QgsVectorLayer('Point?crs=epsg:4326&field=fid:integer&field=value:integer&field=join_pk:integer', 'data', 'memory')
join_layer = QgsVectorLayer('NoGeometry?field=fid:integer&field=value:string', 'join', 'memory')
tempdir = QTemporaryDir()
gpkg_path = os.path.join(tempdir.path(), 'test_subset.gpkg')
project_path = os.path.join(tempdir.path(), 'test_subset.qgs')
self.assertTrue(data_layer.isValid())
self.assertTrue(join_layer.isValid())
self.assertFalse(join_layer.isSpatial())

f = QgsFeature(data_layer.fields())
f.setAttributes([1, 20, 2])
f.setGeometry(QgsGeometry.fromWkt('point(9 45'))
self.assertTrue(data_layer.dataProvider().addFeature(f))

f = QgsFeature(data_layer.fields())
f.setAttributes([2, 10, 1])
f.setGeometry(QgsGeometry.fromWkt('point(9 45'))
self.assertTrue(data_layer.dataProvider().addFeature(f))

options = QgsVectorFileWriter.SaveVectorOptions()
options.driverName = 'GPKG'
options.actionOnExistingFile = QgsVectorFileWriter.CreateOrOverwriteFile
options.layerName = 'data'

_, _ = QgsVectorFileWriter.writeAsVectorFormatV2(
data_layer,
gpkg_path,
data_layer.transformContext(),
options
)

f = QgsFeature(join_layer.fields())
f.setAttributes([1, "ten"])
self.assertTrue(join_layer.dataProvider().addFeature(f))
f.setAttributes([2, "twenty"])
self.assertTrue(join_layer.dataProvider().addFeature(f))

options.layerName = 'join'
options.actionOnExistingFile = QgsVectorFileWriter.CreateOrOverwriteLayer

_, _ = QgsVectorFileWriter.writeAsVectorFormatV2(
join_layer,
gpkg_path,
join_layer.transformContext(),
options
)

gpkg_join_layer = QgsVectorLayer(gpkg_path + '|layername=join', 'join', 'ogr')
gpkg_data_layer = QgsVectorLayer(gpkg_path + '|layername=data', 'data', 'ogr')

self.assertTrue(gpkg_join_layer.isValid())
self.assertTrue(gpkg_data_layer.isValid())
self.assertEqual(gpkg_data_layer.featureCount(), 2)
self.assertEqual(gpkg_join_layer.featureCount(), 2)

self.assertTrue(project.addMapLayers([gpkg_data_layer, gpkg_join_layer]))

joinInfo = QgsVectorLayerJoinInfo()
joinInfo.setTargetFieldName("join_pk")
joinInfo.setJoinLayer(gpkg_join_layer)
joinInfo.setJoinFieldName("fid")
gpkg_data_layer.addJoin(joinInfo)
self.assertEqual(len(gpkg_data_layer.fields()), 4)

self.assertTrue(project.write(project_path))

# Reload project
self.assertTrue(project.read(project_path))
gpkg_data_layer = project.mapLayersByName('data')[0]
gpkg_join_layer = project.mapLayersByName('join')[0]

self.assertEqual(gpkg_data_layer.vectorJoins()[0], joinInfo)

# Now set a subset filter -> virtual layer
virtual_def = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(gpkg_data_layer)
virtual = QgsVectorLayer(virtual_def.toString(), "virtual_data", "virtual")
self.assertTrue(virtual.isValid())
project.addMapLayers([virtual])

self.assertEqual(virtual.featureCount(), 2)
self.assertTrue(virtual.setSubsetString('"join_value" = \'twenty\''))
self.assertEqual(virtual.featureCount(), 1)
self.assertEqual([f.attributes() for f in virtual.getFeatures()], [[1, 20, 2, 'twenty']])

# Store and reload the project
self.assertTrue(project.write(project_path))
self.assertTrue(project.read(project_path))
gpkg_virtual_layer = project.mapLayersByName('virtual_data')[0]
self.assertEqual(gpkg_virtual_layer.featureCount(), 1)
self.assertEqual(gpkg_virtual_layer.subsetString(), '"join_value" = \'twenty\'')


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

0 comments on commit e0bcc7e

Please sign in to comment.