| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458 |
- /* 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->isHidden(), true);
- QCOMPARE(this->m_window->PresetLabel->isHidden(), true);
- 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->isHidden(), false);
- QCOMPARE(this->m_window->PresetLabel->isHidden(), false);
- 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->isHidden(), false);
- QCOMPARE(this->m_window->PresetLabel->isHidden(), false);
- 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->isHidden(), false);
- QCOMPARE(this->m_window->PresetLabel->isHidden(), false);
- 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->isHidden(), false);
- QCOMPARE(this->m_window->PresetLabel->isHidden(), false);
- 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->isHidden(), false);
- QCOMPARE(this->m_window->PresetLabel->isHidden(), false);
- 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->isHidden(), false);
- QCOMPARE(this->m_window->PresetLabel->isHidden(), false);
- 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->isHidden(), false);
- QCOMPARE(this->m_window->PresetLabel->isHidden(), false);
- 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->isHidden(), true);
- QCOMPARE(this->m_window->PresetLabel->isHidden(), true);
- }
- 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);
- }
|