File indexing completed on 2024-05-12 04:38:22
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 "test_testcontroller.h" 0008 #include <testcontroller.h> 0009 #include <QTest> 0010 #include <QSignalSpy> 0011 0012 #include <tests/autotestshell.h> 0013 #include <tests/testcore.h> 0014 #include <tests/testproject.h> 0015 #include <itestsuite.h> 0016 #include <iproject.h> 0017 #include <language/duchain/indexeddeclaration.h> 0018 0019 using namespace KDevelop; 0020 0021 const char* TestSuiteName = "TestTestSuite"; 0022 const char* TestSuiteNameTwo = "TestTestSuiteTwo"; 0023 const char* TestCaseNameOne = "TestTestCaseOne"; 0024 const char* TestCaseNameTwo = "TestTestCaseTwo"; 0025 0026 Q_DECLARE_METATYPE(KDevelop::TestResult) 0027 0028 class FakeTestSuite : public KDevelop::ITestSuite 0029 { 0030 public: 0031 FakeTestSuite(const QString& name, IProject* project, const QStringList& cases = QStringList()) : m_name(name), m_project(project), m_cases(cases) {} 0032 ~FakeTestSuite() override {} 0033 0034 IProject* project() const override {return m_project;} 0035 QString name() const override {return m_name;} 0036 QStringList cases() const override {return m_cases;} 0037 0038 IndexedDeclaration declaration() const override; 0039 IndexedDeclaration caseDeclaration(const QString& testCase) const override; 0040 0041 KJob* launchAllCases(TestJobVerbosity verbosity) override; 0042 KJob* launchCase(const QString& testCase, TestJobVerbosity verbosity) override; 0043 KJob* launchCases(const QStringList& testCases, TestJobVerbosity verbosity) override; 0044 0045 private: 0046 QString m_name; 0047 IProject* m_project; 0048 QStringList m_cases; 0049 }; 0050 0051 IndexedDeclaration FakeTestSuite::declaration() const 0052 { 0053 return IndexedDeclaration(); 0054 } 0055 0056 IndexedDeclaration FakeTestSuite::caseDeclaration(const QString& testCase) const 0057 { 0058 Q_UNUSED(testCase); 0059 return IndexedDeclaration(); 0060 } 0061 0062 KJob* FakeTestSuite::launchAllCases(ITestSuite::TestJobVerbosity verbosity) 0063 { 0064 Q_UNUSED(verbosity); 0065 return nullptr; 0066 } 0067 0068 KJob* FakeTestSuite::launchCase(const QString& testCase, ITestSuite::TestJobVerbosity verbosity) 0069 { 0070 Q_UNUSED(testCase); 0071 Q_UNUSED(verbosity); 0072 return nullptr; 0073 } 0074 0075 KJob* FakeTestSuite::launchCases(const QStringList& testCases, ITestSuite::TestJobVerbosity verbosity) 0076 { 0077 Q_UNUSED(testCases); 0078 Q_UNUSED(verbosity); 0079 return nullptr; 0080 } 0081 0082 void TestTestController::emitTestResult(ITestSuite* suite, TestResult::TestCaseResult caseResult) 0083 { 0084 TestResult result; 0085 result.suiteResult = caseResult; 0086 const auto testCases = suite->cases(); 0087 for (const QString& testCase : testCases) { 0088 result.testCaseResults.insert(testCase, caseResult); 0089 } 0090 0091 m_testController->notifyTestRunFinished(suite, result); 0092 } 0093 0094 void TestTestController::initTestCase() 0095 { 0096 AutoTestShell::init(); 0097 TestCore::initialize( Core::NoUi ); 0098 0099 m_testController = Core::self()->testControllerInternal(); 0100 m_project = new TestProject(Path(), this); 0101 0102 qRegisterMetaType<KDevelop::ITestSuite*>("KDevelop::ITestSuite*"); 0103 qRegisterMetaType<KDevelop::TestResult>("KDevelop::TestResult"); 0104 } 0105 0106 void TestTestController::cleanupTestCase() 0107 { 0108 delete m_project; 0109 TestCore::shutdown(); 0110 } 0111 0112 void TestTestController::addSuite() 0113 { 0114 FakeTestSuite suite(TestSuiteName, m_project); 0115 m_testController->addTestSuite(&suite); 0116 0117 ITestSuite* found = m_testController->findTestSuite(m_project, TestSuiteName); 0118 0119 QVERIFY(found); 0120 QCOMPARE(found->name(), QString(TestSuiteName)); 0121 QCOMPARE(found->project(), m_project); 0122 0123 m_testController->removeTestSuite(&suite); 0124 } 0125 0126 void TestTestController::removeSuite() 0127 { 0128 FakeTestSuite suite(TestSuiteName, m_project); 0129 m_testController->addTestSuite(&suite); 0130 0131 QVERIFY(m_testController->findTestSuite(m_project, TestSuiteName)); 0132 m_testController->removeTestSuite(&suite); 0133 0134 QCOMPARE(m_testController->findTestSuite(m_project, TestSuiteName), (ITestSuite*)nullptr); 0135 QVERIFY(m_testController->testSuites().isEmpty()); 0136 } 0137 0138 void TestTestController::replaceSuite() 0139 { 0140 auto* suiteOne = new FakeTestSuite(TestSuiteName, m_project, QStringList() << TestCaseNameOne); 0141 m_testController->addTestSuite(suiteOne); 0142 0143 QCOMPARE(m_testController->findTestSuite(m_project, TestSuiteName)->name(), QString(TestSuiteName)); 0144 QCOMPARE(m_testController->findTestSuite(m_project, TestSuiteName)->cases().size(), 1); 0145 0146 auto* suiteTwo = new FakeTestSuite(TestSuiteName, m_project, QStringList() << TestCaseNameOne << TestCaseNameTwo); 0147 m_testController->addTestSuite(suiteTwo); 0148 0149 QCOMPARE(m_testController->testSuites().size(), 1); 0150 QCOMPARE(m_testController->findTestSuite(m_project, TestSuiteName)->name(), QString(TestSuiteName)); 0151 QCOMPARE(m_testController->findTestSuite(m_project, TestSuiteName)->cases().size(), 2); 0152 0153 // TestController deletes the old suite when replacing it, so make sure we don't delete suiteOne manually 0154 0155 m_testController->removeTestSuite(suiteTwo); 0156 delete suiteTwo; 0157 } 0158 0159 void TestTestController::findByProject() 0160 { 0161 IProject* otherProject = new TestProject(Path(), this); 0162 0163 ITestSuite* suiteOne = new FakeTestSuite(TestSuiteName, m_project); 0164 ITestSuite* suiteTwo = new FakeTestSuite(TestSuiteName, otherProject); 0165 m_testController->addTestSuite(suiteOne); 0166 m_testController->addTestSuite(suiteTwo); 0167 0168 QCOMPARE(m_testController->testSuites().size(), 2); 0169 QCOMPARE(m_testController->testSuitesForProject(m_project).size(), 1); 0170 0171 QCOMPARE(m_testController->testSuitesForProject(m_project).at(0), suiteOne); 0172 0173 m_testController->removeTestSuite(suiteOne); 0174 m_testController->removeTestSuite(suiteTwo); 0175 delete suiteOne; 0176 delete suiteTwo; 0177 0178 delete otherProject; 0179 } 0180 0181 void TestTestController::testResults() 0182 { 0183 ITestSuite* suite = new FakeTestSuite(TestSuiteName, m_project); 0184 m_testController->addTestSuite(suite); 0185 0186 QSignalSpy spy(m_testController, SIGNAL(testRunFinished(KDevelop::ITestSuite*,KDevelop::TestResult))); 0187 QVERIFY(spy.isValid()); 0188 0189 QList<TestResult::TestCaseResult> results; 0190 results << TestResult::Passed << TestResult::Failed << TestResult::Error << TestResult::Skipped << TestResult::NotRun; 0191 0192 for (const TestResult::TestCaseResult result : qAsConst(results)) { 0193 emitTestResult(suite, result); 0194 QCOMPARE(spy.size(), 1); 0195 0196 QVariantList arguments = spy.takeFirst(); 0197 QCOMPARE(arguments.size(), 2); 0198 0199 QVERIFY(arguments.first().canConvert<ITestSuite*>()); 0200 QCOMPARE(arguments.first().value<ITestSuite*>(), suite); 0201 0202 QVERIFY(arguments.at(1).canConvert<TestResult>()); 0203 QCOMPARE(arguments.at(1).value<TestResult>().suiteResult, result); 0204 0205 const auto testCases = suite->cases(); 0206 for (const QString& testCase : testCases) { 0207 QCOMPARE(arguments.at(1).value<TestResult>().testCaseResults[testCase], result); 0208 } 0209 } 0210 0211 QCOMPARE(spy.size(), 0); 0212 0213 ITestSuite* suiteTwo = new FakeTestSuite(TestSuiteNameTwo, m_project); 0214 m_testController->addTestSuite(suiteTwo); 0215 0216 // Verify that only one signal gets emitted even with more suites present 0217 emitTestResult(suiteTwo, TestResult::Passed); 0218 0219 QCOMPARE(spy.size(), 1); 0220 0221 m_testController->removeTestSuite(suite); 0222 m_testController->removeTestSuite(suiteTwo); 0223 delete suite; 0224 delete suiteTwo; 0225 } 0226 0227 0228 QTEST_GUILESS_MAIN(TestTestController) 0229 0230 #include "moc_test_testcontroller.cpp"