Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[relations] Add method to manager to retrieve relations by name
Also
- Begin unit tests for QgsRelationManager
- Make project optional when constructing QgsRelationManager
  • Loading branch information
nyalldawson committed May 17, 2016
1 parent 84fc3c3 commit ea06659
Show file tree
Hide file tree
Showing 5 changed files with 202 additions and 3 deletions.
15 changes: 14 additions & 1 deletion python/core/qgsrelationmanager.sip
Expand Up @@ -7,7 +7,11 @@ class QgsRelationManager : QObject
#include "qgsrelationmanager.h"
%End
public:
explicit QgsRelationManager( QgsProject *project );

/** Constructor for QgsRelationManager.
* @param project associated project (used to notify project of changes)
*/
explicit QgsRelationManager( QgsProject *project = nullptr );

/**
* Will set the specified relations and remove any relation currently set.
Expand Down Expand Up @@ -50,9 +54,18 @@ class QgsRelationManager : QObject
* @param id The id to search for
*
* @return A relation. Invalid if not found.
* @see relationsByName()
*/
QgsRelation relation( const QString& id ) const;

/** Returns a list of relations with matching names.
* @param name relation name to search for. Searching is case insensitive.
* @returns a list of matching relations
* @note added in QGIS 2.16
* @see relation()
*/
QList<QgsRelation> relationsByName( const QString& name ) const;

/**
* Remove any relation managed by this class.
*/
Expand Down
16 changes: 15 additions & 1 deletion src/core/qgsrelationmanager.cpp
Expand Up @@ -52,7 +52,8 @@ void QgsRelationManager::addRelation( const QgsRelation& relation )

mRelations.insert( relation.id(), relation );

mProject->setDirty( true );
if ( mProject )
mProject->setDirty( true );
emit changed();
}

Expand All @@ -73,6 +74,19 @@ QgsRelation QgsRelationManager::relation( const QString& id ) const
return mRelations.value( id );
}

QList<QgsRelation> QgsRelationManager::relationsByName( const QString& name ) const
{
QList<QgsRelation> relations;

Q_FOREACH ( const QgsRelation& rel, mRelations )
{
if ( QString::compare( rel.name(), name, Qt::CaseInsensitive ) == 0 )
relations << rel;
}

return relations;
}

void QgsRelationManager::clear()
{
mRelations.clear();
Expand Down
15 changes: 14 additions & 1 deletion src/core/qgsrelationmanager.h
Expand Up @@ -34,7 +34,11 @@ class CORE_EXPORT QgsRelationManager : public QObject
Q_OBJECT

public:
explicit QgsRelationManager( QgsProject *project );

/** Constructor for QgsRelationManager.
* @param project associated project (used to notify project of changes)
*/
explicit QgsRelationManager( QgsProject *project = nullptr );

/**
* Will set the specified relations and remove any relation currently set.
Expand Down Expand Up @@ -77,9 +81,18 @@ class CORE_EXPORT QgsRelationManager : public QObject
* @param id The id to search for
*
* @return A relation. Invalid if not found.
* @see relationsByName()
*/
QgsRelation relation( const QString& id ) const;

/** Returns a list of relations with matching names.
* @param name relation name to search for. Searching is case insensitive.
* @returns a list of matching relations
* @note added in QGIS 2.16
* @see relation()
*/
QList<QgsRelation> relationsByName( const QString& name ) const;

/**
* Remove any relation managed by this class.
*/
Expand Down
1 change: 1 addition & 0 deletions tests/src/python/CMakeLists.txt
Expand Up @@ -62,6 +62,7 @@ ADD_PYTHON_TEST(PyQgsRasterFileWriter test_qgsrasterfilewriter.py)
ADD_PYTHON_TEST(PyQgsRasterLayer test_qgsrasterlayer.py)
ADD_PYTHON_TEST(PyQgsRectangle test_qgsrectangle.py)
ADD_PYTHON_TEST(PyQgsRelation test_qgsrelation.py)
ADD_PYTHON_TEST(PyQgsRelationManager test_qgsrelationmanager.py)
ADD_PYTHON_TEST(PyQgsRulebasedRenderer test_qgsrulebasedrenderer.py)
ADD_PYTHON_TEST(PyQgsSingleSymbolRenderer test_qgssinglesymbolrenderer.py)
ADD_PYTHON_TEST(PyQgsShapefileProvider test_provider_shapefile.py)
Expand Down
158 changes: 158 additions & 0 deletions tests/src/python/test_qgsrelationmanager.py
@@ -0,0 +1,158 @@
# -*- coding: utf-8 -*-
"""QGIS Unit tests for QgsRelationManager.
.. 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__ = '17/05/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

from qgis.core import (QgsVectorLayer,
QgsRelation,
QgsRelationManager,
QgsMapLayerRegistry
)
from qgis.testing import start_app, unittest

start_app()


def createReferencingLayer():
layer = QgsVectorLayer("Point?field=fldtxt:string&field=foreignkey:integer",
"referencinglayer", "memory")
return layer


def createReferencedLayer():
layer = QgsVectorLayer(
"Point?field=x:string&field=y:integer&field=z:integer",
"referencedlayer", "memory")
return layer


class TestQgsRelationManager(unittest.TestCase):

def setUp(self):
self.referencedLayer = createReferencedLayer()
self.referencingLayer = createReferencingLayer()
QgsMapLayerRegistry.instance().addMapLayers([self.referencedLayer, self.referencingLayer])

def tearDown(self):
QgsMapLayerRegistry.instance().removeAllMapLayers()

def createRelation(self):
rel = QgsRelation()
rel.setReferencingLayer(self.referencingLayer.id())
rel.setReferencedLayer(self.referencedLayer.id())
rel.addFieldPair('foreignkey', 'y')
return rel

def test_addRelation(self):
""" test adding relations to a manager """
manager = QgsRelationManager()

relations = manager.relations()
self.assertEqual(len(relations), 0)

rel = self.createRelation()
rel.setRelationId('rel1')
rel.setRelationName('Relation Number One')
assert rel.isValid()

manager.addRelation(rel)

relations = manager.relations()
self.assertEqual(len(relations), 1)
self.assertEqual(relations['rel1'].id(), 'rel1')

rel = self.createRelation()
rel.setRelationId('rel2')
rel.setRelationName('Relation Number Two')
assert rel.isValid()

manager.addRelation(rel)

relations = manager.relations()
self.assertEqual(len(relations), 2)
ids = [r.id() for r in relations.values()]
self.assertEqual(set(ids), set(['rel1', 'rel2']))

def test_relationById(self):
""" test retrieving relation by id"""
manager = QgsRelationManager()

rel = manager.relation('does not exist')
self.assertFalse(rel.isValid())

# add two relations
rel = self.createRelation()
rel.setRelationId('rel1')
rel.setRelationName('Relation Number One')
assert rel.isValid()
manager.addRelation(rel)
rel = self.createRelation()
rel.setRelationId('rel2')
rel.setRelationName('Relation Number Two')
assert rel.isValid()
manager.addRelation(rel)

rel = manager.relation('does not exist')
self.assertFalse(rel.isValid())

rel = manager.relation('rel1')
self.assertEqual(rel.id(), 'rel1')

rel = manager.relation('rel2')
self.assertEqual(rel.id(), 'rel2')

def test_relationByName(self):
""" test retrieving relations by name"""
manager = QgsRelationManager()

rels = manager.relationsByName('does not exist')
self.assertEqual(rels, [])

# add some relations
rel = self.createRelation()
rel.setRelationId('rel1')
rel.setRelationName('my relation')
assert rel.isValid()
manager.addRelation(rel)
rel = self.createRelation()
rel.setRelationId('rel2')
rel.setRelationName('dupe name')
assert rel.isValid()
manager.addRelation(rel)
rel = self.createRelation()
rel.setRelationId('rel3')
rel.setRelationName('dupe name')
assert rel.isValid()
manager.addRelation(rel)

rels = manager.relationsByName('does not exist')
self.assertEqual(rels, [])

rels = manager.relationsByName('my relation')
ids = [r.id() for r in rels]
self.assertEqual(set(ids), set(['rel1']))

# case insensitive
rels = manager.relationsByName('My RelAtion')
ids = [r.id() for r in rels]
self.assertEqual(set(ids), set(['rel1']))

# multiple results
rels = manager.relationsByName('dupe name')
ids = [r.id() for r in rels]
self.assertEqual(set(ids), set(['rel2', 'rel3']))


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

0 comments on commit ea06659

Please sign in to comment.