| 286 | #endif |
| 287 | |
| 288 | static void testConnectionIssues() |
| 289 | { |
| 290 | QVERIFY(ProblemCollector::instance()->isCheckerRegistered("com.kdab.GammaRay.ObjectInspector.ConnectionsCheck")); |
| 291 | |
| 292 | auto task = std::unique_ptr<CrossThreadConnectionTask>(new CrossThreadConnectionTask()); |
| 293 | task->mainThreadObj.reset(new QObject()); |
| 294 | task->mainThreadObj->setObjectName("mainThreadObj"); |
| 295 | task->setAutoDelete(false); |
| 296 | // QThreadPool takes ownership and deletes 'hello' automatically |
| 297 | QThreadPool::globalInstance()->start(task.get()); |
| 298 | |
| 299 | auto o1 = std::unique_ptr<QObject>(new QObject()); |
| 300 | o1->setObjectName("o1"); |
| 301 | auto o2 = std::unique_ptr<QObject>(new QObject()); |
| 302 | o2->setObjectName("o2"); |
| 303 | // clang-format off |
| 304 | connect(o1.get(), SIGNAL(destroyed(QObject*)), o2.get(), SLOT(deleteLater())); |
| 305 | connect(o1.get(), SIGNAL(destroyed(QObject*)), o2.get(), SLOT(deleteLater())); |
| 306 | // clang-format on |
| 307 | |
| 308 | QTest::qWait(10); |
| 309 | ProblemCollector::instance()->requestScan(); |
| 310 | |
| 311 | o1->disconnect(); |
| 312 | task->newThreadObj->disconnect(); |
| 313 | |
| 314 | const auto &problems = ProblemCollector::instance()->problems(); |
| 315 | auto crossThreadProblem = std::find_if(problems.begin(), problems.end(), |
| 316 | [](const Problem &p) { return p.problemId.startsWith("com.kdab.GammaRay.ObjectInspector.ConnectionsCheck.CrossTread"); }); |
| 317 | |
| 318 | QVERIFY(crossThreadProblem != problems.end()); |
| 319 | QCOMPARE(crossThreadProblem->object, ObjectId(task->mainThreadObj.get())); |
| 320 | QVERIFY2(crossThreadProblem->description.contains("direct cross-thread connection"), qPrintable(crossThreadProblem->description)); |
| 321 | QVERIFY2(crossThreadProblem->description.contains("signal QObject (newThreadObj)"), qPrintable(crossThreadProblem->description)); |
| 322 | QVERIFY2(crossThreadProblem->description.contains("slot QObject (mainThreadObj)"), qPrintable(crossThreadProblem->description)); |
| 323 | |
| 324 | auto duplicateProblem = std::find_if(problems.begin(), problems.end(), |
| 325 | [](const Problem &p) { return p.problemId.startsWith("com.kdab.GammaRay.ObjectInspector.ConnectionsCheck.Duplicate"); }); |
| 326 | |
| 327 | QVERIFY(duplicateProblem != problems.end()); |
| 328 | QCOMPARE(duplicateProblem->object, ObjectId(o2.get())); |
| 329 | QVERIFY(duplicateProblem->description.contains("multiple times")); |
| 330 | QVERIFY2(duplicateProblem->description.contains("signal QObject (o1)"), qPrintable(duplicateProblem->description)); |
| 331 | QVERIFY2(duplicateProblem->description.contains("slot QObject (o2)"), qPrintable(duplicateProblem->description)); |
| 332 | |
| 333 | disconnect(o1.get(), nullptr, o2.get(), nullptr); |
| 334 | connect(o1.get(), &QObject::destroyed, o2.get(), &QObject::deleteLater); |
| 335 | connect(o1.get(), &QObject::destroyed, o2.get(), &QObject::deleteLater); |
| 336 | QTest::qWait(10); |
| 337 | ProblemCollector::instance()->requestScan(); |
| 338 | |
| 339 | const auto &problems2 = ProblemCollector::instance()->problems(); |
| 340 | auto duplicateProblem2 = std::find_if(problems2.begin(), problems2.end(), |
| 341 | [&o2](const Problem &p) { |
| 342 | return p.problemId.startsWith("com.kdab.GammaRay.ObjectInspector.ConnectionsCheck.Duplicate") |
| 343 | && p.object == ObjectId(o2.get()); |
| 344 | }); |
| 345 |
nothing calls this directly
no test coverage detected