1 /*
2     SPDX-FileCopyrightText: 2011 Julien Desgats <julien.desgats@gmail.com>
3 
4     SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #include "test_qmakeproject.h"
8 #include "../qmakeconfig.h"
9 #include "qmaketestconfig.h"
10 
11 #include <shell/core.h>
12 #include <tests/autotestshell.h>
13 #include <tests/testcore.h>
14 #include <interfaces/icore.h>
15 #include <interfaces/iprojectcontroller.h>
16 #include <interfaces/iproject.h>
17 #include <project/interfaces/ibuildsystemmanager.h>
18 #include <project/interfaces/iprojectbuilder.h>
19 #include <project/projectmodel.h>
20 #include <serialization/indexedstring.h>
21 
22 #include <QFileInfo>
23 #include <QTest>
24 #include <QSignalSpy>
25 #include <KConfigGroup>
26 #include <KJob>
27 
28 QTEST_MAIN(TestQMakeProject)
29 
30 using namespace KDevelop;
31 
TestQMakeProject(QObject * parent)32 TestQMakeProject::TestQMakeProject(QObject* parent)
33     : QObject(parent)
34 {
35     qRegisterMetaType<IProject*>();
36 }
37 
~TestQMakeProject()38 TestQMakeProject::~TestQMakeProject()
39 {
40 }
41 
initTestCase()42 void TestQMakeProject::initTestCase()
43 {
44     AutoTestShell::init({ "KDevQMakeManager", "KDevQMakeBuilder", "KDevMakeBuilder", "KDevStandardOutputView" });
45     TestCore::initialize();
46 }
47 
cleanupTestCase()48 void TestQMakeProject::cleanupTestCase()
49 {
50     Core::self()->cleanup();
51 }
52 
testBuildDirectory_data()53 void TestQMakeProject::testBuildDirectory_data()
54 {
55     QTest::addColumn<QString>("projectName"); // name of the project (both directory and .kde4 file)
56     QTest::addColumn<QString>("target"); // directory to compile from project root
57     QTest::addColumn<QString>("expected"); // expected build directory from build dir
58 
59     QTest::newRow("Basic Project") << "basic_project"
60                                    << ""
61                                    << "";
62     QTest::newRow("Subdirs Project (root)") << "subdirs_project"
63                                             << ""
64                                             << "";
65     QTest::newRow("Subdirs Project (dir_a)") << "subdirs_project"
66                                              << "dir_a"
67                                              << "dir_a";
68 }
69 
testBuildDirectory()70 void TestQMakeProject::testBuildDirectory()
71 {
72     QFETCH(QString, projectName);
73     QFETCH(QString, target);
74     QFETCH(QString, expected);
75 
76     const QString buildDir = QDir::rootPath() + QStringLiteral("tmp/some/path"); // some dummy directory to build (nothing will be built anyway)
77 
78     foreach (IProject* p, ICore::self()->projectController()->projects()) {
79         ICore::self()->projectController()->closeProject(p);
80     }
81 
82     // setup project config, to avoid build dir chooser dialog popping up
83     {
84         // note: all checks from QMakeProjectManager::projectNeedsConfiguration must be satisfied
85         const QString fileName
86             = QStringLiteral("%1/%2/.kdev4/%2.kdev4").arg(QMAKE_TESTS_PROJECTS_DIR, projectName);
87 
88         KConfig cfg(fileName);
89         KConfigGroup group(&cfg, QMakeConfig::CONFIG_GROUP);
90 
91         group.writeEntry(QMakeConfig::BUILD_FOLDER, buildDir);
92         group.writeEntry(QMakeConfig::QMAKE_EXECUTABLE, QMAKE_TESTS_QMAKE_EXECUTABLE);
93         group.sync();
94 
95         /// create subgroup for one build dir
96         KConfigGroup buildDirGroup = KConfigGroup(&cfg, QMakeConfig::CONFIG_GROUP).group(buildDir);
97         buildDirGroup.writeEntry(QMakeConfig::QMAKE_EXECUTABLE, QMAKE_TESTS_QMAKE_EXECUTABLE);
98         buildDirGroup.sync();
99 
100         QVERIFY(QFileInfo::exists(fileName));
101     }
102 
103     // opens project with kdevelop
104     const QUrl projectUrl = QUrl::fromLocalFile(
105         QStringLiteral("%1/%2/%2.kdev4").arg(QMAKE_TESTS_PROJECTS_DIR, projectName));
106     ICore::self()->projectController()->openProject(projectUrl);
107 
108     // wait for loading finished
109     QSignalSpy spy(ICore::self()->projectController(), SIGNAL(projectOpened(KDevelop::IProject*)));
110     bool gotSignal = spy.wait(30000);
111     QVERIFY2(gotSignal, "Timeout while waiting for opened signal");
112 
113     IProject* project = ICore::self()->projectController()->findProjectByName(projectName);
114 
115     // adds expected directory to our base path
116     Path expectedPath(Path(buildDir), expected);
117 
118     // path for files to build
119     Path buildUrl(QStringLiteral("%1/%2/%3").arg(QMAKE_TESTS_PROJECTS_DIR, projectName, target));
120     QList<ProjectFolderItem*> buildItems = project->foldersForPath(IndexedString(buildUrl.pathOrUrl()));
121     QCOMPARE(buildItems.size(), 1);
122     IBuildSystemManager* buildManager = project->buildSystemManager();
123     const auto buildFolder = buildItems.first();
124 
125     const Path actual = buildManager->buildDirectory(buildFolder);
126 
127     QCOMPARE(actual, expectedPath);
128 
129     auto buildJob = buildManager->builder()->configure(project);
130     QVERIFY(buildJob->exec());
131 }
132