Add test to provider test suite that provider source does not rely

on source layer or provider in any way

Fails for OGR provider! :o
This commit is contained in:
Nyall Dawson 2017-04-23 12:12:35 +10:00
parent 82c66f8aa3
commit 6beaa51837
5 changed files with 45 additions and 4 deletions

View File

@ -343,7 +343,7 @@ class QgsAbstractFeatureSource
* @param request The request
* @return A feature iterator
*/
virtual QgsFeatureIterator getFeatures( const QgsFeatureRequest& request ) = 0;
virtual QgsFeatureIterator getFeatures( const QgsFeatureRequest& request = QgsFeatureRequest() ) = 0;
protected:
void iteratorOpened( QgsAbstractFeatureIterator* it );

View File

@ -2,6 +2,23 @@
// abstract feature iterator implementations are not part of public API
class QgsVectorLayerFeatureSource : QgsAbstractFeatureSource
{
%TypeHeaderCode
#include <qgsvectorlayerfeatureiterator.h>
%End
public:
/** Constructor for QgsVectorLayerFeatureSource.
* \param layer source layer
*/
explicit QgsVectorLayerFeatureSource( const QgsVectorLayer *layer );
~QgsVectorLayerFeatureSource();
virtual QgsFeatureIterator getFeatures( const QgsFeatureRequest &request = QgsFeatureRequest() );
};
class QgsVectorLayerFeatureIterator : QgsAbstractFeatureIterator
{
%TypeHeaderCode

View File

@ -437,7 +437,7 @@ class CORE_EXPORT QgsAbstractFeatureSource
* \param request The request
* \returns A feature iterator
*/
virtual QgsFeatureIterator getFeatures( const QgsFeatureRequest &request ) = 0;
virtual QgsFeatureIterator getFeatures( const QgsFeatureRequest &request = QgsFeatureRequest() ) = 0;
protected:
void iteratorOpened( QgsAbstractFeatureIterator *it );

View File

@ -36,7 +36,6 @@ class QgsVectorLayerFeatureIterator;
/** \ingroup core
* Partial snapshot of vector layer's state (only the members necessary for access to features)
* \note not available in Python bindings
*/
class CORE_EXPORT QgsVectorLayerFeatureSource : public QgsAbstractFeatureSource
{
@ -49,7 +48,7 @@ class CORE_EXPORT QgsVectorLayerFeatureSource : public QgsAbstractFeatureSource
~QgsVectorLayerFeatureSource();
virtual QgsFeatureIterator getFeatures( const QgsFeatureRequest &request ) override;
virtual QgsFeatureIterator getFeatures( const QgsFeatureRequest &request = QgsFeatureRequest() ) override;
friend class QgsVectorLayerFeatureIterator;

View File

@ -24,6 +24,7 @@ from qgis.core import (
QgsExpressionContextScope,
QgsExpressionContext,
QgsVectorDataProvider,
QgsVectorLayerFeatureSource,
NULL
)
@ -477,6 +478,30 @@ class ProviderTestCase(object):
values = [f['pk'] for f in self.vl.getFeatures(request)]
self.assertEqual(values, [5, 4, 3, 2, 1])
def testOpenIteratorAfterLayerRemoval(self):
"""
Test that removing layer after opening an iterator does not crash. All required
information should be captured in the iterator's source and there MUST be no
links between the iterators and the layer's data provider
"""
if not getattr(self, 'getEditableLayer', None):
return
l = self.getEditableLayer()
self.assertTrue(l.isValid())
# store the source
source = QgsVectorLayerFeatureSource(l)
# delete the layer
del l
# get the features
pks = []
for f in source.getFeatures():
pks.append(f['pk'])
self.assertEqual(set(pks), {1, 2, 3, 4, 5})
def testGetFeaturesFidTests(self):
fids = [f.id() for f in self.provider.getFeatures()]
assert len(fids) == 5, 'Expected 5 features, got {} instead'.format(len(fids))