1 /***************************************************************************
2 testmaprendererjob.cpp
3 ---------------------
4 begin : November 2013
5 copyright : (C) 2013 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 #include <QObject>
18
19 #include "qgsapplication.h"
20 #include "qgsproject.h"
21 #include "qgsmaprenderercache.h"
22 #include "qgsmaprendererjob.h"
23 #include "qgsvectorlayer.h"
24
25 class TestQgsMapRendererJob : public QObject
26 {
27 Q_OBJECT
28 private slots:
29 void initTestCase();// will be called before the first testfunction is executed.
30 void cleanupTestCase();// will be called after the last testfunction was executed.
31
32 void testNormal();
33
34 void testTwoTimes();
35
36 void testCancelWithoutStart();
37 void testWaitWithoutStart();
38 void testCancelFinished();
39 void testStartWhileRunning();
40 void testDestructWhileRunning();
41
42 void testErrors();
43
44 void testCache();
45
46 private:
47 QStringList mLayerIds;
48 };
49
_loadLayer(QString path)50 static QString _loadLayer( QString path )
51 {
52 QgsMapLayer *layer = new QgsVectorLayer( path, "testlayer", "ogr" );
53 QVERIFY( layer->isValid() );
54 QgsProject::instance()->addMapLayer( layer );
55 return layer->id();
56 }
57
_mapSettings(QStringList layerIds)58 static QgsMapSettings _mapSettings( QStringList layerIds )
59 {
60 QgsMapSettings settings;
61 settings.setLayers( layerIds );
62 settings.setExtent( settings.fullExtent() );
63 settings.setOutputSize( QSize( 512, 512 ) );
64 return settings;
65 }
66
67
initTestCase()68 void TestQgsMapRendererJob::initTestCase()
69 {
70 QgsApplication::init();
71 QgsApplication::initQgis();
72
73 mLayerIds << _loadLayer( "/data/gis/sas/trans-trail-l.dbf" );
74 mLayerIds << _loadLayer( "/data/gis/sas/bnd-ocean-a.shp" );
75 mLayerIds << _loadLayer( "/data/gis/sas/bnd-political-boundary-a.shp" );
76
77 }
78
cleanupTestCase()79 void TestQgsMapRendererJob::cleanupTestCase()
80 {
81 QgsApplication::exitQgis();
82 }
83
testNormal()84 void TestQgsMapRendererJob::testNormal()
85 {
86 QgsMapSettings settings( _mapSettings( mLayerIds ) );
87
88 QImage imgS, imgP;
89
90 QgsMapRendererSequentialJob jobS( settings );
91 QCOMPARE( jobS.isActive(), false );
92 jobS.start();
93 QCOMPARE( jobS.isActive(), true );
94 jobS.waitForFinished();
95 QCOMPARE( jobS.isActive(), false );
96 imgS = jobS.renderedImage();
97
98 //
99
100 QgsMapRendererParallelJob jobP( settings );
101 QCOMPARE( jobP.isActive(), false );
102 jobP.start();
103 QCOMPARE( jobP.isActive(), true );
104 jobP.waitForFinished();
105 QCOMPARE( jobP.isActive(), false );
106 imgP = jobP.renderedImage();
107
108 // TODO: custom painter
109
110 imgS.save( QDir::tempPath() + "/imgS.png" );
111 imgP.save( QDir::tempPath() + "/imgP.png" );
112 //img.save( QDir::tempPath() + "/img5.png");
113
114 QCOMPARE( imgS, imgP );
115 }
116
testTwoTimes()117 void TestQgsMapRendererJob::testTwoTimes()
118 {
119 QgsMapSettings settings( _mapSettings( mLayerIds ) );
120
121 QgsMapRendererSequentialJob job( settings );
122 job.start();
123 job.waitForFinished();
124
125 QImage img1 = job.renderedImage();
126
127 job.start();
128 job.waitForFinished();
129
130 QImage img2 = job.renderedImage();
131
132 QVERIFY( img1 == img2 );
133
134 //
135
136 QgsMapRendererParallelJob jobP( settings );
137 jobP.start();
138 jobP.waitForFinished();
139
140 QImage img3 = jobP.renderedImage();
141
142 jobP.start();
143 jobP.waitForFinished();
144
145 QImage img4 = jobP.renderedImage();
146
147 QVERIFY( img3 == img4 );
148 }
149
150
testCancelWithoutStart()151 void TestQgsMapRendererJob::testCancelWithoutStart()
152 {
153 QgsMapSettings settings( _mapSettings( mLayerIds ) );
154
155 QgsMapRendererSequentialJob job( settings );
156 job.cancel();
157
158 //
159
160 QgsMapRendererParallelJob jobP( settings );
161 jobP.cancel();
162 }
163
testWaitWithoutStart()164 void TestQgsMapRendererJob::testWaitWithoutStart()
165 {
166 QgsMapSettings settings( _mapSettings( mLayerIds ) );
167
168 QgsMapRendererSequentialJob job( settings );
169 job.waitForFinished();
170
171 //
172
173 QgsMapRendererParallelJob jobP( settings );
174 jobP.waitForFinished();
175 }
176
testCancelFinished()177 void TestQgsMapRendererJob::testCancelFinished()
178 {
179 QgsMapSettings settings( _mapSettings( mLayerIds ) );
180
181 QgsMapRendererSequentialJob job( settings );
182 job.start();
183 job.waitForFinished();
184 job.cancel();
185
186 //
187
188 QgsMapRendererParallelJob jobP( settings );
189 jobP.start();
190 jobP.waitForFinished();
191 jobP.cancel();
192 }
193
testStartWhileRunning()194 void TestQgsMapRendererJob::testStartWhileRunning()
195 {
196 QgsMapSettings settings( _mapSettings( mLayerIds ) );
197
198 QgsMapRendererSequentialJob job( settings );
199 job.start();
200 job.start();
201 job.waitForFinished();
202
203 //
204
205 QgsMapRendererParallelJob jobP( settings );
206 jobP.start();
207 jobP.start();
208 jobP.waitForFinished();
209 }
210
testDestructWhileRunning()211 void TestQgsMapRendererJob::testDestructWhileRunning()
212 {
213 QgsMapSettings settings( _mapSettings( mLayerIds ) );
214
215 QgsMapRendererSequentialJob job( settings );
216 job.start();
217
218 //
219
220 QgsMapRendererParallelJob jobP( settings );
221 jobP.start();
222 }
223
testErrors()224 void TestQgsMapRendererJob::testErrors()
225 {
226 QgsVectorLayer *l = new QgsVectorLayer( "/data/gis/sas/trans-trail-l.dbf", "test", "ogr" );
227 QVERIFY( l->isValid() );
228 QgsProject::instance()->addMapLayer( l );
229 QgsMapSettings settings( _mapSettings( QStringList( l->id() ) ) );
230
231 l->setRenderer( nullptr ); // this has to produce an error
232
233 QgsMapRendererSequentialJob job( settings );
234 job.start();
235 job.waitForFinished();
236
237 QCOMPARE( job.errors().count(), 1 );
238 QCOMPARE( job.errors()[0].layerID, l->id() );
239
240 QgsProject::instance()->removeMapLayer( l->id() );
241
242 QString fakeLayerID = "non-existing layer ID";
243 QgsMapSettings settings2( _mapSettings( QStringList( fakeLayerID ) ) );
244
245 QgsMapRendererSequentialJob job2( settings2 );
246 job2.start();
247 job2.waitForFinished();
248
249 QCOMPARE( job2.errors().count(), 1 );
250 QCOMPARE( job2.errors()[0].layerID, fakeLayerID );
251 }
252
testCache()253 void TestQgsMapRendererJob::testCache()
254 {
255 QgsVectorLayer *l = new QgsVectorLayer( "/data/gis/sas/trans-trail-l.dbf", "test", "ogr" );
256 QVERIFY( l->isValid() );
257 QgsProject::instance()->addMapLayer( l );
258 QgsMapSettings settings( _mapSettings( QStringList( l->id() ) ) );
259
260 QgsMapRendererCache cache;
261
262 QgsMapRendererSequentialJob job( settings );
263 job.setCache( &cache );
264
265 QTime t;
266 t.start();
267 job.start();
268 job.waitForFinished();
269 int timeNotCachedMS = t.elapsed();
270
271 QImage i1 = job.renderedImage();
272
273 QgsMapRendererSequentialJob job2( settings );
274 job2.setCache( &cache );
275
276 t.start();
277 job2.start();
278 job2.waitForFinished();
279 int timeCachedMS = t.elapsed();
280
281 QImage i2 = job2.renderedImage();
282
283 QCOMPARE( i1, i2 );
284 QVERIFY( timeNotCachedMS > 100 );
285 QVERIFY( timeCachedMS < 10 );
286 qDebug( "CACHING %d vs %d (ms)", timeNotCachedMS, timeCachedMS );
287
288 QgsProject::instance()->removeMapLayer( l->id() );
289 }
290
291
292 QGSTEST_MAIN( TestQgsMapRendererJob )
293 #include "testmaprendererjob.moc"
294