File indexing completed on 2024-05-19 04:41:36

0001 /*
0002     SPDX-FileCopyrightText: 2011 Julien Desgats <julien.desgats@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "test_qmakeproject.h"
0008 #include "../qmakeconfig.h"
0009 #include "qmaketestconfig.h"
0010 
0011 #include <shell/core.h>
0012 #include <tests/autotestshell.h>
0013 #include <tests/testcore.h>
0014 #include <interfaces/icore.h>
0015 #include <interfaces/iprojectcontroller.h>
0016 #include <interfaces/iproject.h>
0017 #include <project/interfaces/ibuildsystemmanager.h>
0018 #include <project/interfaces/iprojectbuilder.h>
0019 #include <project/projectmodel.h>
0020 #include <serialization/indexedstring.h>
0021 
0022 #include <QFileInfo>
0023 #include <QTest>
0024 #include <QSignalSpy>
0025 #include <KConfigGroup>
0026 #include <KJob>
0027 
0028 QTEST_MAIN(TestQMakeProject)
0029 
0030 using namespace KDevelop;
0031 
0032 namespace
0033 {
0034 ProjectTargetItem* findTarget(const ProjectFolderItem* folder, const QString& name)
0035 {
0036     const auto items = folder->children();
0037     for (const auto* item : items) {
0038         if (item->target() && item->baseName() == name) {
0039             return item->target();
0040         } else if (item->folder()) {
0041             auto ret = findTarget(item->folder(), name);
0042             if (ret) {
0043                 return ret;
0044             }
0045         }
0046     }
0047     return nullptr;
0048 }
0049 
0050 }
0051 
0052 TestQMakeProject::TestQMakeProject(QObject* parent)
0053     : QObject(parent)
0054 {
0055     qRegisterMetaType<IProject*>();
0056 }
0057 
0058 TestQMakeProject::~TestQMakeProject()
0059 {
0060 }
0061 
0062 void TestQMakeProject::initTestCase()
0063 {
0064     AutoTestShell::init({ "KDevQMakeManager", "KDevQMakeBuilder", "KDevMakeBuilder", "KDevStandardOutputView" });
0065     TestCore::initialize();
0066 
0067     // Verify m_buildDir after initialization. Otherwise cleanupTestCase() crashes if the check fails.
0068     QVERIFY2(m_buildDir.isValid(), qPrintable("couldn't create temporary directory: " + m_buildDir.errorString()));
0069 }
0070 
0071 void TestQMakeProject::cleanupTestCase()
0072 {
0073     Core::self()->cleanup();
0074 }
0075 
0076 void TestQMakeProject::testBuildDirectory_data()
0077 {
0078     QTest::addColumn<QString>("projectName"); // name of the project (both directory and .kde4 file)
0079     QTest::addColumn<QString>("target"); // directory to compile from project root
0080     QTest::addColumn<QString>("expected"); // expected build directory from build dir
0081 
0082     QTest::newRow("Basic Project") << "basic_project"
0083                                    << ""
0084                                    << "";
0085     QTest::newRow("Subdirs Project (dir_a)") << "subdirs_project"
0086                                              << "dir_a"
0087                                              << "dir_a";
0088     QTest::newRow("Subdirs Project (dir_b)") << "subdirs_project"
0089                                              << "dir_b"
0090                                              << "dir_b";
0091 }
0092 
0093 void TestQMakeProject::testBuildDirectory()
0094 {
0095     QFETCH(QString, projectName);
0096     QFETCH(QString, target);
0097     QFETCH(QString, expected);
0098 
0099     const auto projects = ICore::self()->projectController()->projects();
0100     for (IProject* p : projects) {
0101         ICore::self()->projectController()->closeProject(p);
0102     }
0103 
0104     // setup project config, to avoid build dir chooser dialog popping up
0105     {
0106         // note: all checks from QMakeProjectManager::projectNeedsConfiguration must be satisfied
0107         const QString fileName
0108             = QStringLiteral("%1/%2/.kdev4/%2.kdev4").arg(QMAKE_TESTS_PROJECTS_DIR, projectName);
0109 
0110         KConfig cfg(fileName);
0111         KConfigGroup group(&cfg, QMakeConfig::CONFIG_GROUP);
0112 
0113         group.writeEntry(QMakeConfig::BUILD_FOLDER, m_buildDir.path());
0114         group.writeEntry(QMakeConfig::QMAKE_EXECUTABLE, QMAKE_TESTS_QMAKE_EXECUTABLE);
0115         group.sync();
0116 
0117         /// create subgroup for one build dir
0118         KConfigGroup buildDirGroup = KConfigGroup(&cfg, QMakeConfig::CONFIG_GROUP).group(m_buildDir.path());
0119         buildDirGroup.writeEntry(QMakeConfig::QMAKE_EXECUTABLE, QMAKE_TESTS_QMAKE_EXECUTABLE);
0120         buildDirGroup.sync();
0121 
0122         QVERIFY(QFileInfo::exists(fileName));
0123     }
0124 
0125     // opens project with kdevelop
0126     const QUrl projectUrl = QUrl::fromLocalFile(
0127         QStringLiteral("%1/%2/%2.kdev4").arg(QMAKE_TESTS_PROJECTS_DIR, projectName));
0128     ICore::self()->projectController()->openProject(projectUrl);
0129 
0130     // wait for loading finished
0131     QSignalSpy spy(ICore::self()->projectController(), SIGNAL(projectOpened(KDevelop::IProject*)));
0132     bool gotSignal = spy.wait(30000);
0133     QVERIFY2(gotSignal, "Timeout while waiting for opened signal");
0134 
0135     IProject* project = ICore::self()->projectController()->findProjectByName(projectName);
0136 
0137     // adds expected directory to our base path
0138     const Path expectedPath(Path{m_buildDir.path()}, expected);
0139 
0140     auto targetItem = findTarget(project->projectItem(), target.isEmpty() ? projectName : target);
0141     QVERIFY(targetItem);
0142 
0143     IBuildSystemManager* buildManager = project->buildSystemManager();
0144 
0145     const Path actual = buildManager->buildDirectory(targetItem);
0146     QCOMPARE(actual, expectedPath);
0147 
0148     auto buildJob = buildManager->builder()->configure(project);
0149     QVERIFY(buildJob->exec());
0150 }
0151 
0152 #include "moc_test_qmakeproject.cpp"