Skip to content
Permalink
Browse files

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.
  • Loading branch information
wonder-sk committed Dec 11, 2013
1 parent 151bad5 commit 90b10f79cfcbc920e2144cea384025870c15c701
@@ -32,7 +32,8 @@ class QgsRenderChecker
QString imageToHash( QString theImageFile );

void setRenderedImage( QString theImageFileName );
void setMapRenderer( QgsMapRenderer * thepMapRenderer );
void setMapRenderer( QgsMapRenderer * thepMapRenderer ) /Deprecated/;
void setMapSettings( const QgsMapSettings& mapSettings );
bool runTest( QString theTestName, unsigned int theMismatchCount = 0 );

bool compareImages( QString theTestName, unsigned int theMismatchCount = 0, QString theRenderedImageFile = "" );
@@ -29,7 +29,6 @@ QgsFeature::QgsFeature( QgsFeatureId id )
, mGeometry( 0 )
, mOwnsGeometry( 0 )
, mValid( false )
, mFields( 0 )
{
// NOOP
}
@@ -39,7 +38,7 @@ QgsFeature::QgsFeature( const QgsFields &fields, QgsFeatureId id )
, mGeometry( 0 )
, mOwnsGeometry( 0 )
, mValid( false )
, mFields( &fields )
, mFields( fields )
{
initAttributes( fields.count() );
}
@@ -161,7 +160,7 @@ void QgsFeature::setGeometryAndOwnership( unsigned char *geom, size_t length )

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

int QgsFeature::fieldNameIndex( const QString& fieldName ) const
{
if ( !mFields )
return -1;

for ( int i = 0; i < mFields->count(); ++i )
for ( int i = 0; i < mFields.count(); ++i )
{
if ( QString::compare( mFields->at( i ).name(), fieldName, Qt::CaseInsensitive ) == 0 )
if ( QString::compare( mFields.at( i ).name(), fieldName, Qt::CaseInsensitive ) == 0 )
{
return i;
}
@@ -102,7 +102,7 @@ typedef QVector<QVariant> QgsAttributes;
class QgsField;
typedef QMap<int, QgsField> QgsFieldMap;


#include "qgsfield.h"


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

/** Get associated field map. may be NULL
/** Get associated field map.
* @note added in 2.0
*
* TODO: QGIS 3 - return reference or value, not pointer
*/
const QgsFields* fields() const { return mFields; }
const QgsFields* fields() const { return &mFields; }

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

//! Optional field map for name-based attribute lookups
const QgsFields* mFields;
QgsFields mFields;

}; // class QgsFeature

@@ -1070,12 +1070,14 @@ QgsMapRenderer::BlendMode QgsMapRenderer::getBlendModeEnum( const QPainter::Comp
}
}

Q_GUI_EXPORT extern int qt_defaultDpiX();

const QgsMapSettings& QgsMapRenderer::mapSettings()
{
// make sure the settings object is up-to-date
mMapSettings.setExtent( extent() );
mMapSettings.setOutputSize( outputSize() );
mMapSettings.setOutputDpi( outputDpi() );
mMapSettings.setOutputDpi( outputDpi() != 0 ? outputDpi() : qt_defaultDpiX() );
mMapSettings.setLayers( layerSet() );
mMapSettings.setCrsTransformEnabled( hasCrsTransformEnabled() );
mMapSettings.setDestinationCrs( destinationCrs() );
@@ -14,7 +14,9 @@
***************************************************************************/

#include "qgsrenderchecker.h"

#include "qgis.h"
#include "qgsmaprendererjob.h"

#include <QColor>
#include <QPainter>
@@ -33,7 +35,6 @@ QgsRenderChecker::QgsRenderChecker( ) :
mMatchTarget( 0 ),
mElapsedTime( 0 ),
mElapsedTimeTarget( 0 ),
mpMapRenderer( NULL ),
mControlPathPrefix( "" )
{

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

void QgsRenderChecker::setMapRenderer( QgsMapRenderer* thepMapRenderer )
{
mMapSettings = thepMapRenderer->mapSettings();
}

void QgsRenderChecker::setMapSettings( const QgsMapSettings& mapSettings )
{
mMapSettings = mapSettings;
}

bool QgsRenderChecker::isKnownAnomaly( QString theDiffImageFile )
{
QString myControlImageDir = controlImagePath() + mControlName
@@ -138,44 +149,45 @@ bool QgsRenderChecker::runTest( QString theTestName,
//
// Now render our layers onto a pixmap
//
QImage myImage( myExpectedImage.width(),
myExpectedImage.height(),
QImage::Format_RGB32 );
myImage.setDotsPerMeterX( myExpectedImage.dotsPerMeterX() );
myImage.setDotsPerMeterY( myExpectedImage.dotsPerMeterY() );
myImage.fill( qRgb( 152, 219, 249 ) );
QPainter myPainter( &myImage );
myPainter.setRenderHint( QPainter::Antialiasing );
mpMapRenderer->setOutputSize( QSize(
myExpectedImage.width(),
myExpectedImage.height() ),
myExpectedImage.logicalDpiX() );
mMapSettings.setBackgroundColor( qRgb( 152, 219, 249 ) );
mMapSettings.setFlag( QgsMapSettings::Antialiasing );
mMapSettings.setOutputSize( QSize( myExpectedImage.width(), myExpectedImage.height() ) );

QTime myTime;
myTime.start();
mpMapRenderer->render( &myPainter );

QgsMapRendererSequentialJob job( mMapSettings );
job.start();
job.waitForFinished();

mElapsedTime = myTime.elapsed();
myPainter.end();

QImage myImage = job.renderedImage();

//
// Save the pixmap to disk so the user can make a
// visual assessment if needed
//
mRenderedImageFile = QDir::tempPath() + QDir::separator() +
theTestName + "_result.png";

myImage.setDotsPerMeterX( myExpectedImage.dotsPerMeterX() );
myImage.setDotsPerMeterY( myExpectedImage.dotsPerMeterY() );
myImage.save( mRenderedImageFile, "PNG", 100 );

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

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

QTextStream stream( &wldFile );
stream << QString( "%1\r\n0 \r\n0 \r\n%2\r\n%3\r\n%4\r\n" )
.arg( qgsDoubleToString( mpMapRenderer->mapUnitsPerPixel() ) )
.arg( qgsDoubleToString( -mpMapRenderer->mapUnitsPerPixel() ) )
.arg( qgsDoubleToString( r.xMinimum() + mpMapRenderer->mapUnitsPerPixel() / 2.0 ) )
.arg( qgsDoubleToString( r.yMaximum() - mpMapRenderer->mapUnitsPerPixel() / 2.0 ) );
.arg( qgsDoubleToString( mMapSettings.mapUnitsPerPixel() ) )
.arg( qgsDoubleToString( -mMapSettings.mapUnitsPerPixel() ) )
.arg( qgsDoubleToString( r.xMinimum() + mMapSettings.mapUnitsPerPixel() / 2.0 ) )
.arg( qgsDoubleToString( r.yMaximum() - mMapSettings.mapUnitsPerPixel() / 2.0 ) );
}

return compareImages( theTestName, theMismatchCount );
@@ -24,6 +24,7 @@

#include <qgsmaprenderer.h>
#include <qgslogger.h>
#include <qgsmapsettings.h>

class QImage;

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

void setRenderedImage( QString theImageFileName ) { mRenderedImageFile = theImageFileName; };
void setMapRenderer( QgsMapRenderer * thepMapRenderer ) { mpMapRenderer = thepMapRenderer; };
//! @deprecated since 2.1 - use setMapSettings()
Q_DECL_DEPRECATED void setMapRenderer( QgsMapRenderer * thepMapRenderer );

//! @note added in 2.1
void setMapSettings( const QgsMapSettings& mapSettings );

/**
* Test using renderer to generate the image to be compared.
* @param theTestName - to be used as the basis for writing a file to
@@ -111,7 +117,7 @@ class CORE_EXPORT QgsRenderChecker
unsigned int mMatchTarget;
int mElapsedTime;
int mElapsedTimeTarget;
QgsMapRenderer * mpMapRenderer;
QgsMapSettings mMapSettings;
QString mControlPathPrefix;

}; // class QgsRenderChecker
@@ -21,7 +21,7 @@
#include <QPainter>

//qgis includes...
#include <qgsmaprenderer.h>
#include <qgsmapsettings.h>
#include <qgsmaplayer.h>
#include <qgsvectorlayer.h>
#include <qgsapplication.h>
@@ -50,7 +50,7 @@ class TestQgsBlendModes: public QObject
void rasterBlending();
private:
bool imageCheck( QString theType ); //as above
QgsMapRenderer * mpMapRenderer;
QgsMapSettings mMapSettings;
QgsMapLayer * mpPointsLayer;
QgsMapLayer * mpPolysLayer;
QgsVectorLayer * mpLinesLayer;
@@ -109,8 +109,6 @@ void TestQgsBlendModes::initTestCase()
QList<QgsMapLayer *>() << mRasterLayer1 );
QgsMapLayerRegistry::instance()->addMapLayers(
QList<QgsMapLayer *>() << mRasterLayer2 );

mpMapRenderer = new QgsMapRenderer();
}
void TestQgsBlendModes::cleanupTestCase()
{
@@ -123,17 +121,19 @@ void TestQgsBlendModes::vectorBlending()
QStringList myLayers;
myLayers << mpLinesLayer->id();
myLayers << mpPolysLayer->id();
mpMapRenderer->setLayerSet( myLayers );
mMapSettings.setLayers( myLayers );

//Set blending modes for both layers
mpLinesLayer->setBlendMode( QPainter::CompositionMode_Difference );
mpPolysLayer->setBlendMode( QPainter::CompositionMode_Difference );
mpMapRenderer->setExtent( mpPointsLayer->extent() );
QVERIFY( imageCheck( "vector_blendmodes" ) );
mMapSettings.setExtent( mpPointsLayer->extent() );
bool res = imageCheck( "vector_blendmodes" );

//Reset layers
mpLinesLayer->setBlendMode( QPainter::CompositionMode_SourceOver );
mpPolysLayer->setBlendMode( QPainter::CompositionMode_SourceOver );

QVERIFY( res );
}

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

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

//Reset layers
mpLinesLayer->setFeatureBlendMode( QPainter::CompositionMode_SourceOver );

QVERIFY( res );
}

void TestQgsBlendModes::vectorLayerTransparency()
@@ -159,15 +161,17 @@ void TestQgsBlendModes::vectorLayerTransparency()
QStringList myLayers;
myLayers << mpLinesLayer->id();
myLayers << mpPolysLayer->id();
mpMapRenderer->setLayerSet( myLayers );
mMapSettings.setLayers( myLayers );

//Set feature blending modes for point layer
mpLinesLayer->setLayerTransparency( 50 );
mpMapRenderer->setExtent( mpPointsLayer->extent() );
QVERIFY( imageCheck( "vector_layertransparency" ) );
mMapSettings.setExtent( mpPointsLayer->extent() );
bool res = imageCheck( "vector_layertransparency" );

//Reset layers
mpLinesLayer->setLayerTransparency( 0 );

QVERIFY( res );
}

void TestQgsBlendModes::rasterBlending()
@@ -176,8 +180,8 @@ void TestQgsBlendModes::rasterBlending()
QStringList myLayers;
myLayers << mRasterLayer1->id();
myLayers << mRasterLayer2->id();
mpMapRenderer->setLayerSet( myLayers );
mpMapRenderer->setExtent( mRasterLayer1->extent() );
mMapSettings.setLayers( myLayers );
mMapSettings.setExtent( mRasterLayer1->extent() );

// set blending mode for top layer
mRasterLayer1->setBlendMode( QPainter::CompositionMode_Plus );
@@ -194,7 +198,7 @@ bool TestQgsBlendModes::imageCheck( QString theTestType )
//ensure the rendered output matches our control image
QgsRenderChecker myChecker;
myChecker.setControlName( "expected_" + theTestType );
myChecker.setMapRenderer( mpMapRenderer );
myChecker.setMapSettings( mMapSettings );
bool myResultFlag = myChecker.runTest( theTestType );
return myResultFlag;
}
@@ -34,11 +34,12 @@ class TestQgsComposerHtml: public QObject
void tableMultiFrame(); //tests multiframe capabilities of composer html
private:
QgsComposition* mComposition;
QgsMapSettings mMapSettings;
};

void TestQgsComposerHtml::initTestCase()
{
mComposition = new QgsComposition( 0 );
mComposition = new QgsComposition( mMapSettings );
mComposition->setPaperSize( 297, 210 ); //A4 landscape
}

@@ -19,6 +19,7 @@
#include "qgscomposition.h"
#include "qgscompositionchecker.h"
#include "qgscomposershape.h"
#include "qgsmapsettings.h"
#include <QObject>
#include <QtTest>
#include <QColor>
@@ -40,6 +41,7 @@ class TestQgsComposerShapes: public QObject
private:
QgsComposition* mComposition;
QgsComposerShape* mComposerShape;
QgsMapSettings mMapSettings;
};

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

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

0 comments on commit 90b10f7

Please sign in to comment.
You can’t perform that action at this time.