Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[tests] Fix python compositionchecker to derive from render checker, …
…fix most python composer tests (fix #9117)
  • Loading branch information
nyalldawson committed Dec 28, 2013
1 parent 2e107f2 commit 6aed6fe
Show file tree
Hide file tree
Showing 13 changed files with 126 additions and 230 deletions.
3 changes: 3 additions & 0 deletions python/core/qgsrenderchecker.sip
Expand Up @@ -38,4 +38,7 @@ class QgsRenderChecker
bool compareImages( QString theTestName, unsigned int theMismatchCount = 0, QString theRenderedImageFile = "" );

bool isKnownAnomaly( QString theDiffImageFile );

QString expectedImageFile();

};
23 changes: 23 additions & 0 deletions python/core/qgsvectorlayer.sip
Expand Up @@ -920,6 +920,29 @@ class QgsVectorLayer : QgsMapLayer
* @note added in 2.0
*/
int layerTransparency() const;

/** Set the Map2pixel simplification threshold for fast rendering of features */
void setSimplifyDrawingTol( float simplifyDrawingTol );
/** Returns the Map2pixel simplification threshold for fast rendering of features */
float simplifyDrawingTol() const;

/** Simplification flags for fast rendering of features */
enum SimplifyHint
{
NoSimplification = 0, //!< No simplification can be applied
GeometrySimplification = 1, //!< The geometries can be simplified using the current map2pixel context state
EnvelopeSimplification = 2, //!< The geometries can be fully simplified by its BoundingBox using the current map2pixel context state
AntialiasingSimplification = 4, //!< The geometries can be rendered with 'AntiAliasing' disabled because of it is '1-pixel size'
DefaultSimplification = 3, //!< Default simplification hints can be applied ( Geometry + Envelope )
FullSimplification = 7, //!< All simplification hints can be applied ( Geometry + Envelope + AA-disabling )
};
/** Set the Map2pixel simplification hints for fast rendering of features */
void setSimplifyDrawingHints( int simplifyDrawingHints );
/** Returns the Map2pixel simplification hints for fast rendering of features */
int simplifyDrawingHints() const;

/** Returns whether the VectorLayer can apply the specified simplification hint */
bool simplifyDrawingCanbeApplied( int simplifyHint ) const;

public slots:
/**
Expand Down
2 changes: 2 additions & 0 deletions src/core/qgsrenderchecker.h
Expand Up @@ -101,6 +101,8 @@ class CORE_EXPORT QgsRenderChecker
*/
bool isKnownAnomaly( QString theDiffImageFile );

QString expectedImageFile() { return mExpectedImageFile; };

protected:

QString mReport;
Expand Down
9 changes: 1 addition & 8 deletions tests/src/core/qgscompositionchecker.cpp
Expand Up @@ -21,12 +21,11 @@
#include <QImage>
#include <QPainter>

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

QgsCompositionChecker::QgsCompositionChecker()
Expand All @@ -37,12 +36,6 @@ QgsCompositionChecker::~QgsCompositionChecker()
{
}

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

bool QgsCompositionChecker::testComposition( QString &report, int page )
{
if ( !mComposition )
Expand Down
3 changes: 1 addition & 2 deletions tests/src/core/qgscompositionchecker.h
Expand Up @@ -26,11 +26,10 @@ class QImage;
class QgsCompositionChecker : public QgsRenderChecker
{
public:
QgsCompositionChecker( const QString& testName, QgsComposition* composition, const QString& expectedImageFile = QString() );
QgsCompositionChecker( const QString& testName, QgsComposition* composition );
~QgsCompositionChecker();

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

private:
QgsCompositionChecker(); //forbidden
Expand Down
64 changes: 20 additions & 44 deletions tests/src/python/qgscompositionchecker.py
Expand Up @@ -20,35 +20,40 @@
from PyQt4.QtGui import *
from qgis.core import *

class QgsCompositionChecker:

def testComposition(self, mTestName, mComposition, mExpectedImageFile, page=0 ):
if ( mComposition == None):
class QgsCompositionChecker(QgsRenderChecker):
def __init__(self, mTestName, mComposition ):
self.mExpectedImageFile = ""
self.mComposition = mComposition
self.mTestName = mTestName
super(QgsCompositionChecker, self).__init__()

def testComposition(self, page=0 ):
if ( self.mComposition == None):
myMessage = "Composition not valid"
return False, myMessage


#load expected image
expectedImage = QImage( mExpectedImageFile )
self.setControlName("expected_"+self.mTestName);
expectedImage = QImage( self.expectedImageFile() )

#get width/height, create image and render the composition to it
width = expectedImage.width();
height = expectedImage.height();
outputImage = QImage( QSize( width, height ), QImage.Format_ARGB32 )

mComposition.setPlotStyle( QgsComposition.Print )
self.mComposition.setPlotStyle( QgsComposition.Print )
outputImage.setDotsPerMeterX( expectedImage.dotsPerMeterX() )
outputImage.setDotsPerMeterY( expectedImage.dotsPerMeterX() )
outputImage.fill( 0 )
p = QPainter( outputImage )
mComposition.renderPage( p, page )
self.mComposition.renderPage( p, page )
p.end()

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

diffFilePath = QDir.tempPath() + QDir.separator() + QFileInfo( mExpectedImageFile ).baseName() + "_diff_python.png"
testResult = self.compareImages( expectedImage, outputImage, diffFilePath )
diffFilePath = QDir.tempPath() + QDir.separator() + QFileInfo(self.mTestName).baseName() + "_result_diff.png"
testResult = self.compareImages( self.mTestName, 0, renderedFilePath )

myDashMessage = (('<DartMeasurementFile name="Rendered Image '
'%s" type="image/png">'
Expand All @@ -59,44 +64,15 @@ def testComposition(self, mTestName, mComposition, mExpectedImageFile, page=0
'<DartMeasurementFile name="Difference Image '
'%s" type="image/png">'
'%s</DartMeasurementFile>') %
(mTestName, renderedFilePath, mTestName,
mExpectedImageFile, mTestName, diffFilePath )
(self.mTestName, renderedFilePath, self.mTestName,
self.expectedImageFile(), self.mTestName, diffFilePath )
)
qDebug( myDashMessage )
if not testResult:
myMessage = ('Expected: %s\nGot: %s\nDifference: %s\n' %
(mExpectedImageFile, renderedFilePath, diffFilePath))
(self.expectedImageFile(), renderedFilePath, diffFilePath))
else:
myMessage = 'Control and test images matched.'
return testResult, myMessage

def compareImages( self, imgExpected, imgRendered, differenceImagePath ):

if ( imgExpected.width() != imgRendered.width()
or imgExpected.height() != imgRendered.height() ):
return False

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

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

pixel1 = QColor().rgb()
pixel2 = QColor().rgb()
for i in range( imageHeight ):
for j in range( imageWidth ):
pixel1 = imgExpected.pixel( j, i )
pixel2 = imgRendered.pixel( j, i )
if ( pixel1 != pixel2 ):
mismatchCount = mismatchCount + 1
differenceImage.setPixel( j, i, qRgb( 255, 0, 0 ) )

if differenceImagePath != "":
differenceImage.save( differenceImagePath, "PNG" )
return testResult, myMessage

#allow pixel deviation of 1 percent
pixelCount = imageWidth * imageHeight;
return (float(mismatchCount) / float(pixelCount) ) < 0.01
55 changes: 20 additions & 35 deletions tests/src/python/test_qgsatlascomposition.py
Expand Up @@ -121,13 +121,10 @@ def autoscale_render_test( self ):
self.mAtlas.prepareForFeature( i )
self.mLabel1.adjustSizeToText()

checker = QgsCompositionChecker()
res = checker.testComposition( "Atlas autoscale test", self.mComposition, \
self.TEST_DATA_DIR + QDir.separator() + \
"control_images" + QDir.separator() + \
"expected_composermapatlas" + QDir.separator() + \
"autoscale_%d.png" % i )
assert res[0] == True
checker = QgsCompositionChecker('atlas_autoscale%d' % (i + 1), self.mComposition)
myTestResult, myMessage = checker.testComposition()

assert myTestResult == True
self.mAtlas.endRender()

def fixedscale_render_test( self ):
Expand All @@ -140,13 +137,10 @@ def fixedscale_render_test( self ):
self.mAtlas.prepareForFeature( i )
self.mLabel1.adjustSizeToText()

checker = QgsCompositionChecker()
res = checker.testComposition( "Atlas fixed scale test", self.mComposition, \
self.TEST_DATA_DIR + QDir.separator() + \
"control_images" + QDir.separator() + \
"expected_composermapatlas" + QDir.separator() + \
"fixedscale_%d.png" % i )
assert res[0] == True
checker = QgsCompositionChecker('atlas_fixedscale%d' % (i + 1), self.mComposition)
myTestResult, myMessage = checker.testComposition()

assert myTestResult == True
self.mAtlas.endRender()

def hidden_render_test( self ):
Expand All @@ -160,13 +154,10 @@ def hidden_render_test( self ):
self.mAtlas.prepareForFeature( i )
self.mLabel1.adjustSizeToText()

checker = QgsCompositionChecker()
res = checker.testComposition( "Atlas hidden test", self.mComposition, \
self.TEST_DATA_DIR + QDir.separator() + \
"control_images" + QDir.separator() + \
"expected_composermapatlas" + QDir.separator() + \
"hiding_%d.png" % i )
assert res[0] == True
checker = QgsCompositionChecker('atlas_hiding%d' % (i + 1), self.mComposition)
myTestResult, myMessage = checker.testComposition()

assert myTestResult == True
self.mAtlas.endRender()

def sorting_render_test( self ):
Expand All @@ -184,13 +175,10 @@ def sorting_render_test( self ):
self.mAtlas.prepareForFeature( i )
self.mLabel1.adjustSizeToText()

checker = QgsCompositionChecker()
res = checker.testComposition( "Atlas sorting test", self.mComposition, \
self.TEST_DATA_DIR + QDir.separator() + \
"control_images" + QDir.separator() + \
"expected_composermapatlas" + QDir.separator() + \
"sorting_%d.png" % i )
assert res[0] == True
checker = QgsCompositionChecker('atlas_sorting%d' % (i + 1), self.mComposition)
myTestResult, myMessage = checker.testComposition()

assert myTestResult == True
self.mAtlas.endRender()

def filtering_render_test( self ):
Expand All @@ -209,13 +197,10 @@ def filtering_render_test( self ):
self.mAtlas.prepareForFeature( i )
self.mLabel1.adjustSizeToText()

checker = QgsCompositionChecker()
res = checker.testComposition( "Atlas filtering test", self.mComposition, \
self.TEST_DATA_DIR + QDir.separator() + \
"control_images" + QDir.separator() + \
"expected_composermapatlas" + QDir.separator() + \
"filtering_%d.png" % i )
assert res[0] == True
checker = QgsCompositionChecker('atlas_filtering%d' % (i + 1), self.mComposition)
myTestResult, myMessage = checker.testComposition()

assert myTestResult == True
self.mAtlas.endRender()

if __name__ == '__main__':
Expand Down
2 changes: 2 additions & 0 deletions tests/src/python/test_qgsblendmodes.py
Expand Up @@ -66,11 +66,13 @@ def __init__(self, methodName):
# create polygon layer
myShpFile = os.path.join(TEST_DATA_DIR, 'polys.shp')
self.mPolygonLayer = QgsVectorLayer(myShpFile, 'Polygons', 'ogr')
self.mPolygonLayer.setSimplifyDrawingHints(QgsVectorLayer.NoSimplification)
self.mMapRegistry.addMapLayer(self.mPolygonLayer)

# create line layer
myShpFile = os.path.join(TEST_DATA_DIR, 'lines.shp')
self.mLineLayer = QgsVectorLayer(myShpFile, 'Lines', 'ogr')
self.mLineLayer.setSimplifyDrawingHints(QgsVectorLayer.NoSimplification)
self.mMapRegistry.addMapLayer(self.mLineLayer)

# create two raster layers
Expand Down
20 changes: 6 additions & 14 deletions tests/src/python/test_qgscomposereffects.py
Expand Up @@ -61,13 +61,9 @@ def testBlendModes(self):

self.mComposerRect2.setBlendMode(QPainter.CompositionMode_Multiply)

checker = QgsCompositionChecker()
myPath = os.path.join(TEST_DATA_DIR,
'control_images',
'expected_composereffects',
'composereffect_blend.png')
myTestResult, myMessage = checker.testComposition('Composer effects blending',
self.mComposition, myPath)
checker = QgsCompositionChecker('composereffects_blend', self.mComposition)
myTestResult, myMessage = checker.testComposition()

self.mComposerRect2.setBlendMode(QPainter.CompositionMode_SourceOver)

assert myTestResult == True, myMessage
Expand All @@ -77,13 +73,9 @@ def testTransparency(self):

self.mComposerRect2.setTransparency( 50 )

checker = QgsCompositionChecker()
myPath = os.path.join(TEST_DATA_DIR,
'control_images',
'expected_composereffects',
'composereffect_transparency.png')
myTestResult, myMessage = checker.testComposition('Composer effects transparency',
self.mComposition, myPath)
checker = QgsCompositionChecker('composereffects_transparency', self.mComposition)
myTestResult, myMessage = checker.testComposition()

self.mComposerRect2.setTransparency( 100 )

assert myTestResult == True, myMessage
Expand Down

0 comments on commit 6aed6fe

Please sign in to comment.