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

0001 /*
0002     SPDX-FileCopyrightText: 2012 Miha Čančula <miha@noughmad.eu>
0003     SPDX-FileCopyrightText: 2017 Kevin Funk <kfunk@kde.org>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "test_ctestfindsuites.h"
0009 
0010 #include "testhelpers.h"
0011 #include "cmakeutils.h"
0012 #include "cmake-test-paths.h"
0013 
0014 #include <language/duchain/declaration.h>
0015 #include <language/duchain/duchainlock.h>
0016 #include <language/duchain/duchain.h>
0017 #include <language/duchain/topducontext.h>
0018 #include <interfaces/itestcontroller.h>
0019 #include <interfaces/itestsuite.h>
0020 #include <interfaces/iprojectcontroller.h>
0021 #include <interfaces/iproject.h>
0022 #include <interfaces/ibuildsystemmanager.h>
0023 #include <interfaces/iprojectbuilder.h>
0024 #include <testing/ctestsuite.h>
0025 #include <tests/autotestshell.h>
0026 #include <tests/testcore.h>
0027 #include <project/projectmodel.h>
0028 
0029 #include <QDir>
0030 #include <QTest>
0031 #include <KJob>
0032 
0033 using namespace KDevelop;
0034 
0035 void waitForSuites(IProject* project, int count, int secondsTimeout)
0036 {
0037     auto testController = ICore::self()->testController();
0038     QTRY_COMPARE_WITH_TIMEOUT(testController->testSuitesForProject(project).size(), count, secondsTimeout * 1000);
0039 }
0040 
0041 void TestCTestFindSuites::initTestCase()
0042 {
0043     AutoTestShell::init({"KDevCMakeManager", "KDevCMakeBuilder", "KDevMakeBuilder", "KDevStandardOutputView"});
0044     TestCore::initialize();
0045 
0046     qRegisterMetaType<ITestSuite*>();
0047 
0048     cleanup();
0049 }
0050 
0051 void TestCTestFindSuites::cleanup()
0052 {
0053     const auto projects = ICore::self()->projectController()->projects() ;
0054     for (IProject* p : projects) {
0055         if (p && p->buildSystemManager() && p->buildSystemManager()->builder())
0056         {
0057             p->buildSystemManager()->builder()->prune(p)->exec();
0058         }
0059         ICore::self()->projectController()->closeProject(p);
0060     }
0061     QVERIFY(ICore::self()->projectController()->projects().isEmpty());
0062 }
0063 
0064 void TestCTestFindSuites::cleanupTestCase()
0065 {
0066     TestCore::shutdown();
0067 }
0068 
0069 void TestCTestFindSuites::testCTestSuite()
0070 {
0071     IProject* project = loadProject( "unit_tests" );
0072     QVERIFY2(project, "Project was not opened");
0073     waitForSuites(project, 5, 25);
0074     const QList<ITestSuite*> suites = ICore::self()->testController()->testSuitesForProject(project);
0075 
0076     QCOMPARE(suites.size(), 5);
0077 
0078     DUChainReadLocker locker(DUChain::lock());
0079 
0080     for (auto suite : suites) {
0081         QCOMPARE(suite->cases(), QStringList());
0082         auto* ctestSuite = static_cast<CTestSuite*>(suite);
0083         QVERIFY(suite->declaration().isValid());
0084         const auto buildDir = Path(CMake::allBuildDirs(project).at(0));
0085         QString exeSubdir = buildDir.relativePath(ctestSuite->executable().parent());
0086         QCOMPARE(exeSubdir, ctestSuite->name() == "fail" ? QStringLiteral("bin") : QString() );
0087         QString willFail;
0088         const QString workingDirectory = ctestSuite->properties().value(QLatin1String("WORKING_DIRECTORY"), QString());
0089         auto cursor = ctestSuite->declaration().data()->range().start;
0090         if (ctestSuite->name() == QLatin1String("fail")) {
0091             willFail = QLatin1String("TRUE");
0092             QCOMPARE(workingDirectory, QLatin1String("/bar/baz"));
0093             QCOMPARE(ctestSuite->properties().value(QLatin1String("FOO"), QString()), QLatin1String("foo"));
0094             QCOMPARE(ctestSuite->properties().value(QLatin1String("BAR"), QString()), QLatin1String("TRUE"));
0095             QCOMPARE(ctestSuite->properties().value(QLatin1String("MULTILINE"), QString()), QLatin1String("this is \na multi\nline property"));
0096             QCOMPARE(ctestSuite->properties().value(QLatin1String("QUOTES"), QString()), QLatin1String("\"\\\\\"\\\\\\"));
0097             QCOMPARE(cursor.line, 0);
0098         } else if (ctestSuite->name() == QLatin1String("test_three")) {
0099             QCOMPARE(workingDirectory, QLatin1String("/foo"));
0100             QCOMPARE(ctestSuite->arguments(), QStringList("3"));
0101             QCOMPARE(cursor.line, 2);
0102         } else if (ctestSuite->name() == QLatin1String("test_four")) {
0103             QCOMPARE(ctestSuite->arguments(), QStringList("4"));
0104             QCOMPARE(cursor.line, 2);
0105         } else if (ctestSuite->name() == QLatin1String("test_five")) {
0106             QCOMPARE(workingDirectory, QString(buildDir.path() + QLatin1String("/bin")));
0107             QCOMPARE(cursor.line, 2);
0108         } else {
0109             QCOMPARE(workingDirectory, QString());
0110             QCOMPARE(cursor.line, 0);
0111         }
0112         QCOMPARE(ctestSuite->properties().value(QLatin1String("WILL_FAIL")), willFail);
0113     }
0114 }
0115 
0116 void TestCTestFindSuites::testQtTestCases()
0117 {
0118     IProject* project = loadProject( "unit_tests_kde" );
0119     QVERIFY2(project, "Project was not opened");
0120 
0121     waitForSuites(project, 2, 25);
0122 
0123     const QList<ITestSuite*> suites = ICore::self()->testController()->testSuitesForProject(project);
0124     QCOMPARE(suites.size(), 2);
0125 
0126     QMap<QString, int> caseLines = {
0127         {QStringLiteral("passingTestCase"), 9},
0128         {QStringLiteral("failingTestCase"), 14},
0129         {QStringLiteral("expectedFailTestCase"), 19},
0130         {QStringLiteral("unexpectedPassTestCase"), 25},
0131         {QStringLiteral("skippedTestCase"), 31}
0132     };
0133 
0134     DUChainReadLocker locker(DUChain::lock());
0135 
0136     for (auto suite : suites) {
0137         const auto caseNames = suite->cases();
0138         QCOMPARE(caseNames.count(), caseLines.count());
0139         QVERIFY(suite->declaration().isValid());
0140 
0141         for (const auto& caseName : caseNames) {
0142             auto decl = suite->caseDeclaration(caseName);
0143             QVERIFY(decl.isValid());
0144             auto it = caseLines.find(caseName);
0145             QVERIFY(it != caseLines.end());
0146             QCOMPARE(decl.data()->range().start.line, it.value());
0147         }
0148     }
0149 }
0150 
0151 QTEST_MAIN(TestCTestFindSuites)
0152 
0153 #include "moc_test_ctestfindsuites.cpp"