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

0001 /*
0002     SPDX-FileCopyrightText: 2019 Daniel Mensinger <daniel@mensinger-ka.de>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "mesontests.h"
0008 #include <QJsonArray>
0009 #include <QJsonObject>
0010 #include <algorithm>
0011 #include <debug.h>
0012 #include <interfaces/iproject.h>
0013 #include <kjob.h>
0014 #include <outputview/outputexecutejob.h>
0015 #include <util/executecompositejob.h>
0016 
0017 using namespace std;
0018 using namespace KDevelop;
0019 
0020 // Class MesonTest
0021 
0022 MesonTest::MesonTest(const QJsonObject& json, IProject* project)
0023     : m_project(project)
0024 {
0025     fromJson(json);
0026 }
0027 
0028 MesonTest::~MesonTest() {}
0029 
0030 QString MesonTest::name() const
0031 {
0032     return m_name;
0033 }
0034 
0035 QStringList MesonTest::suites() const
0036 {
0037     return m_suites;
0038 }
0039 
0040 IProject* MesonTest::project() const
0041 {
0042     return m_project;
0043 }
0044 
0045 KJob* MesonTest::job(ITestSuite::TestJobVerbosity verbosity)
0046 {
0047     auto convVerbosity = [verbosity]() {
0048         switch (verbosity) {
0049         case KDevelop::ITestSuite::Verbose:
0050             return OutputJob::Verbose;
0051         case KDevelop::ITestSuite::Silent:
0052             return OutputJob::Silent;
0053         }
0054         Q_UNREACHABLE();
0055     }();
0056 
0057     auto* job = new OutputExecuteJob(m_project, convVerbosity);
0058     *job << m_command;
0059     if (!m_workDir.isEmpty()) {
0060         job->setWorkingDirectory(m_workDir.toUrl());
0061     }
0062     job->setJobName(m_name);
0063     for (auto i = begin(m_env); i != end(m_env); ++i) {
0064         job->addEnvironmentOverride(i.key(), i.value());
0065     }
0066     return job;
0067 }
0068 
0069 void MesonTest::fromJson(const QJsonObject& json)
0070 {
0071     m_name = json[QStringLiteral("name")].toString();
0072     m_workDir = Path(json[QStringLiteral("workdir")].toString());
0073 
0074     QJsonArray cmd = json[QStringLiteral("cmd")].toArray();
0075     QJsonArray suites = json[QStringLiteral("suite")].toArray();
0076     QJsonObject env = json[QStringLiteral("env")].toObject();
0077 
0078     transform(begin(cmd), end(cmd), back_inserter(m_command), [](const auto& x) { return x.toString(); });
0079     transform(begin(suites), end(suites), back_inserter(m_suites), [](const auto& x) { return x.toString(); });
0080 
0081     for (auto i = begin(env); i != end(env); ++i) {
0082         m_env[i.key()] = i.value().toString();
0083     }
0084 
0085     qCDebug(KDEV_Meson) << "MINTRO:   - Loaded test" << m_name << "suites:" << m_suites;
0086 }
0087 
0088 // Class MesonTestSuite
0089 
0090 MesonTestSuite::MesonTestSuite(QString name, IProject* project)
0091     : m_name(name)
0092     , m_project(project)
0093 {
0094     qCDebug(KDEV_Meson) << "MINTRO:   - New test suite" << m_name;
0095 }
0096 
0097 MesonTestSuite::~MesonTestSuite() {}
0098 
0099 QString MesonTestSuite::name() const
0100 {
0101     return m_name;
0102 }
0103 
0104 QStringList MesonTestSuite::cases() const
0105 {
0106     QStringList result;
0107     for (auto i : m_tests) {
0108         result << i->name();
0109     }
0110     return result;
0111 }
0112 
0113 IProject* MesonTestSuite::project() const
0114 {
0115     return m_project;
0116 }
0117 
0118 KJob* MesonTestSuite::launchCase(const QString& testCase, TestJobVerbosity verbosity)
0119 {
0120     auto iter = m_tests.find(testCase);
0121     if (iter == end(m_tests)) {
0122         return nullptr;
0123     }
0124 
0125     return (*iter)->job(verbosity);
0126 }
0127 
0128 KJob* MesonTestSuite::launchCases(const QStringList& testCases, TestJobVerbosity verbosity)
0129 {
0130     QList<KJob*> jobs;
0131     for (const auto& i : testCases) {
0132         auto iter = m_tests.find(i);
0133         if (iter == end(m_tests)) {
0134             continue;
0135         }
0136 
0137         jobs << (*iter)->job(verbosity);
0138     }
0139 
0140     return new ExecuteCompositeJob(m_project, jobs);
0141 }
0142 
0143 KJob* MesonTestSuite::launchAllCases(TestJobVerbosity verbosity)
0144 {
0145     QList<KJob*> jobs;
0146     for (auto& i : m_tests) {
0147         jobs << i->job(verbosity);
0148     }
0149 
0150     return new ExecuteCompositeJob(m_project, jobs);
0151 }
0152 
0153 IndexedDeclaration MesonTestSuite::declaration() const
0154 {
0155     return IndexedDeclaration();
0156 }
0157 
0158 IndexedDeclaration MesonTestSuite::caseDeclaration(const QString&) const
0159 {
0160     return IndexedDeclaration();
0161 }
0162 
0163 void MesonTestSuite::addTestCase(MesonTestPtr test)
0164 {
0165     if (!test) {
0166         qCDebug(KDEV_Meson) << "TESTS: Tried to add a nullptr test";
0167         return;
0168     }
0169 
0170     m_tests[test->name()] = test;
0171 }
0172 
0173 QHash<QString, MesonTestPtr> MesonTestSuite::tests()
0174 {
0175     return m_tests;
0176 }
0177 
0178 // Class MesonTestSuites
0179 
0180 MesonTestSuites::MesonTestSuites(const QJsonArray& json, IProject* project)
0181     : m_project(project)
0182 {
0183     fromJSON(json);
0184 }
0185 
0186 MesonTestSuites::~MesonTestSuites() {}
0187 
0188 QHash<QString, MesonTestSuitePtr> MesonTestSuites::testSuites()
0189 {
0190     return m_suites;
0191 }
0192 
0193 MesonTestSuitePtr MesonTestSuites::testSuite(QString name)
0194 {
0195     auto iter = m_suites.find(name);
0196     if (iter == end(m_suites)) {
0197         return nullptr;
0198     }
0199     return *iter;
0200 }
0201 
0202 MesonTestSuitePtr MesonTestSuites::operator[](QString name)
0203 {
0204     return testSuite(name);
0205 }
0206 
0207 void MesonTestSuites::fromJSON(const QJsonArray& json)
0208 {
0209     QVector<MesonTestPtr> tests;
0210     qCDebug(KDEV_Meson) << "MINTRO: -- Loading tests from JSON...";
0211     for (const auto& i : json) {
0212         tests << make_shared<MesonTest>(i.toObject(), m_project);
0213     }
0214 
0215     qCDebug(KDEV_Meson) << "MINTRO: -- Adding tests to suites";
0216     for (auto& i : tests) {
0217         for (QString j : i->suites()) {
0218             auto suite = testSuite(j);
0219             if (!suite) {
0220                 suite = make_shared<MesonTestSuite>(j, m_project);
0221                 m_suites[j] = suite;
0222             }
0223             suite->addTestCase(i);
0224             qCDebug(KDEV_Meson) << "MINTRO:   - Added test" << i->name() << "to suite" << suite->name();
0225         }
0226     }
0227 }