File indexing completed on 2024-06-23 04:36:24
0001 /* 0002 SPDX-FileCopyrightText: 2014 Sergey Kalinichev <kalinichev.so.0@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include "test_compilerprovider.h" 0008 0009 #include <QTest> 0010 #include <QTemporaryFile> 0011 #include <QSignalBlocker> 0012 0013 #include <tests/autotestshell.h> 0014 #include <tests/testcore.h> 0015 #include <tests/projectsgenerator.h> 0016 0017 #include <interfaces/iproject.h> 0018 #include <interfaces/iprojectcontroller.h> 0019 #include <project/projectmodel.h> 0020 0021 #include <serialization/indexedstring.h> 0022 0023 #include <algorithm> 0024 0025 #include "../compilerprovider.h" 0026 #include "../settingsmanager.h" 0027 0028 using namespace KDevelop; 0029 0030 namespace 0031 { 0032 void testCompilerEntry(SettingsManager* settings, KConfig* config){ 0033 auto entries = settings->readPaths(config); 0034 auto entry = entries.first(); 0035 auto compilers = settings->provider()->compilers(); 0036 Q_ASSERT(!compilers.isEmpty()); 0037 bool gccCompilerInstalled = std::any_of(compilers.begin(), compilers.end(), [](const CompilerPointer& compiler){return compiler->name().contains(QLatin1String("gcc"), Qt::CaseInsensitive);}); 0038 if (gccCompilerInstalled) { 0039 QCOMPARE(entry.compiler->name(), QStringLiteral("GCC")); 0040 } 0041 } 0042 0043 void testAddingEntry(SettingsManager* settings, KConfig* config){ 0044 auto entries = settings->readPaths(config); 0045 auto entry = entries.first(); 0046 auto compilers = settings->provider()->compilers(); 0047 ConfigEntry otherEntry; 0048 otherEntry.defines[QStringLiteral("TEST")] = QStringLiteral("lalal"); 0049 otherEntry.includes = QStringList() << QStringLiteral("/foo"); 0050 otherEntry.path = QStringLiteral("test"); 0051 otherEntry.compiler = compilers.first(); 0052 entries << otherEntry; 0053 settings->writePaths(config, entries); 0054 0055 auto readWriteEntries = settings->readPaths(config); 0056 QCOMPARE(readWriteEntries.size(), 2); 0057 QCOMPARE(readWriteEntries.at(0).path, entry.path); 0058 QCOMPARE(readWriteEntries.at(0).defines, entry.defines); 0059 QCOMPARE(readWriteEntries.at(0).includes, entry.includes); 0060 QCOMPARE(readWriteEntries.at(0).compiler->name(), entry.compiler->name()); 0061 0062 QCOMPARE(readWriteEntries.at(1).path, otherEntry.path); 0063 QCOMPARE(readWriteEntries.at(1).defines, otherEntry.defines); 0064 QCOMPARE(readWriteEntries.at(1).includes, otherEntry.includes); 0065 QCOMPARE(readWriteEntries.at(1).compiler->name(), otherEntry.compiler->name()); 0066 } 0067 } 0068 0069 void TestCompilerProvider::initTestCase() 0070 { 0071 AutoTestShell::init({QStringLiteral("kdevdefinesandincludesmanager"), QStringLiteral("KDevCustomBuildSystem"), QStringLiteral("KDevStandardOutputView")}); 0072 TestCore::initialize(); 0073 } 0074 0075 void TestCompilerProvider::cleanupTestCase() 0076 { 0077 TestCore::shutdown(); 0078 } 0079 0080 void TestCompilerProvider::testRegisterCompiler() 0081 { 0082 auto settings = SettingsManager::globalInstance(); 0083 auto provider = settings->provider(); 0084 auto cf = provider->compilerFactories(); 0085 for (int i = 0 ; i < cf.size(); ++i) { 0086 auto compiler = cf[i]->createCompiler(QString::number(i), QString::number(i)); 0087 QVERIFY(provider->registerCompiler(compiler)); 0088 QVERIFY(!provider->registerCompiler(compiler)); 0089 QVERIFY(provider->compilers().contains(compiler)); 0090 } 0091 QVERIFY(!provider->registerCompiler({})); 0092 } 0093 0094 void TestCompilerProvider::testCompilerIncludesAndDefines() 0095 { 0096 auto settings = SettingsManager::globalInstance(); 0097 auto provider = settings->provider(); 0098 const auto& compilers = provider->compilers(); 0099 for (auto& c : compilers) { 0100 if (!c->editable() && !c->path().isEmpty()) { 0101 QVERIFY(!c->defines(Utils::Cpp, {}).isEmpty()); 0102 QVERIFY(!c->includes(Utils::Cpp, {}).isEmpty()); 0103 } 0104 } 0105 0106 QVERIFY(!provider->defines(nullptr).isEmpty()); 0107 QVERIFY(!provider->includes(nullptr).isEmpty()); 0108 0109 auto compiler = provider->compilerForItem(nullptr); 0110 QVERIFY(compiler); 0111 QVERIFY(!compiler->defines(Utils::Cpp, QStringLiteral("-std=c++11")).isEmpty()); 0112 QVERIFY(!compiler->includes(Utils::Cpp, QStringLiteral("-std=c++11")).isEmpty()); 0113 } 0114 0115 void TestCompilerProvider::testStorageBackwardsCompatible() 0116 { 0117 auto settings = SettingsManager::globalInstance(); 0118 QTemporaryFile file; 0119 QVERIFY(file.open()); 0120 QTextStream stream(&file); 0121 stream << "[Buildset]\n" << 0122 "BuildItems=@Variant(\\x00\\x00\\x00\\t\\x00\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x0b\\x00\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x1a\\x00S\\x00i\\x00m\\x00p\\x00l\\x00e\\x00P\\x00r\\x00o\\x00j\\x00e\\x00c\\x00t)\n" << 0123 "[CustomBuildSystem]\n" << "CurrentConfiguration=BuildConfig0\n" << 0124 "[CustomDefinesAndIncludes][ProjectPath0]\n" << 0125 "Defines=\\x00\\x00\\x00\\x02\\x00\\x00\\x00\\x0c\\x00_\\x00D\\x00E\\x00B\\x00U\\x00G\\x00\\x00\\x00\\n\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x10\\x00V\\x00A\\x00R\\x00I\\x00A\\x00B\\x00L\\x00E\\x00\\x00\\x00\\n\\x00\\x00\\x00\\x00\\n\\x00V\\x00A\\x00L\\x00U\\x00E\n" << 0126 "Includes=\\x00\\x00\\x00\\x01\\x00\\x00\\x00$\\x00/\\x00u\\x00s\\x00r\\x00/\\x00i\\x00n\\x00c\\x00l\\x00u\\x00d\\x00e\\x00/\\x00m\\x00y\\x00d\\x00i\\x00r\n" << 0127 "Path=/\n" << 0128 "[CustomDefinesAndIncludes][ProjectPath0][Compiler]\nName=GCC\nPath=gcc\nType=GCC\n"; 0129 file.close(); 0130 KConfig config(file.fileName()); 0131 auto entries = settings->readPaths(&config); 0132 QCOMPARE(entries.size(), 1); 0133 auto entry = entries.first(); 0134 Defines defines; 0135 defines[QStringLiteral("VARIABLE")] = QStringLiteral("VALUE"); 0136 defines[QStringLiteral("_DEBUG")] = QString(); 0137 QCOMPARE(entry.defines, defines); 0138 QStringList includes = QStringList() << QStringLiteral("/usr/include/mydir"); 0139 QCOMPARE(entry.includes, includes); 0140 QCOMPARE(entry.path, QString("/")); 0141 QVERIFY(entry.compiler); 0142 0143 testCompilerEntry(settings, &config); 0144 testAddingEntry(settings, &config); 0145 } 0146 0147 void TestCompilerProvider::testStorageNewSystem() 0148 { 0149 auto settings = SettingsManager::globalInstance(); 0150 QTemporaryFile file; 0151 QVERIFY(file.open()); 0152 QTextStream stream(&file); 0153 stream << "[Buildset]\n" << 0154 "BuildItems=@Variant(\\x00\\x00\\x00\\t\\x00\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x0b\\x00\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x1a\\x00S\\x00i\\x00m\\x00p\\x00l\\x00e\\x00P\\x00r\\x00o\\x00j\\x00e\\x00c\\x00t)\n\n" << 0155 "[CustomBuildSystem]\n" << "CurrentConfiguration=BuildConfig0\n\n" << 0156 "[CustomDefinesAndIncludes][ProjectPath0]\n" << "Path=/\n\n" << 0157 "[CustomDefinesAndIncludes][ProjectPath0][Defines]\n" << 0158 "_DEBUG=\n" << 0159 "VARIABLE=VALUE\n" << 0160 "[CustomDefinesAndIncludes][ProjectPath0][Includes]\n" << 0161 "1=/usr/include/mydir\n" << 0162 "2=/usr/local/include/mydir\n" << 0163 "[CustomDefinesAndIncludes][ProjectPath0][Compiler]\nName=GCC\nPath=gcc\nType=GCC\n"; 0164 file.close(); 0165 KConfig config(file.fileName()); 0166 auto entries = settings->readPaths(&config); 0167 QCOMPARE(entries.size(), 1); 0168 auto entry = entries.first(); 0169 QCOMPARE(entry.path, QString("/")); 0170 Defines defines; 0171 defines[QStringLiteral("VARIABLE")] = QStringLiteral("VALUE"); 0172 defines[QStringLiteral("_DEBUG")] = QString(); 0173 QCOMPARE(entry.defines, defines); 0174 QMap<QString, QString> includeMap; 0175 includeMap[QStringLiteral("1")] = QStringLiteral("/usr/include/mydir"); 0176 includeMap[QStringLiteral("2")] = QStringLiteral("/usr/local/include/mydir"); 0177 0178 int i = 0; 0179 for (auto& include : qAsConst(includeMap)) { 0180 QCOMPARE(entry.includes.at(i++), include); 0181 } 0182 0183 testCompilerEntry(settings, &config); 0184 testAddingEntry(settings, &config); 0185 } 0186 0187 void TestCompilerProvider::testCompilerIncludesAndDefinesForProject() 0188 { 0189 auto project = ProjectsGenerator::GenerateMultiPathProject(); 0190 Q_ASSERT(project); 0191 0192 auto settings = SettingsManager::globalInstance(); 0193 auto provider = settings->provider(); 0194 0195 Q_ASSERT(!provider->compilerFactories().isEmpty()); 0196 auto compiler = provider->compilerFactories().first()->createCompiler(QStringLiteral("name"), QStringLiteral("path")); 0197 0198 QVERIFY(provider->registerCompiler(compiler)); 0199 QVERIFY(provider->compilers().contains(compiler)); 0200 0201 auto projectCompiler = provider->compilerForItem(project->projectItem()); 0202 0203 QVERIFY(projectCompiler); 0204 QVERIFY(projectCompiler != compiler); 0205 0206 ProjectBaseItem* mainfile = nullptr; 0207 const auto& fileSet = project->fileSet(); 0208 for (const auto& file: fileSet) { 0209 const auto& files = project->filesForPath(file); 0210 for (auto i: files) { 0211 if( i->text() == QLatin1String("main.cpp") ) { 0212 mainfile = i; 0213 break; 0214 } 0215 } 0216 } 0217 QVERIFY(mainfile); 0218 auto mainCompiler = provider->compilerForItem(mainfile); 0219 QVERIFY(mainCompiler); 0220 QVERIFY(mainCompiler->name() == projectCompiler->name()); 0221 0222 ConfigEntry entry; 0223 entry.path = QStringLiteral("src/main.cpp"); 0224 entry.compiler = compiler; 0225 0226 auto entries = settings->readPaths(project->projectConfiguration().data()); 0227 0228 entries.append(entry); 0229 settings->writePaths(project->projectConfiguration().data(), entries); 0230 0231 QVERIFY(provider->compilers().contains(compiler)); 0232 0233 mainCompiler = provider->compilerForItem(mainfile); 0234 QVERIFY(mainCompiler); 0235 QVERIFY(mainCompiler->name() == compiler->name()); 0236 0237 ICore::self()->projectController()->closeProject(project); 0238 } 0239 0240 QTEST_MAIN(TestCompilerProvider) 0241 0242 #include "moc_test_compilerprovider.cpp"