[QGIS Commit] r8947 - in trunk/qgis/tests: src/core testdata

svn_qgis at osgeo.org svn_qgis at osgeo.org
Tue Jul 29 12:17:47 EDT 2008


Author: timlinux
Date: 2008-07-29 12:17:47 -0400 (Tue, 29 Jul 2008)
New Revision: 8947

Added:
   trunk/qgis/tests/testdata/expected_geometry_bufferCheck.png
   trunk/qgis/tests/testdata/expected_geometry_differenceCheck1.png
   trunk/qgis/tests/testdata/expected_geometry_differenceCheck2.png
   trunk/qgis/tests/testdata/expected_geometry_intersectionCheck1.png
   trunk/qgis/tests/testdata/expected_geometry_unionCheck1.png
   trunk/qgis/tests/testdata/expected_geometry_unionCheck2.png
Modified:
   trunk/qgis/tests/src/core/qgsrenderchecker.cpp
   trunk/qgis/tests/src/core/qgsrenderchecker.h
   trunk/qgis/tests/src/core/testqgsgeometry.cpp
Log:
In renderchecker split runtest into two functions so that image based compares can be done in situations where a maprenderer is not needed. Added more tests for geometry functions (buffer, difference) and provide a visual report of geometry test results.

Modified: trunk/qgis/tests/src/core/qgsrenderchecker.cpp
===================================================================
--- trunk/qgis/tests/src/core/qgsrenderchecker.cpp	2008-07-29 09:17:31 UTC (rev 8946)
+++ trunk/qgis/tests/src/core/qgsrenderchecker.cpp	2008-07-29 16:17:47 UTC (rev 8947)
@@ -25,6 +25,7 @@
 QgsRenderChecker::QgsRenderChecker( ) :
   mReport(""),
   mExpectedImageFile(""),
+  mRenderedImageFile(""), 
   mMismatchCount(0),
   mMatchTarget(0),
   mElapsedTime(0),
@@ -53,10 +54,7 @@
   // Now render our layers onto a pixmap 
   //
   QImage myImage( myExpectedImage.width() , myExpectedImage.height(), QImage::Format_RGB32 );
-  QImage myDifferenceImage( myExpectedImage.width() , myExpectedImage.height(), QImage::Format_RGB32);
-  QString myResultDiffImage = QDir::tempPath() + QDir::separator() + theTestName + "_result_diff.png";
   myImage.fill ( qRgb( 152,219,249  ) );
-  myDifferenceImage.fill ( qRgb( 152,219,249 ) );
   QPainter myPainter( &myImage );
   mpMapRenderer->setOutputSize( QSize ( myExpectedImage.width(),myExpectedImage.height() ),72 ); 
   QTime myTime;
@@ -68,13 +66,47 @@
   // Save the pixmap to disk so the user can make a 
   // visual assessment if needed
   //
-  QString myResultImage = QDir::tempPath() + QDir::separator() + theTestName + "_result.png";
-  myImage.save (myResultImage);
+  mRenderedImageFile = QDir::tempPath() + QDir::separator() + theTestName + "_result.png";
+  myImage.save (mRenderedImageFile);
+  return compareImages(theTestName);
+
+}
+
+
+bool QgsRenderChecker::compareImages( QString theTestName )
+{
+  if (mExpectedImageFile.isEmpty())
+  {
+    qDebug("QgsRenderChecker::runTest failed - Expected Image (control) 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 "
+      "Image File not set.</td></tr></table>\n";
+    return false;
+  }
+  if (mRenderedImageFile.isEmpty())
+  {
+    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 "
+      "Image File not set.</td></tr></table>\n";
+    return false;
+  }
   //
+  // Load /create the images
+  //
+  QImage myExpectedImage (mExpectedImageFile);
+  QImage myResultImage (mRenderedImageFile);
+  QImage myDifferenceImage( myExpectedImage.width() , myExpectedImage.height(), QImage::Format_RGB32);
+  QString myResultDiffImage = QDir::tempPath() + QDir::separator() + theTestName + "_result_diff.png";
+  myDifferenceImage.fill ( qRgb( 152,219,249 ) );
+
+  //
   // Set pixel count score and target
   //
   mMatchTarget = myExpectedImage.width() * myExpectedImage.height();
-  int myPixelCount = myImage.width() * myImage.height();
+  int myPixelCount = myResultImage.width() * myResultImage.height();
   //
   // Set the report with the result
   //
@@ -82,37 +114,33 @@
   mReport += "<tr><td colspan=2>";
   mReport += "Test image and result image for " + theTestName + "<br>"
     "Expected size: " + QString::number(myExpectedImage.width()).toLocal8Bit() + "w x " + 
-                                QString::number(myExpectedImage.width()).toLocal8Bit() + "h (" +
-                                QString::number(mMatchTarget).toLocal8Bit() + " pixels)<br>"
-    "Actual   size: " + QString::number(myImage.width()).toLocal8Bit() + "w x " + 
-                                QString::number(myImage.width()).toLocal8Bit() + "h (" +
-                                QString::number(myPixelCount).toLocal8Bit() + " pixels)";
+    QString::number(myExpectedImage.width()).toLocal8Bit() + "h (" +
+    QString::number(mMatchTarget).toLocal8Bit() + " pixels)<br>"
+    "Actual   size: " + QString::number(myResultImage.width()).toLocal8Bit() + "w x " + 
+    QString::number(myResultImage.width()).toLocal8Bit() + "h (" +
+    QString::number(myPixelCount).toLocal8Bit() + " pixels)";
   mReport += "</td></tr>";
   mReport += "<tr><td colspan = 2>\n";
   mReport += "Expected Duration : <= " + QString::number(mElapsedTimeTarget) + 
-             "ms (0 indicates not specified)<br>";
+    "ms (0 indicates not specified)<br>";
   mReport += "Actual Duration :  " + QString::number(mElapsedTime) + "ms<br>";
   QString myImagesString= "</td></tr>"
     "<tr><td>Test Result:</td><td>Expected Result:</td><td>Difference (all blue is good, any red is bad)</td></tr>\n"
     "<tr><td><img src=\"file://" +
-  myResultImage +
+    mRenderedImageFile +
     "\"></td>\n<td><img src=\"file://" +
-  mExpectedImageFile +
+    mExpectedImageFile +
     "\"></td><td><img src=\"file://" +
-  myResultDiffImage  +
+    myResultDiffImage  +
     "\"></td>\n</tr>\n</table>";
   //
   // Put the same info to debug too
   //
-  qDebug ("Expected size: " + QString::number(myExpectedImage.width()).toLocal8Bit() + + "w x " + 
-                                QString::number(myExpectedImage.width()).toLocal8Bit() + + "h");
-  qDebug ("Actual   size: " + QString::number(myImage.width()).toLocal8Bit() + + "w x " + 
-                                QString::number(myImage.width()).toLocal8Bit() + + "h");
-  //
-  // Now load the renderered image and the expected image
-  // and then iterate through them counting how many 
-  // dissimilar pixel values there are
-  //
+  
+  qDebug ("Expected size: " + QString::number(myExpectedImage.width()).toLocal8Bit() + "w x " + 
+      QString::number(myExpectedImage.width()).toLocal8Bit() + "h");
+  qDebug ("Actual   size: " + QString::number(myResultImage.width()).toLocal8Bit() + "w x " + 
+      QString::number(myResultImage.width()).toLocal8Bit() + "h");
 
   if (mMatchTarget!= myPixelCount )
   {
@@ -123,13 +151,19 @@
     mReport += myImagesString;
     return false;
   }
+
+  //
+  // Now iterate through them counting how many 
+  // dissimilar pixel values there are
+  //
+  
   mMismatchCount = 0;
   for (int x = 0; x < myExpectedImage.width(); ++x) 
   {
     for (int y = 0; y < myExpectedImage.height(); ++y) 
     {
       QRgb myExpectedPixel = myExpectedImage.pixel(x,y);
-      QRgb myActualPixel = myImage.pixel(x,y);
+      QRgb myActualPixel = myResultImage.pixel(x,y);
       if (myExpectedPixel != myActualPixel)
       {
         ++mMismatchCount;
@@ -141,14 +175,14 @@
   //save the diff image to disk
   //
   myDifferenceImage.save (myResultDiffImage);
-  
+
   //
   // Send match result to debug
   //
   qDebug (QString::number(mMismatchCount).toLocal8Bit() + "/" +
-          QString::number(mMatchTarget).toLocal8Bit() + 
-    " pixels mismatched");; 
-  
+      QString::number(mMatchTarget).toLocal8Bit() + 
+      " pixels mismatched");; 
+
   //
   // Send match result to report
   //
@@ -158,7 +192,7 @@
     " pixels mismatched"; 
   mReport += "</td></tr>";
 
-  
+
   if ( mMismatchCount==0 )
   {
     mReport += "<tr><td colspan = 3>\n";

Modified: trunk/qgis/tests/src/core/qgsrenderchecker.h
===================================================================
--- trunk/qgis/tests/src/core/qgsrenderchecker.h	2008-07-29 09:17:31 UTC (rev 8946)
+++ trunk/qgis/tests/src/core/qgsrenderchecker.h	2008-07-29 16:17:47 UTC (rev 8947)
@@ -44,16 +44,27 @@
   int elapsedTime() { return mElapsedTime; };
   void setElapsedTimeTarget(int theTarget) { mElapsedTimeTarget = theTarget; };
   void setExpectedImage (QString theImageFileName) { mExpectedImageFile = theImageFileName; };
+  void setRenderedImage (QString theImageFileName) { mRenderedImageFile = theImageFileName; };
   void setMapRenderer ( QgsMapRender *  thepMapRenderer) { mpMapRenderer = thepMapRenderer; };
   /**
+   * Test using renderer to generate the image to be compared.
    * @param theTestName - to be used as the basis for writing a file to 
-   * /tmp/theTestName.png
+   * e.g. /tmp/theTestName.png
+   * @note make sure to call setExpectedImage and setMapRenderer first
    */
   bool runTest( QString theTestName );
 
+  /**
+   * Test using two arbitary images (map renderer will not be used)
+   * @param theTestName - to be used as the basis for writing a file to 
+   * e.g. /tmp/theTestName.png
+   * @note: make sure to call setExpectedImage and setRenderedImage first.
+   */
+  bool compareImages( QString theTestName );
 private:
   QString mReport;
   QString mExpectedImageFile;
+  QString mRenderedImageFile; 
   unsigned int mMismatchCount;
   unsigned int mMatchTarget;
   int mElapsedTime;

Modified: trunk/qgis/tests/src/core/testqgsgeometry.cpp
===================================================================
--- trunk/qgis/tests/src/core/testqgsgeometry.cpp	2008-07-29 09:17:31 UTC (rev 8946)
+++ trunk/qgis/tests/src/core/testqgsgeometry.cpp	2008-07-29 16:17:47 UTC (rev 8947)
@@ -21,6 +21,10 @@
 #include <QFileInfo>
 #include <QDir>
 #include <QDesktopServices>
+#include <QVector>
+#include <QPointF>
+#include <QImage>
+#include <QPainter>
 
 #include <iostream>
 //qgis includes...
@@ -28,6 +32,9 @@
 #include <qgsgeometry.h>
 #include <qgspoint.h>
 
+//qgs unit test utility class
+#include "qgsrenderchecker.h"
+
 /** \ingroup UnitTests
  * This is a unit test for the different geometry operations on vector features.
  */
@@ -40,10 +47,16 @@
     void init();// will be called before each testfunction is executed.
     void cleanup();// will be called after every testfunction.
 
-    void intersectionCheck();
+    void intersectionCheck1();
+    void intersectionCheck2();
     void unionCheck1();
     void unionCheck2();
+    void differenceCheck1();
+    void differenceCheck2();
+    void bufferCheck();
   private:
+    /** A helper method to do a render check to see if the geometry op is as expected */
+    bool renderCheck(QString theTestName, QString theComment="");
     /** A helper method to return wkb geometry type as a string */
     QString wkbTypeAsString( QGis::WKBTYPE theType );
     /** A helper method to dump to qdebug the geometry of a multipolygon */
@@ -73,6 +86,11 @@
     QgsGeometry * mpPolygonGeometryC;
 
     QString mTestDataDir;
+    QImage mImage;
+    QPainter * mpPainter;
+    QPen mPen1;
+    QPen mPen2;
+    QString mReport;
 };
 
 
@@ -89,10 +107,10 @@
   mPointB = QgsPoint(100.0,40.0); 
   mPointC = QgsPoint(100.0,100.0); 
   mPointD = QgsPoint(40.0,100.0); 
-  mPointW = QgsPoint(1000.0,1000.0); 
-  mPointX = QgsPoint(1040.0,1000.0); 
-  mPointY = QgsPoint(1040.0,1040.0); 
-  mPointZ = QgsPoint(1000.0,1040.0); 
+  mPointW = QgsPoint(200.0,200.0); 
+  mPointX = QgsPoint(240.0,200.0); 
+  mPointY = QgsPoint(240.0,240.0); 
+  mPointZ = QgsPoint(200.0,240.0); 
   
   mPolygonA.clear();
   mPolygonB.clear();
@@ -115,6 +133,33 @@
   mpPolygonGeometryB = QgsGeometry::fromPolygon(mPolygonB);
   mpPolygonGeometryC = QgsGeometry::fromPolygon(mPolygonC);
 
+  mImage = QImage ( 250,250, QImage::Format_RGB32 );
+  mImage.fill ( qRgb( 152,219,249  ) );
+  mpPainter = new QPainter(&mImage);
+
+  // Draw the test shapes first
+  mPen1 = QPen();
+  mPen1.setWidth(5);
+  mPen1.setBrush(Qt::green);
+  mpPainter->setPen(mPen1);
+  dumpPolygon(mPolygonA);
+  mPen1.setBrush(Qt::red);
+  mpPainter->setPen(mPen1);
+  dumpPolygon(mPolygonB);
+  mPen1.setBrush(Qt::blue);
+  mpPainter->setPen(mPen1);
+  dumpPolygon(mPolygonC);
+
+  mPen2 = QPen();
+  mPen2.setWidth(1);
+  mPen2.setBrush(Qt::black);
+  QBrush myBrush(Qt::DiagCrossPattern);
+
+
+  //set the pen to a different colour - 
+  //any test outs will be drawn in pen2
+  mpPainter->setPen(mPen2);
+  mpPainter->setBrush(myBrush);
 }
 
 void TestQgsGeometry::cleanup()
@@ -123,6 +168,7 @@
   delete mpPolygonGeometryA;
   delete mpPolygonGeometryB;
   delete mpPolygonGeometryC;
+  delete mpPainter;
 }
 
 void TestQgsGeometry::initTestCase()
@@ -134,19 +180,47 @@
   QString qgisPath = QCoreApplication::applicationDirPath ();
   QgsApplication::setPrefixPath(INSTALL_PREFIX, true);
   QgsApplication::showSettings();
+  mReport += "<h1>Geometry Tests</h1>\n";
+  mReport += "<p><font color=\"green\">Green = polygonA</font></p>\n";
+  mReport += "<p><font color=\"red\">Red = polygonB</font></p>\n";
+  mReport += "<p><font color=\"blue\">Blue = polygonC</font></p>\n";
 }
 
+
 void TestQgsGeometry::cleanupTestCase()
 {
   //
   // Runs once after all tests are run
   //
+  QString myReportFile = QDir::tempPath() + QDir::separator() + "geometrytest.html";
+  QFile myFile ( myReportFile);
+  if ( myFile.open ( QIODevice::WriteOnly ) )
+  {
+    QTextStream myQTextStream ( &myFile );
+    myQTextStream << mReport;
+    myFile.close();
+    QDesktopServices::openUrl("file://"+myReportFile);
+  }
   
 }
 
-void TestQgsGeometry::intersectionCheck()
+  
+
+void TestQgsGeometry::intersectionCheck1()
 {
   QVERIFY ( mpPolygonGeometryA->intersects(mpPolygonGeometryB));
+  // should be a single polygon as A intersect B
+  QgsGeometry * mypIntersectionGeometry  =  mpPolygonGeometryA->intersection(mpPolygonGeometryB);
+  qDebug ("Geometry Type: " + wkbTypeAsString(mypIntersectionGeometry->wkbType()).toLocal8Bit());
+  QVERIFY (mypIntersectionGeometry->wkbType() == QGis::WKBPolygon);
+  QgsPolygon myPolygon = mypIntersectionGeometry->asPolygon();
+  QVERIFY (myPolygon.size() > 0); //check that the union created a feature
+  dumpPolygon(myPolygon);
+  delete mypIntersectionGeometry;
+  QVERIFY(renderCheck("geometry_intersectionCheck1","Checking if A intersects B"));
+}
+void TestQgsGeometry::intersectionCheck2()
+{
   QVERIFY ( !mpPolygonGeometryA->intersects(mpPolygonGeometryC));
 }
 
@@ -159,7 +233,10 @@
   QgsMultiPolygon myMultiPolygon = mypUnionGeometry->asMultiPolygon();
   QVERIFY (myMultiPolygon.size() > 0); //check that the union did not fail
   dumpMultiPolygon(myMultiPolygon);
+  delete mypUnionGeometry;
+  QVERIFY(renderCheck("geometry_unionCheck1","Checking A union C produces 2 polys"));
 }
+
 void TestQgsGeometry::unionCheck2()
 {
   // should be a single polygon as A intersect B
@@ -170,8 +247,63 @@
   QVERIFY (myPolygon.size() > 0); //check that the union created a feature
   dumpPolygon(myPolygon);
   delete mypUnionGeometry;
+  QVERIFY(renderCheck("geometry_unionCheck2", "Checking A union B produces single union poly"));
 }
 
+void TestQgsGeometry::differenceCheck1()
+{
+  // should be same as A since A does not intersect C so diff is 100% of A
+  QgsGeometry * mypDifferenceGeometry  =  mpPolygonGeometryA->difference(mpPolygonGeometryC);
+  qDebug ("Geometry Type: " + wkbTypeAsString(mypDifferenceGeometry->wkbType()).toLocal8Bit());
+  QVERIFY (mypDifferenceGeometry->wkbType() == QGis::WKBPolygon);
+  QgsPolygon myPolygon = mypDifferenceGeometry->asPolygon();
+  QVERIFY (myPolygon.size() > 0); //check that the union did not fail
+  dumpPolygon(myPolygon);
+  delete mypDifferenceGeometry;
+  QVERIFY(renderCheck("geometry_differenceCheck1","Checking (A - C) = A"));
+}
+
+void TestQgsGeometry::differenceCheck2()
+{
+  // should be a single polygon as (A - B) = subset of A
+  QgsGeometry * mypDifferenceGeometry  =  mpPolygonGeometryA->difference(mpPolygonGeometryB);
+  qDebug ("Geometry Type: " + wkbTypeAsString(mypDifferenceGeometry->wkbType()).toLocal8Bit());
+  QVERIFY (mypDifferenceGeometry->wkbType() == QGis::WKBPolygon);
+  QgsPolygon myPolygon = mypDifferenceGeometry->asPolygon();
+  QVERIFY (myPolygon.size() > 0); //check that the union created a feature
+  dumpPolygon(myPolygon);
+  delete mypDifferenceGeometry;
+  QVERIFY(renderCheck("geometry_differenceCheck2", "Checking (A - B) = subset of A"));
+}
+void TestQgsGeometry::bufferCheck()
+{
+  // should be a single polygon
+  QgsGeometry * mypBufferGeometry  =  mpPolygonGeometryB->buffer(10,10);
+  qDebug ("Geometry Type: " + wkbTypeAsString(mypBufferGeometry->wkbType()).toLocal8Bit());
+  QVERIFY (mypBufferGeometry->wkbType() == QGis::WKBPolygon);
+  QgsPolygon myPolygon = mypBufferGeometry->asPolygon();
+  QVERIFY (myPolygon.size() > 0); //check that the buffer created a feature
+  dumpPolygon(myPolygon);
+  delete mypBufferGeometry;
+  QVERIFY(renderCheck("geometry_bufferCheck", "Checking buffer(10,10) of B"));
+}
+bool TestQgsGeometry::renderCheck(QString theTestName, QString theComment)
+{
+  mReport += "<h2>" + theTestName + "</h2>\n";
+  mReport += "<h3>" + theComment + "</h3>\n";
+  QString myTmpDir = QDir::tempPath() + QDir::separator() ;
+  QString myFileName = myTmpDir + theTestName + ".png";
+  QString myDataDir (TEST_DATA_DIR); //defined in CmakeLists.txt
+  QString myTestDataDir = myDataDir + QDir::separator();
+  mImage.save(myFileName,"PNG");
+  QgsRenderChecker myChecker;
+  myChecker.setExpectedImage ( myTestDataDir + "expected_" + theTestName + ".png" );
+  myChecker.setRenderedImage ( myFileName );
+  bool myResultFlag = myChecker.compareImages(theTestName);
+  mReport += myChecker.report();
+  return myResultFlag;
+}
+
 void TestQgsGeometry::dumpMultiPolygon( QgsMultiPolygon &theMultiPolygon )
 {
   qDebug ("Multipolygon Geometry Dump");
@@ -185,6 +317,7 @@
 
 void TestQgsGeometry::dumpPolygon( QgsPolygon &thePolygon )
 {
+  QVector<QPointF> myPoints;
   for ( int j = 0; j < thePolygon.size(); j++ )
   {
     QgsPolyline myPolyline = thePolygon.at( j ); //rings of polygon
@@ -194,8 +327,10 @@
     {
       QgsPoint myPoint = myPolyline.at( k );
       qDebug( "\t\t\tPoint in ring " + QString::number( k ).toLocal8Bit() + " :" + myPoint.stringRep().toLocal8Bit() );
+      myPoints << QPointF(myPoint.x(),myPoint.y());
     }
   }
+  mpPainter->drawPolygon(myPoints);
 }
 
 QString TestQgsGeometry::wkbTypeAsString( QGis::WKBTYPE theType )

Added: trunk/qgis/tests/testdata/expected_geometry_bufferCheck.png
===================================================================
(Binary files differ)


Property changes on: trunk/qgis/tests/testdata/expected_geometry_bufferCheck.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/qgis/tests/testdata/expected_geometry_differenceCheck1.png
===================================================================
(Binary files differ)


Property changes on: trunk/qgis/tests/testdata/expected_geometry_differenceCheck1.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/qgis/tests/testdata/expected_geometry_differenceCheck2.png
===================================================================
(Binary files differ)


Property changes on: trunk/qgis/tests/testdata/expected_geometry_differenceCheck2.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/qgis/tests/testdata/expected_geometry_intersectionCheck1.png
===================================================================
(Binary files differ)


Property changes on: trunk/qgis/tests/testdata/expected_geometry_intersectionCheck1.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/qgis/tests/testdata/expected_geometry_unionCheck1.png
===================================================================
(Binary files differ)


Property changes on: trunk/qgis/tests/testdata/expected_geometry_unionCheck1.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/qgis/tests/testdata/expected_geometry_unionCheck2.png
===================================================================
(Binary files differ)


Property changes on: trunk/qgis/tests/testdata/expected_geometry_unionCheck2.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream



More information about the QGIS-commit mailing list