99
1010from builtins import str
1111from builtins import object
12+
1213__author__ = 'Matthias Kuhn'
1314__date__ = '2015-04-27'
1415__copyright__ = 'Copyright 2015, The QGIS Project'
3536
3637
3738class ProviderTestCase(FeatureSourceTestCase):
38-
3939 '''
4040 This is a collection of tests for vector data providers and kept generic.
4141 To make use of it, subclass it and set self.source to a provider you want to test.
@@ -101,15 +101,33 @@ def runPolyGetFeatureTests(self, provider):
101101 self.assert_query(provider, 'ymax($geometry) > 80', [1, 2])
102102 self.assert_query(provider, 'area($geometry) > 10', [1])
103103 self.assert_query(provider, 'perimeter($geometry) < 12', [2, 3])
104- self.assert_query(provider, 'relate($geometry,geom_from_wkt( \'Polygon ((-68.2 82.1, -66.95 82.1, -66.95 79.05, -68.2 79.05, -68.2 82.1))\')) = \'FF2FF1212\'', [1, 3])
105- self.assert_query(provider, 'relate($geometry,geom_from_wkt( \'Polygon ((-68.2 82.1, -66.95 82.1, -66.95 79.05, -68.2 79.05, -68.2 82.1))\'), \'****F****\')', [1, 3])
106- self.assert_query(provider, 'crosses($geometry,geom_from_wkt( \'Linestring (-68.2 82.1, -66.95 82.1, -66.95 79.05)\'))', [2])
107- self.assert_query(provider, 'overlaps($geometry,geom_from_wkt( \'Polygon ((-68.2 82.1, -66.95 82.1, -66.95 79.05, -68.2 79.05, -68.2 82.1))\'))', [2])
108- self.assert_query(provider, 'within($geometry,geom_from_wkt( \'Polygon ((-75.1 76.1, -75.1 81.6, -68.8 81.6, -68.8 76.1, -75.1 76.1))\'))', [1])
109- self.assert_query(provider, 'overlaps(translate($geometry,-1,-1),geom_from_wkt( \'Polygon ((-75.1 76.1, -75.1 81.6, -68.8 81.6, -68.8 76.1, -75.1 76.1))\'))', [1])
110- self.assert_query(provider, 'overlaps(buffer($geometry,1),geom_from_wkt( \'Polygon ((-75.1 76.1, -75.1 81.6, -68.8 81.6, -68.8 76.1, -75.1 76.1))\'))', [1, 3])
111- self.assert_query(provider, 'intersects(centroid($geometry),geom_from_wkt( \'Polygon ((-74.4 78.2, -74.4 79.1, -66.8 79.1, -66.8 78.2, -74.4 78.2))\'))', [2])
112- self.assert_query(provider, 'intersects(point_on_surface($geometry),geom_from_wkt( \'Polygon ((-74.4 78.2, -74.4 79.1, -66.8 79.1, -66.8 78.2, -74.4 78.2))\'))', [1, 2])
104+ self.assert_query(provider,
105+ 'relate($geometry,geom_from_wkt( \'Polygon ((-68.2 82.1, -66.95 82.1, -66.95 79.05, -68.2 79.05, -68.2 82.1))\')) = \'FF2FF1212\'',
106+ [1, 3])
107+ self.assert_query(provider,
108+ 'relate($geometry,geom_from_wkt( \'Polygon ((-68.2 82.1, -66.95 82.1, -66.95 79.05, -68.2 79.05, -68.2 82.1))\'), \'****F****\')',
109+ [1, 3])
110+ self.assert_query(provider,
111+ 'crosses($geometry,geom_from_wkt( \'Linestring (-68.2 82.1, -66.95 82.1, -66.95 79.05)\'))',
112+ [2])
113+ self.assert_query(provider,
114+ 'overlaps($geometry,geom_from_wkt( \'Polygon ((-68.2 82.1, -66.95 82.1, -66.95 79.05, -68.2 79.05, -68.2 82.1))\'))',
115+ [2])
116+ self.assert_query(provider,
117+ 'within($geometry,geom_from_wkt( \'Polygon ((-75.1 76.1, -75.1 81.6, -68.8 81.6, -68.8 76.1, -75.1 76.1))\'))',
118+ [1])
119+ self.assert_query(provider,
120+ 'overlaps(translate($geometry,-1,-1),geom_from_wkt( \'Polygon ((-75.1 76.1, -75.1 81.6, -68.8 81.6, -68.8 76.1, -75.1 76.1))\'))',
121+ [1])
122+ self.assert_query(provider,
123+ 'overlaps(buffer($geometry,1),geom_from_wkt( \'Polygon ((-75.1 76.1, -75.1 81.6, -68.8 81.6, -68.8 76.1, -75.1 76.1))\'))',
124+ [1, 3])
125+ self.assert_query(provider,
126+ 'intersects(centroid($geometry),geom_from_wkt( \'Polygon ((-74.4 78.2, -74.4 79.1, -66.8 79.1, -66.8 78.2, -74.4 78.2))\'))',
127+ [2])
128+ self.assert_query(provider,
129+ 'intersects(point_on_surface($geometry),geom_from_wkt( \'Polygon ((-74.4 78.2, -74.4 79.1, -66.8 79.1, -66.8 78.2, -74.4 78.2))\'))',
130+ [1, 2])
113131 self.assert_query(provider, 'distance($geometry,geom_from_wkt( \'Point (-70 70)\')) > 7', [1, 2])
114132
115133 def testGetFeaturesUncompiled(self):
@@ -145,7 +163,8 @@ def testSubsetString(self):
145163 self.source.setSubsetString(None)
146164
147165 expected = set([2, 3, 4])
148- assert set(expected) == result, 'Expected {} and got {} when testing subset string {}'.format(set(expected), result, subset)
166+ assert set(expected) == result, 'Expected {} and got {} when testing subset string {}'.format(set(expected),
167+ result, subset)
149168 self.assertTrue(all_valid)
150169
151170 # Subset string AND filter rect
@@ -156,7 +175,8 @@ def testSubsetString(self):
156175 all_valid = (all(f.isValid() for f in self.source.getFeatures(request)))
157176 self.source.setSubsetString(None)
158177 expected = set([2])
159- assert set(expected) == result, 'Expected {} and got {} when testing subset string {}'.format(set(expected), result, subset)
178+ assert set(expected) == result, 'Expected {} and got {} when testing subset string {}'.format(set(expected),
179+ result, subset)
160180 self.assertTrue(all_valid)
161181
162182 # Subset string AND filter rect, version 2
@@ -165,7 +185,8 @@ def testSubsetString(self):
165185 result = set([f['pk'] for f in self.source.getFeatures(QgsFeatureRequest().setFilterRect(extent))])
166186 self.source.setSubsetString(None)
167187 expected = set([2, 4])
168- assert set(expected) == result, 'Expected {} and got {} when testing subset string {}'.format(set(expected), result, subset)
188+ assert set(expected) == result, 'Expected {} and got {} when testing subset string {}'.format(set(expected),
189+ result, subset)
169190
170191 # Subset string AND expression
171192 self.source.setSubsetString(subset)
@@ -174,7 +195,8 @@ def testSubsetString(self):
174195 all_valid = (all(f.isValid() for f in self.source.getFeatures(request)))
175196 self.source.setSubsetString(None)
176197 expected = set([2, 4])
177- assert set(expected) == result, 'Expected {} and got {} when testing subset string {}'.format(set(expected), result, subset)
198+ assert set(expected) == result, 'Expected {} and got {} when testing subset string {}'.format(set(expected),
199+ result, subset)
178200 self.assertTrue(all_valid)
179201
180202 def getSubsetString(self):
@@ -330,8 +352,11 @@ def testExtent(self):
330352 self.assertTrue(provider_extent.isNull())
331353
332354 def testUnique(self):
333- self.assertEqual(set(self.source.uniqueValues(self.source.fields().lookupField('cnt'))), set([-200, 100, 200, 300, 400]))
334- assert set(['Apple', 'Honey', 'Orange', 'Pear', NULL]) == set(self.source.uniqueValues(self.source.fields().lookupField('name'))), 'Got {}'.format(set(self.source.uniqueValues(self.source.fields().lookupField('name'))))
355+ self.assertEqual(set(self.source.uniqueValues(self.source.fields().lookupField('cnt'))),
356+ set([-200, 100, 200, 300, 400]))
357+ assert set(['Apple', 'Honey', 'Orange', 'Pear', NULL]) == set(
358+ self.source.uniqueValues(self.source.fields().lookupField('name'))), 'Got {}'.format(
359+ set(self.source.uniqueValues(self.source.fields().lookupField('name'))))
335360
336361 if self.source.supportsSubsetString():
337362 subset = self.getSubsetString2()
@@ -352,7 +377,8 @@ def testUniqueStringsMatching(self):
352377 self.assertEqual(len(result), 2)
353378 self.assertTrue(result.issubset(set(['Pear', 'Orange', 'Apple'])))
354379
355- assert set([u'Apple', u'Honey', u'Orange', u'Pear', NULL]) == set(self.source.uniqueValues(field_index)), 'Got {}'.format(set(self.source.uniqueValues(field_index)))
380+ assert set([u'Apple', u'Honey', u'Orange', u'Pear', NULL]) == set(
381+ self.source.uniqueValues(field_index)), 'Got {}'.format(set(self.source.uniqueValues(field_index)))
356382
357383 if self.source.supportsSubsetString():
358384 subset = self.getSubsetString2()
@@ -365,7 +391,7 @@ def testFeatureCount(self):
365391 self.assertEqual(self.source.featureCount(), 5)
366392
367393 if self.source.supportsSubsetString():
368- #Add a subset string and test feature count
394+ # Add a subset string and test feature count
369395 subset = self.getSubsetString()
370396 self.source.setSubsetString(subset)
371397 count = self.source.featureCount()
@@ -425,7 +451,8 @@ def testAddFeature(self):
425451
426452 else:
427453 # expect fail
428- self.assertFalse(l.dataProvider().addFeatures([f1, f2]), 'Provider reported no AddFeatures capability, but returned true to addFeatures')
454+ self.assertFalse(l.dataProvider().addFeatures([f1, f2]),
455+ 'Provider reported no AddFeatures capability, but returned true to addFeatures')
429456
430457 def testAddFeatureFastInsert(self):
431458 if not getattr(self, 'getEditableLayer', None):
@@ -465,7 +492,8 @@ def testAddFeatureMissingAttributes(self):
465492 f2.setAttributes([7, 330])
466493
467494 result, added = l.dataProvider().addFeatures([f1, f2])
468- self.assertTrue(result, 'Provider returned False to addFeatures with missing attributes. Providers should accept these features but add NULL attributes to the end of the existing attributes to the required field length.')
495+ self.assertTrue(result,
496+ 'Provider returned False to addFeatures with missing attributes. Providers should accept these features but add NULL attributes to the end of the existing attributes to the required field length.')
469497 f1.setId(added[0].id())
470498 f2.setId(added[1].id())
471499
@@ -519,7 +547,8 @@ def testAddFeatureWrongGeomType(self):
519547 f2.setAttributes([8])
520548
521549 result, added = l.dataProvider().addFeatures([f1, f2])
522- self.assertFalse(result, 'Provider returned True to addFeatures with incorrect geometry type. Providers should reject these features.')
550+ self.assertFalse(result,
551+ 'Provider returned True to addFeatures with incorrect geometry type. Providers should reject these features.')
523552
524553 # make sure feature was not added
525554 added = [f for f in l.dataProvider().getFeatures() if f['pk'] == 7]
@@ -561,7 +590,7 @@ def testDeleteFeatures(self):
561590 l = self.getEditableLayer()
562591 self.assertTrue(l.isValid())
563592
564- #find 2 features to delete
593+ # find 2 features to delete
565594 features = [f for f in l.dataProvider().getFeatures()]
566595 to_delete = [f.id() for f in features if f.attributes()[0] in [1, 3]]
567596
@@ -610,7 +639,8 @@ def testTruncate(self):
610639 if l.dataProvider().capabilities() & QgsVectorDataProvider.FastTruncate or l.dataProvider().capabilities() & QgsVectorDataProvider.DeleteFeatures:
611640 # expect success
612641 result = l.dataProvider().truncate()
613- self.assertTrue(result, 'Provider reported FastTruncate or DeleteFeatures capability, but returned False to truncate()')
642+ self.assertTrue(result,
643+ 'Provider reported FastTruncate or DeleteFeatures capability, but returned False to truncate()')
614644
615645 # check result
616646 features = [f['pk'] for f in l.dataProvider().getFeatures()]
@@ -627,7 +657,7 @@ def testChangeAttributes(self):
627657 l = self.getEditableLayer()
628658 self.assertTrue(l.isValid())
629659
630- #find 2 features to change
660+ # find 2 features to change
631661 features = [f for f in l.dataProvider().getFeatures()]
632662 # need to keep order here
633663 to_change = [f for f in features if f.attributes()[0] == 1]
@@ -640,7 +670,8 @@ def testChangeAttributes(self):
640670 if l.dataProvider().capabilities() & QgsVectorDataProvider.ChangeAttributeValues:
641671 # expect success
642672 result = l.dataProvider().changeAttributeValues(changes)
643- self.assertTrue(result, 'Provider reported ChangeAttributeValues capability, but returned False to changeAttributeValues')
673+ self.assertTrue(result,
674+ 'Provider reported ChangeAttributeValues capability, but returned False to changeAttributeValues')
644675
645676 # check result
646677 self.testGetFeatures(l.dataProvider(), changed_attributes=new_attr_map)
@@ -733,3 +764,56 @@ def testChangeFeatures(self):
733764 # expect fail
734765 self.assertFalse(l.dataProvider().changeFeatures(attribute_changes, geometry_changes),
735766 'Provider reported no ChangeAttributeValues capability, but returned true to changeFeatures')
767+
768+ def testMinMaxAfterChanges(self):
769+ """
770+ Tests retrieving field min and max value after making changes to the provider's features
771+ """
772+ if not getattr(self, 'getEditableLayer', None):
773+ return
774+
775+ vl = self.getEditableLayer()
776+ self.assertTrue(vl.isValid())
777+
778+ self.assertEqual(vl.dataProvider().minimumValue(0), 1)
779+ self.assertEqual(vl.dataProvider().minimumValue(1), -200)
780+ self.assertEqual(vl.dataProvider().maximumValue(0), 5)
781+ self.assertEqual(vl.dataProvider().maximumValue(1), 400)
782+
783+ # add feature
784+ f6 = QgsFeature()
785+ f6.setAttributes([15, 1400])
786+ res, [f6] = vl.dataProvider().addFeatures([f6])
787+ self.assertTrue(res)
788+ self.assertEqual(vl.dataProvider().minimumValue(0), 1)
789+ self.assertEqual(vl.dataProvider().minimumValue(1), -200)
790+ self.assertEqual(vl.dataProvider().maximumValue(0), 15)
791+ self.assertEqual(vl.dataProvider().maximumValue(1), 1400)
792+ f7 = QgsFeature()
793+ f7.setAttributes([0, -1400])
794+ res, [f7] = vl.dataProvider().addFeatures([f7])
795+ self.assertTrue(res)
796+ self.assertEqual(vl.dataProvider().minimumValue(0), 0)
797+ self.assertEqual(vl.dataProvider().minimumValue(1), -1400)
798+ self.assertEqual(vl.dataProvider().maximumValue(0), 15)
799+ self.assertEqual(vl.dataProvider().maximumValue(1), 1400)
800+
801+ # change attribute values
802+ self.assertTrue(vl.dataProvider().changeAttributeValues({f6.id(): {1: 150}, f7.id(): {1: -100}}))
803+ self.assertEqual(vl.dataProvider().minimumValue(1), -200)
804+ self.assertEqual(vl.dataProvider().maximumValue(1), 400)
805+
806+ # delete features
807+ f1 = [f for f in vl.getFeatures() if f['pk'] == 5][0]
808+ f3 = [f for f in vl.getFeatures() if f['pk'] == 3][0]
809+ self.assertTrue(vl.dataProvider().deleteFeatures([f6.id(), f7.id()]))
810+ self.assertEqual(vl.dataProvider().minimumValue(0), 1)
811+ self.assertEqual(vl.dataProvider().minimumValue(1), -200)
812+ self.assertEqual(vl.dataProvider().maximumValue(0), 5)
813+ self.assertEqual(vl.dataProvider().maximumValue(1), 400)
814+
815+ if vl.dataProvider().capabilities() & QgsVectorDataProvider.DeleteAttributes:
816+ # delete attributes
817+ self.assertTrue(vl.dataProvider().deleteAttributes([0]))
818+ self.assertEqual(vl.dataProvider().minimumValue(0), -200)
819+ self.assertEqual(vl.dataProvider().maximumValue(0), 400)
0 commit comments