From 4c6e5cd0fae57684411d6bf814b4fcc4434c1f50 Mon Sep 17 00:00:00 2001 From: Kyle Edwards Date: Mon, 14 Sep 2020 14:48:07 -0400 Subject: Tests: Add some basic tests for CMake GUI --- Tests/CMakeGUI/CMakeGUITest.cmake | 111 +++++++++++++++++++++ Tests/CMakeGUI/CMakeGUITest.cxx | 89 +++++++++++++++++ Tests/CMakeGUI/CMakeGUITest.h | 21 ++++ Tests/CMakeGUI/CMakeLists.txt | 49 +++++++++ Tests/CMakeGUI/QCMakeCacheModelTest.cxx | 108 ++++++++++++++++++++ Tests/CMakeGUI/QCMakeCacheModelTest.h | 14 +++ .../sourceBinaryArgs-binaryDir/CMakeLists.txt.in | 2 + .../CMakeSetup.ini.in | 2 + .../CMakeLists.txt.in | 2 + .../CMakeSetup.ini.in | 2 + .../sourceBinaryArgs-sourceDir/CMakeLists.txt.in | 2 + Tests/CMakeLists.txt | 4 + 12 files changed, 406 insertions(+) create mode 100644 Tests/CMakeGUI/CMakeGUITest.cmake create mode 100644 Tests/CMakeGUI/CMakeGUITest.cxx create mode 100644 Tests/CMakeGUI/CMakeGUITest.h create mode 100644 Tests/CMakeGUI/CMakeLists.txt create mode 100644 Tests/CMakeGUI/QCMakeCacheModelTest.cxx create mode 100644 Tests/CMakeGUI/QCMakeCacheModelTest.h create mode 100644 Tests/CMakeGUI/sourceBinaryArgs-binaryDir/CMakeLists.txt.in create mode 100644 Tests/CMakeGUI/sourceBinaryArgs-noExistConfig/CMakeSetup.ini.in create mode 100644 Tests/CMakeGUI/sourceBinaryArgs-noExistConfigExists/CMakeLists.txt.in create mode 100644 Tests/CMakeGUI/sourceBinaryArgs-noExistConfigExists/CMakeSetup.ini.in create mode 100644 Tests/CMakeGUI/sourceBinaryArgs-sourceDir/CMakeLists.txt.in diff --git a/Tests/CMakeGUI/CMakeGUITest.cmake b/Tests/CMakeGUI/CMakeGUITest.cmake new file mode 100644 index 0000000..3d8c27e --- /dev/null +++ b/Tests/CMakeGUI/CMakeGUITest.cmake @@ -0,0 +1,111 @@ +function(run_cmake_gui_test name) + if(DEFINED ENV{CMakeGUITest_TEST_FILTER} AND NOT name MATCHES "$ENV{CMakeGUITest_TEST_FILTER}") + return() + endif() + + set(_fail) + + cmake_parse_arguments(_rcgt + "DO_CONFIGURE" + "GENERATOR" + "ARGS;CONFIGURE_ARGS" + ${ARGN} + ) + + string(REPLACE ":" "-" _file_name "${name}") + set(_srcdir "${CMakeGUITest_SOURCE_DIR}/${_file_name}") + set(_workdir "${CMakeGUITest_BINARY_DIR}/${_file_name}") + + file(REMOVE_RECURSE "${_workdir}") + file(MAKE_DIRECTORY "${_workdir}") + + set(_ini_in "${_srcdir}/CMakeSetup.ini.in") + if(EXISTS "${_ini_in}") + configure_file("${_ini_in}" "${_workdir}/config/Kitware/CMakeSetup.ini" @ONLY) + endif() + set(_cmakelists_in "${_srcdir}/CMakeLists.txt.in") + if(EXISTS "${_cmakelists_in}") + configure_file("${_cmakelists_in}" "${_workdir}/src/CMakeLists.txt" @ONLY) + endif() + if(_rcgt_DO_CONFIGURE) + if(NOT _rcgt_GENERATOR) + set(_rcgt_GENERATOR "${CMakeGUITest_GENERATOR}") + endif() + execute_process( + COMMAND "${CMAKE_COMMAND}" + -S "${_workdir}/src" + -B "${_workdir}/build" + -G "${_rcgt_GENERATOR}" + ${_rcgt_CONFIGURE_ARGS} + RESULT_VARIABLE _result + OUTPUT_VARIABLE _output + ERROR_VARIABLE _error + ) + if(_result) + set(_fail 1) + string(REPLACE "\n" "\n " _formatted_output "${_output}") + string(REPLACE "\n" "\n " _formatted_error "${_error}") + message(SEND_ERROR + "Configuring ${_workdir}/src failed with exit code ${_result}, should be 0\n" + "stdout:\n ${_formatted_output}\n" + "stderr:\n ${_formatted_error}" + ) + endif() + endif() + + set(ENV{CMake_GUI_TEST_NAME} "${name}") + set(ENV{CMake_GUI_CONFIG_DIR} "${_workdir}/config") + execute_process( + COMMAND "${CMakeGUITest_COMMAND}" ${_rcgt_ARGS} + WORKING_DIRECTORY "${_workdir}" + RESULT_VARIABLE _result + OUTPUT_VARIABLE _output + ERROR_VARIABLE _error + ) + if(_result) + set(_fail 1) + string(REPLACE "\n" "\n " _formatted_output "${_output}") + string(REPLACE "\n" "\n " _formatted_error "${_error}") + message(SEND_ERROR "CMake GUI test ${name} failed with exit code ${_result}, should be 0\n" + "stdout:\n ${_formatted_output}\n" + "stderr:\n ${_formatted_error}" + ) + endif() + + if(NOT _fail) + message(STATUS "${name} -- passed") + endif() +endfunction() + +run_cmake_gui_test(sourceBinaryArgs:sourceAndBinaryDir + ARGS + -S "${CMakeGUITest_BINARY_DIR}/sourceBinaryArgs-sourceAndBinaryDir/src" + -B "${CMakeGUITest_BINARY_DIR}/sourceBinaryArgs-sourceAndBinaryDir/build" + ) +run_cmake_gui_test(sourceBinaryArgs:sourceAndBinaryDirRelative + ARGS + "-Ssrc" + "-Bbuild" + ) +run_cmake_gui_test(sourceBinaryArgs:sourceDir + ARGS + "${CMakeGUITest_BINARY_DIR}/sourceBinaryArgs-sourceDir/src" + ) +run_cmake_gui_test(sourceBinaryArgs:binaryDir + DO_CONFIGURE + ARGS + "${CMakeGUITest_BINARY_DIR}/sourceBinaryArgs-binaryDir/build" + ) +run_cmake_gui_test(sourceBinaryArgs:noExist + ARGS + "${CMakeGUITest_BINARY_DIR}/sourceBinaryArgs-noExist/noexist" + ) +run_cmake_gui_test(sourceBinaryArgs:noExistConfig + ARGS + "${CMakeGUITest_BINARY_DIR}/sourceBinaryArgs-noExistConfig/noexist" + ) +run_cmake_gui_test(sourceBinaryArgs:noExistConfigExists + DO_CONFIGURE + ARGS + "${CMakeGUITest_BINARY_DIR}/sourceBinaryArgs-noExistConfigExists/noexist" + ) diff --git a/Tests/CMakeGUI/CMakeGUITest.cxx b/Tests/CMakeGUI/CMakeGUITest.cxx new file mode 100644 index 0000000..a7a5d17 --- /dev/null +++ b/Tests/CMakeGUI/CMakeGUITest.cxx @@ -0,0 +1,89 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "CMakeGUITest.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "CMakeSetupDialog.h" + +namespace { +void loopSleep(int msecs = 100) +{ + QEventLoop loop; + QTimer::singleShot(msecs, &loop, &QEventLoop::quit); + loop.exec(); +} +} + +CMakeGUITest::CMakeGUITest(CMakeSetupDialog* window, QObject* parent) + : QObject(parent) + , m_window(window) +{ +} + +void CMakeGUITest::sourceBinaryArgs() +{ + QFETCH(QString, sourceDir); + QFETCH(QString, binaryDir); + + // Wait a bit for everything to update + loopSleep(); + + QCOMPARE(this->m_window->SourceDirectory->text(), sourceDir); + QCOMPARE(this->m_window->BinaryDirectory->currentText(), binaryDir); +} + +void CMakeGUITest::sourceBinaryArgs_data() +{ + QTest::addColumn("sourceDir"); + QTest::addColumn("binaryDir"); + + QTest::newRow("sourceAndBinaryDir") + << CMakeGUITest_BINARY_DIR "/sourceBinaryArgs-sourceAndBinaryDir/src" + << CMakeGUITest_BINARY_DIR "/sourceBinaryArgs-sourceAndBinaryDir/build"; + QTest::newRow("sourceAndBinaryDirRelative") << CMakeGUITest_BINARY_DIR + "/sourceBinaryArgs-sourceAndBinaryDirRelative/src" + << CMakeGUITest_BINARY_DIR + "/sourceBinaryArgs-sourceAndBinaryDirRelative/build"; + QTest::newRow("sourceDir") + << CMakeGUITest_BINARY_DIR "/sourceBinaryArgs-sourceDir/src" + << CMakeGUITest_BINARY_DIR "/sourceBinaryArgs-sourceDir"; + QTest::newRow("binaryDir") + << CMakeGUITest_BINARY_DIR "/sourceBinaryArgs-binaryDir/src" + << CMakeGUITest_BINARY_DIR "/sourceBinaryArgs-binaryDir/build"; + QTest::newRow("noExist") << "" + << ""; + QTest::newRow("noExistConfig") + << "" + << CMakeGUITest_BINARY_DIR "/sourceBinaryArgs-noExistConfig/oldbuild"; + QTest::newRow("noExistConfigExists") + << CMakeGUITest_BINARY_DIR "/sourceBinaryArgs-noExistConfigExists/src" + << CMakeGUITest_BINARY_DIR "/sourceBinaryArgs-noExistConfigExists/build"; +} + +void SetupDefaultQSettings() +{ + QSettings::setDefaultFormat(QSettings::IniFormat); + QSettings::setPath(QSettings::IniFormat, QSettings::UserScope, + QString::fromLocal8Bit(qgetenv("CMake_GUI_CONFIG_DIR"))); +} + +int CMakeGUIExec(CMakeSetupDialog* window) +{ + auto nameArray = qgetenv("CMake_GUI_TEST_NAME"); + auto name = QString::fromLocal8Bit(nameArray); + if (name.isEmpty()) { + return QApplication::exec(); + } + + QStringList args{ "CMakeGUITest", name }; + CMakeGUITest obj(window); + return QTest::qExec(&obj, args); +} diff --git a/Tests/CMakeGUI/CMakeGUITest.h b/Tests/CMakeGUI/CMakeGUITest.h new file mode 100644 index 0000000..55a885b --- /dev/null +++ b/Tests/CMakeGUI/CMakeGUITest.h @@ -0,0 +1,21 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#pragma once + +#include + +class CMakeSetupDialog; + +class CMakeGUITest : public QObject +{ + Q_OBJECT +public: + CMakeGUITest(CMakeSetupDialog* window, QObject* parent = nullptr); + +private: + CMakeSetupDialog* m_window = nullptr; + +private slots: + void sourceBinaryArgs(); + void sourceBinaryArgs_data(); +}; diff --git a/Tests/CMakeGUI/CMakeLists.txt b/Tests/CMakeGUI/CMakeLists.txt new file mode 100644 index 0000000..2a2ee1a --- /dev/null +++ b/Tests/CMakeGUI/CMakeLists.txt @@ -0,0 +1,49 @@ +include(CMakeParseArguments) + +find_package(Qt5Test REQUIRED) + +include_directories( + ${CMake_SOURCE_DIR}/Source + ${CMake_SOURCE_DIR}/Source/QtDialog + ${CMake_BINARY_DIR}/Source/QtDialog + ) + +set(MOC_SRCS) +qt5_wrap_cpp(MOC_SRCS + CMakeGUITest.h + ) +add_executable(CMakeGUITest CMakeGUITest.cxx ${MOC_SRCS}) +target_link_libraries(CMakeGUITest CMakeGUIMainLib Qt5::Core Qt5::Test Qt5::Widgets) +target_compile_definitions(CMakeGUITest PRIVATE + "CMakeGUITest_SOURCE_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}\"" + "CMakeGUITest_BINARY_DIR=\"${CMAKE_CURRENT_BINARY_DIR}\"" + ) + +add_test(NAME CMakeGUI COMMAND ${CMAKE_CMAKE_COMMAND} + "-DCMakeGUITest_COMMAND=$" + "-DCMakeGUITest_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}" + "-DCMakeGUITest_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}" + "-DCMakeGUITest_GENERATOR=${CMAKE_GENERATOR}" + -P "${CMAKE_CURRENT_LIST_DIR}/CMakeGUITest.cmake" + ) + +function(add_cmake_gui_lib_test name) + cmake_parse_arguments(_t "" "" "SOURCES;MOC_SOURCES" ${ARGN}) + + set(MOC_SRCS) + qt5_wrap_cpp(MOC_SRCS + ${_t_MOC_SOURCES} + ) + add_executable(${name} ${_t_SOURCES} ${MOC_SRCS}) + target_link_libraries(${name} CMakeGUILib Qt5::Core Qt5::Test Qt5::Widgets) + + add_test(NAME "CMakeGUILib.${name}" COMMAND ${name}) +endfunction() + +add_cmake_gui_lib_test(QCMakeCacheModel + SOURCES + QCMakeCacheModelTest.cxx + QCMakeCacheModelTest.h + MOC_SOURCES + QCMakeCacheModelTest.h + ) diff --git a/Tests/CMakeGUI/QCMakeCacheModelTest.cxx b/Tests/CMakeGUI/QCMakeCacheModelTest.cxx new file mode 100644 index 0000000..f9bc6ae --- /dev/null +++ b/Tests/CMakeGUI/QCMakeCacheModelTest.cxx @@ -0,0 +1,108 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "QCMakeCacheModelTest.h" + +#include +#include + +#include "QCMakeCacheView.h" +#include + +namespace { +QCMakeProperty makeProperty( + const QString& name, const QString& value, + QCMakeProperty::PropertyType type = QCMakeProperty::STRING, + bool advanced = false) +{ + return QCMakeProperty{ + /*Key=*/name, + /*Value=*/value, + /*Strings=*/{}, + /*Help=*/"", + /*Type=*/type, + /*Advanced=*/advanced, + }; +} +} + +void QCMakeCacheModelTest::setNewProperties() +{ + QFETCH(QCMakePropertyList, oldList); + QFETCH(QCMakePropertyList, newList); + QFETCH(QVector, names); + QFETCH(QVector, values); + QFETCH(QVector, background); + + QCMakeCacheModel model; + model.setViewType(QCMakeCacheModel::FlatView); + model.setProperties(oldList); + model.setProperties(newList); + + auto rows = model.rowCount(); + QVector actualNames(rows); + QVector actualValues(rows); + QVector actualBackground1(rows); + QVector actualBackground2(rows); + for (int i = 0; i < rows; ++i) { + auto idx1 = model.index(i, 0); + auto idx2 = model.index(i, 1); + + auto name = model.data(idx1, Qt::DisplayRole); + QVERIFY(name.canConvert()); + actualNames[i] = name.value(); + + auto value = model.data(idx2, Qt::DisplayRole); + QVERIFY(name.canConvert()); + actualValues[i] = value.value(); + + actualBackground1[i] = model.data(idx1, Qt::BackgroundRole); + actualBackground2[i] = model.data(idx2, Qt::BackgroundRole); + } + + QCOMPARE(actualNames, names); + QCOMPARE(actualValues, values); + QCOMPARE(actualBackground1, background); + QCOMPARE(actualBackground2, background); +} + +void QCMakeCacheModelTest::setNewProperties_data() +{ + QTest::addColumn("oldList"); + QTest::addColumn("newList"); + QTest::addColumn>("names"); + QTest::addColumn>("values"); + QTest::addColumn>("background"); + + QTest::newRow("empty") << QCMakePropertyList{} << QCMakePropertyList{} + << QVector{} << QVector{} + << QVector{}; + QTest::newRow("noNew") << QCMakePropertyList{ makeProperty("VARIABLE_1", + "Value 1") } + << QCMakePropertyList{} << QVector{} + << QVector{} << QVector{}; + QTest::newRow("allNew") + << QCMakePropertyList{} + << QCMakePropertyList{ makeProperty("VARIABLE_1", "Value 1") } + << QVector{ "VARIABLE_1" } << QVector{ "Value 1" } + << QVector{ QBrush{ QColor{ 255, 100, 100 } } }; + QTest::newRow("mixed") + << QCMakePropertyList{ makeProperty("VARIABLE_1", "Value 1") } + << QCMakePropertyList{ makeProperty("VARIABLE_2", "Value 2") } + << QVector{ "VARIABLE_2" } << QVector{ "Value 2" } + << QVector{ QBrush{ QColor{ 255, 100, 100 } } }; + QTest::newRow("overridden") + << QCMakePropertyList{ makeProperty("VARIABLE_1", "Value 1") } + << QCMakePropertyList{ makeProperty("VARIABLE_1", "Overridden value") } + << QVector{ "VARIABLE_1" } + << QVector{ "Overridden value" } + << QVector{ QVariant{} }; + QTest::newRow("overriddenMixed") + << QCMakePropertyList{ makeProperty("VARIABLE_1", "Value 1") } + << QCMakePropertyList{ makeProperty("VARIABLE_1", "Overridden value"), + makeProperty("VARIABLE_2", "Value 2") } + << QVector{ "VARIABLE_2", "VARIABLE_1" } + << QVector{ "Value 2", "Overridden value" } + << QVector{ QBrush{ QColor{ 255, 100, 100 } }, QVariant{} }; +} + +QTEST_MAIN(QCMakeCacheModelTest) diff --git a/Tests/CMakeGUI/QCMakeCacheModelTest.h b/Tests/CMakeGUI/QCMakeCacheModelTest.h new file mode 100644 index 0000000..e88db94 --- /dev/null +++ b/Tests/CMakeGUI/QCMakeCacheModelTest.h @@ -0,0 +1,14 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#pragma once + +#include "QCMakeCacheView.h" +#include + +class QCMakeCacheModelTest : public QObject +{ + Q_OBJECT +private slots: + void setNewProperties(); + void setNewProperties_data(); +}; diff --git a/Tests/CMakeGUI/sourceBinaryArgs-binaryDir/CMakeLists.txt.in b/Tests/CMakeGUI/sourceBinaryArgs-binaryDir/CMakeLists.txt.in new file mode 100644 index 0000000..2ae4a57 --- /dev/null +++ b/Tests/CMakeGUI/sourceBinaryArgs-binaryDir/CMakeLists.txt.in @@ -0,0 +1,2 @@ +cmake_minimum_required(VERSION 3.18) +project(sourceBinaryArgs-sourceDir NONE) diff --git a/Tests/CMakeGUI/sourceBinaryArgs-noExistConfig/CMakeSetup.ini.in b/Tests/CMakeGUI/sourceBinaryArgs-noExistConfig/CMakeSetup.ini.in new file mode 100644 index 0000000..db49eea --- /dev/null +++ b/Tests/CMakeGUI/sourceBinaryArgs-noExistConfig/CMakeSetup.ini.in @@ -0,0 +1,2 @@ +[Settings] +StartPath\WhereBuild0=@CMakeGUITest_BINARY_DIR@/sourceBinaryArgs-noExistConfig/oldbuild diff --git a/Tests/CMakeGUI/sourceBinaryArgs-noExistConfigExists/CMakeLists.txt.in b/Tests/CMakeGUI/sourceBinaryArgs-noExistConfigExists/CMakeLists.txt.in new file mode 100644 index 0000000..2ae4a57 --- /dev/null +++ b/Tests/CMakeGUI/sourceBinaryArgs-noExistConfigExists/CMakeLists.txt.in @@ -0,0 +1,2 @@ +cmake_minimum_required(VERSION 3.18) +project(sourceBinaryArgs-sourceDir NONE) diff --git a/Tests/CMakeGUI/sourceBinaryArgs-noExistConfigExists/CMakeSetup.ini.in b/Tests/CMakeGUI/sourceBinaryArgs-noExistConfigExists/CMakeSetup.ini.in new file mode 100644 index 0000000..4ffd917 --- /dev/null +++ b/Tests/CMakeGUI/sourceBinaryArgs-noExistConfigExists/CMakeSetup.ini.in @@ -0,0 +1,2 @@ +[Settings] +StartPath\WhereBuild0=@CMakeGUITest_BINARY_DIR@/sourceBinaryArgs-noExistConfigExists/build diff --git a/Tests/CMakeGUI/sourceBinaryArgs-sourceDir/CMakeLists.txt.in b/Tests/CMakeGUI/sourceBinaryArgs-sourceDir/CMakeLists.txt.in new file mode 100644 index 0000000..2ae4a57 --- /dev/null +++ b/Tests/CMakeGUI/sourceBinaryArgs-sourceDir/CMakeLists.txt.in @@ -0,0 +1,2 @@ +cmake_minimum_required(VERSION 3.18) +project(sourceBinaryArgs-sourceDir NONE) diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index ee3ac3d..9aa401d 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -3532,6 +3532,10 @@ if(BUILD_TESTING) add_subdirectory(CMakeTests) endif() + if(BUILD_QtDialog AND CMake_TEST_GUI AND NOT CMake_TEST_EXTERNAL_CMAKE) + add_subdirectory(CMakeGUI) + endif() + # If this is not an in-source build, provide a target to wipe out # all the test build directories. This must come at the end after # all the above logic has finished adding to TEST_BUILD_DIRS -- cgit v0.12