Skip to content

Commit 90b10f7

Browse files
committed
Fix unit tests
- QgsFeature owns QgsFields (otherwise the assigned QgsFields may get deleted) - updated QgsRenderChecker to use map settings + map renderer job - fixed DPI issue in map renderer to map settings conversion - fixed vector layer cache (failing file operations) There are still few tests that keep failing compared to master branch, but the reason for failure are tiny pixel diffs and we should probably just update the expected images.
1 parent 151bad5 commit 90b10f7

13 files changed

+110
-77
lines changed

python/core/qgsrenderchecker.sip

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ class QgsRenderChecker
3232
QString imageToHash( QString theImageFile );
3333

3434
void setRenderedImage( QString theImageFileName );
35-
void setMapRenderer( QgsMapRenderer * thepMapRenderer );
35+
void setMapRenderer( QgsMapRenderer * thepMapRenderer ) /Deprecated/;
36+
void setMapSettings( const QgsMapSettings& mapSettings );
3637
bool runTest( QString theTestName, unsigned int theMismatchCount = 0 );
3738

3839
bool compareImages( QString theTestName, unsigned int theMismatchCount = 0, QString theRenderedImageFile = "" );

src/core/qgsfeature.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ QgsFeature::QgsFeature( QgsFeatureId id )
2929
, mGeometry( 0 )
3030
, mOwnsGeometry( 0 )
3131
, mValid( false )
32-
, mFields( 0 )
3332
{
3433
// NOOP
3534
}
@@ -39,7 +38,7 @@ QgsFeature::QgsFeature( const QgsFields &fields, QgsFeatureId id )
3938
, mGeometry( 0 )
4039
, mOwnsGeometry( 0 )
4140
, mValid( false )
42-
, mFields( &fields )
41+
, mFields( fields )
4342
{
4443
initAttributes( fields.count() );
4544
}
@@ -161,7 +160,7 @@ void QgsFeature::setGeometryAndOwnership( unsigned char *geom, size_t length )
161160

162161
void QgsFeature::setFields( const QgsFields* fields, bool init )
163162
{
164-
mFields = fields;
163+
mFields = *fields;
165164
if ( init )
166165
{
167166
initAttributes( fields->count() );
@@ -239,12 +238,9 @@ QVariant QgsFeature::attribute( const QString& name ) const
239238

240239
int QgsFeature::fieldNameIndex( const QString& fieldName ) const
241240
{
242-
if ( !mFields )
243-
return -1;
244-
245-
for ( int i = 0; i < mFields->count(); ++i )
241+
for ( int i = 0; i < mFields.count(); ++i )
246242
{
247-
if ( QString::compare( mFields->at( i ).name(), fieldName, Qt::CaseInsensitive ) == 0 )
243+
if ( QString::compare( mFields.at( i ).name(), fieldName, Qt::CaseInsensitive ) == 0 )
248244
{
249245
return i;
250246
}

src/core/qgsfeature.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ typedef QVector<QVariant> QgsAttributes;
102102
class QgsField;
103103
typedef QMap<int, QgsField> QgsFieldMap;
104104

105-
105+
#include "qgsfield.h"
106106

107107

108108
/** \ingroup core
@@ -221,13 +221,17 @@ class CORE_EXPORT QgsFeature
221221
* C++: Defaults to false
222222
* Python: Defaults to true
223223
* @note added in 2.0
224+
*
225+
* TODO: QGIS3 - take reference, not pointer
224226
*/
225227
void setFields( const QgsFields* fields, bool initAttributes = false );
226228

227-
/** Get associated field map. may be NULL
229+
/** Get associated field map.
228230
* @note added in 2.0
231+
*
232+
* TODO: QGIS 3 - return reference or value, not pointer
229233
*/
230-
const QgsFields* fields() const { return mFields; }
234+
const QgsFields* fields() const { return &mFields; }
231235

232236
/** Insert a value into attribute. Returns false if attribute name could not be converted to index.
233237
* Field map must be associated to make this work.
@@ -308,7 +312,7 @@ class CORE_EXPORT QgsFeature
308312
bool mValid;
309313

310314
//! Optional field map for name-based attribute lookups
311-
const QgsFields* mFields;
315+
QgsFields mFields;
312316

313317
}; // class QgsFeature
314318

src/core/qgsmaprenderer.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1070,12 +1070,14 @@ QgsMapRenderer::BlendMode QgsMapRenderer::getBlendModeEnum( const QPainter::Comp
10701070
}
10711071
}
10721072

1073+
Q_GUI_EXPORT extern int qt_defaultDpiX();
1074+
10731075
const QgsMapSettings& QgsMapRenderer::mapSettings()
10741076
{
10751077
// make sure the settings object is up-to-date
10761078
mMapSettings.setExtent( extent() );
10771079
mMapSettings.setOutputSize( outputSize() );
1078-
mMapSettings.setOutputDpi( outputDpi() );
1080+
mMapSettings.setOutputDpi( outputDpi() != 0 ? outputDpi() : qt_defaultDpiX() );
10791081
mMapSettings.setLayers( layerSet() );
10801082
mMapSettings.setCrsTransformEnabled( hasCrsTransformEnabled() );
10811083
mMapSettings.setDestinationCrs( destinationCrs() );

src/core/qgsrenderchecker.cpp

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
***************************************************************************/
1515

1616
#include "qgsrenderchecker.h"
17+
1718
#include "qgis.h"
19+
#include "qgsmaprendererjob.h"
1820

1921
#include <QColor>
2022
#include <QPainter>
@@ -33,7 +35,6 @@ QgsRenderChecker::QgsRenderChecker( ) :
3335
mMatchTarget( 0 ),
3436
mElapsedTime( 0 ),
3537
mElapsedTimeTarget( 0 ),
36-
mpMapRenderer( NULL ),
3738
mControlPathPrefix( "" )
3839
{
3940

@@ -67,6 +68,16 @@ QString QgsRenderChecker::imageToHash( QString theImageFile )
6768
return myHash.result().toHex().constData();
6869
}
6970

71+
void QgsRenderChecker::setMapRenderer( QgsMapRenderer* thepMapRenderer )
72+
{
73+
mMapSettings = thepMapRenderer->mapSettings();
74+
}
75+
76+
void QgsRenderChecker::setMapSettings( const QgsMapSettings& mapSettings )
77+
{
78+
mMapSettings = mapSettings;
79+
}
80+
7081
bool QgsRenderChecker::isKnownAnomaly( QString theDiffImageFile )
7182
{
7283
QString myControlImageDir = controlImagePath() + mControlName
@@ -138,44 +149,45 @@ bool QgsRenderChecker::runTest( QString theTestName,
138149
//
139150
// Now render our layers onto a pixmap
140151
//
141-
QImage myImage( myExpectedImage.width(),
142-
myExpectedImage.height(),
143-
QImage::Format_RGB32 );
144-
myImage.setDotsPerMeterX( myExpectedImage.dotsPerMeterX() );
145-
myImage.setDotsPerMeterY( myExpectedImage.dotsPerMeterY() );
146-
myImage.fill( qRgb( 152, 219, 249 ) );
147-
QPainter myPainter( &myImage );
148-
myPainter.setRenderHint( QPainter::Antialiasing );
149-
mpMapRenderer->setOutputSize( QSize(
150-
myExpectedImage.width(),
151-
myExpectedImage.height() ),
152-
myExpectedImage.logicalDpiX() );
152+
mMapSettings.setBackgroundColor( qRgb( 152, 219, 249 ) );
153+
mMapSettings.setFlag( QgsMapSettings::Antialiasing );
154+
mMapSettings.setOutputSize( QSize( myExpectedImage.width(), myExpectedImage.height() ) );
155+
153156
QTime myTime;
154157
myTime.start();
155-
mpMapRenderer->render( &myPainter );
158+
159+
QgsMapRendererSequentialJob job( mMapSettings );
160+
job.start();
161+
job.waitForFinished();
162+
156163
mElapsedTime = myTime.elapsed();
157-
myPainter.end();
164+
165+
QImage myImage = job.renderedImage();
166+
158167
//
159168
// Save the pixmap to disk so the user can make a
160169
// visual assessment if needed
161170
//
162171
mRenderedImageFile = QDir::tempPath() + QDir::separator() +
163172
theTestName + "_result.png";
173+
174+
myImage.setDotsPerMeterX( myExpectedImage.dotsPerMeterX() );
175+
myImage.setDotsPerMeterY( myExpectedImage.dotsPerMeterY() );
164176
myImage.save( mRenderedImageFile, "PNG", 100 );
165177

166178
//create a world file to go with the image...
167179

168180
QFile wldFile( QDir::tempPath() + QDir::separator() + theTestName + "_result.wld" );
169181
if ( wldFile.open( QIODevice::WriteOnly ) )
170182
{
171-
QgsRectangle r = mpMapRenderer->extent();
183+
QgsRectangle r = mMapSettings.extent();
172184

173185
QTextStream stream( &wldFile );
174186
stream << QString( "%1\r\n0 \r\n0 \r\n%2\r\n%3\r\n%4\r\n" )
175-
.arg( qgsDoubleToString( mpMapRenderer->mapUnitsPerPixel() ) )
176-
.arg( qgsDoubleToString( -mpMapRenderer->mapUnitsPerPixel() ) )
177-
.arg( qgsDoubleToString( r.xMinimum() + mpMapRenderer->mapUnitsPerPixel() / 2.0 ) )
178-
.arg( qgsDoubleToString( r.yMaximum() - mpMapRenderer->mapUnitsPerPixel() / 2.0 ) );
187+
.arg( qgsDoubleToString( mMapSettings.mapUnitsPerPixel() ) )
188+
.arg( qgsDoubleToString( -mMapSettings.mapUnitsPerPixel() ) )
189+
.arg( qgsDoubleToString( r.xMinimum() + mMapSettings.mapUnitsPerPixel() / 2.0 ) )
190+
.arg( qgsDoubleToString( r.yMaximum() - mMapSettings.mapUnitsPerPixel() / 2.0 ) );
179191
}
180192

181193
return compareImages( theTestName, theMismatchCount );

src/core/qgsrenderchecker.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#include <qgsmaprenderer.h>
2626
#include <qgslogger.h>
27+
#include <qgsmapsettings.h>
2728

2829
class QImage;
2930

@@ -67,7 +68,12 @@ class CORE_EXPORT QgsRenderChecker
6768
QString imageToHash( QString theImageFile );
6869

6970
void setRenderedImage( QString theImageFileName ) { mRenderedImageFile = theImageFileName; };
70-
void setMapRenderer( QgsMapRenderer * thepMapRenderer ) { mpMapRenderer = thepMapRenderer; };
71+
//! @deprecated since 2.1 - use setMapSettings()
72+
Q_DECL_DEPRECATED void setMapRenderer( QgsMapRenderer * thepMapRenderer );
73+
74+
//! @note added in 2.1
75+
void setMapSettings( const QgsMapSettings& mapSettings );
76+
7177
/**
7278
* Test using renderer to generate the image to be compared.
7379
* @param theTestName - to be used as the basis for writing a file to
@@ -111,7 +117,7 @@ class CORE_EXPORT QgsRenderChecker
111117
unsigned int mMatchTarget;
112118
int mElapsedTime;
113119
int mElapsedTimeTarget;
114-
QgsMapRenderer * mpMapRenderer;
120+
QgsMapSettings mMapSettings;
115121
QString mControlPathPrefix;
116122

117123
}; // class QgsRenderChecker

tests/src/core/testqgsblendmodes.cpp

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#include <QPainter>
2222

2323
//qgis includes...
24-
#include <qgsmaprenderer.h>
24+
#include <qgsmapsettings.h>
2525
#include <qgsmaplayer.h>
2626
#include <qgsvectorlayer.h>
2727
#include <qgsapplication.h>
@@ -50,7 +50,7 @@ class TestQgsBlendModes: public QObject
5050
void rasterBlending();
5151
private:
5252
bool imageCheck( QString theType ); //as above
53-
QgsMapRenderer * mpMapRenderer;
53+
QgsMapSettings mMapSettings;
5454
QgsMapLayer * mpPointsLayer;
5555
QgsMapLayer * mpPolysLayer;
5656
QgsVectorLayer * mpLinesLayer;
@@ -109,8 +109,6 @@ void TestQgsBlendModes::initTestCase()
109109
QList<QgsMapLayer *>() << mRasterLayer1 );
110110
QgsMapLayerRegistry::instance()->addMapLayers(
111111
QList<QgsMapLayer *>() << mRasterLayer2 );
112-
113-
mpMapRenderer = new QgsMapRenderer();
114112
}
115113
void TestQgsBlendModes::cleanupTestCase()
116114
{
@@ -123,17 +121,19 @@ void TestQgsBlendModes::vectorBlending()
123121
QStringList myLayers;
124122
myLayers << mpLinesLayer->id();
125123
myLayers << mpPolysLayer->id();
126-
mpMapRenderer->setLayerSet( myLayers );
124+
mMapSettings.setLayers( myLayers );
127125

128126
//Set blending modes for both layers
129127
mpLinesLayer->setBlendMode( QPainter::CompositionMode_Difference );
130128
mpPolysLayer->setBlendMode( QPainter::CompositionMode_Difference );
131-
mpMapRenderer->setExtent( mpPointsLayer->extent() );
132-
QVERIFY( imageCheck( "vector_blendmodes" ) );
129+
mMapSettings.setExtent( mpPointsLayer->extent() );
130+
bool res = imageCheck( "vector_blendmodes" );
133131

134132
//Reset layers
135133
mpLinesLayer->setBlendMode( QPainter::CompositionMode_SourceOver );
136134
mpPolysLayer->setBlendMode( QPainter::CompositionMode_SourceOver );
135+
136+
QVERIFY( res );
137137
}
138138

139139
void TestQgsBlendModes::featureBlending()
@@ -142,15 +142,17 @@ void TestQgsBlendModes::featureBlending()
142142
QStringList myLayers;
143143
myLayers << mpLinesLayer->id();
144144
myLayers << mpPolysLayer->id();
145-
mpMapRenderer->setLayerSet( myLayers );
145+
mMapSettings.setLayers( myLayers );
146146

147147
//Set feature blending modes for point layer
148148
mpLinesLayer->setFeatureBlendMode( QPainter::CompositionMode_Plus );
149-
mpMapRenderer->setExtent( mpPointsLayer->extent() );
150-
QVERIFY( imageCheck( "vector_featureblendmodes" ) );
149+
mMapSettings.setExtent( mpPointsLayer->extent() );
150+
bool res = imageCheck( "vector_featureblendmodes" );
151151

152152
//Reset layers
153153
mpLinesLayer->setFeatureBlendMode( QPainter::CompositionMode_SourceOver );
154+
155+
QVERIFY( res );
154156
}
155157

156158
void TestQgsBlendModes::vectorLayerTransparency()
@@ -159,15 +161,17 @@ void TestQgsBlendModes::vectorLayerTransparency()
159161
QStringList myLayers;
160162
myLayers << mpLinesLayer->id();
161163
myLayers << mpPolysLayer->id();
162-
mpMapRenderer->setLayerSet( myLayers );
164+
mMapSettings.setLayers( myLayers );
163165

164166
//Set feature blending modes for point layer
165167
mpLinesLayer->setLayerTransparency( 50 );
166-
mpMapRenderer->setExtent( mpPointsLayer->extent() );
167-
QVERIFY( imageCheck( "vector_layertransparency" ) );
168+
mMapSettings.setExtent( mpPointsLayer->extent() );
169+
bool res = imageCheck( "vector_layertransparency" );
168170

169171
//Reset layers
170172
mpLinesLayer->setLayerTransparency( 0 );
173+
174+
QVERIFY( res );
171175
}
172176

173177
void TestQgsBlendModes::rasterBlending()
@@ -176,8 +180,8 @@ void TestQgsBlendModes::rasterBlending()
176180
QStringList myLayers;
177181
myLayers << mRasterLayer1->id();
178182
myLayers << mRasterLayer2->id();
179-
mpMapRenderer->setLayerSet( myLayers );
180-
mpMapRenderer->setExtent( mRasterLayer1->extent() );
183+
mMapSettings.setLayers( myLayers );
184+
mMapSettings.setExtent( mRasterLayer1->extent() );
181185

182186
// set blending mode for top layer
183187
mRasterLayer1->setBlendMode( QPainter::CompositionMode_Plus );
@@ -194,7 +198,7 @@ bool TestQgsBlendModes::imageCheck( QString theTestType )
194198
//ensure the rendered output matches our control image
195199
QgsRenderChecker myChecker;
196200
myChecker.setControlName( "expected_" + theTestType );
197-
myChecker.setMapRenderer( mpMapRenderer );
201+
myChecker.setMapSettings( mMapSettings );
198202
bool myResultFlag = myChecker.runTest( theTestType );
199203
return myResultFlag;
200204
}

tests/src/core/testqgscomposerhtml.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,12 @@ class TestQgsComposerHtml: public QObject
3434
void tableMultiFrame(); //tests multiframe capabilities of composer html
3535
private:
3636
QgsComposition* mComposition;
37+
QgsMapSettings mMapSettings;
3738
};
3839

3940
void TestQgsComposerHtml::initTestCase()
4041
{
41-
mComposition = new QgsComposition( 0 );
42+
mComposition = new QgsComposition( mMapSettings );
4243
mComposition->setPaperSize( 297, 210 ); //A4 landscape
4344
}
4445

tests/src/core/testqgscomposershapes.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "qgscomposition.h"
2020
#include "qgscompositionchecker.h"
2121
#include "qgscomposershape.h"
22+
#include "qgsmapsettings.h"
2223
#include <QObject>
2324
#include <QtTest>
2425
#include <QColor>
@@ -40,6 +41,7 @@ class TestQgsComposerShapes: public QObject
4041
private:
4142
QgsComposition* mComposition;
4243
QgsComposerShape* mComposerShape;
44+
QgsMapSettings mMapSettings;
4345
};
4446

4547
void TestQgsComposerShapes::initTestCase()
@@ -48,7 +50,7 @@ void TestQgsComposerShapes::initTestCase()
4850
QgsApplication::initQgis();
4951

5052
//create composition with two rectangles
51-
mComposition = new QgsComposition( 0 );
53+
mComposition = new QgsComposition( mMapSettings );
5254
mComposition->setPaperSize( 297, 210 ); //A4 landscape
5355
mComposerShape = new QgsComposerShape( 20, 20, 150, 100, mComposition );
5456
mComposerShape->setBackgroundColor( QColor::fromRgb( 255, 150, 0 ) );

0 commit comments

Comments
 (0)