Skip to content

Commit e79bf3f

Browse files
committed
Add some unit tests for QgsExpressionBuilderWidget
1 parent 878ee5c commit e79bf3f

File tree

5 files changed

+179
-0
lines changed

5 files changed

+179
-0
lines changed

python/gui/qgsexpressionbuilderwidget.sip

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,14 @@ Sets the expression string for the widget
236236
Update the list of function files found at the given path
237237
%End
238238

239+
QStandardItemModel *model();
240+
%Docstring
241+
Returns a pointer to the dialog's function item model.
242+
This method is exposed for testing purposes only - it should not be used to modify the model.
243+
.. versionadded:: 3.0
244+
:rtype: QStandardItemModel
245+
%End
246+
239247
public slots:
240248

241249
void loadSampleValues();

src/gui/qgsexpressionbuilderwidget.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,11 @@ QString QgsExpressionBuilderWidget::formatLayerHelp( const QgsMapLayer *layer )
657657
return text;
658658
}
659659

660+
QStandardItemModel *QgsExpressionBuilderWidget::model()
661+
{
662+
return mModel;
663+
}
664+
660665
void QgsExpressionBuilderWidget::showEvent( QShowEvent *e )
661666
{
662667
QWidget::showEvent( e );

src/gui/qgsexpressionbuilderwidget.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,13 @@ class GUI_EXPORT QgsExpressionBuilderWidget : public QWidget, private Ui::QgsExp
226226
*/
227227
void updateFunctionFileList( const QString &path );
228228

229+
/**
230+
* Returns a pointer to the dialog's function item model.
231+
* This method is exposed for testing purposes only - it should not be used to modify the model.
232+
* \since QGIS 3.0
233+
*/
234+
QStandardItemModel *model();
235+
229236
public slots:
230237

231238
/**

tests/src/python/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ ADD_PYTHON_TEST(PyQgsDistanceArea test_qgsdistancearea.py)
4747
ADD_PYTHON_TEST(PyQgsEditWidgets test_qgseditwidgets.py)
4848
ADD_PYTHON_TEST(PyQgsEllipsoidUtils test_qgsellipsoidutils.py)
4949
ADD_PYTHON_TEST(PyQgsExpression test_qgsexpression.py)
50+
ADD_PYTHON_TEST(PyQgsExpressionBuilderWidget test_qgsexpressionbuilderwidget.py)
5051
ADD_PYTHON_TEST(PyQgsExpressionLineEdit test_qgsexpressionlineedit.py)
5152
ADD_PYTHON_TEST(PyQgsExtentGroupBox test_qgsextentgroupbox.py)
5253
ADD_PYTHON_TEST(PyQgsFeature test_qgsfeature.py)
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
# -*- coding: utf-8 -*-
2+
"""QGIS Unit tests for QgsExpressionBuilderWidget
3+
4+
.. note:: This program is free software; you can redistribute it and/or modify
5+
it under the terms of the GNU General Public License as published by
6+
the Free Software Foundation; either version 2 of the License, or
7+
(at your option) any later version.
8+
"""
9+
__author__ = 'Nyall Dawson'
10+
__date__ = '30/07/2017'
11+
__copyright__ = 'Copyright 2017, The QGIS Project'
12+
# This will get replaced with a git SHA1 when you do a git archive
13+
__revision__ = '$Format:%H$'
14+
15+
import qgis # NOQA
16+
17+
from qgis.PyQt.QtCore import Qt
18+
from qgis.testing import start_app, unittest
19+
from qgis.gui import QgsExpressionBuilderWidget
20+
from qgis.core import (QgsExpressionContext,
21+
QgsExpressionContextScope,
22+
QgsProject,
23+
QgsVectorLayer,
24+
QgsRelation,
25+
QgsFeature,
26+
QgsGeometry)
27+
start_app()
28+
29+
30+
def createReferencingLayer():
31+
layer = QgsVectorLayer("Point?field=fldtxt:string&field=foreignkey:integer",
32+
"referencinglayer", "memory")
33+
pr = layer.dataProvider()
34+
f1 = QgsFeature()
35+
f1.setFields(layer.pendingFields())
36+
f1.setAttributes(["test1", 123])
37+
f2 = QgsFeature()
38+
f2.setFields(layer.pendingFields())
39+
f2.setAttributes(["test2", 123])
40+
f3 = QgsFeature()
41+
f3.setFields(layer.pendingFields())
42+
f3.setAttributes(["foobar'bar", 124])
43+
assert pr.addFeatures([f1, f2, f3])
44+
return layer
45+
46+
47+
def createReferencedLayer():
48+
layer = QgsVectorLayer(
49+
"Point?field=x:string&field=y:integer&field=z:integer",
50+
"referencedlayer", "memory")
51+
pr = layer.dataProvider()
52+
f1 = QgsFeature()
53+
f1.setFields(layer.pendingFields())
54+
f1.setAttributes(["foo", 123, 321])
55+
f2 = QgsFeature()
56+
f2.setFields(layer.pendingFields())
57+
f2.setAttributes(["bar", 456, 654])
58+
f3 = QgsFeature()
59+
f3.setFields(layer.pendingFields())
60+
f3.setAttributes(["foobar'bar", 789, 554])
61+
assert pr.addFeatures([f1, f2, f3])
62+
return layer
63+
64+
65+
class TestQgsExpressionBuilderWidget(unittest.TestCase):
66+
67+
def setUp(self):
68+
self.referencedLayer = createReferencedLayer()
69+
self.referencingLayer = createReferencingLayer()
70+
QgsProject.instance().addMapLayers([self.referencedLayer, self.referencingLayer])
71+
72+
def testFunctionPresent(self):
73+
""" check through widget model to ensure it is initially populated with functions """
74+
w = QgsExpressionBuilderWidget()
75+
m = w.model()
76+
# check that some standard expression functions are shown
77+
items = m.findItems('lower', Qt.MatchRecursive)
78+
self.assertEqual(len(items), 1)
79+
items = m.findItems('upper', Qt.MatchRecursive)
80+
self.assertEqual(len(items), 1)
81+
items = m.findItems('asdasdasda#$@#$', Qt.MatchRecursive)
82+
self.assertEqual(len(items), 0)
83+
84+
def testVariables(self):
85+
""" check through widget model to ensure it is populated with variables """
86+
w = QgsExpressionBuilderWidget()
87+
m = w.model()
88+
89+
s = QgsExpressionContextScope()
90+
s.setVariable('my_var1', 'x')
91+
s.setVariable('my_var2', 'y')
92+
c = QgsExpressionContext()
93+
c.appendScope(s)
94+
95+
# check that variables are added when setting context
96+
w.setExpressionContext(c)
97+
items = m.findItems('my_var1', Qt.MatchRecursive)
98+
self.assertEqual(len(items), 1)
99+
items = m.findItems('my_var2', Qt.MatchRecursive)
100+
self.assertEqual(len(items), 1)
101+
items = m.findItems('not_my_var', Qt.MatchRecursive)
102+
self.assertEqual(len(items), 0)
103+
# double check that functions are still only there once
104+
items = m.findItems('lower', Qt.MatchRecursive)
105+
self.assertEqual(len(items), 1)
106+
items = m.findItems('upper', Qt.MatchRecursive)
107+
self.assertEqual(len(items), 1)
108+
109+
def testLayers(self):
110+
""" check that layers are shown in widget model"""
111+
p = QgsProject.instance()
112+
layer = QgsVectorLayer("Point", "layer1", "memory")
113+
layer2 = QgsVectorLayer("Point", "layer2", "memory")
114+
p.addMapLayers([layer, layer2])
115+
116+
w = QgsExpressionBuilderWidget()
117+
m = w.model()
118+
119+
# check that layers are shown
120+
items = m.findItems('layer1', Qt.MatchRecursive)
121+
self.assertEqual(len(items), 1)
122+
items = m.findItems('layer2', Qt.MatchRecursive)
123+
self.assertEqual(len(items), 1)
124+
125+
def testRelations(self):
126+
""" check that layers are shown in widget model"""
127+
p = QgsProject.instance()
128+
129+
# not valid, but doesn't matter for test....
130+
rel = QgsRelation()
131+
rel.setId('rel1')
132+
rel.setName('Relation Number One')
133+
rel.setReferencingLayer(self.referencingLayer.id())
134+
rel.setReferencedLayer(self.referencedLayer.id())
135+
rel.addFieldPair('foreignkey', 'y')
136+
137+
rel2 = QgsRelation()
138+
rel2.setId('rel2')
139+
rel2.setName('Relation Number Two')
140+
rel2.setReferencingLayer(self.referencingLayer.id())
141+
rel2.setReferencedLayer(self.referencedLayer.id())
142+
rel2.addFieldPair('foreignkey', 'y')
143+
144+
p.relationManager().addRelation(rel)
145+
p.relationManager().addRelation(rel2)
146+
147+
w = QgsExpressionBuilderWidget()
148+
m = w.model()
149+
150+
# check that relations are shown
151+
items = m.findItems('Relation Number One', Qt.MatchRecursive)
152+
self.assertEqual(len(items), 1)
153+
items = m.findItems('Relation Number Two', Qt.MatchRecursive)
154+
self.assertEqual(len(items), 1)
155+
156+
157+
if __name__ == '__main__':
158+
unittest.main()

0 commit comments

Comments
 (0)