From 7ff31d79023d2d1017e16a2ef46380c1cc57787b Mon Sep 17 00:00:00 2001
From: Gennady Pospelov <g.pospelov@fz-juelich.de>
Date: Fri, 8 Dec 2017 12:47:16 +0100
Subject: [PATCH] Preparing to migrate GUI unit tests to google test

---
 Tests/UnitTests/CMakeLists.txt                |   5 +
 Tests/UnitTests/Core/CMakeLists.txt           |   1 -
 Tests/UnitTests/Core/main.cpp                 |  32 -----
 Tests/UnitTests/GUI2/CMakeLists.txt           |  39 ++++++
 Tests/UnitTests/GUI2/TestComboProperty.h      | 126 ++++++++++++++++++
 Tests/UnitTests/GUI2/TestGUI.cpp              |  25 ++++
 Tests/UnitTests/GUI2/test_utils.cpp           |  26 ++++
 Tests/UnitTests/GUI2/test_utils.h             |  62 +++++++++
 .../{Core/utils => utilities}/google_test.h   |   8 +-
 9 files changed, 288 insertions(+), 36 deletions(-)
 delete mode 100644 Tests/UnitTests/Core/main.cpp
 create mode 100644 Tests/UnitTests/GUI2/CMakeLists.txt
 create mode 100644 Tests/UnitTests/GUI2/TestComboProperty.h
 create mode 100644 Tests/UnitTests/GUI2/TestGUI.cpp
 create mode 100644 Tests/UnitTests/GUI2/test_utils.cpp
 create mode 100644 Tests/UnitTests/GUI2/test_utils.h
 rename Tests/UnitTests/{Core/utils => utilities}/google_test.h (74%)

diff --git a/Tests/UnitTests/CMakeLists.txt b/Tests/UnitTests/CMakeLists.txt
index 0ac9fc5affa..70be9b2fe4b 100644
--- a/Tests/UnitTests/CMakeLists.txt
+++ b/Tests/UnitTests/CMakeLists.txt
@@ -8,5 +8,10 @@ if(UNITTESTS)
 
     if(BORNAGAIN_GUI)
         add_subdirectory(GUI)
+        add_subdirectory(GUI2)
     endif()
+
+    # to show directory in Qt creator project tree
+    FILE(GLOB_RECURSE UtilityFiles "utilities/*.h")
+    add_custom_target(UnitTestUtilities SOURCES ${UtilityFiles})
 endif()
diff --git a/Tests/UnitTests/Core/CMakeLists.txt b/Tests/UnitTests/Core/CMakeLists.txt
index bbcb53d2fad..f2b228a4dd2 100644
--- a/Tests/UnitTests/Core/CMakeLists.txt
+++ b/Tests/UnitTests/Core/CMakeLists.txt
@@ -13,7 +13,6 @@ include_directories(
     ${GSL_INCLUDE_DIR}
     ${gtest_SOURCE_DIR}
     ${gtest_SOURCE_DIR}/include
-    utils/
     )
 if(BORNAGAIN_OPENMPI)
     include_directories(${MPI_INCLUDE_PATH})
diff --git a/Tests/UnitTests/Core/main.cpp b/Tests/UnitTests/Core/main.cpp
deleted file mode 100644
index 78ad33c8d72..00000000000
--- a/Tests/UnitTests/Core/main.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifdef _MSC_VER
-#define _VARIADIC_MAX 10
-#endif
-#include <gtest/gtest.h>
-
-#include "testlist.h"
-
-struct ErrorStreamRedirect {
-    ErrorStreamRedirect( std::streambuf* new_buffer )
-        : old( std::cerr.rdbuf(new_buffer) )
-    {}
-
-    ~ErrorStreamRedirect() {
-        std::cerr.rdbuf(old);
-    }
-
-private:
-    std::streambuf* old;
-};
-
-int main(int argc, char** argv)
-{
-    ::testing::InitGoogleTest(&argc, argv);
-
-    // redirect std::cerr stream
-    std::stringstream oss;
-    ErrorStreamRedirect redirecter( oss.rdbuf() );
-    (void)redirecter;
-
-    // run all google tests
-    return RUN_ALL_TESTS();
-}
diff --git a/Tests/UnitTests/GUI2/CMakeLists.txt b/Tests/UnitTests/GUI2/CMakeLists.txt
new file mode 100644
index 00000000000..526bc502f79
--- /dev/null
+++ b/Tests/UnitTests/GUI2/CMakeLists.txt
@@ -0,0 +1,39 @@
+
+set(TestName TestGUI2)
+
+if(POLICY CMP0020)
+    cmake_policy(SET CMP0020 NEW)
+endif()
+if(POLICY CMP0043)
+    cmake_policy(SET CMP0043 NEW)
+endif()
+
+file(GLOB source_files "*.cpp")
+file(GLOB include_files "*.h")
+
+find_package(Qt5Widgets REQUIRED)
+
+include_directories(
+    ../utilities
+    ${Boost_INCLUDE_DIRS}
+    ${BornAgainCore_INCLUDE_DIRS}
+    ${EIGEN3_INCLUDE_DIR}
+    ${GSL_INCLUDE_DIR}
+    ${BornAgainGUI_INCLUDE_DIRS}
+    ${BornAgainFit_INCLUDE_DIRS}
+    ${gtest_SOURCE_DIR}
+    ${gtest_SOURCE_DIR}/include
+)
+
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DGTEST_LINKED_AS_SHARED_LIBRARY=1")
+
+set(CMAKE_AUTOMOC ON)
+
+add_executable(${TestName} ${source_files} ${include_files})
+
+target_link_libraries(${TestName} ${BornAgainGUI_LIBRARY} gtest)
+
+qt5_use_modules(${TestName} Widgets Core Gui Designer PrintSupport Network)
+
+# add execution of TestCore just after compilation
+add_custom_target(${TestName}Target ALL DEPENDS TestGUI COMMAND ${TestName})
diff --git a/Tests/UnitTests/GUI2/TestComboProperty.h b/Tests/UnitTests/GUI2/TestComboProperty.h
new file mode 100644
index 00000000000..f82533a7892
--- /dev/null
+++ b/Tests/UnitTests/GUI2/TestComboProperty.h
@@ -0,0 +1,126 @@
+#include "google_test.h"
+#include "ComboProperty.h"
+#include "test_utils.h"
+
+class TestComboProperty :  public ::testing::Test
+{
+public:
+    ~TestComboProperty();
+    ComboProperty propertyFromXML(const QString& buffer) {
+        return TestUtils::propertyFromXML<ComboProperty>(buffer);
+    }
+
+};
+
+TestComboProperty::~TestComboProperty() = default;
+
+TEST_F(TestComboProperty, test_ComboEquality)
+{
+    EXPECT_EQ(1, 1);
+        ComboProperty c1;
+        ComboProperty c2;
+        EXPECT_TRUE(c1 == c2);
+
+        c1 << "a1" << "a2";
+        c2 << "a1" << "a2";
+        EXPECT_TRUE(c1 == c2);
+
+        c2 << "a3";
+        EXPECT_TRUE(c1 != c2);
+        c2.setValue("a2");
+        EXPECT_TRUE(c1 != c2);
+
+        c1 << "a3";
+        c1.setValue("a2");
+        EXPECT_TRUE(c1 == c2);
+}
+
+TEST_F(TestComboProperty, test_VariantEquality)
+{
+    QVariant v1(1.0);
+    QVariant v2(2.0);
+    QVariant v3(2.0);
+    EXPECT_TRUE(v1 != v2);
+    EXPECT_TRUE(v2 == v3);
+
+    ComboProperty c1 = ComboProperty() << "a1" << "a2";
+    ComboProperty c2 = ComboProperty() << "a1" << "a2";
+    EXPECT_TRUE(c1.variant() == c2.variant());
+
+    c2 << "a3";
+    EXPECT_TRUE(c1.variant() != c2.variant());
+    c2.setValue("a2");
+    EXPECT_TRUE(c1.variant() != c2.variant());
+
+    c1 << "a3";
+    c1.setValue("a2");
+    EXPECT_TRUE(c1.variant() == c2.variant());
+}
+
+TEST_F(TestComboProperty, test_setValue)
+{
+    QStringList expectedValues = QStringList() << "a1" << "a2";
+    ComboProperty combo = ComboProperty() << expectedValues;
+
+    EXPECT_EQ(combo.getValue(), QString("a1"));
+
+    QStringList newValues = QStringList() << "b1" << "b2" << "b3";
+    combo.setValues(newValues);
+    EXPECT_EQ(combo.getValue(), QString("b1"));
+    EXPECT_EQ(combo.getValues(), newValues);
+
+    // checking that old value is preserved
+    newValues = QStringList() << "c1" << "b1" << "c2";
+    combo.setValues(newValues);
+    EXPECT_EQ(combo.getValue(), QString("b1"));
+    EXPECT_EQ(combo.getValues(), newValues);
+}
+
+TEST_F(TestComboProperty, test_currentIndex)
+{
+    ComboProperty combo;
+    EXPECT_EQ(combo.currentIndex(), -1);
+    combo << "c1" << "c2";
+    EXPECT_EQ(combo.currentIndex(), 0);
+    combo.setValue("c2");
+    EXPECT_EQ(combo.currentIndex(), 1);
+
+    combo.setCurrentIndex(0);
+    EXPECT_EQ(combo.getValue(), QString("c1"));
+}
+
+TEST_F(TestComboProperty, test_stringOfValues)
+{
+    QStringList expectedValues = QStringList() << "a1" << "a2";
+    ComboProperty combo = ComboProperty() << expectedValues;
+
+    EXPECT_EQ(combo.stringOfValues(), QString("a1;a2"));
+
+    // setting string of values, current value should change
+    QString stringOfValues("b1;b2;b3");
+    combo.setStringOfValues(stringOfValues);
+    EXPECT_EQ(combo.stringOfValues(), stringOfValues);
+    EXPECT_EQ(combo.getValue(), QString("b1"));
+
+    // setting new string of values, containing current value. Current values should remain.
+    stringOfValues = QString("c1;b1;c3");
+    combo.setStringOfValues(stringOfValues);
+    EXPECT_EQ(combo.stringOfValues(), stringOfValues);
+    EXPECT_EQ(combo.getValue(), QString("b1"));
+}
+
+TEST_F(TestComboProperty, test_comboXML)
+{
+    // Writing combo to XML
+    ComboProperty combo = ComboProperty() << "a1" << "a2" << "a3";
+
+    QString expected = "<Parameter ParType=\"ComboProperty\" ParRole=\"0\" ParValue=\"0\" "
+                       "ParExt=\"a1;a2;a3\"/>";
+    EXPECT_EQ(TestUtils::propertyToXML(combo), expected);
+
+    // reading from XML
+    ComboProperty combo_property = propertyFromXML(expected);
+    EXPECT_EQ(combo_property.getValue(), QString("a1"));
+    EXPECT_EQ(combo_property.stringOfValues(), QString("a1;a2;a3"));
+    EXPECT_TRUE(combo_property == combo);
+}
diff --git a/Tests/UnitTests/GUI2/TestGUI.cpp b/Tests/UnitTests/GUI2/TestGUI.cpp
new file mode 100644
index 00000000000..449c1920c55
--- /dev/null
+++ b/Tests/UnitTests/GUI2/TestGUI.cpp
@@ -0,0 +1,25 @@
+#include "google_test.h"
+#include <QString>
+#include <QCoreApplication>
+#include "ComboProperty.h"
+#include "TestComboProperty.h"
+#include <memory>
+
+#include "ErrorStreamRedirect.h"
+
+int main(int argc, char** argv) {
+    QCoreApplication app(argc, argv);
+    Q_UNUSED(app);
+
+    QMetaType::registerComparators<ComboProperty>();
+
+    ::testing::InitGoogleTest(&argc, argv);
+
+    // redirect std::cerr stream
+    std::stringstream oss;
+    ErrorStreamRedirect redirecter( oss.rdbuf() );
+    (void)redirecter;
+
+    // run all google tests
+    return RUN_ALL_TESTS();
+}
diff --git a/Tests/UnitTests/GUI2/test_utils.cpp b/Tests/UnitTests/GUI2/test_utils.cpp
new file mode 100644
index 00000000000..60f6f3cd544
--- /dev/null
+++ b/Tests/UnitTests/GUI2/test_utils.cpp
@@ -0,0 +1,26 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      Tests/UnitTests/GUI/test_utils.h
+//! @brief     Implements auxiliary test functions in a namespace.
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2015
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#include "test_utils.h"
+#include "ProjectUtils.h"
+#include "GUIHelpers.h"
+
+void TestUtils::create_dir(const QString& dir_name)
+{
+    if (ProjectUtils::exists(dir_name))
+        ProjectUtils::removeRecursively(dir_name);
+
+    GUIHelpers::createSubdir(".", dir_name);
+}
diff --git a/Tests/UnitTests/GUI2/test_utils.h b/Tests/UnitTests/GUI2/test_utils.h
new file mode 100644
index 00000000000..1516eee6e26
--- /dev/null
+++ b/Tests/UnitTests/GUI2/test_utils.h
@@ -0,0 +1,62 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      Tests/UnitTests/GUI/test_utils.h
+//! @brief     Defines auxiliary test functions in a namespace.
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2015
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#ifndef TEST_UTILS
+#define TEST_UTILS
+
+#include <QString>
+#include "SessionXML.h"
+#include "PropertyItem.h"
+#include <QXmlStreamWriter>
+
+namespace TestUtils
+{
+
+//! Creates directory in current working directory. If such directory already exists,
+//! it will be removed with all its content.
+void create_dir(const QString& dir_name);
+
+
+//! Converts property to XML string
+template <typename T>
+QString propertyToXML(const T& property)
+{
+    QString result;
+    QXmlStreamWriter writer(&result);
+    SessionXML::writeVariant(&writer, property.variant(), /*role*/0);
+    return result;
+}
+
+//! Converts XML string to property
+template <typename T>
+T propertyFromXML(const QString& buffer) {
+    std::unique_ptr<PropertyItem> item(new PropertyItem);
+    QXmlStreamReader reader(buffer);
+
+    while (!reader.atEnd()) {
+        reader.readNext();
+        if (reader.isStartElement()) {
+            if (reader.name() == SessionXML::ParameterTag) {
+                SessionXML::readProperty(&reader, item.get());
+            }
+        }
+    }
+
+    return item->value().value<T>();
+}
+
+}
+
+#endif // TEST_UTILS
diff --git a/Tests/UnitTests/Core/utils/google_test.h b/Tests/UnitTests/utilities/google_test.h
similarity index 74%
rename from Tests/UnitTests/Core/utils/google_test.h
rename to Tests/UnitTests/utilities/google_test.h
index 8d92be21ef0..a0757d8afa7 100644
--- a/Tests/UnitTests/Core/utils/google_test.h
+++ b/Tests/UnitTests/utilities/google_test.h
@@ -1,8 +1,10 @@
-// include this header file for each Unit Test
-
 #ifndef GOOGLE_TEST_H
 #define GOOGLE_TEST_H
 
+#ifdef _MSC_VER
+#define _VARIADIC_MAX 10
+#endif
+
 #ifdef _WIN32
 #pragma warning ( push )
 #pragma warning ( disable: 4275 )
@@ -12,5 +14,5 @@
 #include <gtest/gtest.h>
 #endif
 
+#endif
 
-#endif //GOOGLE_TEST_H
-- 
GitLab