Skip to content

Commit

Permalink
Rework composition checker to derive from render checker, so that com…
Browse files Browse the repository at this point in the history
…position tests can have anomoly images
  • Loading branch information
nyalldawson committed Dec 28, 2013
1 parent 5a7dff7 commit 3b1f789
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 59 deletions.
12 changes: 6 additions & 6 deletions src/core/qgsrenderchecker.cpp
Expand Up @@ -27,13 +27,13 @@

QgsRenderChecker::QgsRenderChecker( ) :
mReport( "" ),
mExpectedImageFile( "" ),
mRenderedImageFile( "" ),
mMismatchCount( 0 ),
mMatchTarget( 0 ),
mpMapRenderer( NULL ),
mElapsedTime( 0 ),
mRenderedImageFile( "" ),
mExpectedImageFile( "" ),
mMismatchCount( 0 ),
mElapsedTimeTarget( 0 ),
mpMapRenderer( NULL ),
mControlPathPrefix( "" )
{

Expand Down Expand Up @@ -78,7 +78,7 @@ bool QgsRenderChecker::isKnownAnomaly( QString theDiffImageFile )
QDir::Files | QDir::NoSymLinks );
//remove the control file from the list as the anomalies are
//all files except the control file
myList.removeAt( myList.indexOf( mExpectedImageFile ) );
myList.removeAt( myList.indexOf( QFileInfo( mExpectedImageFile ).fileName() ) );

QString myImageHash = imageToHash( theDiffImageFile );

Expand Down Expand Up @@ -204,7 +204,7 @@ bool QgsRenderChecker::compareImages( QString theTestName,
qDebug( "QgsRenderChecker::runTest failed - Rendered Image File not set." );
mReport = "<table>"
"<tr><td>Test Result:</td><td>Expected Result:</td></tr>\n"
"<tr><td>Nothing rendered</td>\n<td>Failed because Expected "
"<tr><td>Nothing rendered</td>\n<td>Failed because Rendered "
"Image File not set.</td></tr></table>\n";
return false;
}
Expand Down
13 changes: 8 additions & 5 deletions src/core/qgsrenderchecker.h
Expand Up @@ -101,17 +101,20 @@ class CORE_EXPORT QgsRenderChecker
*/
bool isKnownAnomaly( QString theDiffImageFile );

private:
protected:

QString mReport;
unsigned int mMatchTarget;
QgsMapRenderer * mpMapRenderer;
int mElapsedTime;
QString mRenderedImageFile;
QString mExpectedImageFile;

private:

QString mControlName;
QString mRenderedImageFile;
unsigned int mMismatchCount;
unsigned int mMatchTarget;
int mElapsedTime;
int mElapsedTimeTarget;
QgsMapRenderer * mpMapRenderer;
QString mControlPathPrefix;

}; // class QgsRenderChecker
Expand Down
61 changes: 17 additions & 44 deletions tests/src/core/qgscompositionchecker.cpp
Expand Up @@ -21,9 +21,12 @@
#include <QImage>
#include <QPainter>

QgsCompositionChecker::QgsCompositionChecker( const QString& testName, QgsComposition* composition, const QString& expectedImageFile ): mTestName( testName ),
mComposition( composition ), mExpectedImageFile( expectedImageFile )
QgsCompositionChecker::QgsCompositionChecker( const QString& testName, QgsComposition* composition, const QString& expectedImageFile )
: QgsRenderChecker( ),
mTestName( testName ),
mComposition( composition )
{
Q_UNUSED( expectedImageFile );
}

QgsCompositionChecker::QgsCompositionChecker()
Expand All @@ -35,6 +38,12 @@ QgsCompositionChecker::~QgsCompositionChecker()
}

bool QgsCompositionChecker::testComposition( int page )
{
QString fake;
return testComposition( fake, page );
}

bool QgsCompositionChecker::testComposition( QString &report, int page )
{
if ( !mComposition )
{
Expand All @@ -59,6 +68,7 @@ bool QgsCompositionChecker::testComposition( int page )
#endif //0

//load expected image
setControlName( "expected_" + mTestName );
QImage expectedImage( mExpectedImageFile );

//get width/height, create image and render the composition to it
Expand All @@ -74,11 +84,12 @@ bool QgsCompositionChecker::testComposition( int page )
mComposition->renderPage( &p, page );
p.end();

QString renderedFilePath = QDir::tempPath() + QDir::separator() + QFileInfo( mExpectedImageFile ).baseName() + "_rendered.png";
QString renderedFilePath = QDir::tempPath() + QDir::separator() + QFileInfo( mTestName ).baseName() + "_rendered.png";
outputImage.save( renderedFilePath, "PNG" );

QString diffFilePath = QDir::tempPath() + QDir::separator() + QFileInfo( mExpectedImageFile ).baseName() + "_diff.png";
bool testResult = compareImages( expectedImage, outputImage, diffFilePath );
QString diffFilePath = QDir::tempPath() + QDir::separator() + QFileInfo( mTestName ).baseName() + "_result_diff.png";

bool testResult = compareImages( mTestName, 0, renderedFilePath );

QString myDashMessage = "<DartMeasurementFile name=\"Rendered Image " + mTestName + "\""
" type=\"image/png\">" + renderedFilePath +
Expand All @@ -89,44 +100,6 @@ bool QgsCompositionChecker::testComposition( int page )
diffFilePath + "</DartMeasurementFile>";
qDebug( ) << myDashMessage;

report += mReport;
return testResult;
}

bool QgsCompositionChecker::compareImages( const QImage& imgExpected, const QImage& imgRendered, const QString& differenceImagePath ) const
{
if ( imgExpected.width() != imgRendered.width() || imgExpected.height() != imgRendered.height() )
{
return false;
}

int imageWidth = imgExpected.width();
int imageHeight = imgExpected.height();
int mismatchCount = 0;

QImage differenceImage( imageWidth, imageHeight, QImage::Format_ARGB32_Premultiplied );
differenceImage.fill( qRgb( 152, 219, 249 ) );

QRgb pixel1, pixel2;
for ( int i = 0; i < imageHeight; ++i )
{
for ( int j = 0; j < imageWidth; ++j )
{
pixel1 = imgExpected.pixel( j, i );
pixel2 = imgRendered.pixel( j, i );
if ( pixel1 != pixel2 )
{
++mismatchCount;
differenceImage.setPixel( j, i, qRgb( 255, 0, 0 ) );
}
}
}

if ( !differenceImagePath.isEmpty() )
{
differenceImage.save( differenceImagePath, "PNG" );
}

//allow pixel deviation of 1 per mille
int pixelCount = imageWidth * imageHeight;
return (( double )mismatchCount / ( double )pixelCount ) < 0.001;
}
11 changes: 7 additions & 4 deletions tests/src/core/qgscompositionchecker.h
Expand Up @@ -16,26 +16,29 @@
#ifndef QGSCOMPOSITIONCHECKER_H
#define QGSCOMPOSITIONCHECKER_H

#include "qgsrenderchecker.h"
#include <QString>

class QgsComposition;
class QImage;

/**Renders a composition to an image and compares with an expected output*/
class QgsCompositionChecker
class QgsCompositionChecker : public QgsRenderChecker
{
public:
QgsCompositionChecker( const QString& testName, QgsComposition* composition, const QString& expectedImageFile );
QgsCompositionChecker( const QString& testName, QgsComposition* composition, const QString& expectedImageFile = QString() );
~QgsCompositionChecker();

bool testComposition( QString &report, int page = 0 );
bool testComposition( int page = 0 );

private:
QgsCompositionChecker(); //forbidden
bool compareImages( const QImage& imgExpected, const QImage& imgRendered, const QString& differenceImagePath = QString() ) const;

QString mTestName;
QgsComposition* mComposition;
QString mExpectedImageFile;


};

#endif // QGSCOMPOSITIONCHECKER_H

0 comments on commit 3b1f789

Please sign in to comment.