Rename edit buffer methods to is..., add tests

This commit is contained in:
Nyall Dawson 2016-07-15 07:58:21 +10:00
parent dc10c8fac2
commit 0736bf726d
7 changed files with 415 additions and 23 deletions

View File

@ -70,42 +70,70 @@ class QgsVectorLayerEditBuffer : QObject
/** Stop editing and discard the edits */
virtual void rollBack();
/** Returns a map of new features which are not committed. */
/** Returns a map of new features which are not committed.
* @see isFeatureAdded()
*/
QgsFeatureMap addedFeatures() const;
/** Returns true if the specified feature ID has been added but not committed.
* @param id feature ID
* @note added in QGIS 3.0
* @see addedFeatures()
*/
bool featureIsAdded( QgsFeatureId id ) const;
bool isFeatureAdded( QgsFeatureId id ) const;
/** Returns a map of features with changed attributes values which are not committed */
/** Returns a map of features with changed attributes values which are not committed.
* @see isFeatureAttributesChanged()
*/
QgsChangedAttributesMap changedAttributeValues() const;
/** Returns true if the specified feature ID has had an attribute changed but not committed.
* @param id feature ID
* @note added in QGIS 3.0
* @see changedAttributeValues()
*/
bool featureHasAttributeChanges( QgsFeatureId id ) const;
bool isFeatureAttributesChanged( QgsFeatureId id ) const;
/** Returns a list of deleted attributes fields which are not committed. The list is kept sorted. */
/** Returns a list of deleted attributes fields which are not committed. The list is kept sorted.
* @see isAttributeDeleted()
*/
QgsAttributeList deletedAttributeIds() const;
/** Returns true if the specified attribute has been deleted but not committed.
* @param index attribute index
* @note added in QGIS 3.0
* @see deletedAttributeIds()
*/
bool isAttributeDeleted( int index ) const;
/** Returns a list of added attributes fields which are not committed */
QList<QgsField> addedAttributes() const;
/** Returns a map of features with changed geometries which are not committed. */
/** Returns a map of features with changed geometries which are not committed.
* @see hasFeatureGeometryChange()
*/
QgsGeometryMap changedGeometries() const;
/** Returns true if the specified feature ID has had its geometry changed but not committed.
* @param id feature ID
* @note added in QGIS 3.0
* @see changedGeometries()
*/
bool featureHasGeometryChange( QgsFeatureId id ) const;
bool isFeatureGeometryChanged( QgsFeatureId id ) const;
/** Returns a list of deleted feature IDs which are not committed. */
/** Returns a list of deleted feature IDs which are not committed.
* @see isFeatureDeleted()
*/
QgsFeatureIds deletedFeatureIds() const;
/** Returns true if the specified feature ID has been deleted but not committed.
* @param id feature ID
* @note added in QGIS 3.0
* @see deletedFeatureIds()
*/
bool isFeatureDeleted( QgsFeatureId id ) const;
//QString dumpEditBuffer();
protected slots:

View File

@ -99,42 +99,70 @@ class CORE_EXPORT QgsVectorLayerEditBuffer : public QObject
/** Stop editing and discard the edits */
virtual void rollBack();
/** Returns a map of new features which are not committed. */
/** Returns a map of new features which are not committed.
* @see isFeatureAdded()
*/
QgsFeatureMap addedFeatures() const { return mAddedFeatures; }
/** Returns true if the specified feature ID has been added but not committed.
* @param id feature ID
* @note added in QGIS 3.0
* @see addedFeatures()
*/
bool featureIsAdded( QgsFeatureId id ) const { return mAddedFeatures.contains( id ); }
bool isFeatureAdded( QgsFeatureId id ) const { return mAddedFeatures.contains( id ); }
/** Returns a map of features with changed attributes values which are not committed */
/** Returns a map of features with changed attributes values which are not committed.
* @see isFeatureAttributesChanged()
*/
QgsChangedAttributesMap changedAttributeValues() const { return mChangedAttributeValues; }
/** Returns true if the specified feature ID has had an attribute changed but not committed.
* @param id feature ID
* @note added in QGIS 3.0
* @see changedAttributeValues()
*/
bool featureHasAttributeChanges( QgsFeatureId id ) const { return mChangedAttributeValues.contains( id ); }
bool isFeatureAttributesChanged( QgsFeatureId id ) const { return mChangedAttributeValues.contains( id ); }
/** Returns a list of deleted attributes fields which are not committed. The list is kept sorted. */
/** Returns a list of deleted attributes fields which are not committed. The list is kept sorted.
* @see isAttributeDeleted()
*/
QgsAttributeList deletedAttributeIds() const { return mDeletedAttributeIds; }
/** Returns a list of added attributes fields which are not committed */
/** Returns true if the specified attribute has been deleted but not committed.
* @param index attribute index
* @note added in QGIS 3.0
* @see deletedAttributeIds()
*/
bool isAttributeDeleted( int index ) const { return mDeletedAttributeIds.contains( index ); }
/** Returns a list of added attributes fields which are not committed.
*/
QList<QgsField> addedAttributes() const { return mAddedAttributes; }
/** Returns a map of features with changed geometries which are not committed. */
/** Returns a map of features with changed geometries which are not committed.
* @see hasFeatureGeometryChange()
*/
QgsGeometryMap changedGeometries() const { return mChangedGeometries; }
/** Returns true if the specified feature ID has had its geometry changed but not committed.
* @param id feature ID
* @note added in QGIS 3.0
* @see changedGeometries()
*/
bool featureHasGeometryChange( QgsFeatureId id ) const { return mChangedGeometries.contains( id ); }
bool isFeatureGeometryChanged( QgsFeatureId id ) const { return mChangedGeometries.contains( id ); }
/** Returns a list of deleted feature IDs which are not committed. */
/** Returns a list of deleted feature IDs which are not committed.
* @see isFeatureDeleted()
*/
QgsFeatureIds deletedFeatureIds() const { return mDeletedFeatureIds; }
/** Returns true if the specified feature ID has been deleted but not committed.
* @param id feature ID
* @note added in QGIS 3.0
* @see deletedFeatureIds()
*/
bool isFeatureDeleted( QgsFeatureId id ) const { return mDeletedFeatureIds.contains( id ); }
//QString dumpEditBuffer();
protected slots:

View File

@ -326,13 +326,13 @@ bool QgsAttributeTableFilterModel::filterAcceptsRow( int sourceRow, const QModel
{
QgsFeatureId fid = masterModel()->rowToId( sourceRow );
if ( editBuffer->featureIsAdded( fid ) )
if ( editBuffer->isFeatureAdded( fid ) )
return true;
if ( editBuffer->featureHasAttributeChanges( fid ) )
if ( editBuffer->isFeatureAttributesChanged( fid ) )
return true;
if ( editBuffer->featureHasGeometryChange( fid ) )
if ( editBuffer->isFeatureGeometryChanged( fid ) )
return true;
return false;

View File

@ -111,11 +111,11 @@ QVariant QgsFeatureListModel::data( const QModelIndex &index, int role ) const
if ( editBuffer )
{
if ( editBuffer->featureIsAdded( feat.id() ) )
if ( editBuffer->isFeatureAdded( feat.id() ) )
{
featInfo.isNew = true;
}
if ( editBuffer->featureHasAttributeChanges( feat.id() ) )
if ( editBuffer->isFeatureAttributesChanged( feat.id() ) )
{
featInfo.isEdited = true;
}

View File

@ -1219,7 +1219,7 @@ void QgsGrassProvider::onFeatureAdded( QgsFeatureId fid )
}
// geometry
const QgsAbstractGeometryV2 *geometry = 0;
if ( !mEditBuffer->featureIsAdded( fid ) )
if ( !mEditBuffer->isFeatureAdded( fid ) )
{
#ifdef QGISDEBUG
QgsDebugMsg( "the feature is missing in buffer addedFeatures :" );

View File

@ -94,6 +94,7 @@ ADD_PYTHON_TEST(PyQgsUnitTypes test_qgsunittypes.py)
ADD_PYTHON_TEST(PyQgsVectorColorRamp test_qgsvectorcolorramp.py)
ADD_PYTHON_TEST(PyQgsVectorFileWriter test_qgsvectorfilewriter.py)
ADD_PYTHON_TEST(PyQgsVectorLayer test_qgsvectorlayer.py)
ADD_PYTHON_TEST(PyQgsVectorLayerEditBuffer test_qgsvectorlayereditbuffer.py)
ADD_PYTHON_TEST(PyQgsZonalStatistics test_qgszonalstatistics.py)
ADD_PYTHON_TEST(PyQgsMapLayerRegistry test_qgsmaplayerregistry.py)
ADD_PYTHON_TEST(PyQgsVirtualLayerProvider test_provider_virtual.py)

View File

@ -0,0 +1,335 @@
# -*- coding: utf-8 -*-
"""QGIS Unit tests for QgsVectorLayerEditBuffer.
.. note:: This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
"""
__author__ = 'Nyall Dawson'
__date__ = '15/07/2016'
__copyright__ = 'Copyright 2016, The QGIS Project'
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'
import qgis # NOQA
import os
from qgis.PyQt.QtCore import QVariant
from qgis.PyQt.QtGui import QPainter
from qgis.core import (QGis,
QgsVectorLayer,
QgsRectangle,
QgsFeature,
QgsFeatureRequest,
QgsGeometry,
QgsPoint,
QgsField,
QgsFields,
QgsMapLayerRegistry,
QgsVectorJoinInfo,
QgsSymbolV2,
QgsSingleSymbolRendererV2,
QgsCoordinateReferenceSystem,
QgsProject,
QgsUnitTypes,
QgsAggregateCalculator)
from qgis.testing import start_app, unittest
from utilities import unitTestDataPath
start_app()
def createEmptyLayer():
layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer",
"addfeat", "memory")
assert layer.isValid()
return layer
def createLayerWithOnePoint():
layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer",
"addfeat", "memory")
pr = layer.dataProvider()
f = QgsFeature()
f.setAttributes(["test", 123])
f.setGeometry(QgsGeometry.fromPoint(QgsPoint(100, 200)))
assert pr.addFeatures([f])
assert layer.pendingFeatureCount() == 1
return layer
class TestQgsVectorLayerEditBuffer(unittest.TestCase):
def testAddFeatures(self):
# test adding features to an edit buffer
layer = createEmptyLayer()
self.assertTrue(layer.startEditing())
self.assertEqual(layer.editBuffer().addedFeatures(), {})
self.assertFalse(layer.editBuffer().isFeatureAdded(1))
self.assertFalse(layer.editBuffer().isFeatureAdded(3))
# add two features
f1 = QgsFeature(layer.fields(), 1)
f1.setGeometry(QgsGeometry.fromPoint(QgsPoint(1, 2)))
f1.setAttributes(["test", 123])
self.assertTrue(layer.addFeature(f1))
f2 = QgsFeature(layer.fields(), 2)
f2.setGeometry(QgsGeometry.fromPoint(QgsPoint(2, 4)))
f2.setAttributes(["test2", 246])
self.assertTrue(layer.addFeature(f2))
# test contents of buffer
added = layer.editBuffer().addedFeatures()
new_feature_ids = added.keys()
self.assertEqual(added[new_feature_ids[0]]['fldtxt'], 'test2')
self.assertEqual(added[new_feature_ids[0]]['fldint'], 246)
self.assertEqual(added[new_feature_ids[1]]['fldtxt'], 'test')
self.assertEqual(added[new_feature_ids[1]]['fldint'], 123)
self.assertTrue(layer.editBuffer().isFeatureAdded(new_feature_ids[0]))
self.assertTrue(layer.editBuffer().isFeatureAdded(new_feature_ids[1]))
def testAddMultipleFeatures(self):
# test adding multiple features to an edit buffer
layer = createEmptyLayer()
self.assertTrue(layer.startEditing())
self.assertEqual(layer.editBuffer().addedFeatures(), {})
self.assertFalse(layer.editBuffer().isFeatureAdded(1))
self.assertFalse(layer.editBuffer().isFeatureAdded(3))
# add two features
f1 = QgsFeature(layer.fields(), 1)
f1.setGeometry(QgsGeometry.fromPoint(QgsPoint(1, 2)))
f1.setAttributes(["test", 123])
f2 = QgsFeature(layer.fields(), 2)
f2.setGeometry(QgsGeometry.fromPoint(QgsPoint(2, 4)))
f2.setAttributes(["test2", 246])
self.assertTrue(layer.addFeatures([f1, f2]))
# test contents of buffer
added = layer.editBuffer().addedFeatures()
new_feature_ids = added.keys()
self.assertEqual(added[new_feature_ids[0]]['fldtxt'], 'test2')
self.assertEqual(added[new_feature_ids[0]]['fldint'], 246)
self.assertEqual(added[new_feature_ids[1]]['fldtxt'], 'test')
self.assertEqual(added[new_feature_ids[1]]['fldint'], 123)
self.assertTrue(layer.editBuffer().isFeatureAdded(new_feature_ids[0]))
self.assertTrue(layer.editBuffer().isFeatureAdded(new_feature_ids[1]))
def testDeleteFeatures(self):
# test deleting features from an edit buffer
# make a layer with two features
layer = createEmptyLayer()
self.assertTrue(layer.startEditing())
# add two features
f1 = QgsFeature(layer.fields(), 1)
f1.setGeometry(QgsGeometry.fromPoint(QgsPoint(1, 2)))
f1.setAttributes(["test", 123])
self.assertTrue(layer.addFeature(f1))
f2 = QgsFeature(layer.fields(), 2)
f2.setGeometry(QgsGeometry.fromPoint(QgsPoint(2, 4)))
f2.setAttributes(["test2", 246])
self.assertTrue(layer.addFeature(f2))
layer.commitChanges()
layer.startEditing()
self.assertEqual(layer.editBuffer().deletedFeatureIds(), [])
self.assertFalse(layer.editBuffer().isFeatureDeleted(1))
self.assertFalse(layer.editBuffer().isFeatureDeleted(2))
# delete a feature
layer.deleteFeature(1)
# test contents of buffer
self.assertEqual(layer.editBuffer().deletedFeatureIds(), [1])
self.assertTrue(layer.editBuffer().isFeatureDeleted(1))
self.assertFalse(layer.editBuffer().isFeatureDeleted(2))
# delete a feature
layer.deleteFeature(2)
# test contents of buffer
self.assertEqual(layer.editBuffer().deletedFeatureIds(), [1, 2])
self.assertTrue(layer.editBuffer().isFeatureDeleted(1))
self.assertTrue(layer.editBuffer().isFeatureDeleted(2))
def testDeleteMultipleFeatures(self):
# test deleting multiple features from an edit buffer
# make a layer with two features
layer = createEmptyLayer()
self.assertTrue(layer.startEditing())
# add two features
f1 = QgsFeature(layer.fields(), 1)
f1.setGeometry(QgsGeometry.fromPoint(QgsPoint(1, 2)))
f1.setAttributes(["test", 123])
self.assertTrue(layer.addFeature(f1))
f2 = QgsFeature(layer.fields(), 2)
f2.setGeometry(QgsGeometry.fromPoint(QgsPoint(2, 4)))
f2.setAttributes(["test2", 246])
self.assertTrue(layer.addFeature(f2))
layer.commitChanges()
layer.startEditing()
self.assertEqual(layer.editBuffer().deletedFeatureIds(), [])
self.assertFalse(layer.editBuffer().isFeatureDeleted(1))
self.assertFalse(layer.editBuffer().isFeatureDeleted(2))
# delete features
layer.deleteFeatures([1, 2])
# test contents of buffer
self.assertEqual(layer.editBuffer().deletedFeatureIds(), [1, 2])
self.assertTrue(layer.editBuffer().isFeatureDeleted(1))
self.assertTrue(layer.editBuffer().isFeatureDeleted(2))
def testChangeAttributeValues(self):
# test changing attributes values from an edit buffer
# make a layer with two features
layer = createEmptyLayer()
self.assertTrue(layer.startEditing())
# add two features
f1 = QgsFeature(layer.fields(), 1)
f1.setGeometry(QgsGeometry.fromPoint(QgsPoint(1, 2)))
f1.setAttributes(["test", 123])
self.assertTrue(layer.addFeature(f1))
f2 = QgsFeature(layer.fields(), 2)
f2.setGeometry(QgsGeometry.fromPoint(QgsPoint(2, 4)))
f2.setAttributes(["test2", 246])
self.assertTrue(layer.addFeature(f2))
layer.commitChanges()
layer.startEditing()
self.assertEqual(layer.editBuffer().changedAttributeValues(), {})
self.assertFalse(layer.editBuffer().isFeatureAttributesChanged(1))
self.assertFalse(layer.editBuffer().isFeatureAttributesChanged(2))
# change attribute values
layer.changeAttributeValue(1, 0, 'a')
# test contents of buffer
self.assertEqual(layer.editBuffer().changedAttributeValues().keys(), [1])
self.assertEqual(layer.editBuffer().changedAttributeValues()[1], {0: 'a'})
self.assertTrue(layer.editBuffer().isFeatureAttributesChanged(1))
self.assertFalse(layer.editBuffer().isFeatureAttributesChanged(2))
layer.changeAttributeValue(2, 1, 5)
# test contents of buffer
self.assertEqual(set(layer.editBuffer().changedAttributeValues().keys()), set([1, 2]))
self.assertEqual(layer.editBuffer().changedAttributeValues()[1], {0: 'a'})
self.assertEqual(layer.editBuffer().changedAttributeValues()[2], {1: 5})
self.assertTrue(layer.editBuffer().isFeatureAttributesChanged(1))
self.assertTrue(layer.editBuffer().isFeatureAttributesChanged(2))
def testChangeGeometry(self):
# test changing geometries values from an edit buffer
# make a layer with two features
layer = createEmptyLayer()
self.assertTrue(layer.startEditing())
# add two features
f1 = QgsFeature(layer.fields(), 1)
f1.setGeometry(QgsGeometry.fromPoint(QgsPoint(1, 2)))
f1.setAttributes(["test", 123])
self.assertTrue(layer.addFeature(f1))
f2 = QgsFeature(layer.fields(), 2)
f2.setGeometry(QgsGeometry.fromPoint(QgsPoint(2, 4)))
f2.setAttributes(["test2", 246])
self.assertTrue(layer.addFeature(f2))
layer.commitChanges()
layer.startEditing()
self.assertEqual(layer.editBuffer().changedGeometries(), {})
self.assertFalse(layer.editBuffer().isFeatureGeometryChanged(1))
self.assertFalse(layer.editBuffer().isFeatureGeometryChanged(2))
# change attribute values
layer.changeGeometry(1, QgsGeometry.fromPoint(QgsPoint(10, 20)))
# test contents of buffer
self.assertEqual(layer.editBuffer().changedGeometries().keys(), [1])
self.assertEqual(layer.editBuffer().changedGeometries()[1].geometry().x(), 10)
self.assertTrue(layer.editBuffer().isFeatureGeometryChanged(1))
self.assertFalse(layer.editBuffer().isFeatureGeometryChanged(2))
layer.changeGeometry(2, QgsGeometry.fromPoint(QgsPoint(20, 40)))
# test contents of buffer
self.assertEqual(set(layer.editBuffer().changedGeometries().keys()), set([1, 2]))
self.assertEqual(layer.editBuffer().changedGeometries()[1].geometry().x(), 10)
self.assertEqual(layer.editBuffer().changedGeometries()[2].geometry().x(), 20)
self.assertTrue(layer.editBuffer().isFeatureGeometryChanged(1))
self.assertTrue(layer.editBuffer().isFeatureGeometryChanged(2))
def testDeleteAttribute(self):
# test deleting attributes from an edit buffer
layer = createEmptyLayer()
layer.startEditing()
self.assertEqual(layer.editBuffer().deletedAttributeIds(), [])
self.assertFalse(layer.editBuffer().isAttributeDeleted(0))
self.assertFalse(layer.editBuffer().isAttributeDeleted(1))
# delete attribute
layer.deleteAttribute(0)
# test contents of buffer
self.assertEqual(layer.editBuffer().deletedAttributeIds(), [0])
self.assertTrue(layer.editBuffer().isAttributeDeleted(0))
self.assertFalse(layer.editBuffer().isAttributeDeleted(1))
# delete remaining attribute (now at position 0)
layer.deleteAttribute(0)
# test contents of buffer
self.assertEqual(layer.editBuffer().deletedAttributeIds(), [0, 1])
self.assertTrue(layer.editBuffer().isAttributeDeleted(0))
self.assertTrue(layer.editBuffer().isAttributeDeleted(1))
def testAddAttribute(self):
# test adding attributes to an edit buffer
layer = createEmptyLayer()
layer.startEditing()
self.assertEqual(layer.editBuffer().addedAttributes(), [])
# add attribute
layer.addAttribute(QgsField('new1', QVariant.String))
# test contents of buffer
self.assertEqual(layer.editBuffer().addedAttributes()[0].name(), 'new1')
# add another attribute
layer.addAttribute(QgsField('new2', QVariant.String))
# test contents of buffer
self.assertEqual(layer.editBuffer().addedAttributes()[0].name(), 'new1')
self.assertEqual(layer.editBuffer().addedAttributes()[1].name(), 'new2')
if __name__ == '__main__':
unittest.main()