Skip to content

Commit 1c202e7

Browse files
committedMar 29, 2017
Added unit testing for the new node tool
1 parent bd5799b commit 1c202e7

File tree

4 files changed

+370
-19
lines changed

4 files changed

+370
-19
lines changed
 

‎src/app/nodetool/qgsnodetool2.cpp

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -343,16 +343,6 @@ void QgsNodeTool2::deactivate()
343343
QgsMapToolAdvancedDigitizing::deactivate();
344344
}
345345

346-
bool QgsNodeTool2::canUseCurrentLayer()
347-
{
348-
if ( QgsVectorLayer* layer = qobject_cast<QgsVectorLayer*>( canvas()->currentLayer() ) )
349-
{
350-
if ( layer->isEditable() )
351-
return true;
352-
}
353-
return false;
354-
}
355-
356346
void QgsNodeTool2::addDragBand( const QgsPoint &v1, const QgsPoint &v2 )
357347
{
358348
QgsRubberBand* dragBand = createRubberBand( QgsWkbTypes::LineGeometry, true );
@@ -372,9 +362,6 @@ void QgsNodeTool2::clearDragBands()
372362

373363
void QgsNodeTool2::cadCanvasPressEvent( QgsMapMouseEvent *e )
374364
{
375-
if ( !canUseCurrentLayer() )
376-
return;
377-
378365
setHighlightedNodes( QList<Vertex>() ); // reset selection
379366

380367
if ( e->button() == Qt::LeftButton )
@@ -399,9 +386,6 @@ void QgsNodeTool2::cadCanvasPressEvent( QgsMapMouseEvent *e )
399386

400387
void QgsNodeTool2::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
401388
{
402-
if ( !canUseCurrentLayer() )
403-
return;
404-
405389
if ( mNewVertexFromDoubleClick )
406390
{
407391
QgsPointLocator::Match m( *mNewVertexFromDoubleClick );

‎src/app/nodetool/qgsnodetool2.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include <memory>
2020

21+
#include "qgis_app.h"
2122
#include "qgsmaptooladvanceddigitizing.h"
2223

2324
class QRubberBand;
@@ -63,7 +64,7 @@ struct Edge
6364

6465

6566

66-
class QgsNodeTool2 : public QgsMapToolAdvancedDigitizing
67+
class APP_EXPORT QgsNodeTool2 : public QgsMapToolAdvancedDigitizing
6768
{
6869
Q_OBJECT
6970
public:
@@ -96,8 +97,6 @@ class QgsNodeTool2 : public QgsMapToolAdvancedDigitizing
9697

9798
private:
9899

99-
bool canUseCurrentLayer();
100-
101100
void addDragBand( const QgsPoint& v1, const QgsPoint& v2 );
102101

103102
void clearDragBands();

‎tests/src/app/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,4 +114,5 @@ ADD_QGIS_TEST(fieldcalculatortest testqgsfieldcalculator.cpp)
114114
ADD_QGIS_TEST(maptoolidentifyaction testqgsmaptoolidentifyaction.cpp)
115115
ADD_QGIS_TEST(maptoolselect testqgsmaptoolselect.cpp)
116116
ADD_QGIS_TEST(measuretool testqgsmeasuretool.cpp)
117+
ADD_QGIS_TEST(nodetool testqgsnodetool.cpp)
117118
ADD_QGIS_TEST(vectorlayersaveasdialogtest testqgsvectorlayersaveasdialog.cpp)

‎tests/src/app/testqgsnodetool.cpp

Lines changed: 367 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,367 @@
1+
/***************************************************************************
2+
testqgsnodetool.cpp
3+
----------------------
4+
Date : 2017-03-01
5+
Copyright : (C) 2017 by Martin Dobias
6+
Email : wonder dot sk at gmail dot com
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#include "qgstest.h"
17+
18+
#include "qgsadvanceddigitizingdockwidget.h"
19+
#include "qgsgeometry.h"
20+
#include "qgsmapcanvas.h"
21+
#include "qgsproject.h"
22+
#include "qgsvectorlayer.h"
23+
24+
#include "nodetool/qgsnodetool2.h"
25+
26+
bool operator==( const QgsGeometry& g1, const QgsGeometry& g2 )
27+
{
28+
return g1.isGeosEqual( g2 );
29+
}
30+
31+
namespace QTest
32+
{
33+
// pretty printing of geometries in comparison tests
34+
template<> char *toString( const QgsGeometry& geom )
35+
{
36+
QByteArray ba = geom.exportToWkt().toAscii();
37+
return qstrdup( ba.data() );
38+
}
39+
}
40+
41+
/** \ingroup UnitTests
42+
* This is a unit test for the node tool
43+
*/
44+
class TestQgsNodeTool : public QObject
45+
{
46+
Q_OBJECT
47+
public:
48+
TestQgsNodeTool();
49+
50+
private slots:
51+
void initTestCase();// will be called before the first testfunction is executed.
52+
void cleanupTestCase();// will be called after the last testfunction was executed.
53+
54+
void testMoveVertex();
55+
void testMoveEdge();
56+
void testAddVertex();
57+
void testDeleteVertex();
58+
59+
private:
60+
QPoint mapToScreen( double mapX, double mapY )
61+
{
62+
QgsPoint pt = mCanvas->mapSettings().mapToPixel().transform( mapX, mapY );
63+
return QPoint( qRound( pt.x() ), qRound( pt.y() ) );
64+
}
65+
66+
void mouseClick( double mapX, double mapY, Qt::MouseButton button, Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers() )
67+
{
68+
QgsMapMouseEvent e1( mCanvas, QEvent::MouseButtonPress, mapToScreen( mapX, mapY ), button, button, stateKey );
69+
mNodeTool->cadCanvasPressEvent( &e1 );
70+
71+
QgsMapMouseEvent e2( mCanvas, QEvent::MouseButtonRelease, mapToScreen( mapX, mapY ), button, Qt::MouseButton(), stateKey );
72+
mNodeTool->cadCanvasReleaseEvent( &e2 );
73+
}
74+
75+
void keyClick( int key )
76+
{
77+
QKeyEvent e1( QEvent::KeyPress, key, Qt::KeyboardModifiers() );
78+
mNodeTool->keyPressEvent( &e1 );
79+
80+
QKeyEvent e2( QEvent::KeyRelease, key, Qt::KeyboardModifiers() );
81+
mNodeTool->keyReleaseEvent( &e2 );
82+
}
83+
84+
private:
85+
QgsMapCanvas* mCanvas = nullptr;
86+
QgsAdvancedDigitizingDockWidget* mAdvancedDigitizingDockWidget = nullptr;
87+
QgsNodeTool2* mNodeTool = nullptr;
88+
QgsVectorLayer* mLayerLine = nullptr;
89+
QgsVectorLayer* mLayerPolygon = nullptr;
90+
QgsVectorLayer* mLayerPoint = nullptr;
91+
QgsFeatureId mFidLineF1 = 0;
92+
QgsFeatureId mFidPolygonF1 = 0;
93+
QgsFeatureId mFidPointF1 = 0;
94+
};
95+
96+
TestQgsNodeTool::TestQgsNodeTool()
97+
: mCanvas( nullptr )
98+
{
99+
}
100+
101+
102+
//runs before all tests
103+
void TestQgsNodeTool::initTestCase()
104+
{
105+
qDebug() << "TestQgisAppClipboard::initTestCase()";
106+
// init QGIS's paths - true means that all path will be inited from prefix
107+
QgsApplication::init();
108+
QgsApplication::initQgis();
109+
110+
// Set up the QSettings environment
111+
QCoreApplication::setOrganizationName( QStringLiteral( "QGIS" ) );
112+
QCoreApplication::setOrganizationDomain( QStringLiteral( "qgis.org" ) );
113+
QCoreApplication::setApplicationName( QStringLiteral( "QGIS-TEST" ) );
114+
115+
mCanvas = new QgsMapCanvas();
116+
117+
mAdvancedDigitizingDockWidget = new QgsAdvancedDigitizingDockWidget( mCanvas );
118+
119+
// make testing layers
120+
mLayerLine = new QgsVectorLayer( "LineString?crs=EPSG:27700", "layer line", "memory" );
121+
QVERIFY( mLayerLine->isValid() );
122+
mLayerPolygon = new QgsVectorLayer( "Polygon?crs=EPSG:27700", "layer polygon", "memory" );
123+
QVERIFY( mLayerPolygon->isValid() );
124+
mLayerPoint = new QgsVectorLayer( "Point?crs=EPSG:27700", "layer point", "memory" );
125+
QVERIFY( mLayerPoint->isValid() );
126+
QgsProject::instance()->addMapLayers( QList<QgsMapLayer*>() << mLayerLine << mLayerPolygon << mLayerPoint );
127+
128+
QgsPolyline line1;
129+
line1 << QgsPoint( 2, 1 ) << QgsPoint( 1, 1 ) << QgsPoint( 1, 3 );
130+
QgsFeature lineF1;
131+
lineF1.setGeometry( QgsGeometry::fromPolyline( line1 ) );
132+
133+
QgsPolygon polygon1;
134+
QgsPolyline polygon1exterior;
135+
polygon1exterior << QgsPoint( 4, 1 ) << QgsPoint( 7, 1 ) << QgsPoint( 7, 4 ) << QgsPoint( 4, 4 ) << QgsPoint( 4, 1 );
136+
polygon1 << polygon1exterior;
137+
QgsFeature polygonF1;
138+
polygonF1.setGeometry( QgsGeometry::fromPolygon( polygon1 ) );
139+
140+
QgsFeature pointF1;
141+
pointF1.setGeometry( QgsGeometry::fromPoint( QgsPoint( 2, 3 ) ) );
142+
143+
mLayerLine->startEditing();
144+
mLayerLine->addFeature( lineF1 );
145+
mFidLineF1 = lineF1.id();
146+
QCOMPARE( mLayerLine->featureCount(), ( long )1 );
147+
148+
mLayerPolygon->startEditing();
149+
mLayerPolygon->addFeature( polygonF1 );
150+
mFidPolygonF1 = polygonF1.id();
151+
QCOMPARE( mLayerPolygon->featureCount(), ( long )1 );
152+
153+
mLayerPoint->startEditing();
154+
mLayerPoint->addFeature( pointF1 );
155+
mFidPointF1 = pointF1.id();
156+
QCOMPARE( mLayerPoint->featureCount(), ( long )1 );
157+
158+
// just one added feature in each undo stack
159+
QCOMPARE( mLayerLine->undoStack()->index(), 1 );
160+
QCOMPARE( mLayerPolygon->undoStack()->index(), 1 );
161+
QCOMPARE( mLayerPoint->undoStack()->index(), 1 );
162+
163+
mCanvas->setFrameStyle( QFrame::NoFrame );
164+
mCanvas->resize( 512, 512 );
165+
mCanvas->setExtent( QgsRectangle( 0, 0, 8, 8 ) );
166+
mCanvas->show(); // to make the canvas resize
167+
mCanvas->hide();
168+
QCOMPARE( mCanvas->mapSettings().outputSize(), QSize( 512, 512 ) );
169+
QCOMPARE( mCanvas->mapSettings().visibleExtent(), QgsRectangle( 0, 0, 8, 8 ) );
170+
171+
mCanvas->setLayers( QList<QgsMapLayer*>() << mLayerLine << mLayerPolygon << mLayerPoint );
172+
173+
// TODO: set up snapping
174+
175+
// create node tool
176+
mNodeTool = new QgsNodeTool2( mCanvas, mAdvancedDigitizingDockWidget );
177+
178+
mCanvas->setMapTool( mNodeTool );
179+
}
180+
181+
//runs after all tests
182+
void TestQgsNodeTool::cleanupTestCase()
183+
{
184+
delete mNodeTool;
185+
delete mAdvancedDigitizingDockWidget;
186+
delete mCanvas;
187+
QgsApplication::exitQgis();
188+
}
189+
190+
191+
void TestQgsNodeTool::testMoveVertex()
192+
{
193+
// move vertex of linestring
194+
195+
mouseClick( 2, 1, Qt::LeftButton );
196+
mouseClick( 2, 2, Qt::LeftButton );
197+
198+
QCOMPARE( mLayerLine->undoStack()->index(), 2 );
199+
QCOMPARE( mLayerLine->getFeature( mFidLineF1 ).geometry(), QgsGeometry::fromWkt( "LINESTRING(2 2, 1 1, 1 3)" ) );
200+
201+
mLayerLine->undoStack()->undo();
202+
QCOMPARE( mLayerLine->undoStack()->index(), 1 );
203+
204+
QCOMPARE( mLayerLine->getFeature( mFidLineF1 ).geometry(), QgsGeometry::fromWkt( "LINESTRING(2 1, 1 1, 1 3)" ) );
205+
206+
mouseClick( 1, 1, Qt::LeftButton );
207+
mouseClick( 0.5, 0.5, Qt::LeftButton );
208+
209+
QCOMPARE( mLayerLine->undoStack()->index(), 2 );
210+
QCOMPARE( mLayerLine->getFeature( mFidLineF1 ).geometry(), QgsGeometry::fromWkt( "LINESTRING(2 1, 0.5 0.5, 1 3)" ) );
211+
212+
mLayerLine->undoStack()->undo();
213+
214+
// move point
215+
216+
mouseClick( 2, 3, Qt::LeftButton );
217+
mouseClick( 1, 4, Qt::LeftButton );
218+
219+
QCOMPARE( mLayerPoint->undoStack()->index(), 2 );
220+
QCOMPARE( mLayerPoint->getFeature( mFidPointF1 ).geometry(), QgsGeometry::fromWkt( "POINT(1 4)" ) );
221+
222+
mLayerPoint->undoStack()->undo();
223+
224+
QCOMPARE( mLayerPoint->getFeature( mFidPointF1 ).geometry(), QgsGeometry::fromWkt( "POINT(2 3)" ) );
225+
226+
// move vertex of polygon
227+
228+
mouseClick( 4, 1, Qt::LeftButton );
229+
mouseClick( 5, 2, Qt::LeftButton );
230+
231+
QCOMPARE( mLayerPolygon->undoStack()->index(), 2 );
232+
QCOMPARE( mLayerPolygon->getFeature( mFidPolygonF1 ).geometry(), QgsGeometry::fromWkt( "POLYGON((5 2, 7 1, 7 4, 4 4, 5 2))" ) );
233+
234+
mLayerPolygon->undoStack()->undo();
235+
236+
QCOMPARE( mLayerPolygon->getFeature( mFidPolygonF1 ).geometry(), QgsGeometry::fromWkt( "POLYGON((4 1, 7 1, 7 4, 4 4, 4 1))" ) );
237+
238+
mouseClick( 4, 4, Qt::LeftButton );
239+
mouseClick( 5, 5, Qt::LeftButton );
240+
241+
QCOMPARE( mLayerPolygon->undoStack()->index(), 2 );
242+
QCOMPARE( mLayerPolygon->getFeature( mFidPolygonF1 ).geometry(), QgsGeometry::fromWkt( "POLYGON((4 1, 7 1, 7 4, 5 5, 4 1))" ) );
243+
244+
mLayerPolygon->undoStack()->undo();
245+
246+
QCOMPARE( mLayerPolygon->getFeature( mFidPolygonF1 ).geometry(), QgsGeometry::fromWkt( "POLYGON((4 1, 7 1, 7 4, 4 4, 4 1))" ) );
247+
248+
// cancel moving of a linestring with right mouse button
249+
mouseClick( 2, 1, Qt::LeftButton );
250+
mouseClick( 2, 2, Qt::RightButton );
251+
252+
QCOMPARE( mLayerLine->undoStack()->index(), 1 );
253+
QCOMPARE( mLayerLine->getFeature( mFidLineF1 ).geometry(), QgsGeometry::fromWkt( "LINESTRING(2 1, 1 1, 1 3)" ) );
254+
255+
// clicks somewhere away from features - should do nothing
256+
mouseClick( 2, 2, Qt::LeftButton );
257+
mouseClick( 2, 4, Qt::LeftButton );
258+
259+
// no other unexpected changes happened
260+
QCOMPARE( mLayerLine->undoStack()->index(), 1 );
261+
QCOMPARE( mLayerPolygon->undoStack()->index(), 1 );
262+
QCOMPARE( mLayerPoint->undoStack()->index(), 1 );
263+
}
264+
265+
void TestQgsNodeTool::testMoveEdge()
266+
{
267+
// move edge of linestring
268+
269+
mouseClick( 1.2, 1, Qt::LeftButton );
270+
mouseClick( 1.2, 2, Qt::LeftButton );
271+
272+
QCOMPARE( mLayerLine->undoStack()->index(), 2 );
273+
QCOMPARE( mLayerLine->getFeature( mFidLineF1 ).geometry(), QgsGeometry::fromWkt( "LINESTRING(2 2, 1 2, 1 3)" ) );
274+
275+
mLayerLine->undoStack()->undo();
276+
QCOMPARE( mLayerLine->undoStack()->index(), 1 );
277+
278+
QCOMPARE( mLayerLine->getFeature( mFidLineF1 ).geometry(), QgsGeometry::fromWkt( "LINESTRING(2 1, 1 1, 1 3)" ) );
279+
280+
// move edge of polygon
281+
282+
mouseClick( 5, 1, Qt::LeftButton );
283+
mouseClick( 6, 1, Qt::LeftButton );
284+
285+
QCOMPARE( mLayerPolygon->undoStack()->index(), 2 );
286+
QCOMPARE( mLayerPolygon->getFeature( mFidPolygonF1 ).geometry(), QgsGeometry::fromWkt( "POLYGON((5 1, 8 1, 7 4, 4 4, 5 1))" ) );
287+
288+
mLayerPolygon->undoStack()->undo();
289+
290+
QCOMPARE( mLayerPolygon->getFeature( mFidPolygonF1 ).geometry(), QgsGeometry::fromWkt( "POLYGON((4 1, 7 1, 7 4, 4 4, 4 1))" ) );
291+
292+
// no other unexpected changes happened
293+
QCOMPARE( mLayerLine->undoStack()->index(), 1 );
294+
QCOMPARE( mLayerPolygon->undoStack()->index(), 1 );
295+
QCOMPARE( mLayerPoint->undoStack()->index(), 1 );
296+
}
297+
298+
299+
void TestQgsNodeTool::testAddVertex()
300+
{
301+
// add vertex in linestring
302+
303+
mouseClick( 1.5, 1, Qt::LeftButton );
304+
mouseClick( 1.5, 2, Qt::LeftButton );
305+
306+
QCOMPARE( mLayerLine->undoStack()->index(), 2 );
307+
QCOMPARE( mLayerLine->getFeature( mFidLineF1 ).geometry(), QgsGeometry::fromWkt( "LINESTRING(2 1, 1.5 2, 1 1, 1 3)" ) );
308+
309+
mLayerLine->undoStack()->undo();
310+
QCOMPARE( mLayerLine->undoStack()->index(), 1 );
311+
312+
QCOMPARE( mLayerLine->getFeature( mFidLineF1 ).geometry(), QgsGeometry::fromWkt( "LINESTRING(2 1, 1 1, 1 3)" ) );
313+
314+
// add vertex in polygon
315+
316+
mouseClick( 4, 2.5, Qt::LeftButton );
317+
mouseClick( 3, 2.5, Qt::LeftButton );
318+
319+
QCOMPARE( mLayerPolygon->undoStack()->index(), 2 );
320+
QCOMPARE( mLayerPolygon->getFeature( mFidPolygonF1 ).geometry(), QgsGeometry::fromWkt( "POLYGON((4 1, 7 1, 7 4, 4 4, 3 2.5, 4 1))" ) );
321+
322+
mLayerPolygon->undoStack()->undo();
323+
324+
QCOMPARE( mLayerPolygon->getFeature( mFidPolygonF1 ).geometry(), QgsGeometry::fromWkt( "POLYGON((4 1, 7 1, 7 4, 4 4, 4 1))" ) );
325+
326+
// no other unexpected changes happened
327+
QCOMPARE( mLayerLine->undoStack()->index(), 1 );
328+
QCOMPARE( mLayerPolygon->undoStack()->index(), 1 );
329+
QCOMPARE( mLayerPoint->undoStack()->index(), 1 );
330+
}
331+
332+
333+
void TestQgsNodeTool::testDeleteVertex()
334+
{
335+
// delete vertex in linestring
336+
337+
mouseClick( 1, 1, Qt::LeftButton );
338+
keyClick( Qt::Key_Delete );
339+
340+
QCOMPARE( mLayerLine->undoStack()->index(), 2 );
341+
QCOMPARE( mLayerLine->getFeature( mFidLineF1 ).geometry(), QgsGeometry::fromWkt( "LINESTRING(2 1, 1 3)" ) );
342+
343+
mLayerLine->undoStack()->undo();
344+
QCOMPARE( mLayerLine->undoStack()->index(), 1 );
345+
346+
QCOMPARE( mLayerLine->getFeature( mFidLineF1 ).geometry(), QgsGeometry::fromWkt( "LINESTRING(2 1, 1 1, 1 3)" ) );
347+
348+
// delete vertex in polygon
349+
350+
mouseClick( 7, 4, Qt::LeftButton );
351+
keyClick( Qt::Key_Delete );
352+
353+
QCOMPARE( mLayerPolygon->undoStack()->index(), 2 );
354+
QCOMPARE( mLayerPolygon->getFeature( mFidPolygonF1 ).geometry(), QgsGeometry::fromWkt( "POLYGON((4 1, 7 1, 4 4, 4 1))" ) );
355+
356+
mLayerPolygon->undoStack()->undo();
357+
358+
QCOMPARE( mLayerPolygon->getFeature( mFidPolygonF1 ).geometry(), QgsGeometry::fromWkt( "POLYGON((4 1, 7 1, 7 4, 4 4, 4 1))" ) );
359+
360+
// no other unexpected changes happened
361+
QCOMPARE( mLayerLine->undoStack()->index(), 1 );
362+
QCOMPARE( mLayerPolygon->undoStack()->index(), 1 );
363+
QCOMPARE( mLayerPoint->undoStack()->index(), 1 );
364+
}
365+
366+
QGSTEST_MAIN( TestQgsNodeTool )
367+
#include "testqgsnodetool.moc"

0 commit comments

Comments
 (0)
Please sign in to comment.