Tests: Add some basic tests for CMake GUI

This commit is contained in:
Kyle Edwards
2020-09-14 14:48:07 -04:00
parent 41e223deb3
commit 4c6e5cd0fa
12 changed files with 406 additions and 0 deletions

View File

@@ -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"
)

View File

@@ -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);
}

View File

@@ -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();
};

View File

@@ -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
)

View File

@@ -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)

View File

@@ -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();
};

View File

@@ -0,0 +1,2 @@
cmake_minimum_required(VERSION 3.18)
project(sourceBinaryArgs-sourceDir NONE)

View File

@@ -0,0 +1,2 @@
[Settings]
StartPath\WhereBuild0=@CMakeGUITest_BINARY_DIR@/sourceBinaryArgs-noExistConfig/oldbuild

View File

@@ -0,0 +1,2 @@
cmake_minimum_required(VERSION 3.18)
project(sourceBinaryArgs-sourceDir NONE)

View File

@@ -0,0 +1,2 @@
[Settings]
StartPath\WhereBuild0=@CMakeGUITest_BINARY_DIR@/sourceBinaryArgs-noExistConfigExists/build

View File

@@ -0,0 +1,2 @@
cmake_minimum_required(VERSION 3.18)
project(sourceBinaryArgs-sourceDir NONE)

View File

@@ -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