File indexing completed on 2024-04-28 04:39:53

0001 /*
0002     SPDX-FileCopyrightText: 2012 Miha ?an?ula <miha@noughmad.eu>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "testviewplugin.h"
0008 #include "testview.h"
0009 
0010 #include <interfaces/icore.h>
0011 #include <interfaces/iuicontroller.h>
0012 #include <interfaces/itestsuite.h>
0013 #include <interfaces/itestcontroller.h>
0014 #include <interfaces/iruncontroller.h>
0015 #include <interfaces/iprojectcontroller.h>
0016 #include <interfaces/iproject.h>
0017 #include <util/executecompositejob.h>
0018 
0019 #include <KPluginFactory>
0020 #include <KLocalizedString>
0021 #include <KActionCollection>
0022 
0023 #include <QAction>
0024 
0025 K_PLUGIN_FACTORY_WITH_JSON(TestViewFactory, "kdevtestview.json", registerPlugin<TestViewPlugin>();)
0026 
0027 using namespace KDevelop;
0028 
0029 class TestToolViewFactory: public KDevelop::IToolViewFactory
0030 {
0031     public:
0032         explicit TestToolViewFactory( TestViewPlugin *plugin ): mplugin( plugin )
0033         {}
0034         QWidget* create( QWidget *parent = nullptr ) override
0035         {
0036             return new TestView( mplugin, parent );
0037         }
0038         Qt::DockWidgetArea defaultPosition() const override
0039         {
0040             return Qt::LeftDockWidgetArea;
0041         }
0042         QString id() const override
0043         {
0044             return QStringLiteral("org.kdevelop.TestView");
0045         }
0046         QList< QAction* > contextMenuActions(QWidget* viewWidget) const override
0047         {
0048             return qobject_cast<TestView*>(viewWidget)->contextMenuActions();
0049         }
0050     private:
0051         TestViewPlugin *mplugin;
0052 };
0053 
0054 TestViewPlugin::TestViewPlugin(QObject* parent, const QVariantList& args)
0055     : IPlugin(QStringLiteral("kdevtestview"), parent)
0056 {
0057     Q_UNUSED(args)
0058 
0059     auto* runAll = new QAction( QIcon::fromTheme(QStringLiteral("system-run")), i18nc("@action", "Run All Tests"), this );
0060     connect(runAll, &QAction::triggered, this, &TestViewPlugin::runAllTests);
0061     actionCollection()->addAction(QStringLiteral("run_all_tests"), runAll);
0062     
0063     auto* stopTest = new QAction( QIcon::fromTheme(QStringLiteral("process-stop")), i18nc("@action", "Stop Running Tests"), this );
0064     connect(stopTest, &QAction::triggered, this, &TestViewPlugin::stopRunningTests);
0065     actionCollection()->addAction(QStringLiteral("stop_running_tests"), stopTest);
0066 
0067     setXMLFile(QStringLiteral("kdevtestview.rc"));
0068 
0069     m_viewFactory = new TestToolViewFactory(this);
0070     core()->uiController()->addToolView(i18nc("@title:window", "Unit Tests"), m_viewFactory);
0071     
0072     connect(core()->runController(),&IRunController::jobRegistered, this, &TestViewPlugin::jobStateChanged);
0073     connect(core()->runController(),&IRunController::jobUnregistered, this, &TestViewPlugin::jobStateChanged);
0074     
0075     jobStateChanged();
0076 }
0077 
0078 TestViewPlugin::~TestViewPlugin()
0079 {
0080 
0081 }
0082 
0083 void TestViewPlugin::unload()
0084 {
0085     core()->uiController()->removeToolView(m_viewFactory);
0086 }
0087 
0088 void TestViewPlugin::runAllTests()
0089 {
0090     ITestController* tc = core()->testController();
0091     const auto projects = core()->projectController()->projects();
0092     for (IProject* project : projects) {
0093         QList<KJob*> jobs;
0094         const auto suites = tc->testSuitesForProject(project);
0095         for (ITestSuite* suite : suites) {
0096             if (KJob* job = suite->launchAllCases(ITestSuite::Silent))
0097             {
0098                 jobs << job;
0099             }
0100         }
0101         if (!jobs.isEmpty())
0102         {
0103             auto* compositeJob = new KDevelop::ExecuteCompositeJob(this, jobs);
0104             compositeJob->setObjectName(i18np("Run 1 test in %2", "Run %1 tests in %2",
0105                                               jobs.size(), project->name()));
0106             compositeJob->setProperty("test_job", true);
0107             core()->runController()->registerJob(compositeJob);
0108         }
0109     }
0110 }
0111 
0112 void TestViewPlugin::stopRunningTests()
0113 {
0114     const auto jobs = core()->runController()->currentJobs();
0115     for (KJob* job : jobs) {
0116         if (job->property("test_job").toBool())
0117         {
0118             job->kill();
0119         }
0120     }
0121 }
0122 
0123 void TestViewPlugin::jobStateChanged()
0124 {
0125     const auto jobs = core()->runController()->currentJobs();
0126     const bool found = std::any_of(jobs.begin(), jobs.end(), [](KJob* job) {
0127         return (job->property("test_job").toBool());
0128     });
0129 
0130     actionCollection()->action(QStringLiteral("run_all_tests"))->setEnabled(!found);
0131     actionCollection()->action(QStringLiteral("stop_running_tests"))->setEnabled(found);
0132 }
0133 
0134 #include "testviewplugin.moc"
0135 #include "moc_testviewplugin.cpp"