Skip to content

Commit 6beaa51

Browse files
committedApr 23, 2017
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
1 parent 82c66f8 commit 6beaa51

File tree

5 files changed

+45
-4
lines changed

5 files changed

+45
-4
lines changed
 

‎python/core/qgsfeaturerequest.sip

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ class QgsAbstractFeatureSource
343343
* @param request The request
344344
* @return A feature iterator
345345
*/
346-
virtual QgsFeatureIterator getFeatures( const QgsFeatureRequest& request ) = 0;
346+
virtual QgsFeatureIterator getFeatures( const QgsFeatureRequest& request = QgsFeatureRequest() ) = 0;
347347

348348
protected:
349349
void iteratorOpened( QgsAbstractFeatureIterator* it );

‎python/core/qgsvectorlayerfeatureiterator.sip

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,23 @@
22
// abstract feature iterator implementations are not part of public API
33

44

5+
class QgsVectorLayerFeatureSource : QgsAbstractFeatureSource
6+
{
7+
%TypeHeaderCode
8+
#include <qgsvectorlayerfeatureiterator.h>
9+
%End
10+
public:
11+
12+
/** Constructor for QgsVectorLayerFeatureSource.
13+
* \param layer source layer
14+
*/
15+
explicit QgsVectorLayerFeatureSource( const QgsVectorLayer *layer );
16+
17+
~QgsVectorLayerFeatureSource();
18+
19+
virtual QgsFeatureIterator getFeatures( const QgsFeatureRequest &request = QgsFeatureRequest() );
20+
};
21+
522
class QgsVectorLayerFeatureIterator : QgsAbstractFeatureIterator
623
{
724
%TypeHeaderCode

‎src/core/qgsfeaturerequest.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,7 @@ class CORE_EXPORT QgsAbstractFeatureSource
437437
* \param request The request
438438
* \returns A feature iterator
439439
*/
440-
virtual QgsFeatureIterator getFeatures( const QgsFeatureRequest &request ) = 0;
440+
virtual QgsFeatureIterator getFeatures( const QgsFeatureRequest &request = QgsFeatureRequest() ) = 0;
441441

442442
protected:
443443
void iteratorOpened( QgsAbstractFeatureIterator *it );

‎src/core/qgsvectorlayerfeatureiterator.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ class QgsVectorLayerFeatureIterator;
3636

3737
/** \ingroup core
3838
* Partial snapshot of vector layer's state (only the members necessary for access to features)
39-
* \note not available in Python bindings
4039
*/
4140
class CORE_EXPORT QgsVectorLayerFeatureSource : public QgsAbstractFeatureSource
4241
{
@@ -49,7 +48,7 @@ class CORE_EXPORT QgsVectorLayerFeatureSource : public QgsAbstractFeatureSource
4948

5049
~QgsVectorLayerFeatureSource();
5150

52-
virtual QgsFeatureIterator getFeatures( const QgsFeatureRequest &request ) override;
51+
virtual QgsFeatureIterator getFeatures( const QgsFeatureRequest &request = QgsFeatureRequest() ) override;
5352

5453
friend class QgsVectorLayerFeatureIterator;
5554

‎tests/src/python/providertestbase.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
QgsExpressionContextScope,
2525
QgsExpressionContext,
2626
QgsVectorDataProvider,
27+
QgsVectorLayerFeatureSource,
2728
NULL
2829
)
2930

@@ -477,6 +478,30 @@ def runOrderByTests(self):
477478
values = [f['pk'] for f in self.vl.getFeatures(request)]
478479
self.assertEqual(values, [5, 4, 3, 2, 1])
479480

481+
def testOpenIteratorAfterLayerRemoval(self):
482+
"""
483+
Test that removing layer after opening an iterator does not crash. All required
484+
information should be captured in the iterator's source and there MUST be no
485+
links between the iterators and the layer's data provider
486+
"""
487+
if not getattr(self, 'getEditableLayer', None):
488+
return
489+
490+
l = self.getEditableLayer()
491+
self.assertTrue(l.isValid())
492+
493+
# store the source
494+
source = QgsVectorLayerFeatureSource(l)
495+
496+
# delete the layer
497+
del l
498+
499+
# get the features
500+
pks = []
501+
for f in source.getFeatures():
502+
pks.append(f['pk'])
503+
self.assertEqual(set(pks), {1, 2, 3, 4, 5})
504+
480505
def testGetFeaturesFidTests(self):
481506
fids = [f.id() for f in self.provider.getFeatures()]
482507
assert len(fids) == 5, 'Expected 5 features, got {} instead'.format(len(fids))

0 commit comments

Comments
 (0)
Please sign in to comment.