File indexing completed on 2024-05-12 04:39:30

0001 /*
0002     SPDX-FileCopyrightText: 2012 Aleix Pol Gonzalez <aleixpol@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #ifndef TESTHELPERS_H
0008 #define TESTHELPERS_H
0009 
0010 #include "cmake-test-paths.h"
0011 #include <cmakebuilddirchooser.h>
0012 #include <cmakeconfiggroupkeys.h>
0013 #include <KConfig>
0014 #include <KConfigGroup>
0015 #include <QFile>
0016 #include <QFileInfo>
0017 #include <QDir>
0018 #include <interfaces/iproject.h>
0019 #include <interfaces/icore.h>
0020 #include <interfaces/iprojectcontroller.h>
0021 #include <interfaces/iruntimecontroller.h>
0022 #include <interfaces/iruntime.h>
0023 #include <QSignalSpy>
0024 
0025 struct TestProjectPaths {
0026     // foo/
0027     KDevelop::Path sourceDir;
0028     // foo/foo.kdev4
0029     KDevelop::Path projectFile;
0030     // foo/.kdev4/foo.kdev4
0031     KDevelop::Path configFile;
0032 };
0033 
0034 inline TestProjectPaths projectPaths(const QString& project, const QString& name = QString())
0035 {
0036     TestProjectPaths paths;
0037     if(QDir::isRelativePath(project)) {
0038         QFileInfo info(QStringLiteral(CMAKE_TESTS_PROJECTS_DIR)+"/"+project);
0039         Q_ASSERT(info.exists());
0040         paths.sourceDir = KDevelop::Path(info.canonicalFilePath());
0041     } else {
0042         paths.sourceDir = KDevelop::Path(project);
0043     }
0044     Q_ASSERT(QFile::exists(paths.sourceDir.toLocalFile()));
0045 
0046     QString kdev4Name;
0047     if (name.isEmpty()) {
0048         QDir d(paths.sourceDir.toLocalFile());
0049         kdev4Name = d.entryList(QStringList(QStringLiteral("*.kdev4")), QDir::Files).takeFirst();
0050     } else
0051         kdev4Name = name+".kdev4";
0052 
0053     paths.projectFile = KDevelop::Path(paths.sourceDir, kdev4Name);
0054     Q_ASSERT(QFile::exists(paths.projectFile.toLocalFile()));
0055 
0056     paths.configFile = KDevelop::Path(paths.sourceDir, QString(QStringLiteral(".kdev4/") + kdev4Name));
0057 
0058     return paths;
0059 }
0060 
0061 /**
0062  * apply default configuration to project in @p sourceDir called @p projectName
0063  * 
0064  * this prevents the dialog to popup asking for user interaction
0065  * which should never happen in an automated unit test
0066  */
0067 inline void defaultConfigure(const TestProjectPaths& paths)
0068 {
0069     KConfig config(paths.configFile.toLocalFile());
0070     // clear config
0071     config.deleteGroup(Config::groupName);
0072 
0073     // apply default configuration
0074     CMakeBuildDirChooser bd;
0075     bd.setSourceFolder(paths.sourceDir);
0076     bd.setBuildFolder(KDevelop::Path(CMAKE_TESTS_BINARY_DIR + QStringLiteral("/build-") + paths.sourceDir.lastPathSegment()));
0077     // we don't want to execute, just pick the defaults from the dialog
0078 
0079     KConfigGroup cmakeGroup = config.group(Config::groupName);
0080     {
0081         QDir buildFolder( bd.buildFolder().toLocalFile() );
0082         if ( !buildFolder.exists() ) {
0083             if ( !buildFolder.mkpath( buildFolder.absolutePath() ) ) {
0084                 Q_ASSERT(false && "The build directory did not exist and could not be created.");
0085             }
0086         }
0087     }
0088 
0089     cmakeGroup.writeEntry(Config::buildDirCountKey, 1);
0090     cmakeGroup.writeEntry(Config::buildDirIndexKey(), 0);
0091 
0092     KConfigGroup buildDirGroup = cmakeGroup.group(Config::groupNameBuildDir(0));
0093     buildDirGroup.writeEntry(Config::Specific::buildDirPathKey, bd.buildFolder().toLocalFile());
0094     buildDirGroup.writeEntry(Config::Specific::cmakeExecutableKey, bd.cmakeExecutable().toLocalFile());
0095     buildDirGroup.writeEntry(Config::Specific::cmakeInstallDirKey, bd.installPrefix().toLocalFile());
0096     buildDirGroup.writeEntry(Config::Specific::cmakeArgumentsKey, bd.extraArguments());
0097     buildDirGroup.writeEntry(Config::Specific::cmakeBuildTypeKey, bd.buildType());
0098     buildDirGroup.writeEntry(Config::Specific::buildDirRuntime, KDevelop::ICore::self()->runtimeController()->currentRuntime()->name());
0099 
0100     config.sync();
0101 }
0102 
0103 inline KDevelop::IProject* loadProject(const QString& name, const QString& relative = QString())
0104 {
0105     qRegisterMetaType<KDevelop::IProject*>();
0106 
0107     const TestProjectPaths paths = projectPaths(name+relative, name);
0108     defaultConfigure(paths);
0109 
0110     QSignalSpy spy(KDevelop::ICore::self()->projectController(),
0111                    SIGNAL(projectOpened(KDevelop::IProject*)));
0112     Q_ASSERT(spy.isValid());
0113 
0114     KDevelop::ICore::self()->projectController()->openProject(paths.projectFile.toUrl());
0115 
0116     if ( spy.isEmpty() && !spy.wait(30000) ) {
0117         qFatal( "Timeout while waiting for opened signal" );
0118     }
0119 
0120     KDevelop::IProject* project = KDevelop::ICore::self()->projectController()->findProjectByName(name);
0121     Q_ASSERT(project);
0122     Q_ASSERT(project->buildSystemManager());
0123     Q_ASSERT(paths.projectFile == project->projectFile());
0124     return project;
0125 }
0126 
0127 #endif