Skip to content

Commit

Permalink
Add "contains" method to QgsObjectCustomProperties, improve dox, add …
Browse files Browse the repository at this point in the history
…tests
  • Loading branch information
nyalldawson committed Jun 2, 2020
1 parent 33fc5d4 commit eee4327
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 16 deletions.
27 changes: 20 additions & 7 deletions python/core/auto_generated/qgsobjectcustomproperties.sip.in
Expand Up @@ -31,38 +31,51 @@ Constructor for QgsObjectCustomProperties.

QStringList keys() const;
%Docstring
Returns list of stored keys
Returns a list of all stored keys.
%End

void setValue( const QString &key, const QVariant &value );
%Docstring
Add an entry to the store. If the entry with the keys exists already, it will be overwritten
Add an entry to the store with the specified ``key``.

If an entry with the same ``key`` exists already, it will be overwritten.
%End

QVariant value( const QString &key, const QVariant &defaultValue = QVariant() ) const;
%Docstring
Returns value for the given key. If the key is not stored, default value will be used
Returns the value for the given ``key``.

If the ``key`` is not present in the properties, the ``defaultValue`` will be returned.
%End

void remove( const QString &key );
%Docstring
Remove a key (entry) from the store
Removes a ``key`` (entry) from the store.
%End

bool contains( const QString &key ) const;
%Docstring
Returns ``True`` if the properties contains a ``key`` with the specified name.

.. versionadded:: 3.14
%End

void readXml( const QDomNode &parentNode, const QString &keyStartsWith = QString() );
%Docstring
Read store contents from XML
Read store contents from an XML node.

:param parentNode: node to read from
:param keyStartsWith: reads only properties starting with the specified string (or all if the string is empty)

.. seealso:: :py:func:`writeXml`
%End

void writeXml( QDomNode &parentNode, QDomDocument &doc ) const;
%Docstring
Write store contents to XML
%End
Writes the store contents to an XML node.

.. seealso:: :py:func:`readXml`
%End

protected:

Expand Down
4 changes: 4 additions & 0 deletions src/core/qgsobjectcustomproperties.cpp
Expand Up @@ -42,6 +42,10 @@ void QgsObjectCustomProperties::remove( const QString &key )
mMap.remove( key );
}

bool QgsObjectCustomProperties::contains( const QString &key ) const
{
return mMap.contains( key );
}

void QgsObjectCustomProperties::readXml( const QDomNode &parentNode, const QString &keyStartsWith )
{
Expand Down
41 changes: 32 additions & 9 deletions src/core/qgsobjectcustomproperties.h
Expand Up @@ -41,30 +41,53 @@ class CORE_EXPORT QgsObjectCustomProperties
*/
QgsObjectCustomProperties() = default;

//! Returns list of stored keys
/**
* Returns a list of all stored keys.
*/
QStringList keys() const;

//! Add an entry to the store. If the entry with the keys exists already, it will be overwritten
/**
* Add an entry to the store with the specified \a key.
*
* If an entry with the same \a key exists already, it will be overwritten.
*/
void setValue( const QString &key, const QVariant &value );

//! Returns value for the given key. If the key is not stored, default value will be used
/**
* Returns the value for the given \a key.
*
* If the \a key is not present in the properties, the \a defaultValue will be returned.
*/
QVariant value( const QString &key, const QVariant &defaultValue = QVariant() ) const;

//! Remove a key (entry) from the store
/**
* Removes a \a key (entry) from the store.
*/
void remove( const QString &key );

/**
* Returns TRUE if the properties contains a \a key with the specified name.
*
* \since QGIS 3.14
*/
bool contains( const QString &key ) const;

/**
* Read store contents from XML
\param parentNode node to read from
\param keyStartsWith reads only properties starting with the specified string (or all if the string is empty)
* Read store contents from an XML node.
* \param parentNode node to read from
* \param keyStartsWith reads only properties starting with the specified string (or all if the string is empty)
*
* \see writeXml()
*/
void readXml( const QDomNode &parentNode, const QString &keyStartsWith = QString() );

//! Write store contents to XML
/**
* Writes the store contents to an XML node.
*
* \see readXml()
*/
void writeXml( QDomNode &parentNode, QDomDocument &doc ) const;


protected:
QMap<QString, QVariant> mMap;

Expand Down
1 change: 1 addition & 0 deletions tests/src/python/CMakeLists.txt
Expand Up @@ -171,6 +171,7 @@ ADD_PYTHON_TEST(PyQgsNumericFormat test_qgsnumericformat.py)
ADD_PYTHON_TEST(PyQgsNumericFormatGui test_qgsnumericformatgui.py)
ADD_PYTHON_TEST(PyQgsNewGeoPackageLayerDialog test_qgsnewgeopackagelayerdialog.py)
ADD_PYTHON_TEST(PyQgsNoApplication test_qgsnoapplication.py)
ADD_PYTHON_TEST(PyQgsObjectCustomProperties test_qgsobjectcustomproperties.py)
ADD_PYTHON_TEST(PyQgsOgcUtils test_qgsogcutils.py)
ADD_PYTHON_TEST(PyQgsOGRProviderGpkg test_provider_ogr_gpkg.py)
ADD_PYTHON_TEST(PyQgsOGRProviderSqlite test_provider_ogr_sqlite.py)
Expand Down
84 changes: 84 additions & 0 deletions tests/src/python/test_qgsobjectcustomproperties.py
@@ -0,0 +1,84 @@
# -*- coding: utf-8 -*-
"""QGIS Unit tests for QgsObjectCustomProperties
.. 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__ = '02/06/2020'
__copyright__ = 'Copyright 2020, The QGIS Project'

import qgis # NOQA

from qgis.core import QgsObjectCustomProperties

from qgis.testing import start_app, unittest
from qgis.PyQt.QtXml import QDomDocument

start_app()


class TestQgsObjectCustomProperties(unittest.TestCase):

def testSimple(self):
""" test storing/retrieving properties """
props = QgsObjectCustomProperties()
self.assertFalse(props.keys())
self.assertFalse(props.contains('a'))
self.assertFalse(props.value('a'))
self.assertEqual(props.value('a', defaultValue=6), 6)

# remove non-present key, no crash
props.remove('a')

props.setValue('a', 7)
self.assertEqual(props.keys(), ['a'])
self.assertTrue(props.contains('a'))
self.assertFalse(props.contains('b'))
self.assertEqual(props.value('a', defaultValue=6), 7)
self.assertEqual(props.value('b', defaultValue='yy'), 'yy')
props.setValue('b', 'xx')
self.assertCountEqual(props.keys(), ['a', 'b'])
self.assertTrue(props.contains('a'))
self.assertTrue(props.contains('b'))
self.assertEqual(props.value('a', defaultValue=6), 7)
self.assertEqual(props.value('b', defaultValue='yy'), 'xx')

props.remove('a')
self.assertCountEqual(props.keys(), ['b'])
self.assertFalse(props.contains('a'))
self.assertTrue(props.contains('b'))
self.assertEqual(props.value('a', defaultValue=6), 6)
self.assertEqual(props.value('b', defaultValue='yy'), 'xx')

props.remove('b')
self.assertFalse(props.keys())
self.assertFalse(props.contains('a'))
self.assertFalse(props.contains('b'))
self.assertEqual(props.value('a', defaultValue=6), 6)
self.assertEqual(props.value('b', defaultValue='yy'), 'yy')

def testSaveRestore(self):
doc = QDomDocument()
elem = doc.createElement('test')

props = QgsObjectCustomProperties()
props.setValue('a', '7')
props.setValue('b', 'xx')

props.writeXml(elem, doc)

props2 = QgsObjectCustomProperties()
props2.readXml(elem)

self.assertCountEqual(props2.keys(), ['a', 'b'])
self.assertTrue(props2.contains('a'))
self.assertTrue(props2.contains('b'))
self.assertEqual(props2.value('a', defaultValue=6), '7')
self.assertEqual(props2.value('b', defaultValue='yy'), 'xx')


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

0 comments on commit eee4327

Please sign in to comment.