summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2020-09-24 19:15:11 (GMT)
committerKitware Robot <kwrobot@kitware.com>2020-09-24 19:15:19 (GMT)
commit0ff74958f4b0e8ea7b27cf706af55e6192481985 (patch)
tree4d3c7c6605de0501a764cfa716814883417d74e0
parent4ae8cc7f0bc0ce95bc2a719bb13e4d19a0cd49ed (diff)
parent1dcc5698289a49359c70f022d673cacc42b82239 (diff)
downloadCMake-0ff74958f4b0e8ea7b27cf706af55e6192481985.zip
CMake-0ff74958f4b0e8ea7b27cf706af55e6192481985.tar.gz
CMake-0ff74958f4b0e8ea7b27cf706af55e6192481985.tar.bz2
Merge topic 'cmake-gui-tests'
1dcc569828 gitlab-ci: Add GUI testing to each OS 4c6e5cd0fa Tests: Add some basic tests for CMake GUI 41e223deb3 CMake GUI: Split up into libraries, add test shim b7995b62f0 QCMakeCacheView: Default to nullptr for parent Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !5224
-rw-r--r--.gitlab-ci.yml2
-rw-r--r--.gitlab/artifacts.yml1
-rw-r--r--.gitlab/ci/configure_fedora31_ninja.cmake1
-rw-r--r--.gitlab/ci/configure_macos_common.cmake6
-rw-r--r--.gitlab/ci/configure_macos_makefiles.cmake1
-rw-r--r--.gitlab/ci/configure_macos_ninja.cmake1
-rw-r--r--.gitlab/ci/configure_windows_vs2019_x64_ninja.cmake1
-rw-r--r--.gitlab/os-linux.yml8
-rw-r--r--Source/QtDialog/CMakeGUIExec.cxx15
-rw-r--r--Source/QtDialog/CMakeLists.txt16
-rw-r--r--Source/QtDialog/CMakeSetup.cxx7
-rw-r--r--Source/QtDialog/QCMakeCacheView.h2
-rw-r--r--Tests/CMakeGUI/CMakeGUITest.cmake111
-rw-r--r--Tests/CMakeGUI/CMakeGUITest.cxx89
-rw-r--r--Tests/CMakeGUI/CMakeGUITest.h21
-rw-r--r--Tests/CMakeGUI/CMakeLists.txt49
-rw-r--r--Tests/CMakeGUI/QCMakeCacheModelTest.cxx108
-rw-r--r--Tests/CMakeGUI/QCMakeCacheModelTest.h14
-rw-r--r--Tests/CMakeGUI/sourceBinaryArgs-binaryDir/CMakeLists.txt.in2
-rw-r--r--Tests/CMakeGUI/sourceBinaryArgs-noExistConfig/CMakeSetup.ini.in2
-rw-r--r--Tests/CMakeGUI/sourceBinaryArgs-noExistConfigExists/CMakeLists.txt.in2
-rw-r--r--Tests/CMakeGUI/sourceBinaryArgs-noExistConfigExists/CMakeSetup.ini.in2
-rw-r--r--Tests/CMakeGUI/sourceBinaryArgs-sourceDir/CMakeLists.txt.in2
-rw-r--r--Tests/CMakeLists.txt4
24 files changed, 458 insertions, 9 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index f8d5292..f4ebb02 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -109,7 +109,7 @@ test:fedora31-ninja:
extends:
- .fedora31_ninja
- .cmake_test_linux
- - .linux_builder_tags_qt
+ - .linux_builder_tags_x11
- .cmake_test_artifacts
- .run_automatically
dependencies:
diff --git a/.gitlab/artifacts.yml b/.gitlab/artifacts.yml
index 2eadcb1..f1c0c7e 100644
--- a/.gitlab/artifacts.yml
+++ b/.gitlab/artifacts.yml
@@ -60,6 +60,7 @@
- build/Tests/RunCMake/
- build/Tests/CMakeOnly/
- build/Tests/CMakeTests/
+ - build/Tests/CMakeGUI/
# CTest/CDash information.
- build/Testing/
diff --git a/.gitlab/ci/configure_fedora31_ninja.cmake b/.gitlab/ci/configure_fedora31_ninja.cmake
index dad6d45..2743412 100644
--- a/.gitlab/ci/configure_fedora31_ninja.cmake
+++ b/.gitlab/ci/configure_fedora31_ninja.cmake
@@ -1,2 +1,3 @@
set(CMake_TEST_ISPC "ON" CACHE STRING "")
+set(CMake_TEST_GUI "ON" CACHE BOOL "")
include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora31_common.cmake")
diff --git a/.gitlab/ci/configure_macos_common.cmake b/.gitlab/ci/configure_macos_common.cmake
index bd5902b..3d09779 100644
--- a/.gitlab/ci/configure_macos_common.cmake
+++ b/.gitlab/ci/configure_macos_common.cmake
@@ -6,4 +6,10 @@ set(Java_JAVA_EXECUTABLE "" CACHE FILEPATH "")
set(Java_JAVAC_EXECUTABLE "" CACHE FILEPATH "")
set(Java_JAR_EXECUTABLE "" CACHE FILEPATH "")
+# Qt binaries get placed inside the source directory, which causes them to not
+# be included in the install-time rpath, but we still want them in the
+# build-time rpath. CMake sets CMAKE_BUILD_WITH_INSTALL_RPATH to ON by default,
+# so set it to OFF.
+set(CMAKE_BUILD_WITH_INSTALL_RPATH OFF CACHE BOOL "")
+
set(BUILD_QtDialog ON CACHE BOOL "")
diff --git a/.gitlab/ci/configure_macos_makefiles.cmake b/.gitlab/ci/configure_macos_makefiles.cmake
index 85f67b5..f657d98 100644
--- a/.gitlab/ci/configure_macos_makefiles.cmake
+++ b/.gitlab/ci/configure_macos_makefiles.cmake
@@ -1,2 +1,3 @@
+set(CMake_TEST_GUI "ON" CACHE BOOL "")
include("${CMAKE_CURRENT_LIST_DIR}/configure_macos_common.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/configure_common.cmake")
diff --git a/.gitlab/ci/configure_macos_ninja.cmake b/.gitlab/ci/configure_macos_ninja.cmake
index 85f67b5..f657d98 100644
--- a/.gitlab/ci/configure_macos_ninja.cmake
+++ b/.gitlab/ci/configure_macos_ninja.cmake
@@ -1,2 +1,3 @@
+set(CMake_TEST_GUI "ON" CACHE BOOL "")
include("${CMAKE_CURRENT_LIST_DIR}/configure_macos_common.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/configure_common.cmake")
diff --git a/.gitlab/ci/configure_windows_vs2019_x64_ninja.cmake b/.gitlab/ci/configure_windows_vs2019_x64_ninja.cmake
index 719c93c..9c30a4b 100644
--- a/.gitlab/ci/configure_windows_vs2019_x64_ninja.cmake
+++ b/.gitlab/ci/configure_windows_vs2019_x64_ninja.cmake
@@ -1,3 +1,4 @@
set(CMake_TEST_WIX_NO_VERIFY "ON" CACHE BOOL "")
+set(CMake_TEST_GUI "ON" CACHE BOOL "")
include("${CMAKE_CURRENT_LIST_DIR}/configure_windows_common.cmake")
diff --git a/.gitlab/os-linux.yml b/.gitlab/os-linux.yml
index 1ec5413..75f8156 100644
--- a/.gitlab/os-linux.yml
+++ b/.gitlab/os-linux.yml
@@ -119,6 +119,14 @@
- linux
- linux-3.17 # Needed to be able to load Fedora's Qt libraries.
+.linux_builder_tags_x11:
+ tags:
+ - cmake
+ - docker
+ - linux
+ - linux-3.17 # Needed to be able to load Fedora's Qt libraries.
+ - x11
+
.linux_builder_tags_cuda:
tags:
- cmake
diff --git a/Source/QtDialog/CMakeGUIExec.cxx b/Source/QtDialog/CMakeGUIExec.cxx
new file mode 100644
index 0000000..1572112
--- /dev/null
+++ b/Source/QtDialog/CMakeGUIExec.cxx
@@ -0,0 +1,15 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include <QApplication>
+
+class CMakeSetupDialog;
+
+void SetupDefaultQSettings()
+{
+}
+
+int CMakeGUIExec(CMakeSetupDialog* /*window*/)
+{
+ return QApplication::exec();
+}
diff --git a/Source/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt
index e6d6b17..0ec012c 100644
--- a/Source/QtDialog/CMakeLists.txt
+++ b/Source/QtDialog/CMakeLists.txt
@@ -81,7 +81,6 @@ endif()
set(SRCS
AddCacheEntry.cxx
AddCacheEntry.h
- CMakeSetup.cxx
CMakeSetupDialog.cxx
CMakeSetupDialog.h
Compilers.h
@@ -150,11 +149,18 @@ endif()
set(CMAKE_INCLUDE_CURRENT_DIR ON)
-add_executable(cmake-gui WIN32 MACOSX_BUNDLE ${SRCS} ${MANIFEST_FILE})
-target_link_libraries(cmake-gui CMakeLib Qt5::Core Qt5::Widgets ${CMake_QT_EXTRA_LIBRARIES})
+add_library(CMakeGUILib STATIC ${SRCS})
+# CMake_QT_EXTRA_LIBRARIES have to come before the main libraries on the link line
+target_link_libraries(CMakeGUILib PUBLIC CMakeLib ${CMake_QT_EXTRA_LIBRARIES} Qt5::Core Qt5::Widgets)
+
+add_library(CMakeGUIMainLib STATIC CMakeSetup.cxx)
+target_link_libraries(CMakeGUIMainLib PUBLIC CMakeGUILib)
+
+add_executable(cmake-gui WIN32 MACOSX_BUNDLE CMakeGUIExec.cxx ${MANIFEST_FILE})
+target_link_libraries(cmake-gui CMakeGUIMainLib Qt5::Core)
if(WIN32)
- target_sources(cmake-gui PRIVATE $<TARGET_OBJECTS:CMakeVersion>)
+ target_sources(CMakeGUILib INTERFACE $<TARGET_OBJECTS:CMakeVersion>)
endif()
if(CMake_JOB_POOL_LINK_BIN)
@@ -163,7 +169,7 @@ endif()
# cmake-gui has not been updated for `include-what-you-use`.
# Block the tool until this is done.
-set_target_properties(cmake-gui PROPERTIES
+set_target_properties(CMakeGUILib CMakeGUIMainLib cmake-gui PROPERTIES
CXX_INCLUDE_WHAT_YOU_USE ""
)
diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx
index 7ef5a72..37c1f15 100644
--- a/Source/QtDialog/CMakeSetup.cxx
+++ b/Source/QtDialog/CMakeSetup.cxx
@@ -21,7 +21,6 @@
#include "cmDocumentationEntry.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h" // IWYU pragma: keep
-#include "cmVersion.h"
#include "cmake.h"
static const char* cmDocumentationName[][2] = { { nullptr,
@@ -55,6 +54,9 @@ Q_IMPORT_PLUGIN(QWindowsVistaStylePlugin);
# endif
#endif
+int CMakeGUIExec(CMakeSetupDialog* window);
+void SetupDefaultQSettings();
+
int main(int argc, char** argv)
{
cmSystemTools::EnsureStdPipes();
@@ -108,6 +110,7 @@ int main(int argc, char** argv)
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
+ SetupDefaultQSettings();
QApplication app(argc, argv);
setlocale(LC_NUMERIC, "C");
@@ -215,7 +218,7 @@ int main(int argc, char** argv)
}
}
- return QApplication::exec();
+ return CMakeGUIExec(&dialog);
}
#if defined(Q_OS_MAC)
diff --git a/Source/QtDialog/QCMakeCacheView.h b/Source/QtDialog/QCMakeCacheView.h
index 836a939..11c6d3e 100644
--- a/Source/QtDialog/QCMakeCacheView.h
+++ b/Source/QtDialog/QCMakeCacheView.h
@@ -48,7 +48,7 @@ class QCMakeCacheModel : public QStandardItemModel
{
Q_OBJECT
public:
- QCMakeCacheModel(QObject* parent);
+ QCMakeCacheModel(QObject* parent = nullptr);
~QCMakeCacheModel();
// roles used to retrieve extra data such has help strings, types of
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 <QApplication>
+#include <QEventLoop>
+#include <QSettings>
+#include <QString>
+#include <QStringList>
+#include <QTimer>
+#include <QtGlobal>
+#include <QtTest>
+
+#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<QString>("sourceDir");
+ QTest::addColumn<QString>("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 <QObject>
+
+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=$<TARGET_FILE:CMakeGUITest>"
+ "-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 <algorithm>
+#include <iostream>
+
+#include "QCMakeCacheView.h"
+#include <QtTest>
+
+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<QString>, names);
+ QFETCH(QVector<QString>, values);
+ QFETCH(QVector<QVariant>, background);
+
+ QCMakeCacheModel model;
+ model.setViewType(QCMakeCacheModel::FlatView);
+ model.setProperties(oldList);
+ model.setProperties(newList);
+
+ auto rows = model.rowCount();
+ QVector<QString> actualNames(rows);
+ QVector<QString> actualValues(rows);
+ QVector<QVariant> actualBackground1(rows);
+ QVector<QVariant> 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<QString>());
+ actualNames[i] = name.value<QString>();
+
+ auto value = model.data(idx2, Qt::DisplayRole);
+ QVERIFY(name.canConvert<QString>());
+ actualValues[i] = value.value<QString>();
+
+ 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<QCMakePropertyList>("oldList");
+ QTest::addColumn<QCMakePropertyList>("newList");
+ QTest::addColumn<QVector<QString>>("names");
+ QTest::addColumn<QVector<QString>>("values");
+ QTest::addColumn<QVector<QVariant>>("background");
+
+ QTest::newRow("empty") << QCMakePropertyList{} << QCMakePropertyList{}
+ << QVector<QString>{} << QVector<QString>{}
+ << QVector<QVariant>{};
+ QTest::newRow("noNew") << QCMakePropertyList{ makeProperty("VARIABLE_1",
+ "Value 1") }
+ << QCMakePropertyList{} << QVector<QString>{}
+ << QVector<QString>{} << QVector<QVariant>{};
+ QTest::newRow("allNew")
+ << QCMakePropertyList{}
+ << QCMakePropertyList{ makeProperty("VARIABLE_1", "Value 1") }
+ << QVector<QString>{ "VARIABLE_1" } << QVector<QString>{ "Value 1" }
+ << QVector<QVariant>{ QBrush{ QColor{ 255, 100, 100 } } };
+ QTest::newRow("mixed")
+ << QCMakePropertyList{ makeProperty("VARIABLE_1", "Value 1") }
+ << QCMakePropertyList{ makeProperty("VARIABLE_2", "Value 2") }
+ << QVector<QString>{ "VARIABLE_2" } << QVector<QString>{ "Value 2" }
+ << QVector<QVariant>{ QBrush{ QColor{ 255, 100, 100 } } };
+ QTest::newRow("overridden")
+ << QCMakePropertyList{ makeProperty("VARIABLE_1", "Value 1") }
+ << QCMakePropertyList{ makeProperty("VARIABLE_1", "Overridden value") }
+ << QVector<QString>{ "VARIABLE_1" }
+ << QVector<QString>{ "Overridden value" }
+ << QVector<QVariant>{ QVariant{} };
+ QTest::newRow("overriddenMixed")
+ << QCMakePropertyList{ makeProperty("VARIABLE_1", "Value 1") }
+ << QCMakePropertyList{ makeProperty("VARIABLE_1", "Overridden value"),
+ makeProperty("VARIABLE_2", "Value 2") }
+ << QVector<QString>{ "VARIABLE_2", "VARIABLE_1" }
+ << QVector<QString>{ "Value 2", "Overridden value" }
+ << QVector<QVariant>{ 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 <QObject>
+
+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