QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgsrenderchecker.h
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrenderchecker.h - check maprender output against an expected image
3  --------------------------------------
4  Date : 18 Jan 2008
5  Copyright : (C) 2008 by Tim Sutton
6  email : tim @ linfiniti.com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #ifndef QGSRENDERCHECKER_H
17 #define QGSRENDERCHECKER_H
18 
19 #include "qgis_core.h"
20 #include "qgis_sip.h"
21 
22 #include "qgslogger.h"
23 #include "qgsmapsettings.h"
24 #include "qgsdartmeasurement.h"
25 
26 #include <QDir>
27 #include <QString>
28 #include <QRegularExpression>
29 #include <QList>
30 
31 class QImage;
32 
33 #define DUMP_BASE64_IMAGES 0
34 
41 class CORE_EXPORT QgsRenderChecker
42 {
43  Q_GADGET
44 
45  public:
46 
51 
57  static QDir testReportDir();
58 
65  static bool shouldGenerateReport();
66 
74  QString controlImagePath() const;
75 
82  void setControlImagePath( const QString &path );
83 
90  QString report( bool ignoreSuccess = true ) const;
91 
95  float matchPercent() const
96  {
97  return static_cast<float>( mMismatchCount ) /
98  static_cast<float>( mMatchTarget ) * 100;
99  }
100 
104  unsigned int mismatchCount() const { return mMismatchCount; }
105 
109  unsigned int matchTarget() const { return mMatchTarget; }
110 
116  int elapsedTime() const { return mElapsedTime; }
117  void setElapsedTimeTarget( int target ) { mElapsedTimeTarget = target; }
118 
126  void setControlName( const QString &name );
127 
132  void setControlExtension( const QString &extension ) { mControlExtension = extension; }
133 
138  void setControlPathPrefix( const QString &name ) { mControlPathPrefix = name + '/'; }
139 
140  void setControlPathSuffix( const QString &name );
141 
143  QString imageToHash( const QString &imageFile );
144 
148  void setRenderedImage( const QString &imageFileName ) { mRenderedImageFile = imageFileName; }
149 
155  void setExpectFail( bool expectFail ) { mExpectFail = expectFail; }
156 
162  QString renderedImage() const { return mRenderedImageFile; }
163 
165  void setMapSettings( const QgsMapSettings &mapSettings );
166 
174  void setColorTolerance( unsigned int colorTolerance ) { mColorTolerance = colorTolerance; }
175 
182  void setSizeTolerance( int xTolerance, int yTolerance ) { mMaxSizeDifferenceX = xTolerance; mMaxSizeDifferenceY = yTolerance; }
183 
189  enum class Flag : int
190  {
191  AvoidExportingRenderedImage = 1 << 0,
192  };
193  Q_ENUM( Flag )
194 
195 
200  Q_DECLARE_FLAGS( Flags, Flag )
201  Q_FLAG( Flags )
202 
203 
214  bool runTest( const QString &testName, unsigned int mismatchCount = 0, QgsRenderChecker::Flags flags = QgsRenderChecker::Flags() );
215 
228  bool compareImages( const QString &testName, unsigned int mismatchCount = 0, const QString &renderedImageFile = QString(), QgsRenderChecker::Flags flags = QgsRenderChecker::Flags() );
229 
235  bool compareImages( const QString &testName, const QString &referenceImageFile, const QString &renderedImageFile, unsigned int mismatchCount = 0, QgsRenderChecker::Flags flags = QgsRenderChecker::Flags() );
236 
245  bool isKnownAnomaly( const QString &diffImageFile );
246 
251  static void drawBackground( QImage *image );
252 
258  QString expectedImageFile() const { return mExpectedImageFile; }
259 
267  void enableDashBuffering( bool enable ) { mBufferDashMessages = enable; }
268 
275  QVector<QgsDartMeasurement> dartMeasurements() const { return mDashMessages; }
276 
277  protected:
278  QString mReport;
279  unsigned int mMatchTarget = 0;
280  int mElapsedTime = 0;
283 
284  private:
285  void emitDashMessage( const QgsDartMeasurement &dashMessage );
286  void emitDashMessage( const QString &name, QgsDartMeasurement::Type type, const QString &value );
287 
288 #if DUMP_BASE64_IMAGES
289  void dumpRenderedImageAsBase64();
290 #endif
291 
292  void performPostTestActions( Flags flags );
293 
294  bool mResult = false;
295  bool mExpectFail = false;
296 
297  QString mBasePath;
298 
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;
305  QgsMapSettings mMapSettings;
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;
313 };
314 
315 Q_DECLARE_OPERATORS_FOR_FLAGS( QgsRenderChecker::Flags )
316 
317 
325 inline bool compareWkt( const QString &a, const QString &b, double tolerance = 0.000001 )
326 {
327  QgsDebugMsg( QStringLiteral( "a:%1 b:%2 tol:%3" ).arg( a, b ).arg( tolerance ) );
328  const thread_local QRegularExpression re( "-?\\d+(?:\\.\\d+)?(?:[eE]\\d+)?" );
329 
330  QString a0( a ), b0( b );
331  a0.replace( re, QStringLiteral( "#" ) );
332  b0.replace( re, QStringLiteral( "#" ) );
333 
334  QgsDebugMsg( QStringLiteral( "a0:%1 b0:%2" ).arg( a0, b0 ) );
335 
336  if ( a0 != b0 )
337  return false;
338 
339  QList<double> al, bl;
340 
341  int pos = 0;
342  QRegularExpressionMatch match = re.match( a );
343  while ( match.hasMatch() )
344  {
345  al << match.captured( 0 ).toDouble();
346  pos = match.capturedStart( 0 ) + match.capturedLength( 0 );
347  match = re.match( a, pos );
348  }
349  match = re.match( b );
350  while ( match.hasMatch() )
351  {
352  bl << match.captured( 0 ).toDouble();
353  pos = match.capturedStart( 0 ) + match.capturedLength( 0 );
354  match = re.match( b, pos );
355  }
356 
357  if ( al.size() != bl.size() )
358  return false;
359 
360  for ( int i = 0; i < al.size(); i++ )
361  {
362  if ( !qgsDoubleNear( al[i], bl[i], tolerance ) )
363  return false;
364  }
365 
366  return true;
367 }
368 
369 #endif
QgsRenderChecker::mExpectedImageFile
QString mExpectedImageFile
Definition: qgsrenderchecker.h:282
QgsRenderChecker::setControlExtension
void setControlExtension(const QString &extension)
Sets file extension for the control image.
Definition: qgsrenderchecker.h:132
QgsRenderChecker::setElapsedTimeTarget
void setElapsedTimeTarget(int target)
Definition: qgsrenderchecker.h:117
QgsRenderChecker::mismatchCount
unsigned int mismatchCount() const
Returns the number of pixels which did not match the control image.
Definition: qgsrenderchecker.h:104
QgsDebugMsg
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
qgsmapsettings.h
QgsRenderChecker::setExpectFail
void setExpectFail(bool expectFail)
Sets whether the comparison is expected to fail.
Definition: qgsrenderchecker.h:155
QgsRenderChecker::mReport
QString mReport
Definition: qgsrenderchecker.h:278
QgsRenderChecker::matchPercent
float matchPercent() const
Returns the percent of pixels which matched the control image.
Definition: qgsrenderchecker.h:95
qgsDoubleNear
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:2265
QgsRenderChecker::expectedImageFile
QString expectedImageFile() const
Returns the path to the expected image file.
Definition: qgsrenderchecker.h:258
QgsRenderChecker::setColorTolerance
void setColorTolerance(unsigned int colorTolerance)
Set tolerance for color components used by runTest() and compareImages().
Definition: qgsrenderchecker.h:174
qgis_sip.h
qgsdartmeasurement.h
Q_DECLARE_OPERATORS_FOR_FLAGS
Q_DECLARE_OPERATORS_FOR_FLAGS(QgsField::ConfigurationFlags) CORE_EXPORT QDataStream &operator<<(QDataStream &out
Writes the field to stream out. QGIS version compatibility is not guaranteed.
QgsDartMeasurement::Type
Type
Definition: qgsdartmeasurement.h:30
QgsRenderChecker::matchTarget
unsigned int matchTarget() const
Returns the total number of pixels in the control image.
Definition: qgsrenderchecker.h:109
QgsRenderChecker::setSizeTolerance
void setSizeTolerance(int xTolerance, int yTolerance)
Sets the largest allowable difference in size between the rendered and the expected image.
Definition: qgsrenderchecker.h:182
QgsRenderChecker::elapsedTime
int elapsedTime() const
Returns the total elapsed time for the rendering test.
Definition: qgsrenderchecker.h:116
QgsRenderChecker::Flag
Flag
Render checker flags.
Definition: qgsrenderchecker.h:189
QgsRenderChecker::renderedImage
QString renderedImage() const
Returns the path of the rendered image generated by the test.
Definition: qgsrenderchecker.h:162
QgsDartMeasurement
Definition: qgsdartmeasurement.h:27
QgsRenderChecker::enableDashBuffering
void enableDashBuffering(bool enable)
Call this to enable internal buffering of dash messages.
Definition: qgsrenderchecker.h:267
compareWkt
bool compareWkt(const QString &a, const QString &b, double tolerance=0.000001)
Compare two WKT strings with some tolerance.
Definition: qgsrenderchecker.h:325
QgsRenderChecker::setControlPathPrefix
void setControlPathPrefix(const QString &name)
Sets the path prefix where the control images are kept.
Definition: qgsrenderchecker.h:138
QgsRenderChecker::setRenderedImage
void setRenderedImage(const QString &imageFileName)
Sets the file name of the rendered image generated by the test.
Definition: qgsrenderchecker.h:148
QgsRenderChecker
This is a helper class for unit tests that need to write an image and compare it to an expected resul...
Definition: qgsrenderchecker.h:41
qgslogger.h
QgsMapSettings
The QgsMapSettings class contains configuration for rendering of the map. The rendering itself is don...
Definition: qgsmapsettings.h:88
QgsRenderChecker::mRenderedImageFile
QString mRenderedImageFile
Definition: qgsrenderchecker.h:281
QgsRenderChecker::dartMeasurements
QVector< QgsDartMeasurement > dartMeasurements() const
Gets access to buffered dash messages.
Definition: qgsrenderchecker.h:275