Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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 90b10f7
Show file tree
Hide file tree
Showing 13 changed files with 110 additions and 77 deletions.
3 changes: 2 additions & 1 deletion python/core/qgsrenderchecker.sip
Expand Up @@ -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 = "" );
Expand Down
12 changes: 4 additions & 8 deletions src/core/qgsfeature.cpp
Expand Up @@ -29,7 +29,6 @@ QgsFeature::QgsFeature( QgsFeatureId id )
, mGeometry( 0 )
, mOwnsGeometry( 0 )
, mValid( false )
, mFields( 0 )
{
// NOOP
}
Expand All @@ -39,7 +38,7 @@ QgsFeature::QgsFeature( const QgsFields &fields, QgsFeatureId id )
, mGeometry( 0 )
, mOwnsGeometry( 0 )
, mValid( false )
, mFields( &fields )
, mFields( fields )
{
initAttributes( fields.count() );
}
Expand Down Expand Up @@ -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() );
Expand Down Expand Up @@ -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;
}
Expand Down
12 changes: 8 additions & 4 deletions src/core/qgsfeature.h
Expand Up @@ -102,7 +102,7 @@ typedef QVector<QVariant> QgsAttributes;
class QgsField;
typedef QMap<int, QgsField> QgsFieldMap;


#include "qgsfield.h"


/** \ingroup core
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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

Expand Down
4 changes: 3 additions & 1 deletion src/core/qgsmaprenderer.cpp
Expand Up @@ -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() );
Expand Down
52 changes: 32 additions & 20 deletions src/core/qgsrenderchecker.cpp
Expand Up @@ -14,7 +14,9 @@
***************************************************************************/

#include "qgsrenderchecker.h"

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

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

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 );
Expand Down
10 changes: 8 additions & 2 deletions src/core/qgsrenderchecker.h
Expand Up @@ -24,6 +24,7 @@

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

class QImage;

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -111,7 +117,7 @@ class CORE_EXPORT QgsRenderChecker
unsigned int mMatchTarget;
int mElapsedTime;
int mElapsedTimeTarget;
QgsMapRenderer * mpMapRenderer;
QgsMapSettings mMapSettings;
QString mControlPathPrefix;

}; // class QgsRenderChecker
Expand Down
36 changes: 20 additions & 16 deletions tests/src/core/testqgsblendmodes.cpp
Expand Up @@ -21,7 +21,7 @@
#include <QPainter>

//qgis includes...
#include <qgsmaprenderer.h>
#include <qgsmapsettings.h>
#include <qgsmaplayer.h>
#include <qgsvectorlayer.h>
#include <qgsapplication.h>
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -109,8 +109,6 @@ void TestQgsBlendModes::initTestCase()
QList<QgsMapLayer *>() << mRasterLayer1 );
QgsMapLayerRegistry::instance()->addMapLayers(
QList<QgsMapLayer *>() << mRasterLayer2 );

mpMapRenderer = new QgsMapRenderer();
}
void TestQgsBlendModes::cleanupTestCase()
{
Expand All @@ -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()
Expand All @@ -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()
Expand All @@ -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()
Expand All @@ -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 );
Expand All @@ -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;
}
Expand Down
3 changes: 2 additions & 1 deletion tests/src/core/testqgscomposerhtml.cpp
Expand Up @@ -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
}

Expand Down
4 changes: 3 additions & 1 deletion tests/src/core/testqgscomposershapes.cpp
Expand Up @@ -19,6 +19,7 @@
#include "qgscomposition.h"
#include "qgscompositionchecker.h"
#include "qgscomposershape.h"
#include "qgsmapsettings.h"
#include <QObject>
#include <QtTest>
#include <QColor>
Expand All @@ -40,6 +41,7 @@ class TestQgsComposerShapes: public QObject
private:
QgsComposition* mComposition;
QgsComposerShape* mComposerShape;
QgsMapSettings mMapSettings;
};

void TestQgsComposerShapes::initTestCase()
Expand All @@ -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 ) );
Expand Down

0 comments on commit 90b10f7

Please sign in to comment.