summaryrefslogtreecommitdiff
path: root/Tests/CMakeGUI/CMakeGUITest.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Tests/CMakeGUI/CMakeGUITest.cxx')
-rw-r--r--Tests/CMakeGUI/CMakeGUITest.cxx449
1 files changed, 449 insertions, 0 deletions
diff --git a/Tests/CMakeGUI/CMakeGUITest.cxx b/Tests/CMakeGUI/CMakeGUITest.cxx
new file mode 100644
index 000000000..2b5d9730f
--- /dev/null
+++ b/Tests/CMakeGUI/CMakeGUITest.cxx
@@ -0,0 +1,449 @@
+/* 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 "QCMake.h"
+#include <QApplication>
+#include <QEventLoop>
+#include <QFile>
+#include <QJsonArray>
+#include <QJsonDocument>
+#include <QJsonObject>
+#include <QMessageBox>
+#include <QSettings>
+#include <QString>
+#include <QStringList>
+#include <QTimer>
+#include <QtGlobal>
+#include <QtTest>
+
+#include "CMakeSetupDialog.h"
+
+#include "CatchShow.h"
+#include "FirstConfigure.h"
+
+using WindowSetupHelper = std::function<void(CMakeSetupDialog*)>;
+Q_DECLARE_METATYPE(WindowSetupHelper)
+
+namespace {
+void loopSleep(int msecs = 500)
+{
+ QEventLoop loop;
+ QTimer::singleShot(msecs, &loop, &QEventLoop::quit);
+ loop.exec();
+}
+}
+
+CMakeGUITest::CMakeGUITest(CMakeSetupDialog* window, QObject* parent)
+ : QObject(parent)
+ , m_window(window)
+{
+}
+
+void CMakeGUITest::tryConfigure(int expectedResult, int timeout)
+{
+ auto* cmake = this->m_window->findChild<QCMakeThread*>()->cmakeInstance();
+
+ bool done = false;
+ CatchShow catchConfigure;
+ catchConfigure.setCallback<FirstConfigure>([&done](FirstConfigure* dialog) {
+ if (done) {
+ return;
+ }
+ done = true;
+
+ dialog->findChild<StartCompilerSetup*>()->setCurrentGenerator(
+ CMAKE_GENERATOR);
+ dialog->accept();
+ });
+
+ CatchShow catchMessages;
+ catchMessages.setCallback<QMessageBox>([](QMessageBox* box) {
+ if (box->text().contains("Build directory does not exist")) {
+ box->accept();
+ }
+
+ if (box->text().contains("Error in configuration process")) {
+ box->accept();
+ }
+ });
+
+ QSignalSpy configureDoneSpy(cmake, &QCMake::configureDone);
+ QVERIFY(configureDoneSpy.isValid());
+ QMetaObject::invokeMethod(
+ this->m_window, [this]() { this->m_window->ConfigureButton->click(); },
+ Qt::QueuedConnection);
+ QVERIFY(configureDoneSpy.wait(timeout));
+
+ QCOMPARE(configureDoneSpy, { { expectedResult } });
+}
+
+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 CMakeGUITest::simpleConfigure()
+{
+ QFETCH(QString, sourceDir);
+ QFETCH(QString, binaryDir);
+ QFETCH(int, expectedResult);
+
+ this->m_window->SourceDirectory->setText(sourceDir);
+ this->m_window->BinaryDirectory->setCurrentText(binaryDir);
+
+ // Wait a bit for everything to update
+ loopSleep();
+
+ this->tryConfigure(expectedResult, 1000);
+}
+
+void CMakeGUITest::simpleConfigure_data()
+{
+ QTest::addColumn<QString>("sourceDir");
+ QTest::addColumn<QString>("binaryDir");
+ QTest::addColumn<int>("expectedResult");
+
+ QTest::newRow("success") << CMakeGUITest_BINARY_DIR
+ "/simpleConfigure-success/src"
+ << CMakeGUITest_BINARY_DIR
+ "/simpleConfigure-success/build"
+ << 0;
+ QTest::newRow("fail") << CMakeGUITest_BINARY_DIR "/simpleConfigure-fail/src"
+ << CMakeGUITest_BINARY_DIR
+ "/simpleConfigure-fail/build"
+ << -1;
+}
+
+void CMakeGUITest::environment()
+{
+ auto* cmake = this->m_window->findChild<QCMakeThread*>()->cmakeInstance();
+
+ this->m_window->SourceDirectory->setText(CMakeGUITest_BINARY_DIR
+ "/environment/src");
+ this->m_window->BinaryDirectory->setCurrentText(CMakeGUITest_BINARY_DIR
+ "/environment/build");
+
+ // We are already testing EnvironmentDialog, so just trust that it's
+ // connected correctly and modify the environment directly.
+ auto env = cmake->environment();
+ env.insert("ADDED_VARIABLE", "Added variable");
+ env.insert("CHANGED_VARIABLE", "Changed variable");
+ env.remove("REMOVED_VARIABLE");
+ cmake->setEnvironment(env);
+
+ // Wait a bit for everything to update
+ loopSleep();
+
+ this->tryConfigure();
+
+ auto penv = QProcessEnvironment::systemEnvironment();
+ QVERIFY(!penv.contains("ADDED_VARIABLE"));
+ QCOMPARE(penv.value("KEPT_VARIABLE"), "Kept variable");
+ QCOMPARE(penv.value("CHANGED_VARIABLE"), "This variable will be changed");
+ QCOMPARE(penv.value("REMOVED_VARIABLE"), "Removed variable");
+}
+
+void CMakeGUITest::presetArg()
+{
+ QFETCH(WindowSetupHelper, setupFunction);
+ QFETCH(QString, presetName);
+ QFETCH(QString, sourceDir);
+ QFETCH(QString, binaryDir);
+ QFETCH(QCMakePropertyList, properties);
+
+ if (setupFunction) {
+ setupFunction(this->m_window);
+ }
+
+ // Wait a bit for everything to update
+ loopSleep();
+
+ QCOMPARE(this->m_window->Preset->presetName(), presetName);
+ QCOMPARE(this->m_window->SourceDirectory->text(), sourceDir);
+ QCOMPARE(this->m_window->BinaryDirectory->currentText(), binaryDir);
+
+ auto actualProperties =
+ this->m_window->CacheValues->cacheModel()->properties();
+ QCOMPARE(actualProperties.size(), properties.size());
+ for (int i = 0; i < actualProperties.size(); ++i) {
+ // operator==() only compares Key, we need to compare Value and Type too
+ QCOMPARE(actualProperties[i].Key, properties[i].Key);
+ QCOMPARE(actualProperties[i].Value, properties[i].Value);
+ QCOMPARE(actualProperties[i].Type, properties[i].Type);
+ }
+}
+
+namespace {
+QCMakePropertyList makePresetProperties(const QString& name)
+{
+ return QCMakePropertyList{
+ QCMakeProperty{
+ /*Key=*/"FALSE_VARIABLE",
+ /*Value=*/false,
+ /*Strings=*/{},
+ /*Help=*/"",
+ /*Type=*/QCMakeProperty::BOOL,
+ /*Advanced=*/false,
+ },
+ QCMakeProperty{
+ /*Key=*/"FILEPATH_VARIABLE",
+ /*Value=*/
+ QString::fromLocal8Bit(CMakeGUITest_BINARY_DIR "/%1/src/CMakeLists.txt")
+ .arg(name),
+ /*Strings=*/{},
+ /*Help=*/"",
+ /*Type=*/QCMakeProperty::FILEPATH,
+ /*Advanced=*/false,
+ },
+ QCMakeProperty{
+ /*Key=*/"ON_VARIABLE",
+ /*Value=*/true,
+ /*Strings=*/{},
+ /*Help=*/"",
+ /*Type=*/QCMakeProperty::BOOL,
+ /*Advanced=*/false,
+ },
+ QCMakeProperty{
+ /*Key=*/"PATH_VARIABLE",
+ /*Value=*/
+ QString::fromLocal8Bit(CMakeGUITest_BINARY_DIR "/%1/src").arg(name),
+ /*Strings=*/{},
+ /*Help=*/"",
+ /*Type=*/QCMakeProperty::PATH,
+ /*Advanced=*/false,
+ },
+ QCMakeProperty{
+ /*Key=*/"STRING_VARIABLE",
+ /*Value=*/"String value",
+ /*Strings=*/{},
+ /*Help=*/"",
+ /*Type=*/QCMakeProperty::STRING,
+ /*Advanced=*/false,
+ },
+ QCMakeProperty{
+ /*Key=*/"UNINITIALIZED_VARIABLE",
+ /*Value=*/"Uninitialized value",
+ /*Strings=*/{},
+ /*Help=*/"",
+ /*Type=*/QCMakeProperty::STRING,
+ /*Advanced=*/false,
+ },
+ };
+}
+}
+
+void CMakeGUITest::presetArg_data()
+{
+ QTest::addColumn<WindowSetupHelper>("setupFunction");
+ QTest::addColumn<QString>("presetName");
+ QTest::addColumn<QString>("sourceDir");
+ QTest::addColumn<QString>("binaryDir");
+ QTest::addColumn<QCMakePropertyList>("properties");
+
+ QTest::newRow("preset") << WindowSetupHelper{} << "ninja"
+ << CMakeGUITest_BINARY_DIR "/presetArg-preset/src"
+ << CMakeGUITest_BINARY_DIR
+ "/presetArg-preset/src/build"
+ << makePresetProperties("presetArg-preset");
+ QTest::newRow("presetBinary")
+ << WindowSetupHelper{} << "ninja"
+ << CMakeGUITest_BINARY_DIR "/presetArg-presetBinary/src"
+ << CMakeGUITest_BINARY_DIR "/presetArg-presetBinary/build"
+ << makePresetProperties("presetArg-presetBinary");
+ QTest::newRow("presetBinaryChange")
+ << WindowSetupHelper{ [](CMakeSetupDialog* window) {
+ loopSleep();
+ window->Preset->setPresetName("ninja2");
+ } }
+ << "ninja2" << CMakeGUITest_BINARY_DIR "/presetArg-presetBinaryChange/src"
+ << CMakeGUITest_BINARY_DIR "/presetArg-presetBinaryChange/src/build"
+ << makePresetProperties("presetArg-presetBinaryChange");
+ QTest::newRow("noPresetBinaryChange")
+ << WindowSetupHelper{ [](CMakeSetupDialog* window) {
+ loopSleep();
+ window->Preset->setPresetName("ninja");
+ } }
+ << "ninja" << CMakeGUITest_BINARY_DIR "/presetArg-noPresetBinaryChange/src"
+ << CMakeGUITest_BINARY_DIR "/presetArg-noPresetBinaryChange/src/build"
+ << makePresetProperties("presetArg-noPresetBinaryChange");
+ QTest::newRow("presetConfigExists")
+ << WindowSetupHelper{} << "ninja"
+ << CMakeGUITest_BINARY_DIR "/presetArg-presetConfigExists/src"
+ << CMakeGUITest_BINARY_DIR "/presetArg-presetConfigExists/src/build"
+ << makePresetProperties("presetArg-presetConfigExists");
+ QTest::newRow("noExist") << WindowSetupHelper{} << QString{}
+ << CMakeGUITest_BINARY_DIR "/presetArg-noExist/src"
+ << "" << QCMakePropertyList{};
+}
+
+namespace {
+void writePresets(const QString& buildDir, const QStringList& names)
+{
+ QJsonArray presets{
+ QJsonObject{
+ { "name", "base" },
+ { "generator", "Ninja" },
+ { "binaryDir",
+ QString::fromLocal8Bit("${sourceDir}/%1/${presetName}")
+ .arg(buildDir) },
+ { "hidden", true },
+ },
+ };
+
+ for (auto const& name : names) {
+ presets.append(QJsonObject{
+ { "name", name },
+ { "inherits", QJsonArray{ "base" } },
+ });
+ }
+
+ QJsonDocument doc{ QJsonObject{
+ { "version", 1 },
+ { "configurePresets", presets },
+ } };
+
+ QFile presetsFile(CMakeGUITest_BINARY_DIR
+ "/changingPresets/src/CMakePresets.json");
+ bool open = presetsFile.open(QIODevice::WriteOnly);
+ Q_ASSERT(open);
+ presetsFile.write(doc.toJson());
+}
+}
+
+void CMakeGUITest::changingPresets()
+{
+ QDir::root().mkpath(CMakeGUITest_BINARY_DIR "/changingPresets/src");
+
+ this->m_window->SourceDirectory->setText(CMakeGUITest_BINARY_DIR
+ "/changingPresets/src");
+ loopSleep();
+ QCOMPARE(this->m_window->Preset->presetName(), QString{});
+ QCOMPARE(this->m_window->Preset->presets().size(), 0);
+ QCOMPARE(this->m_window->BinaryDirectory->currentText(), "");
+ QCOMPARE(this->m_window->Preset->isEnabled(), false);
+
+ writePresets("build1", { "preset" });
+ loopSleep(1500);
+ QCOMPARE(this->m_window->Preset->presetName(), QString{});
+ QCOMPARE(this->m_window->Preset->presets().size(), 1);
+ QCOMPARE(this->m_window->BinaryDirectory->currentText(), "");
+ QCOMPARE(this->m_window->Preset->isEnabled(), true);
+
+ this->m_window->Preset->setPresetName("preset");
+ loopSleep();
+ QCOMPARE(this->m_window->Preset->presetName(), "preset");
+ QCOMPARE(this->m_window->Preset->presets().size(), 1);
+ QCOMPARE(this->m_window->BinaryDirectory->currentText(),
+ CMakeGUITest_BINARY_DIR "/changingPresets/src/build1/preset");
+ QCOMPARE(this->m_window->Preset->isEnabled(), true);
+
+ writePresets("build2", { "preset2", "preset" });
+ loopSleep(1500);
+ QCOMPARE(this->m_window->Preset->presetName(), "preset");
+ QCOMPARE(this->m_window->Preset->presets().size(), 2);
+ QCOMPARE(this->m_window->BinaryDirectory->currentText(),
+ CMakeGUITest_BINARY_DIR "/changingPresets/src/build1/preset");
+ QCOMPARE(this->m_window->Preset->isEnabled(), true);
+
+ writePresets("build3", { "preset2" });
+ loopSleep(1500);
+ QCOMPARE(this->m_window->Preset->presetName(), QString{});
+ QCOMPARE(this->m_window->Preset->presets().size(), 1);
+ QCOMPARE(this->m_window->BinaryDirectory->currentText(),
+ CMakeGUITest_BINARY_DIR "/changingPresets/src/build1/preset");
+ QCOMPARE(this->m_window->Preset->isEnabled(), true);
+
+ this->m_window->Preset->setPresetName("preset2");
+ loopSleep();
+ QCOMPARE(this->m_window->Preset->presetName(), "preset2");
+ QCOMPARE(this->m_window->Preset->presets().size(), 1);
+ QCOMPARE(this->m_window->BinaryDirectory->currentText(),
+ CMakeGUITest_BINARY_DIR "/changingPresets/src/build3/preset2");
+ QCOMPARE(this->m_window->Preset->isEnabled(), true);
+
+ QDir::root().mkpath(CMakeGUITest_BINARY_DIR "/changingPresets/src2");
+ QFile::copy(CMakeGUITest_BINARY_DIR "/changingPresets/src/CMakePresets.json",
+ CMakeGUITest_BINARY_DIR
+ "/changingPresets/src2/CMakePresets.json");
+ this->m_window->SourceDirectory->setText(CMakeGUITest_BINARY_DIR
+ "/changingPresets/src2");
+ loopSleep();
+ QCOMPARE(this->m_window->Preset->presetName(), QString{});
+ QCOMPARE(this->m_window->Preset->presets().size(), 1);
+ QCOMPARE(this->m_window->BinaryDirectory->currentText(),
+ CMakeGUITest_BINARY_DIR "/changingPresets/src/build3/preset2");
+ QCOMPARE(this->m_window->Preset->isEnabled(), true);
+
+ this->m_window->Preset->setPresetName("preset2");
+ loopSleep();
+ QCOMPARE(this->m_window->Preset->presetName(), "preset2");
+ QCOMPARE(this->m_window->Preset->presets().size(), 1);
+ QCOMPARE(this->m_window->BinaryDirectory->currentText(),
+ CMakeGUITest_BINARY_DIR "/changingPresets/src2/build3/preset2");
+ QCOMPARE(this->m_window->Preset->isEnabled(), true);
+
+ QFile(CMakeGUITest_BINARY_DIR "/changingPresets/src2/CMakePresets.json")
+ .remove();
+ loopSleep(1500);
+ QCOMPARE(this->m_window->Preset->presetName(), QString{});
+ QCOMPARE(this->m_window->Preset->presets().size(), 0);
+ QCOMPARE(this->m_window->BinaryDirectory->currentText(),
+ CMakeGUITest_BINARY_DIR "/changingPresets/src2/build3/preset2");
+ QCOMPARE(this->m_window->Preset->isEnabled(), false);
+}
+
+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);
+}