Fix tests

This commit is contained in:
Matthias Kuhn 2017-03-23 09:01:52 +01:00
parent f33aabd90a
commit baa4c86262
9 changed files with 140 additions and 130 deletions

View File

@ -3,20 +3,22 @@ class QgsLayerTree : QgsLayerTreeGroup
%TypeHeaderCode
#include <qgslayertree.h>
%End
static bool isGroup( QgsLayerTreeNode *node );
static bool isLayer( const QgsLayerTreeNode *node );
//! Cast node to a group. No type checking is done - use isGroup() to find out whether this operation is legal.
// PYTHON: automatic cast
//inline QgsLayerTreeGroup* toGroup( QgsLayerTreeNode* node );
public:
static bool isGroup( QgsLayerTreeNode *node );
static bool isLayer( const QgsLayerTreeNode *node );
//! Cast node to a layer. No type checking is done - use isLayer() to find out whether this operation is legal.
// PYTHON: automatic cast
//inline QgsLayerTreeLayer* toLayer( QgsLayerTreeNode* node );
//! Cast node to a group. No type checking is done - use isGroup() to find out whether this operation is legal.
// PYTHON: automatic cast
//inline QgsLayerTreeGroup* toGroup( QgsLayerTreeNode* node );
//! Cast node to a layer. No type checking is done - use isLayer() to find out whether this operation is legal.
// PYTHON: automatic cast
//inline QgsLayerTreeLayer* toLayer( QgsLayerTreeNode* node );
QList<QgsMapLayer *> customLayerOrder() const;
void setCustomLayerOrder( const QList<QgsMapLayer *> &customLayerOrder );
void setCustomLayerOrder( const QStringList &customLayerOrder );
void setCustomLayerOrder( const QStringList &customLayerOrder ) /PyName=setCustomLayerOrderByIds/;
QList<QgsMapLayer *> layerOrder() const;
bool hasCustomLayerOrder() const;
void setHasCustomLayerOrder( bool hasCustomLayerOrder );

View File

@ -51,6 +51,8 @@ class QgsLayerTreeNode : QObject
QgsLayerTreeNode* node = qobject_cast<QgsLayerTreeNode*>(sipCpp);
if (QgsLayerTree::isLayer(node))
sipType = sipType_QgsLayerTreeLayer;
else if (qobject_cast<QgsLayerTree*>(sipCpp))
sipType = sipType_QgsLayerTree;
else if (QgsLayerTree::isGroup(node))
sipType = sipType_QgsLayerTreeGroup;
}

View File

@ -418,46 +418,6 @@ bool QgsComposerLegend::writeXml( QDomElement &elem, QDomDocument &doc ) const
return _writeXml( composerLegendElem, doc );
}
static void _readOldLegendGroup( QDomElement &elem, QgsLayerTreeGroup *parentGroup, QgsProject *project )
{
QDomElement itemElem = elem.firstChildElement();
while ( !itemElem.isNull() )
{
if ( itemElem.tagName() == QLatin1String( "LayerItem" ) )
{
QString layerId = itemElem.attribute( QStringLiteral( "layerId" ) );
if ( QgsMapLayer *layer = project->mapLayer( layerId ) )
{
QgsLayerTreeLayer *nodeLayer = parentGroup->addLayer( layer );
QString userText = itemElem.attribute( QStringLiteral( "userText" ) );
if ( !userText.isEmpty() )
nodeLayer->setCustomProperty( QStringLiteral( "legend/title-label" ), userText );
QString style = itemElem.attribute( QStringLiteral( "style" ) );
if ( !style.isEmpty() )
nodeLayer->setCustomProperty( QStringLiteral( "legend/title-style" ), style );
QString showFeatureCount = itemElem.attribute( QStringLiteral( "showFeatureCount" ) );
if ( showFeatureCount.toInt() )
nodeLayer->setCustomProperty( QStringLiteral( "showFeatureCount" ), 1 );
// support for individual legend items (user text, order) not implemented yet
}
}
else if ( itemElem.tagName() == QLatin1String( "GroupItem" ) )
{
QgsLayerTreeGroup *nodeGroup = parentGroup->addGroup( itemElem.attribute( QStringLiteral( "userText" ) ) );
QString style = itemElem.attribute( QStringLiteral( "style" ) );
if ( !style.isEmpty() )
nodeGroup->setCustomProperty( QStringLiteral( "legend/title-style" ), style );
_readOldLegendGroup( itemElem, nodeGroup, project );
}
itemElem = itemElem.nextSiblingElement();
}
}
bool QgsComposerLegend::readXml( const QDomElement &itemElem, const QDomDocument &doc )
{
if ( itemElem.isNull() )

View File

@ -58,6 +58,7 @@ class CORE_EXPORT QgsLayerTree : public QgsLayerTreeGroup
* Cast node to a group. No type checking is done - use isGroup() to find out whether this operation is legal.
*
* @note Added in QGIS 2.4
* @note Not available in python bindings, because cast is automatic.
*/
static inline QgsLayerTreeGroup *toGroup( QgsLayerTreeNode *node )
{
@ -68,6 +69,7 @@ class CORE_EXPORT QgsLayerTree : public QgsLayerTreeGroup
* Cast node to a layer. No type checking is done - use isLayer() to find out whether this operation is legal.
*
* @note Added in QGIS 2.4
* @note Not available in python bindings, because cast is automatic.
*/
static inline QgsLayerTreeLayer *toLayer( QgsLayerTreeNode *node )
{
@ -78,14 +80,21 @@ class CORE_EXPORT QgsLayerTree : public QgsLayerTreeGroup
* Cast node to a layer. No type checking is done - use isLayer() to find out whether this operation is legal.
*
* @note Added in QGIS 2.4
* @note Not available in python bindings, because cast is automatic.
*/
static inline const QgsLayerTreeLayer *toLayer( const QgsLayerTreeNode *node )
{
return static_cast< const QgsLayerTreeLayer *>( node );
}
//! Constructor
/**
* Create a new empty layer tree
*/
QgsLayerTree();
/**
* Copy constructor
*/
QgsLayerTree( const QgsLayerTree &other );
/**

View File

@ -64,6 +64,7 @@ ADD_PYTHON_TEST(PyQgsGraduatedSymbolRenderer test_qgsgraduatedsymbolrenderer.py)
ADD_PYTHON_TEST(PyQgsInterval test_qgsinterval.py)
ADD_PYTHON_TEST(PyQgsJSONUtils test_qgsjsonutils.py)
ADD_PYTHON_TEST(PyQgsLayerTreeMapCanvasBridge test_qgslayertreemapcanvasbridge.py)
ADD_PYTHON_TEST(PyQgsLayerTree test_qgslayertree.py)
ADD_PYTHON_TEST(PyQgsLayoutManager test_qgslayoutmanager.py)
ADD_PYTHON_TEST(PyQgsLineSymbolLayers test_qgslinesymbollayers.py)
ADD_PYTHON_TEST(PyQgsMapCanvas test_qgsmapcanvas.py)

View File

@ -0,0 +1,83 @@
# -*- coding: utf-8 -*-
"""QGIS Unit tests for QgsLayerTree.
.. 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__ = 'Matthias Kuhn'
__date__ = '22.3.2017'
__copyright__ = 'Copyright 2017, 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.core import (
QgsLayerTree,
QgsProject,
QgsVectorLayer
)
from qgis.testing import start_app, unittest
from utilities import (unitTestDataPath)
from qgis.PyQt.QtTest import QSignalSpy
from qgis.PyQt.QtCore import QDir
app = start_app()
TEST_DATA_DIR = unitTestDataPath()
class TestQgsLayerTree(unittest.TestCase):
def __init__(self, methodName):
"""Run once on class initialization."""
unittest.TestCase.__init__(self, methodName)
def testCustomLayerOrder(self):
""" test project layer order"""
prj = QgsProject()
layer = QgsVectorLayer("Point?field=fldtxt:string",
"layer1", "memory")
layer2 = QgsVectorLayer("Point?field=fldtxt:string",
"layer2", "memory")
layer3 = QgsVectorLayer("Point?field=fldtxt:string",
"layer3", "memory")
prj.addMapLayers([layer, layer2, layer3])
layer_order_changed_spy = QSignalSpy(prj.layerTreeRoot().customLayerOrderChanged)
prj.layerTreeRoot().setCustomLayerOrder([layer2, layer])
self.assertEqual(len(layer_order_changed_spy), 1)
prj.layerTreeRoot().setCustomLayerOrder([layer2, layer])
self.assertEqual(len(layer_order_changed_spy), 1) # no signal, order not changed
self.assertEqual(prj.layerTreeRoot().customLayerOrder(), [layer2, layer])
prj.layerTreeRoot().setCustomLayerOrder([layer])
self.assertEqual(prj.layerTreeRoot().customLayerOrder(), [layer])
self.assertEqual(len(layer_order_changed_spy), 2)
# remove a layer
prj.layerTreeRoot().setCustomLayerOrder([layer2, layer, layer3])
self.assertEqual(len(layer_order_changed_spy), 3)
prj.removeMapLayer(layer)
self.assertEqual(prj.layerTreeRoot().customLayerOrder(), [layer2, layer3])
self.assertEqual(len(layer_order_changed_spy), 4)
# save and restore
file_name = os.path.join(QDir.tempPath(), 'proj.qgs')
prj.setFileName(file_name)
prj.write()
prj2 = QgsProject()
prj2.setFileName(file_name)
prj2.read()
self.assertEqual([l.id() for l in prj2.layerTreeRoot().customLayerOrder()], [layer2.id(), layer3.id()])
# clear project
prj.clear()
self.assertEqual(prj.layerTreeRoot().customLayerOrder(), [])
if __name__ == '__main__':
unittest.main()

View File

@ -54,32 +54,34 @@ class TestQgsLayerTreeMapCanvasBridge(unittest.TestCase):
bridge = QgsLayerTreeMapCanvasBridge(prj.layerTreeRoot(), canvas)
#custom layer order
bridge.setHasCustomLayerOrder(True)
bridge.setCustomLayerOrder([layer3.id(), layer.id(), layer2.id()])
prj.layerTreeRoot().setHasCustomLayerOrder(True)
prj.layerTreeRoot().setCustomLayerOrder([layer3, layer, layer2])
app.processEvents()
self.assertEqual([l.id() for l in prj.layerOrder()], [layer3.id(), layer.id(), layer2.id()])
self.assertEqual([l for l in prj.layerTreeRoot().customLayerOrder()], [layer3, layer, layer2])
self.assertEqual([l for l in prj.layerTreeRoot().layerOrder()], [layer3, layer, layer2])
# no custom layer order
bridge.setHasCustomLayerOrder(False)
prj.layerTreeRoot().setHasCustomLayerOrder(False)
app.processEvents()
self.assertEqual([l.id() for l in prj.layerOrder()], [layer.id(), layer2.id(), layer3.id()])
self.assertEqual([l for l in prj.layerTreeRoot().customLayerOrder()], [layer3, layer, layer2])
self.assertEqual([l for l in prj.layerTreeRoot().layerOrder()], [layer, layer2, layer3])
# mess around with the layer tree order
root = prj.layerTreeRoot()
layer_node = root.findLayer(layer2.id())
layer_node = root.findLayer(layer2)
cloned_node = layer_node.clone()
parent = layer_node.parent()
parent.insertChildNode(0, cloned_node)
parent.removeChildNode(layer_node)
app.processEvents()
# make sure project respects this
self.assertEqual([l.id() for l in prj.layerOrder()], [layer2.id(), layer.id(), layer3.id()])
self.assertEqual([l for l in prj.layerTreeRoot().layerOrder()], [layer2, layer, layer3])
# make sure project order includes ALL layers, not just visible ones
layer_node = root.findLayer(layer.id())
layer_node = root.findLayer(layer)
layer_node.setItemVisibilityChecked(False)
app.processEvents()
self.assertEqual([l.id() for l in prj.layerOrder()], [layer2.id(), layer.id(), layer3.id()])
self.assertEqual([l for l in prj.layerTreeRoot().layerOrder()], [layer2, layer, layer3])
def testCustomLayerOrderUpdatedFromProject(self):
""" test that setting project layer order is reflected in custom layer order panel """
@ -99,37 +101,35 @@ class TestQgsLayerTreeMapCanvasBridge(unittest.TestCase):
custom_order_widget = QgsCustomLayerOrderWidget(bridge)
#custom layer order
bridge.setHasCustomLayerOrder(True)
bridge.setCustomLayerOrder([layer3.id(), layer.id(), layer2.id()])
prj.layerTreeRoot().setHasCustomLayerOrder(True)
prj.layerTreeRoot().setCustomLayerOrder([layer3, layer, layer2])
app.processEvents()
self.assertEqual([l.id() for l in prj.layerOrder()], [layer3.id(), layer.id(), layer2.id()])
self.assertEqual([l for l in prj.layerTreeRoot().customLayerOrder()], [layer3, layer, layer2])
# no custom layer order
bridge.setHasCustomLayerOrder(False)
prj.layerTreeRoot().setHasCustomLayerOrder(False)
app.processEvents()
self.assertEqual([l.id() for l in prj.layerOrder()], [layer.id(), layer2.id(), layer3.id()])
self.assertEqual([l for l in prj.layerTreeRoot().layerOrder()], [layer, layer2, layer3])
# mess around with the project layer order
prj.setLayerOrder([layer3, layer, layer2])
prj.layerTreeRoot().setCustomLayerOrder([layer3, layer, layer2])
app.processEvents()
# make sure bridge respects this new order
self.assertTrue(bridge.hasCustomLayerOrder())
self.assertEqual(bridge.customLayerOrder(), [layer3.id(), layer.id(), layer2.id()])
self.assertEqual(prj.layerTreeRoot().layerOrder(), [layer, layer2, layer3])
# try reordering through bridge
bridge.setHasCustomLayerOrder(False)
prj.layerTreeRoot().setHasCustomLayerOrder(False)
app.processEvents()
self.assertEqual([l.id() for l in prj.layerOrder()], [layer.id(), layer2.id(), layer3.id()])
self.assertEqual([l for l in prj.layerTreeRoot().layerOrder()], [layer, layer2, layer3])
root = prj.layerTreeRoot()
layer_node = root.findLayer(layer2.id())
layer_node = root.findLayer(layer2)
cloned_node = layer_node.clone()
parent = layer_node.parent()
parent.insertChildNode(0, cloned_node)
parent.removeChildNode(layer_node)
app.processEvents()
# make sure project respects this
self.assertEqual([l.id() for l in prj.layerOrder()], [layer2.id(), layer.id(), layer3.id()])
self.assertFalse(bridge.hasCustomLayerOrder())
self.assertEqual([l for l in prj.layerTreeRoot().layerOrder()], [layer2, layer, layer3])
self.assertFalse(prj.layerTreeRoot().hasCustomLayerOrder())
if __name__ == '__main__':

View File

@ -111,10 +111,11 @@ class TestQgsMapThemeCollection(unittest.TestCase):
"layer3", "memory")
prj.addMapLayers([layer, layer2, layer3])
prj.setLayerOrder([layer2, layer])
prj.layerTreeRoot().setHasCustomLayerOrder(True)
prj.layerTreeRoot().setCustomLayerOrder([layer2, layer])
self.assertEqual(prj.mapThemeCollection().masterLayerOrder(), [layer2, layer])
prj.setLayerOrder([layer, layer2, layer3])
prj.layerTreeRoot().setCustomLayerOrder([layer, layer2, layer3])
# make some themes...
theme1 = QgsMapThemeCollection.MapThemeRecord()
theme1.setLayerRecords([QgsMapThemeCollection.MapThemeLayerRecord(layer3),
@ -144,7 +145,7 @@ class TestQgsMapThemeCollection(unittest.TestCase):
self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayerIds('theme3'), [layer.id(), layer2.id()])
# reset master order
prj.setLayerOrder([layer2, layer3, layer])
prj.layerTreeRoot().setCustomLayerOrder([layer2, layer3, layer])
self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayers('theme1'), [layer3, layer])
self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayers('theme2'), [layer2, layer3, layer])
self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayers('theme3'), [layer2, layer])
@ -159,6 +160,7 @@ class TestQgsMapThemeCollection(unittest.TestCase):
layer_node = root.findLayer(layer2.id())
layer_node.setItemVisibilityChecked(False)
app.processEvents()
prj.layerTreeRoot().setHasCustomLayerOrder(False)
self.assertEqual(prj.mapThemeCollection().masterLayerOrder(), [layer, layer2, layer3])
self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayers('theme1'), [layer, layer3])
@ -169,12 +171,6 @@ class TestQgsMapThemeCollection(unittest.TestCase):
[layer.id(), layer2.id(), layer3.id()])
self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayerIds('theme3'), [layer.id(), layer2.id()])
# no layer order - should use stored order as a last resort
prj.setLayerOrder([])
self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayers('theme1'), [layer3, layer])
self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayers('theme2'), [layer3, layer2, layer])
self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayers('theme3'), [layer2, layer])
def testMasterVisibleLayers(self):
""" test master visible layers"""
prj = QgsProject.instance()
@ -188,9 +184,10 @@ class TestQgsMapThemeCollection(unittest.TestCase):
prj.addMapLayers([layer, layer2, layer3])
# general setup...
prj.setLayerOrder([layer2, layer])
prj.layerTreeRoot().setHasCustomLayerOrder(True)
prj.layerTreeRoot().setCustomLayerOrder([layer2, layer])
self.assertEqual(prj.mapThemeCollection().masterVisibleLayers(), [layer2, layer])
prj.setLayerOrder([layer3, layer, layer2])
prj.layerTreeRoot().setCustomLayerOrder([layer3, layer, layer2])
self.assertEqual(prj.mapThemeCollection().masterVisibleLayers(), [layer3, layer, layer2])
#hide some layers
@ -201,11 +198,11 @@ class TestQgsMapThemeCollection(unittest.TestCase):
layer_node.setItemVisibilityChecked(True)
self.assertEqual(prj.mapThemeCollection().masterVisibleLayers(), [layer3, layer, layer2])
layer_node.setItemVisibilityChecked(False)
prj.setLayerOrder([layer, layer2, layer3])
prj.layerTreeRoot().setCustomLayerOrder([layer, layer2, layer3])
self.assertEqual(prj.mapThemeCollection().masterVisibleLayers(), [layer, layer3])
# test with no project layer order set, should respect tree order
prj.setLayerOrder([])
prj.layerTreeRoot().setCustomLayerOrder([])
self.assertEqual(prj.mapThemeCollection().masterVisibleLayers(), [layer, layer3])
layer_node.setItemVisibilityChecked(True)
self.assertEqual(prj.mapThemeCollection().masterVisibleLayers(), [layer, layer2, layer3])

View File

@ -27,8 +27,6 @@ from qgis.gui import (QgsLayerTreeMapCanvasBridge,
QgsMapCanvas)
from qgis.testing import start_app, unittest
from utilities import (unitTestDataPath)
from qgis.PyQt.QtCore import QDir
from qgis.PyQt.QtTest import QSignalSpy
app = start_app()
TEST_DATA_DIR = unitTestDataPath()
@ -183,48 +181,6 @@ class TestQgsProject(unittest.TestCase):
expected = ['polys', 'lines']
self.assertEqual(sorted(layers_names), sorted(expected))
def testLayerOrder(self):
""" test project layer order"""
prj = QgsProject()
layer = QgsVectorLayer("Point?field=fldtxt:string",
"layer1", "memory")
layer2 = QgsVectorLayer("Point?field=fldtxt:string",
"layer2", "memory")
layer3 = QgsVectorLayer("Point?field=fldtxt:string",
"layer3", "memory")
prj.addMapLayers([layer, layer2, layer3])
layer_order_changed_spy = QSignalSpy(prj.layerOrderChanged)
prj.setLayerOrder([layer2, layer])
self.assertEqual(len(layer_order_changed_spy), 1)
prj.setLayerOrder([layer2, layer])
self.assertEqual(len(layer_order_changed_spy), 1) # no signal, order not changed
self.assertEqual(prj.layerOrder(), [layer2, layer])
prj.setLayerOrder([layer])
self.assertEqual(prj.layerOrder(), [layer])
self.assertEqual(len(layer_order_changed_spy), 2)
# remove a layer
prj.setLayerOrder([layer2, layer, layer3])
self.assertEqual(len(layer_order_changed_spy), 3)
prj.removeMapLayer(layer)
self.assertEqual(prj.layerOrder(), [layer2, layer3])
self.assertEqual(len(layer_order_changed_spy), 3) # should be no signal
# save and restore
file_name = os.path.join(str(QDir.tempPath()), 'proj.qgs')
prj.setFileName(file_name)
prj.write()
prj2 = QgsProject()
prj2.setFileName(file_name)
prj2.read()
self.assertEqual([l.id() for l in prj2.layerOrder()], [layer2.id(), layer3.id()])
# clear project
prj.clear()
self.assertEqual(prj.layerOrder(), [])
if __name__ == '__main__':
unittest.main()