File indexing completed on 2024-05-12 04:38:21
0001 /* 0002 SPDX-FileCopyrightText: 2015 Laszlo Kis-Adam <laszlo.kis-adam@kdemail.net> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include <QTest> 0008 0009 #include <shell/problemmodel.h> 0010 #include <shell/problem.h> 0011 #include <shell/problemconstants.h> 0012 #include <language/editor/documentrange.h> 0013 0014 #include <tests/testcore.h> 0015 #include <tests/autotestshell.h> 0016 0017 #include <KLocalizedString> 0018 0019 #define MYCOMPARE(actual, expected) \ 0020 if (!QTest::qCompare(actual, expected, #actual, #expected, __FILE__, __LINE__)) \ 0021 return false 0022 0023 #define MYVERIFY(statement) \ 0024 if (!QTest::qVerify((statement), #statement, "", __FILE__, __LINE__))\ 0025 return false 0026 0027 using namespace KDevelop; 0028 0029 class TestProblemModel : public QObject 0030 { 0031 Q_OBJECT 0032 private Q_SLOTS: 0033 void initTestCase(); 0034 void cleanupTestCase(); 0035 0036 void testNoGrouping(); 0037 void testPathGrouping(); 0038 void testSeverityGrouping(); 0039 void testPlaceholderText(); 0040 0041 private: 0042 QString prependPathRoot(QString const& currentPath) const; 0043 void generateProblems(); 0044 bool checkIsSame(int row, const QModelIndex &parent, const IProblem::Ptr &problem); 0045 bool checkDiagnostics(int row, const QModelIndex &parent); 0046 bool checkDisplay(int row, const QModelIndex &parent, const IProblem::Ptr &problem); 0047 bool checkLabel(int row, const QModelIndex &parent, const QString &label); 0048 bool checkPathGroup(int row, const IProblem::Ptr &problem); 0049 bool checkSeverityGroup(int row, const IProblem::Ptr &problem); 0050 0051 QScopedPointer<ProblemModel> m_model; 0052 QVector<IProblem::Ptr> m_problems; 0053 IProblem::Ptr m_diagnosticTestProblem; 0054 }; 0055 0056 void TestProblemModel::initTestCase() 0057 { 0058 AutoTestShell::init(); 0059 TestCore::initialize(Core::NoUi); 0060 0061 m_model.reset(new ProblemModel(nullptr)); 0062 m_model->setScope(BypassScopeFilter); 0063 0064 generateProblems(); 0065 } 0066 0067 void TestProblemModel::cleanupTestCase() 0068 { 0069 TestCore::shutdown(); 0070 } 0071 0072 void TestProblemModel::testNoGrouping() 0073 { 0074 m_model->setGrouping(NoGrouping); 0075 m_model->setSeverity(IProblem::Hint); 0076 0077 QCOMPARE(m_model->rowCount(), 0); 0078 0079 // Check if setting the problems works 0080 m_model->setProblems(m_problems); 0081 QCOMPARE(m_model->rowCount(), 3); 0082 0083 for (int i = 0; i < m_model->rowCount(); i++) { 0084 QVERIFY(checkIsSame(i, QModelIndex(), m_problems[i])); 0085 } 0086 0087 // Check if displaying various data parts works 0088 QVERIFY(checkDisplay(0, QModelIndex(), m_problems[0])); 0089 0090 // Check if clearing the problems works 0091 m_model->clearProblems(); 0092 QCOMPARE(m_model->rowCount(), 0); 0093 0094 // Check if adding the problems works 0095 int c = 0; 0096 for (const IProblem::Ptr& p : qAsConst(m_problems)) { 0097 m_model->addProblem(p); 0098 c++; 0099 0100 QCOMPARE(m_model->rowCount(), c); 0101 } 0102 0103 for (int i = 0; i < m_model->rowCount(); i++) { 0104 QVERIFY(checkIsSame(i, QModelIndex(), m_problems[i])); 0105 } 0106 0107 0108 // Check if filtering works 0109 // old-style setSeverity 0110 // Error filter 0111 m_model->setSeverity(IProblem::Error); 0112 QCOMPARE(m_model->rowCount(), 1); 0113 QVERIFY(checkIsSame(0, QModelIndex(), m_problems[0])); 0114 0115 // Warning filter 0116 m_model->setSeverity(IProblem::Warning); 0117 QCOMPARE(m_model->rowCount(), 2); 0118 QVERIFY(checkIsSame(0, QModelIndex(), m_problems[0])); 0119 QVERIFY(checkIsSame(1, QModelIndex(), m_problems[1])); 0120 0121 // Hint filter 0122 m_model->setSeverity(IProblem::Hint); 0123 QCOMPARE(m_model->rowCount(), 3); 0124 QVERIFY(checkIsSame(0, QModelIndex(), m_problems[0])); 0125 QVERIFY(checkIsSame(1, QModelIndex(), m_problems[1])); 0126 QVERIFY(checkIsSame(2, QModelIndex(), m_problems[2])); 0127 0128 // Check if filtering works 0129 // new style 0130 // Error filter 0131 m_model->setSeverities(IProblem::Error); 0132 QCOMPARE(m_model->rowCount(), 1); 0133 QVERIFY(checkIsSame(0, QModelIndex(), m_problems[0])); 0134 0135 // Warning filter 0136 m_model->setSeverities(IProblem::Warning); 0137 QCOMPARE(m_model->rowCount(), 1); 0138 QVERIFY(checkIsSame(0, QModelIndex(), m_problems[1])); 0139 0140 // Hint filter 0141 m_model->setSeverities(IProblem::Hint); 0142 QCOMPARE(m_model->rowCount(), 1); 0143 QVERIFY(checkIsSame(0, QModelIndex(), m_problems[2])); 0144 0145 // Error + Hint filter 0146 m_model->setSeverities(IProblem::Error | IProblem::Hint); 0147 QCOMPARE(m_model->rowCount(), 2); 0148 QVERIFY(checkIsSame(0, QModelIndex(), m_problems[0])); 0149 QVERIFY(checkIsSame(1, QModelIndex(), m_problems[2])); 0150 0151 m_model->setSeverities(IProblem::Error | IProblem::Warning | IProblem::Hint); 0152 0153 // Check if diagnostics are added properly 0154 m_model->clearProblems(); 0155 m_model->addProblem(m_diagnosticTestProblem); 0156 QVERIFY(checkDiagnostics(0, QModelIndex())); 0157 0158 m_model->clearProblems(); 0159 } 0160 0161 void TestProblemModel::testPathGrouping() 0162 { 0163 m_model->setGrouping(PathGrouping); 0164 m_model->setSeverity(IProblem::Hint); 0165 QCOMPARE(m_model->rowCount(), 0); 0166 0167 // Check if setting problems works 0168 m_model->setProblems(m_problems); 0169 QCOMPARE(m_model->rowCount(), 3); 0170 0171 for (int i = 0; i < m_model->rowCount(); i++) { 0172 QVERIFY(checkLabel(i, QModelIndex(), m_problems[i]->finalLocation().document.str())); 0173 0174 QModelIndex idx = m_model->index(i, 0); 0175 QVERIFY(idx.isValid()); 0176 QVERIFY(checkIsSame(0, idx, m_problems[i])); 0177 } 0178 0179 // Check if displaying various data parts works 0180 { 0181 QModelIndex idx = m_model->index(0, 0); 0182 QVERIFY(idx.isValid()); 0183 QVERIFY(checkDisplay(0, idx, m_problems[0])); 0184 } 0185 0186 // Check if clearing works 0187 m_model->clearProblems(); 0188 QCOMPARE(m_model->rowCount(), 0); 0189 0190 // Check if add problems works 0191 int c = 0; 0192 for (const IProblem::Ptr& p : qAsConst(m_problems)) { 0193 m_model->addProblem(p); 0194 c++; 0195 0196 QCOMPARE(m_model->rowCount(), c); 0197 } 0198 0199 for (int i = 0; i < m_model->rowCount(); i++) { 0200 QVERIFY(checkLabel(i, QModelIndex(), m_problems[i]->finalLocation().document.str())); 0201 0202 QModelIndex idx = m_model->index(i, 0); 0203 QVERIFY(idx.isValid()); 0204 QVERIFY(checkIsSame(0, idx, m_problems[i])); 0205 } 0206 0207 // Check if filtering works 0208 // old-style setSeverity 0209 // Error filtering 0210 m_model->setSeverity(IProblem::Error); 0211 QCOMPARE(m_model->rowCount(), 1); 0212 QVERIFY(checkPathGroup(0, m_problems[0])); 0213 0214 // Warning filtering 0215 m_model->setSeverity(IProblem::Warning); 0216 QCOMPARE(m_model->rowCount(), 2); 0217 QVERIFY(checkPathGroup(0, m_problems[0])); 0218 QVERIFY(checkPathGroup(1, m_problems[1])); 0219 0220 // Hint filtering 0221 m_model->setSeverity(IProblem::Hint); 0222 QCOMPARE(m_model->rowCount(), 3); 0223 QVERIFY(checkPathGroup(0, m_problems[0])); 0224 QVERIFY(checkPathGroup(1, m_problems[1])); 0225 QVERIFY(checkPathGroup(2, m_problems[2])); 0226 0227 // Check if filtering works 0228 // new style 0229 // Error filtering 0230 m_model->setSeverities(IProblem::Error); 0231 QCOMPARE(m_model->rowCount(), 1); 0232 QVERIFY(checkPathGroup(0, m_problems[0])); 0233 0234 // Warning filtering 0235 m_model->setSeverities(IProblem::Warning); 0236 QCOMPARE(m_model->rowCount(), 1); 0237 QVERIFY(checkPathGroup(0, m_problems[1])); 0238 0239 // Hint filtering 0240 m_model->setSeverities(IProblem::Hint); 0241 QCOMPARE(m_model->rowCount(), 1); 0242 QVERIFY(checkPathGroup(0, m_problems[2])); 0243 0244 // Error + Hint filtering 0245 m_model->setSeverities(IProblem::Error | IProblem::Hint); 0246 QCOMPARE(m_model->rowCount(), 2); 0247 QVERIFY(checkPathGroup(0, m_problems[0])); 0248 QVERIFY(checkPathGroup(1, m_problems[2])); 0249 0250 m_model->setSeverities(IProblem::Error | IProblem::Warning | IProblem::Hint); 0251 0252 // Check if diagnostics get to the right place 0253 m_model->clearProblems(); 0254 m_model->addProblem(m_diagnosticTestProblem); 0255 { 0256 QModelIndex parent = m_model->index(0, 0); 0257 QVERIFY(parent.isValid()); 0258 checkDiagnostics(0, parent); 0259 } 0260 0261 m_model->clearProblems(); 0262 } 0263 0264 void TestProblemModel::testSeverityGrouping() 0265 { 0266 m_model->setGrouping(SeverityGrouping); 0267 m_model->setSeverity(IProblem::Hint); 0268 QCOMPARE(m_model->rowCount(), 3); 0269 0270 // Check if setting problems works 0271 m_model->setProblems(m_problems); 0272 QCOMPARE(m_model->rowCount(), 3); 0273 for (int i = 0; i < m_model->rowCount(); i++) { 0274 QVERIFY(checkSeverityGroup(i, m_problems[i])); 0275 } 0276 0277 // Check if displaying works 0278 for (int i = 0; i < m_model->rowCount(); i++) { 0279 QModelIndex parent = m_model->index(i, 0); 0280 QVERIFY(parent.isValid()); 0281 0282 QVERIFY(checkDisplay(0, parent, m_problems[i])); 0283 } 0284 0285 // Check if clearing works 0286 m_model->clearProblems(); 0287 QCOMPARE(m_model->rowCount(), 3); 0288 0289 // Check if adding problems works 0290 int c = 0; 0291 for (const IProblem::Ptr& p : qAsConst(m_problems)) { 0292 m_model->addProblem(p); 0293 QVERIFY(checkSeverityGroup(c, m_problems[c])); 0294 c++; 0295 } 0296 0297 // Check if filtering works 0298 // old-style setSeverity 0299 // Error filtering 0300 m_model->setSeverity(IProblem::Error); 0301 QCOMPARE(m_model->rowCount(), 3); 0302 checkSeverityGroup(0, m_problems[0]); 0303 0304 // Warning filtering 0305 m_model->setSeverity(IProblem::Warning); 0306 QCOMPARE(m_model->rowCount(), 3); 0307 checkSeverityGroup(0, m_problems[0]); 0308 checkSeverityGroup(1, m_problems[1]); 0309 0310 // Hint filtering 0311 m_model->setSeverity(IProblem::Hint); 0312 QCOMPARE(m_model->rowCount(), 3); 0313 checkSeverityGroup(0, m_problems[0]); 0314 checkSeverityGroup(1, m_problems[1]); 0315 checkSeverityGroup(2, m_problems[2]); 0316 0317 // Check if filtering works 0318 // Error filtering 0319 m_model->setSeverities(IProblem::Error); 0320 QCOMPARE(m_model->rowCount(), 3); 0321 checkSeverityGroup(0, m_problems[0]); 0322 0323 // Warning filtering 0324 m_model->setSeverities(IProblem::Warning); 0325 QCOMPARE(m_model->rowCount(), 3); 0326 checkSeverityGroup(1, m_problems[1]); 0327 0328 // Hint filtering 0329 m_model->setSeverities(IProblem::Hint); 0330 QCOMPARE(m_model->rowCount(), 3); 0331 checkSeverityGroup(2, m_problems[2]); 0332 0333 // Error + Hint filtering 0334 m_model->setSeverities(IProblem::Error | IProblem::Hint); 0335 QCOMPARE(m_model->rowCount(), 3); 0336 checkSeverityGroup(0, m_problems[0]); 0337 checkSeverityGroup(2, m_problems[2]); 0338 0339 m_model->setSeverities(IProblem::Error | IProblem::Warning | IProblem::Hint); 0340 0341 // Check if diagnostics get to the right place 0342 m_model->clearProblems(); 0343 m_model->addProblem(m_diagnosticTestProblem); 0344 { 0345 QModelIndex parent = m_model->index(0, 0); 0346 QVERIFY(parent.isValid()); 0347 0348 checkDiagnostics(0, parent); 0349 } 0350 0351 m_model->clearProblems(); 0352 } 0353 0354 void TestProblemModel::testPlaceholderText() 0355 { 0356 const QString text1 = QStringLiteral("testPlaceholderText1"); 0357 const QString text2 = QStringLiteral("testPlaceholderText2"); 0358 const QString empty; 0359 0360 m_model->setGrouping(NoGrouping); 0361 0362 // Test model with empty placeholder text 0363 0364 QCOMPARE(m_model->rowCount(), 0); 0365 m_model->setPlaceholderText(empty); 0366 QCOMPARE(m_model->rowCount(), 0); 0367 m_model->setProblems(m_problems); 0368 QCOMPARE(m_model->rowCount(), 3); 0369 m_model->clearProblems(); 0370 QCOMPARE(m_model->rowCount(), 0); 0371 0372 // Test empty model with non-empty placeholder text 0373 0374 m_model->setPlaceholderText(text1); 0375 QCOMPARE(m_model->rowCount(), 1); 0376 QVERIFY(checkLabel(0, QModelIndex(), text1)); 0377 0378 m_model->setPlaceholderText(text2); 0379 QCOMPARE(m_model->rowCount(), 1); 0380 QVERIFY(checkLabel(0, QModelIndex(), text2)); 0381 0382 // Test non-empty model with non-empty placeholder text 0383 0384 m_model->setProblems(m_problems); 0385 QCOMPARE(m_model->rowCount(), 3); 0386 0387 m_model->clearProblems(); 0388 QCOMPARE(m_model->rowCount(), 1); 0389 QVERIFY(checkLabel(0, QModelIndex(), text2)); 0390 0391 m_model->addProblem(m_problems[0]); 0392 QCOMPARE(m_model->rowCount(), 1); 0393 QVERIFY(checkIsSame(0, QModelIndex(), m_problems[0])); 0394 0395 m_model->addProblem(m_problems[1]); 0396 QCOMPARE(m_model->rowCount(), 2); 0397 QVERIFY(checkIsSame(1, QModelIndex(), m_problems[1])); 0398 0399 m_model->setPlaceholderText(text1); 0400 QCOMPARE(m_model->rowCount(), 2); 0401 QVERIFY(checkIsSame(0, QModelIndex(), m_problems[0])); 0402 QVERIFY(checkIsSame(1, QModelIndex(), m_problems[1])); 0403 0404 m_model->setProblems({}); 0405 QCOMPARE(m_model->rowCount(), 1); 0406 QVERIFY(checkLabel(0, QModelIndex(), text1)); 0407 } 0408 0409 // Needed because util/Path.cpp asserts e.g. C: on Windows 0410 QString TestProblemModel::prependPathRoot(QString const& currentPath) const 0411 { 0412 #ifdef Q_OS_WIN 0413 QString pathRoot = QStringLiteral("x:/"); 0414 #else 0415 QString pathRoot = QStringLiteral("/"); 0416 #endif 0417 return pathRoot + currentPath; 0418 } 0419 0420 // Generate 3 problems, all with different paths, different severity 0421 // Also generates a problem with diagnostics 0422 void TestProblemModel::generateProblems() 0423 { 0424 IProblem::Ptr p1(new DetectedProblem()); 0425 IProblem::Ptr p2(new DetectedProblem()); 0426 IProblem::Ptr p3(new DetectedProblem()); 0427 0428 DocumentRange r1; 0429 r1.document = IndexedString( prependPathRoot("just/a/random/path") ); 0430 0431 p1->setDescription(QStringLiteral("PROBLEM1")); 0432 p1->setSeverity(IProblem::Error); 0433 p1->setFinalLocation(r1); 0434 0435 DocumentRange r2; 0436 r2.document = IndexedString( prependPathRoot("just/another/path") ); 0437 0438 p2->setDescription(QStringLiteral("PROBLEM2")); 0439 p2->setSeverity(IProblem::Warning); 0440 p2->setFinalLocation(r2); 0441 0442 DocumentRange r3; 0443 r3.document = IndexedString( prependPathRoot("yet/another/test/path") ); 0444 0445 p2->setDescription(QStringLiteral("PROBLEM3")); 0446 p3->setSeverity(IProblem::Hint); 0447 p3->setFinalLocation(r3); 0448 0449 m_problems.push_back(p1); 0450 m_problems.push_back(p2); 0451 m_problems.push_back(p3); 0452 0453 // Problem for diagnostic testing 0454 IProblem::Ptr p(new DetectedProblem()); 0455 DocumentRange r; 0456 r.document = IndexedString("DIAGTEST"); 0457 p->setFinalLocation(r); 0458 p->setDescription(QStringLiteral("PROBLEM")); 0459 p->setSeverity(IProblem::Error); 0460 0461 IProblem::Ptr d(new DetectedProblem()); 0462 d->setDescription(QStringLiteral("DIAG")); 0463 0464 IProblem::Ptr dd(new DetectedProblem()); 0465 dd->setDescription(QStringLiteral("DIAGDIAG")); 0466 d->addDiagnostic(dd); 0467 p->addDiagnostic(d); 0468 m_diagnosticTestProblem = p; 0469 } 0470 0471 bool TestProblemModel::checkIsSame(int row, const QModelIndex &parent, const IProblem::Ptr &problem) 0472 { 0473 QModelIndex idx; 0474 0475 idx = m_model->index(row, 0, parent); 0476 MYVERIFY(idx.isValid()); 0477 MYCOMPARE(m_model->data(idx).toString(), problem->description()); 0478 0479 return true; 0480 } 0481 0482 bool TestProblemModel::checkDiagnostics(int row, const QModelIndex &parent) 0483 { 0484 MYCOMPARE(m_model->rowCount(parent), 1); 0485 0486 QModelIndex idx; 0487 idx = m_model->index(row, 0, parent); 0488 MYVERIFY(idx.isValid()); 0489 MYCOMPARE(m_model->data(idx).toString(), m_diagnosticTestProblem->description()); 0490 0491 QModelIndex diagidx; 0492 IProblem::Ptr diag = m_diagnosticTestProblem->diagnostics().at(0); 0493 diagidx = m_model->index(0, 0, idx); 0494 MYVERIFY(diagidx.isValid()); 0495 MYCOMPARE(m_model->data(diagidx).toString(), diag->description()); 0496 0497 QModelIndex diagdiagidx; 0498 IProblem::Ptr diagdiag = diag->diagnostics().at(0); 0499 diagdiagidx = m_model->index(0, 0, diagidx); 0500 MYVERIFY(diagdiagidx.isValid()); 0501 MYCOMPARE(m_model->data(diagdiagidx).toString(), diagdiag->description()); 0502 0503 return true; 0504 } 0505 0506 bool TestProblemModel::checkDisplay(int row, const QModelIndex &parent, const IProblem::Ptr &problem) 0507 { 0508 QModelIndex idx; 0509 0510 idx = m_model->index(row, 0, parent); 0511 MYVERIFY(idx.isValid()); 0512 MYCOMPARE(m_model->data(idx).toString(), problem->description()); 0513 0514 idx = m_model->index(row, 1, parent); 0515 MYVERIFY(idx.isValid()); 0516 MYCOMPARE(m_model->data(idx).toString(), problem->sourceString()); 0517 0518 idx = m_model->index(row, 2, parent); 0519 MYVERIFY(idx.isValid()); 0520 MYCOMPARE(m_model->data(idx).toString(), problem->finalLocation().document.str()); 0521 0522 idx = m_model->index(row, 3, parent); 0523 MYVERIFY(idx.isValid()); 0524 MYCOMPARE(m_model->data(idx).toString(), QString::number(problem->finalLocation().start().line() + 1)); 0525 0526 idx = m_model->index(row, 4, parent); 0527 MYVERIFY(idx.isValid()); 0528 MYCOMPARE(m_model->data(idx).toString(), QString::number(problem->finalLocation().start().column() + 1)); 0529 0530 return true; 0531 } 0532 0533 bool TestProblemModel::checkLabel(int row, const QModelIndex &parent, const QString &label) 0534 { 0535 QModelIndex idx = m_model->index(row, 0, parent); 0536 MYVERIFY(idx.isValid()); 0537 MYCOMPARE(m_model->data(idx).toString(), label); 0538 0539 return true; 0540 } 0541 0542 bool TestProblemModel::checkPathGroup(int row, const IProblem::Ptr &problem) 0543 { 0544 QModelIndex parent = m_model->index(row, 0); 0545 MYVERIFY(parent.isValid()); 0546 MYCOMPARE(m_model->data(parent).toString(), problem->finalLocation().document.str()); 0547 0548 QModelIndex idx = m_model->index(0, 0, parent); 0549 MYVERIFY(idx.isValid()); 0550 MYCOMPARE(m_model->data(idx).toString(), problem->description()); 0551 0552 return true; 0553 } 0554 0555 bool TestProblemModel::checkSeverityGroup(int row, const IProblem::Ptr &problem) 0556 { 0557 QModelIndex parent = m_model->index(row, 0); 0558 MYVERIFY(parent.isValid()); 0559 MYCOMPARE(m_model->data(parent).toString(), problem->severityString()); 0560 0561 QModelIndex idx = m_model->index(0, 0, parent); 0562 MYVERIFY(idx.isValid()); 0563 MYCOMPARE(m_model->data(idx).toString(), problem->description()); 0564 0565 return true; 0566 } 0567 0568 QTEST_MAIN(TestProblemModel) 0569 0570 #include "test_problemmodel.moc"