Преглед на файлове

Merge pull request #732 from msmolens/ci-enable-widgets

Test widgets on CI
Max Smolens преди 7 години
родител
ревизия
36458b3b37

+ 15 - 2
CMake/CircleCI/CircleCI_CTK_Docker.cmake

@@ -67,20 +67,33 @@ set( CMAKE_BUILD_TYPE "${SITE_BUILD_TYPE}")
 set( BUILD_TESTING ON )
 set( CTK_BUILD_EXAMPLES OFF )
 
+# Disable MIT_SHM X11 extension
+set( ENV{QT_X11_NO_MITSHM} 1 )
 
 ###################
 
+set(ctk_configure_options
+  -DCTK_QT_VERSION:STRING=${CTK_QT_VERSION}
+  -DCTK_ENABLE_Widgets:BOOL=ON
+  )
 
 ctest_start( "${SITE_CTEST_MODE}" )
 
 ctest_configure(
   BUILD "${CTK_BINARY_DIR}"
   SOURCE "${CTK_SOURCE_DIR}"
-  OPTIONS -DCTK_QT_VERSION:STRING=${CTK_QT_VERSION}
+  OPTIONS "${ctk_configure_options}"
   )
 
 ctest_build( BUILD ${CTK_BINARY_DIR} )
 
-ctest_test( BUILD ${CTEST_BINARY_DIRECTORY} )
+ctest_test(
+  BUILD ${CTEST_BINARY_DIRECTORY}
+  RETURN_VALUE result
+  )
 
 ctest_submit()
+
+if(result)
+  message(FATAL_ERROR "ERROR: Tests failed")
+endif()

+ 3 - 3
Libs/Core/Testing/Cpp/ctkAbstractFactoryTest1.cpp

@@ -109,10 +109,10 @@ int ctkAbstractFactoryTest1(int argc, char * argv [] )
     }
   factory.registerItems();
   if (factory.itemKeys().count() != 2 ||
-      factory.itemKeys()[0] != "item1" ||
-      factory.itemKeys()[1] != "item2")
+      !factory.itemKeys().contains("item1") ||
+      !factory.itemKeys().contains("item2"))
     {
-    std::cerr<< "ctkAbstractFactory::keys() failed" << std::endl;
+    std::cerr<< "ctkAbstractFactory::itemKeys() failed" << std::endl;
     return EXIT_FAILURE;
     }
   item1 = factory.instantiate("item1");

+ 2 - 0
Libs/Widgets/CMakeLists.txt

@@ -197,6 +197,8 @@ set(KIT_SRCS
   ctkTransferFunctionView.h
   ctkTreeComboBox.cpp
   ctkTreeComboBox.h
+  ctkWidgetsTestingUtilities.cpp
+  ctkWidgetsTestingUtilities.h
   ctkWidgetsUtils.cpp
   ctkWidgetsUtils.h
   ctkWorkflowAbstractPagedWidget.cpp

+ 3 - 1
Libs/Widgets/Testing/Cpp/CMakeLists.txt

@@ -56,6 +56,7 @@ set(TEST_SOURCES
   ctkFlowLayoutTest1.cpp
   ctkFontButtonTest.cpp
   ctkHistogramTest1.cpp
+  ctkLanguageComboBoxTest.cpp
   ctkLayoutManagerTest1.cpp
   ctkMaterialPropertyPreviewLabelTest1.cpp
   ctkMaterialPropertyWidgetTest1.cpp
@@ -101,6 +102,7 @@ set(TEST_SOURCES
   ctkTransferFunctionRepresentationTest1.cpp
   ctkTransferFunctionRepresentationTest2.cpp
   ctkTreeComboBoxTest1.cpp
+  ctkWidgetsTestingUtilitiesTest.cpp
   ctkWidgetsUtilsTest1.cpp
   ctkWidgetsUtilsTestGrabWidget.cpp
   ctkWorkflowWidgetTest1.cpp
@@ -144,7 +146,6 @@ if(CTK_USE_QTTESTING)
     ctkExpandButtonEventTranslatorPlayerTest1.cpp
     ctkFileDialogEventTranslatorPlayerTest1.cpp
     ctkFontButtonEventTranslatorPlayerTest1.cpp
-    ctkLanguageComboBoxTest.cpp
     ctkMaterialPropertyWidgetEventTranslatorPlayerTest1.cpp
     ctkMatrixWidgetEventTranslatorPlayerTest1.cpp
     ctkMenuButtonEventTranslatorPlayerTest1.cpp
@@ -364,6 +365,7 @@ SIMPLE_TEST( ctkTransferFunctionTest1 )
 SIMPLE_TEST( ctkTransferFunctionRepresentationTest1 )
 SIMPLE_TEST( ctkTransferFunctionRepresentationTest2 )
 SIMPLE_TEST( ctkTreeComboBoxTest1 )
+SIMPLE_TEST( ctkWidgetsTestingUtilitiesTest )
 SIMPLE_TEST( ctkWidgetsUtilsTest1 )
 SIMPLE_TEST( ctkWidgetsUtilsTestGrabWidget )
 SIMPLE_TEST( ctkWorkflowWidgetTest1 )

+ 3 - 2
Libs/Widgets/Testing/Cpp/ctkCrosshairLabelTest2.cpp

@@ -28,6 +28,7 @@
 // CTK includes
 #include "ctkCrosshairLabel.h"
 #include "ctkCommandLineParser.h"
+#include "ctkWidgetsTestingUtilities.h"
 
 // STD includes
 #include <cstdlib>
@@ -39,7 +40,8 @@ bool imageCompare(ctkCrosshairLabel& crosshair, QString baselineDirectory,
 {
   QImage output = QPixmap::grabWidget(&crosshair).toImage();
   QImage baseline(baselineDirectory + "/" + baselineFilename);
-  return output == baseline;
+  const float percentThreshold = 1.5f;
+  return ctkWidgetsTestingUtilities::CheckImagesEqual(output, baseline, percentThreshold);
 }
 
 //-----------------------------------------------------------------------------
@@ -116,7 +118,6 @@ int ctkCrosshairLabelTest2(int argc, char * argv [] )
   // Odd widget size
   crosshair.setMinimumSize(baseSize);
   crosshair.setPixmap(pixmap.scaled(baseSize));
-  crosshair.show();
 
   // Test bullsEyeWidth and line width with odd widget size
   crosshair.setCrosshairType(ctkCrosshairLabel::BullsEyeCrosshair);

+ 1 - 1
Libs/Widgets/Testing/Cpp/ctkErrorLogQtMessageHandlerWithThreadsTest1.cpp

@@ -74,7 +74,7 @@ int ctkErrorLogQtMessageHandlerWithThreadsTest1(int argc, char * argv [])
     model.registerMsgHandler(new ctkErrorLogQtMessageHandler);
     model.setMsgHandlerEnabled(ctkErrorLogQtMessageHandler::HandlerName, true);
 
-    int threadCount = 15;
+    int threadCount = 10;
     int maxIteration = 5;
     int messagesPerIteration = 3;
     startLogMessageThreads<LogQtMessageThread>(threadCount, maxIteration);

+ 1 - 1
Libs/Widgets/Testing/Cpp/ctkLanguageComboBoxTest.cpp

@@ -92,7 +92,7 @@ void ctkLanguageComboBoxTester::testSetDefaultLanguage_data()
   QTest::newRow("en_GB") << QString("en_GB") << QString("en_GB") << QString("en_GB");
   QTest::newRow("fr") << QString("fr") << QString("fr_FR") << QString("fr_FR");
   QTest::newRow("de_CH") << QString("de_CH") << QString("de_CH") << QString("de_CH");
-  QTest::newRow("de_ch") << QString("de_ch") << QString("de_DE") << QString("de_DE");
+  QTest::newRow("de_DE") << QString("de_DE") << QString("de_DE") << QString("de_DE");
   QTest::newRow("xx") << QString("xx") << QString() << QString();
   QTest::newRow("xx_yy") << QString("xx_yy") << QString() << QString();
   QTest::newRow("_en") << QString("_en") << QString() << QString();

+ 1 - 1
Libs/Widgets/Testing/Cpp/ctkScreenshotDialogTest1.cpp

@@ -42,7 +42,7 @@ int ctkScreenshotDialogTest1(int argc, char * argv [] )
   // Check default values
   if (screenshotDialog.widgetToGrab() != 0 ||
       screenshotDialog.baseFileName() != "Untitled" ||
-      screenshotDialog.directory() != "." ||
+      !screenshotDialog.directory().isEmpty() ||
       screenshotDialog.delay() != 0)
     {
     std::cerr << "ctkScreenshotDialog, bad default values: "

+ 175 - 0
Libs/Widgets/Testing/Cpp/ctkWidgetsTestingUtilitiesTest.cpp

@@ -0,0 +1,175 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0.txt
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=========================================================================*/
+
+// CTK includes
+#include "ctkWidgetsTestingUtilities.h"
+
+// Qt includes
+#include <QColor>
+#include <QImage>
+
+// STD includes
+#include <iostream>
+
+using namespace ctkWidgetsTestingUtilities;
+
+//----------------------------------------------------------------------------
+bool TestCheckImagesEqual();
+
+//----------------------------------------------------------------------------
+int ctkWidgetsTestingUtilitiesTest(int , char * [])
+{
+  bool res = true;
+  res = res && TestCheckImagesEqual();
+  return res ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+
+//----------------------------------------------------------------------------
+bool TestCheckImagesEqual()
+{
+  {
+    // Invalid format
+    QImage a(1, 1, QImage::Format_Invalid);
+    QImage b(1, 1, QImage::Format_Invalid);
+    if (CheckImagesEqual(a, b))
+      {
+      std::cerr << "Line " << __LINE__ << " - CheckImagesEqual failed" << std::endl;
+      return false;
+      }
+  }
+
+  {
+    // Unsupported format
+    QImage a(1, 1, QImage::Format_ARGB32);
+    QImage b(1, 1, QImage::Format_ARGB32);
+    if (CheckImagesEqual(a, b))
+      {
+      std::cerr << "Line " << __LINE__ << " - CheckImagesEqual failed" << std::endl;
+      return false;
+      }
+  }
+
+  {
+    // One image in unsupported format
+    QImage a(1, 1, QImage::Format_RGB32);
+    QImage b(1, 1, QImage::Format_ARGB32);
+    if (CheckImagesEqual(a, b))
+      {
+      std::cerr << "Line " << __LINE__ << " - CheckImagesEqual failed" << std::endl;
+      return false;
+      }
+
+    QImage c(1, 1, QImage::Format_ARGB32);
+    QImage d(1, 1, QImage::Format_RGB32);
+    if (CheckImagesEqual(c, d))
+      {
+      std::cerr << "Line " << __LINE__ << " - CheckImagesEqual failed" << std::endl;
+      return false;
+      }
+  }
+
+  {
+    // Images of different size
+    QImage a(1, 1, QImage::Format_RGB32);
+    QImage b(2, 1, QImage::Format_RGB32);
+    if (CheckImagesEqual(a, b))
+      {
+      std::cerr << "Line " << __LINE__ << " - CheckImagesEqual failed" << std::endl;
+      return false;
+      }
+
+    QImage c(1, 2, QImage::Format_ARGB32);
+    QImage d(1, 1, QImage::Format_RGB32);
+    if (CheckImagesEqual(c, d))
+      {
+      std::cerr << "Line " << __LINE__ << " - CheckImagesEqual failed" << std::endl;
+      return false;
+      }
+  }
+
+  {
+    // Identical images
+    QImage a(10, 10, QImage::Format_RGB32);
+    a.fill(Qt::green);
+    QImage b(10, 10, QImage::Format_RGB32);
+    b.fill(Qt::green);
+    if (!CheckImagesEqual(a, b, 0.0f))
+      {
+      std::cerr << "Line " << __LINE__ << " - CheckImagesEqual failed" << std::endl;
+      return false;
+      }
+
+    // Change one pixel in first image
+    a.setPixel(2, 3, qRgb(255, 0, 0));
+    if (CheckImagesEqual(a, b, 0.f))
+      {
+      std::cerr << "Line " << __LINE__ << " - CheckImagesEqual failed" << std::endl;
+      return false;
+      }
+
+    // Percent threshold not met
+    if (CheckImagesEqual(a, b, 0.5f))
+      {
+      std::cerr << "Line " << __LINE__ << " - CheckImagesEqual failed" << std::endl;
+      return false;
+      }
+
+    // Percent threshold met
+    if (!CheckImagesEqual(a, b, 1.f))
+      {
+      std::cerr << "Line " << __LINE__ << " - CheckImagesEqual failed" << std::endl;
+      return false;
+      }
+
+    // Change one pixel in other image
+    // Percent threshold not met
+    b.setPixel(4, 5, qRgb(255, 255, 0));
+    if (CheckImagesEqual(a, b, 1.f))
+      {
+      std::cerr << "Line " << __LINE__ << " - CheckImagesEqual failed" << std::endl;
+      return false;
+      }
+
+    // Percent threshold met
+    if (!CheckImagesEqual(a, b, 2.f))
+      {
+      std::cerr << "Line " << __LINE__ << " - CheckImagesEqual failed" << std::endl;
+      return false;
+      }
+
+    // Change one pixel in first image to match second image
+    a.setPixel(4, 5, qRgb(255, 255, 0));
+    if (!CheckImagesEqual(a, b, 1.f))
+      {
+      std::cerr << "Line " << __LINE__ << " - CheckImagesEqual failed" << std::endl;
+      return false;
+      }
+
+    // Identical images
+    b.setPixel(2, 3, qRgb(255, 0, 0));
+    if (!CheckImagesEqual(a, b, 0.f))
+      {
+      std::cerr << "Line " << __LINE__ << " - CheckImagesEqual failed" << std::endl;
+      return false;
+      }
+  }
+
+  return true;
+}

+ 1 - 1
Libs/Widgets/ctkDoubleSpinBox.h

@@ -320,7 +320,7 @@ Q_SIGNALS:
   void decimalsChanged(int);
 
 protected:
-  QScopedPointer<ctkDoubleSpinBoxPrivate> d_ptr;
+  ctkDoubleSpinBoxPrivate* const d_ptr;
 
   /// Reimplemented to support shortcuts.
   virtual void keyPressEvent(QKeyEvent* event);

+ 1 - 1
Libs/Widgets/ctkDoubleSpinBox_p.h

@@ -59,7 +59,7 @@ public:
   /// Expose publicly QAbstractSpinBox::initStyleOption()
   void initStyleOptionSpinBox(QStyleOptionSpinBox* option);
 protected:
-  ctkDoubleSpinBoxPrivate* const d_ptr;
+  QScopedPointer<ctkDoubleSpinBoxPrivate> d_ptr;
 
   /// If the invertedControls property is false (by default) then this function
   /// behavesLike QDoubleSpinBox::stepEnabled(). If the property is true then

+ 53 - 0
Libs/Widgets/ctkWidgetsTestingUtilities.cpp

@@ -0,0 +1,53 @@
+// CTK includes
+#include "ctkWidgetsTestingUtilities.h"
+
+// Qt includes
+#include <QImage>
+
+// STD includes
+#include <iostream>
+
+namespace ctkWidgetsTestingUtilities
+{
+//---------------------------------------------------------------------------- */
+bool CheckImagesEqual(const QImage& current, const QImage& expected,
+                      float percentThreshold)
+{
+  if (current.width() != expected.width() ||
+      current.height() != expected.height() ||
+      current.format() != expected.format())
+    {
+    return false;
+    }
+
+  if (current.format() != QImage::Format_RGB32)
+    {
+    std::cerr << "ERROR: CheckImagesEqual: Unsupported QImage::Format: "
+              << static_cast<int>(current.format()) << std::endl;
+    return false;
+    }
+
+  // Compute number of pixels that differ, masking out alpha channel.
+  // Based on QImage::operator== implementation.
+  unsigned long numDiffs = 0;
+  for (int line = 0; line < current.height(); line++)
+    {
+    int w = current.width();
+    const QRgb* p1 = reinterpret_cast<const QRgb*>(current.constScanLine(line));
+    const QRgb* p2 = reinterpret_cast<const QRgb*>(expected.constScanLine(line));
+    while (w--)
+      {
+      if ((*p1++ & 0x00ffffff) != (*p2++ & 0x00ffffff))
+        {
+        ++numDiffs;
+        }
+      }
+    }
+
+  const int numPixels = current.width() * current.height();
+  const float percentDifferent = (numPixels > 0) ? ((100.f * numDiffs) / numPixels) : 0.f;
+  return (percentDifferent <= percentThreshold);
+}
+
+} // namespace ctkWidgetsTestingUtilities
+

+ 42 - 0
Libs/Widgets/ctkWidgetsTestingUtilities.h

@@ -0,0 +1,42 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0.txt
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=========================================================================*/
+
+#ifndef __ctkWidgetsTestingUtilities_h
+#define __ctkWidgetsTestingUtilities_h
+
+// CTK includes
+#include <ctkWidgetsExport.h>
+
+class QImage;
+
+/// This module provides functions to facilitate writing tests.
+
+namespace ctkWidgetsTestingUtilities
+{
+
+/// Check that two images are equal. Allow for the specified percentage of
+/// pixels to be different.
+CTK_WIDGETS_EXPORT
+bool CheckImagesEqual(const QImage& current, const QImage& expected,
+                      float percentThreshold=0.f);
+
+} // namespace ctkWidgetsTestingUtilities
+
+#endif