16 #ifndef QGSRENDERCHECKER_H
17 #define QGSRENDERCHECKER_H
19 #include "qgis_core.h"
28 #include <QRegularExpression>
33 #define DUMP_BASE64_IMAGES 0
57 static QDir testReportDir();
65 static bool shouldGenerateReport();
74 QString controlImagePath()
const;
82 void setControlImagePath(
const QString &path );
90 QString report(
bool ignoreSuccess =
true )
const;
97 return static_cast<float>( mMismatchCount ) /
98 static_cast<float>( mMatchTarget ) * 100;
126 void setControlName(
const QString &name );
140 void setControlPathSuffix(
const QString &name );
143 QString imageToHash(
const QString &imageFile );
148 void setRenderedImage(
const QString &imageFileName ) { mRenderedImageFile = imageFileName; }
182 void setSizeTolerance(
int xTolerance,
int yTolerance ) { mMaxSizeDifferenceX = xTolerance; mMaxSizeDifferenceY = yTolerance; }
191 AvoidExportingRenderedImage = 1 << 0,
200 Q_DECLARE_FLAGS( Flags, Flag )
214 bool runTest(
const QString &testName,
unsigned int mismatchCount = 0, QgsRenderChecker::Flags flags = QgsRenderChecker::Flags() );
228 bool compareImages(
const QString &testName,
unsigned int mismatchCount = 0,
const QString &renderedImageFile = QString(), QgsRenderChecker::Flags flags = QgsRenderChecker::Flags() );
235 bool compareImages(
const QString &testName,
const QString &referenceImageFile,
const QString &renderedImageFile,
unsigned int mismatchCount = 0, QgsRenderChecker::Flags flags = QgsRenderChecker::Flags() );
245 bool isKnownAnomaly(
const QString &diffImageFile );
251 static void drawBackground( QImage *image );
279 unsigned int mMatchTarget = 0;
280 int mElapsedTime = 0;
288 #if DUMP_BASE64_IMAGES
289 void dumpRenderedImageAsBase64();
292 void performPostTestActions( Flags flags );
294 bool mResult =
false;
295 bool mExpectFail =
false;
299 QString mControlName;
300 unsigned int mMismatchCount = 0;
301 unsigned int mColorTolerance = 0;
302 int mMaxSizeDifferenceX = 0;
303 int mMaxSizeDifferenceY = 0;
304 int mElapsedTimeTarget = 0;
306 QString mControlExtension = QStringLiteral(
"png" );
307 QString mControlPathPrefix;
308 QString mControlPathSuffix;
309 bool mIsCiRun =
false;
310 QVector<QgsDartMeasurement> mDashMessages;
311 bool mBufferDashMessages =
false;
312 QString mDiffImageFile;
325 inline
bool compareWkt( const QString &a, const QString &b,
double tolerance = 0.000001 )
327 QgsDebugMsg( QStringLiteral(
"a:%1 b:%2 tol:%3" ).arg( a, b ).arg( tolerance ) );
328 const thread_local QRegularExpression re(
"-?\\d+(?:\\.\\d+)?(?:[eE]\\d+)?" );
330 QString a0( a ), b0( b );
331 a0.replace( re, QStringLiteral(
"#" ) );
332 b0.replace( re, QStringLiteral(
"#" ) );
334 QgsDebugMsg( QStringLiteral(
"a0:%1 b0:%2" ).arg( a0, b0 ) );
339 QList<double> al, bl;
342 QRegularExpressionMatch match = re.match( a );
343 while ( match.hasMatch() )
345 al << match.captured( 0 ).toDouble();
346 pos = match.capturedStart( 0 ) + match.capturedLength( 0 );
347 match = re.match( a, pos );
349 match = re.match( b );
350 while ( match.hasMatch() )
352 bl << match.captured( 0 ).toDouble();
353 pos = match.capturedStart( 0 ) + match.capturedLength( 0 );
354 match = re.match( b, pos );
357 if ( al.size() != bl.size() )
360 for (
int i = 0; i < al.size(); i++ )