File indexing completed on 2025-04-27 10:10:39
0001 /* 0002 SPDX-FileCopyrightText: 2009 Stephen Kelly <steveire@gmail.com> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #ifndef PROXY_MODEL_TEST_H 0008 #define PROXY_MODEL_TEST_H 0009 0010 #include <QAbstractProxyModel> 0011 #include <QTest> 0012 0013 #include "dynamictreemodel.h" 0014 #include "indexfinder.h" 0015 #include "modelcommander.h" 0016 #include "modelspy.h" 0017 #include "persistentchangelist.h" 0018 0019 #include "proxymodeltestsuite_export.h" 0020 0021 typedef QList<QVariantList> SignalList; 0022 0023 Q_DECLARE_METATYPE(SignalList) 0024 0025 enum Persistence { 0026 LazyPersistence, 0027 ImmediatePersistence, 0028 }; 0029 0030 enum SourceModel { 0031 DynamicTree, 0032 IntermediateProxy, 0033 }; 0034 0035 class PROXYMODELTESTSUITE_EXPORT BuiltinTestDataInterface 0036 { 0037 public: 0038 virtual ~BuiltinTestDataInterface() 0039 { 0040 } 0041 0042 private: 0043 virtual void testInsertWhenEmptyData() = 0; 0044 virtual void testInsertInRootData() = 0; 0045 virtual void testInsertInTopLevelData() = 0; 0046 virtual void testInsertInSecondLevelData() = 0; 0047 0048 virtual void testRemoveFromRootData() = 0; 0049 virtual void testRemoveFromTopLevelData() = 0; 0050 virtual void testRemoveFromSecondLevelData() = 0; 0051 0052 virtual void testMoveFromRootData() = 0; 0053 virtual void testMoveFromTopLevelData() = 0; 0054 virtual void testMoveFromSecondLevelData() = 0; 0055 0056 virtual void testModifyInRootData() = 0; 0057 virtual void testModifyInTopLevelData() = 0; 0058 virtual void testModifyInSecondLevelData() = 0; 0059 }; 0060 0061 class PROXYMODELTESTSUITE_EXPORT BuiltinTestInterface : BuiltinTestDataInterface 0062 { 0063 public: 0064 ~BuiltinTestInterface() override 0065 { 0066 } 0067 0068 private: 0069 virtual void testInsertWhenEmpty_data() = 0; 0070 virtual void testInsertWhenEmpty() = 0; 0071 0072 virtual void testInsertInRoot_data() = 0; 0073 virtual void testInsertInRoot() = 0; 0074 0075 virtual void testInsertInTopLevel_data() = 0; 0076 virtual void testInsertInTopLevel() = 0; 0077 0078 virtual void testInsertInSecondLevel_data() = 0; 0079 virtual void testInsertInSecondLevel() = 0; 0080 0081 virtual void testRemoveFromRoot_data() = 0; 0082 virtual void testRemoveFromRoot() = 0; 0083 0084 virtual void testRemoveFromTopLevel_data() = 0; 0085 virtual void testRemoveFromTopLevel() = 0; 0086 0087 virtual void testRemoveFromSecondLevel_data() = 0; 0088 virtual void testRemoveFromSecondLevel() = 0; 0089 0090 virtual void testMoveFromRoot_data() = 0; 0091 virtual void testMoveFromRoot() = 0; 0092 0093 virtual void testMoveFromTopLevel_data() = 0; 0094 virtual void testMoveFromTopLevel() = 0; 0095 0096 virtual void testMoveFromSecondLevel_data() = 0; 0097 virtual void testMoveFromSecondLevel() = 0; 0098 0099 virtual void testModifyInRoot_data() = 0; 0100 virtual void testModifyInRoot() = 0; 0101 0102 virtual void testModifyInTopLevel_data() = 0; 0103 virtual void testModifyInTopLevel() = 0; 0104 0105 virtual void testModifyInSecondLevel_data() = 0; 0106 virtual void testModifyInSecondLevel() = 0; 0107 }; 0108 0109 class PROXYMODELTESTSUITE_EXPORT ProxyModelTest : public QObject, protected BuiltinTestInterface 0110 { 0111 Q_OBJECT 0112 public: 0113 ProxyModelTest(QObject *parent = nullptr); 0114 ~ProxyModelTest() override 0115 { 0116 } 0117 0118 void setLazyPersistence(Persistence persistence); 0119 void setUseIntermediateProxy(SourceModel sourceModel); 0120 0121 DynamicTreeModel *rootModel() const 0122 { 0123 return m_rootModel; 0124 } 0125 QAbstractItemModel *sourceModel() const 0126 { 0127 return m_sourceModel; 0128 } 0129 QAbstractProxyModel *proxyModel() const 0130 { 0131 return m_proxyModel; 0132 } 0133 ModelSpy *modelSpy() const 0134 { 0135 return m_modelSpy; 0136 } 0137 0138 PersistentIndexChange getChange(IndexFinder sourceFinder, int start, int end, int difference, bool toInvalid = false); 0139 QVariantList noSignal() const 0140 { 0141 return QVariantList() << NoSignal; 0142 } 0143 QVariantList getSignal(SignalType type, IndexFinder parentFinder, int start, int end) const 0144 { 0145 return QVariantList() << type << QVariant::fromValue(parentFinder) << start << end; 0146 } 0147 QVariantList getSignal(SignalType type, IndexFinder srcFinder, int start, int end, IndexFinder destFinder, int destStart) const 0148 { 0149 return QVariantList() << type << QVariant::fromValue(srcFinder) << start << end << QVariant::fromValue(destFinder) << destStart; 0150 } 0151 QVariantList getSignal(SignalType type, IndexFinder topLeftFinder, IndexFinder bottomRightFinder) const 0152 { 0153 return QVariantList() << type << QVariant::fromValue(topLeftFinder) << QVariant::fromValue(bottomRightFinder); 0154 } 0155 0156 protected: 0157 virtual QAbstractProxyModel *getProxy() = 0; 0158 0159 void doCleanupTestCase() 0160 { 0161 cleanupTestCase(); 0162 } 0163 void doCleanup() 0164 { 0165 cleanup(); 0166 } 0167 0168 Q_SIGNALS: 0169 void testInsertWhenEmptyData() override; 0170 void testInsertInRootData() override; 0171 void testInsertInTopLevelData() override; 0172 void testInsertInSecondLevelData() override; 0173 0174 void testRemoveFromRootData() override; 0175 void testRemoveFromTopLevelData() override; 0176 void testRemoveFromSecondLevelData() override; 0177 0178 void testMoveFromRootData() override; 0179 void testMoveFromTopLevelData() override; 0180 void testMoveFromSecondLevelData() override; 0181 0182 void testModifyInRootData() override; 0183 void testModifyInTopLevelData() override; 0184 void testModifyInSecondLevelData() override; 0185 0186 protected Q_SLOTS: 0187 void testMappings(); 0188 void verifyModel(const QModelIndex &parent, int start, int end); 0189 void verifyModel(const QModelIndex &parent, int start, int end, const QModelIndex &destParent, int dest); 0190 void verifyModel(const QModelIndex &topLeft, const QModelIndex &bottomRight); 0191 0192 private Q_SLOTS: 0193 void init(); 0194 void cleanup(); 0195 void cleanupTestCase(); 0196 0197 void testEmptyModel(); 0198 void testSourceReset(); 0199 void testDestroyModel(); 0200 0201 void testInsertWhenEmpty_data() override 0202 { 0203 testInsertWhenEmptyData(); 0204 } 0205 void testInsertWhenEmpty() override 0206 { 0207 doTest(); 0208 } 0209 0210 void testInsertInRoot_data() override 0211 { 0212 testInsertInRootData(); 0213 } 0214 void testInsertInRoot() override 0215 { 0216 doTest(); 0217 } 0218 0219 void testInsertInTopLevel_data() override 0220 { 0221 testInsertInTopLevelData(); 0222 } 0223 void testInsertInTopLevel() override 0224 { 0225 doTest(); 0226 } 0227 0228 void testInsertInSecondLevel_data() override 0229 { 0230 testInsertInSecondLevelData(); 0231 } 0232 void testInsertInSecondLevel() override 0233 { 0234 doTest(); 0235 } 0236 0237 void testRemoveFromRoot_data() override 0238 { 0239 testRemoveFromRootData(); 0240 } 0241 void testRemoveFromRoot() override 0242 { 0243 doTest(); 0244 } 0245 0246 void testRemoveFromTopLevel_data() override 0247 { 0248 testRemoveFromTopLevelData(); 0249 } 0250 void testRemoveFromTopLevel() override 0251 { 0252 doTest(); 0253 } 0254 0255 void testRemoveFromSecondLevel_data() override 0256 { 0257 testRemoveFromSecondLevelData(); 0258 } 0259 void testRemoveFromSecondLevel() override 0260 { 0261 doTest(); 0262 } 0263 0264 void testMoveFromRoot_data() override 0265 { 0266 testMoveFromRootData(); 0267 } 0268 void testMoveFromRoot() override 0269 { 0270 doTest(); 0271 } 0272 0273 void testMoveFromTopLevel_data() override 0274 { 0275 testMoveFromTopLevelData(); 0276 } 0277 void testMoveFromTopLevel() override 0278 { 0279 doTest(); 0280 } 0281 0282 void testMoveFromSecondLevel_data() override 0283 { 0284 testMoveFromSecondLevelData(); 0285 } 0286 void testMoveFromSecondLevel() override 0287 { 0288 doTest(); 0289 } 0290 0291 void testModifyInRoot_data() override 0292 { 0293 testModifyInRootData(); 0294 } 0295 void testModifyInRoot() override 0296 { 0297 doTest(); 0298 } 0299 0300 void testModifyInTopLevel_data() override 0301 { 0302 testModifyInTopLevelData(); 0303 } 0304 void testModifyInTopLevel() override 0305 { 0306 doTest(); 0307 } 0308 0309 void testModifyInSecondLevel_data() override 0310 { 0311 testModifyInSecondLevelData(); 0312 } 0313 void testModifyInSecondLevel() override 0314 { 0315 doTest(); 0316 } 0317 0318 protected: 0319 void connectTestSignals(QObject *receiver); 0320 void disconnectTestSignals(QObject *receiver); 0321 0322 void connectProxy(QAbstractProxyModel *proxyModel); 0323 void doTestMappings(const QModelIndex &parent); 0324 void initRootModel(DynamicTreeModel *rootModel, const QString ¤tTest, const QString ¤tTag); 0325 0326 void doTest(); 0327 void handleSignal(QVariantList expected); 0328 QVariantList getResultSignal(); 0329 int getChange(bool sameParent, int start, int end, int currentPosition, int destinationStart); 0330 QStringList dataTags() const 0331 { 0332 return m_dataTags; 0333 } 0334 void verifyExecutedTests(); 0335 0336 private: 0337 DynamicTreeModel *m_rootModel; 0338 QAbstractItemModel *m_sourceModel; 0339 QAbstractProxyModel *m_proxyModel; 0340 QAbstractProxyModel *m_intermediateProxyModel; 0341 ModelSpy *m_modelSpy; 0342 ModelCommander *m_modelCommander; 0343 QStringList m_dataTags; 0344 QStringList m_modelCommanderTags; 0345 QString m_currentTest; 0346 }; 0347 0348 class PROXYMODELTESTSUITE_EXPORT ProxyModelTestData : public QObject, BuiltinTestDataInterface 0349 { 0350 Q_OBJECT 0351 public: 0352 ProxyModelTestData(ProxyModelTest *parent = nullptr) 0353 : QObject(parent) 0354 , m_proxyModelTest(parent) 0355 { 0356 } 0357 0358 static const char *failTag() 0359 { 0360 return "fail01"; 0361 } 0362 0363 protected: 0364 void dummyTestData() 0365 { 0366 QTest::addColumn<SignalList>("signalList"); 0367 QTest::addColumn<PersistentChangeList>("changeList"); 0368 0369 QTest::newRow(failTag()) << SignalList() << PersistentChangeList(); 0370 QSKIP("Test not implemented"); 0371 } 0372 0373 void skipTestData(const QString &name) 0374 { 0375 processTestName(name); 0376 0377 QTest::addColumn<SignalList>("signalList"); 0378 QTest::addColumn<PersistentChangeList>("changeList"); 0379 0380 QTest::newRow(name.toLatin1()) << (SignalList() << (QVariantList() << "skip")) << PersistentChangeList(); 0381 } 0382 0383 void processTestName(const QString &name) 0384 { 0385 if (m_currentTestFunction != QTest::currentTestFunction()) { 0386 m_testNames.clear(); 0387 m_currentTestFunction = QTest::currentTestFunction(); 0388 } 0389 m_testNames.insert(name); 0390 } 0391 0392 QStringList namedTests() 0393 { 0394 return m_testNames.values(); 0395 } 0396 0397 void noopTest(const QString &name) 0398 { 0399 processTestName(name); 0400 0401 QTest::newRow(name.toLatin1()) << SignalList() << PersistentChangeList(); 0402 } 0403 0404 void noopLayoutChangeTest(const QString &name) 0405 { 0406 processTestName(name); 0407 0408 SignalList signalList; 0409 0410 signalList << (QVariantList() << LayoutAboutToBeChanged); 0411 signalList << (QVariantList() << LayoutChanged); 0412 0413 QTest::newRow(name.toLatin1()) << signalList << PersistentChangeList(); 0414 } 0415 0416 void testForwardingInsertData(const IndexFinder &indexFinder) 0417 { 0418 QTest::addColumn<SignalList>("signalList"); 0419 QTest::addColumn<PersistentChangeList>("changeList"); 0420 0421 newInsertTest(QStringLiteral("insert01"), indexFinder, 0, 0, 10); 0422 newInsertTest(QStringLiteral("insert02"), indexFinder, 0, 9, 10); 0423 newInsertTest(QStringLiteral("insert03"), indexFinder, 10, 10, 10); 0424 newInsertTest(QStringLiteral("insert04"), indexFinder, 10, 19, 10); 0425 newInsertTest(QStringLiteral("insert05"), indexFinder, 4, 4, 10); 0426 newInsertTest(QStringLiteral("insert06"), indexFinder, 4, 13, 10); 0427 newInsertTest(QStringLiteral("insert07"), indexFinder, 0, 0, 10); 0428 newInsertTest(QStringLiteral("insert08"), indexFinder, 10, 10, 10); 0429 newInsertTest(QStringLiteral("insert09"), indexFinder, 4, 4, 10); 0430 newInsertTest(QStringLiteral("insert10"), indexFinder, 0, 4, 10); 0431 newInsertTest(QStringLiteral("insert11"), indexFinder, 10, 14, 10); 0432 newInsertTest(QStringLiteral("insert12"), indexFinder, 4, 8, 10); 0433 QList<int> rows = indexFinder.rows(); 0434 rows.append(0); 0435 newInsertTest(QStringLiteral("insert13"), rows, 0, 0, 0); 0436 newInsertTest(QStringLiteral("insert14"), rows, 0, 9, 0); 0437 newInsertTest(QStringLiteral("insert15"), rows, 0, 4, 0); 0438 rows = indexFinder.rows(); 0439 rows.append(9); 0440 newInsertTest(QStringLiteral("insert16"), rows, 0, 0, 0); 0441 newInsertTest(QStringLiteral("insert17"), rows, 0, 9, 0); 0442 newInsertTest(QStringLiteral("insert18"), rows, 0, 4, 0); 0443 } 0444 0445 void testForwardingRemoveData(const IndexFinder &indexFinder) 0446 { 0447 QTest::addColumn<SignalList>("signalList"); 0448 QTest::addColumn<PersistentChangeList>("changeList"); 0449 0450 newRemoveTest(QStringLiteral("remove01"), indexFinder, 0, 0, 10); 0451 newRemoveTest(QStringLiteral("remove02"), indexFinder, 0, 4, 10); 0452 newRemoveTest(QStringLiteral("remove03"), indexFinder, 9, 9, 10); 0453 } 0454 0455 void testForwardingMoveData(const IndexFinder &srcFinder, const IndexFinder &destFinder) 0456 { 0457 QTest::addColumn<SignalList>("signalList"); 0458 QTest::addColumn<PersistentChangeList>("changeList"); 0459 0460 // noopLayoutChangeTest("move01"); 0461 // noopLayoutChangeTest("move02"); 0462 // noopLayoutChangeTest("move03"); 0463 // noopLayoutChangeTest("move04"); 0464 // noopLayoutChangeTest("move05"); 0465 0466 newMoveTest(QStringLiteral("move01"), srcFinder, 0, 0, 10, destFinder, 5); 0467 newMoveTest(QStringLiteral("move02"), srcFinder, 4, 4, 10, destFinder, 0); 0468 newMoveTest(QStringLiteral("move03"), srcFinder, 4, 4, 10, destFinder, 10); 0469 newMoveTest(QStringLiteral("move04"), srcFinder, 9, 9, 10, destFinder, 4); 0470 newMoveTest(QStringLiteral("move05"), srcFinder, 9, 9, 10, destFinder, 0); 0471 } 0472 0473 void testForwardingModifyData(const IndexFinder &parentFinder) 0474 { 0475 QTest::addColumn<SignalList>("signalList"); 0476 QTest::addColumn<PersistentChangeList>("changeList"); 0477 0478 newModifyTest(QStringLiteral("modify01"), parentFinder, 0, 0); 0479 newModifyTest(QStringLiteral("modify02"), parentFinder, 0, 4); 0480 newModifyTest(QStringLiteral("modify03"), parentFinder, 9, 9); 0481 newModifyTest(QStringLiteral("modify04"), parentFinder, 6, 9); 0482 newModifyTest(QStringLiteral("modify05"), parentFinder, 4, 4); 0483 newModifyTest(QStringLiteral("modify06"), parentFinder, 3, 7); 0484 newModifyTest(QStringLiteral("modify07"), parentFinder, 0, 9); 0485 } 0486 0487 void newInsertTest(const QString &name, const IndexFinder &indexFinder, int start, int end, int rowCount) 0488 { 0489 processTestName(name); 0490 0491 SignalList signalList; 0492 PersistentChangeList persistentList; 0493 0494 signalList << m_proxyModelTest->getSignal(RowsAboutToBeInserted, indexFinder, start, end); 0495 signalList << m_proxyModelTest->getSignal(RowsInserted, indexFinder, start, end); 0496 0497 if (rowCount - 1 + (end - start + 1) > end) { 0498 persistentList << m_proxyModelTest->getChange(indexFinder, start, rowCount - 1, end - start + 1); 0499 } 0500 0501 QTest::newRow(name.toLatin1()) << signalList << persistentList; 0502 } 0503 0504 void newRemoveTest(const QString &name, const IndexFinder &indexFinder, int start, int end, int rowCount) 0505 { 0506 processTestName(name); 0507 0508 SignalList signalList; 0509 PersistentChangeList persistentList; 0510 0511 signalList << m_proxyModelTest->getSignal(RowsAboutToBeRemoved, indexFinder, start, end); 0512 signalList << m_proxyModelTest->getSignal(RowsRemoved, indexFinder, start, end); 0513 0514 persistentList << m_proxyModelTest->getChange(indexFinder, start, end, -1, true); 0515 if (rowCount - 1 != end) { 0516 persistentList << m_proxyModelTest->getChange(indexFinder, end + 1, rowCount - 1, -1 * (end - start + 1)); 0517 } 0518 0519 QTest::newRow(name.toLatin1()) << signalList << persistentList; 0520 } 0521 0522 void newMoveTest(const QString &name, const IndexFinder &srcFinder, int start, int end, int rowCount, const IndexFinder &destFinder, int destStart) 0523 { 0524 Q_UNUSED(rowCount) 0525 processTestName(name); 0526 0527 SignalList signalList; 0528 PersistentChangeList persistentList; 0529 0530 // signalList << m_proxyModelTest->getSignal(RowsAboutToBeMoved, srcFinder, start, end, destFinder, destStart); 0531 // signalList << ( QVariantList() << LayoutAboutToBeChanged ); 0532 // signalList << m_proxyModelTest->getSignal(RowsMoved, srcFinder, start, end, destFinder, destStart); 0533 // signalList << ( QVariantList() << LayoutChanged ); 0534 0535 signalList << (QVariantList() << LayoutAboutToBeChanged); 0536 signalList << (QVariantList() << LayoutChanged); 0537 0538 const bool sameParent = (srcFinder == destFinder); 0539 const bool movingUp = (start > destStart); 0540 0541 if (sameParent) { 0542 if (movingUp) { 0543 persistentList << m_proxyModelTest->getChange(srcFinder, destStart, start - 1, end - start + 1); 0544 persistentList << m_proxyModelTest->getChange(srcFinder, start, end, -1 * (start - destStart)); 0545 } else { 0546 persistentList << m_proxyModelTest->getChange(srcFinder, start, end, destStart - end - 1); 0547 persistentList << m_proxyModelTest->getChange(srcFinder, end + 1, destStart - 1, -1 * (end - start + 1)); 0548 } 0549 } else { 0550 if (movingUp) { 0551 // TODO 0552 } 0553 } 0554 0555 QTest::newRow(name.toLatin1()) << signalList << persistentList; 0556 } 0557 0558 void newModifyTest(const QString &name, const IndexFinder &parentFinder, int top, int bottom) 0559 { 0560 processTestName(name); 0561 0562 SignalList signalList; 0563 0564 IndexFinder topLeftFinder = parentFinder; 0565 topLeftFinder.appendRow(top); 0566 0567 IndexFinder bottomRightFinder = parentFinder; 0568 bottomRightFinder.appendRow(bottom); 0569 0570 signalList << m_proxyModelTest->getSignal(DataChanged, topLeftFinder, bottomRightFinder); 0571 0572 QTest::newRow(name.toLatin1()) << signalList << PersistentChangeList(); 0573 } 0574 0575 void noop_testInsertWhenEmptyData() 0576 { 0577 QTest::addColumn<SignalList>("signalList"); 0578 QTest::addColumn<PersistentChangeList>("changeList"); 0579 0580 noopTest(QStringLiteral("insert01")); 0581 noopTest(QStringLiteral("insert02")); 0582 noopTest(QStringLiteral("insert03")); 0583 } 0584 0585 void noop_testInsertInRootData() 0586 { 0587 QTest::addColumn<SignalList>("signalList"); 0588 QTest::addColumn<PersistentChangeList>("changeList"); 0589 0590 // These commands have no effect because this model shows children of selection. 0591 0592 noopTest(QStringLiteral("insert01")); 0593 noopTest(QStringLiteral("insert02")); 0594 noopTest(QStringLiteral("insert03")); 0595 noopTest(QStringLiteral("insert04")); 0596 noopTest(QStringLiteral("insert05")); 0597 noopTest(QStringLiteral("insert06")); 0598 noopTest(QStringLiteral("insert07")); 0599 noopTest(QStringLiteral("insert08")); 0600 noopTest(QStringLiteral("insert09")); 0601 noopTest(QStringLiteral("insert10")); 0602 noopTest(QStringLiteral("insert11")); 0603 noopTest(QStringLiteral("insert12")); 0604 noopTest(QStringLiteral("insert13")); 0605 noopTest(QStringLiteral("insert14")); 0606 noopTest(QStringLiteral("insert15")); 0607 noopTest(QStringLiteral("insert16")); 0608 noopTest(QStringLiteral("insert17")); 0609 noopTest(QStringLiteral("insert18")); 0610 } 0611 0612 void noop_testInsertInTopLevelData() 0613 { 0614 // Same test names etc. 0615 noop_testInsertInRootData(); 0616 } 0617 0618 void noop_testInsertInSecondLevelData() 0619 { 0620 noop_testInsertInRootData(); 0621 } 0622 0623 void noop_testRemoveFromRootData() 0624 { 0625 QTest::addColumn<SignalList>("signalList"); 0626 QTest::addColumn<PersistentChangeList>("changeList"); 0627 0628 // These commands have no effect because this model shows children of selection. 0629 0630 noopTest(QStringLiteral("remove01")); 0631 noopTest(QStringLiteral("remove02")); 0632 noopTest(QStringLiteral("remove03")); 0633 } 0634 0635 void noop_testRemoveFromTopLevelData() 0636 { 0637 // Same test names etc. 0638 noop_testRemoveFromRootData(); 0639 } 0640 0641 void noop_testRemoveFromSecondLevelData() 0642 { 0643 noop_testRemoveFromRootData(); 0644 } 0645 0646 void noop_testMoveFromRootData() 0647 { 0648 QTest::addColumn<SignalList>("signalList"); 0649 QTest::addColumn<PersistentChangeList>("changeList"); 0650 0651 // These commands have no effect because this model shows children of selection. 0652 0653 noopLayoutChangeTest(QStringLiteral("move01")); 0654 noopLayoutChangeTest(QStringLiteral("move02")); 0655 noopLayoutChangeTest(QStringLiteral("move03")); 0656 noopLayoutChangeTest(QStringLiteral("move04")); 0657 noopLayoutChangeTest(QStringLiteral("move05")); 0658 } 0659 0660 void noop_testMoveFromTopLevelData() 0661 { 0662 // Same test names etc. 0663 noop_testMoveFromRootData(); 0664 } 0665 0666 void noop_testMoveFromSecondLevelData() 0667 { 0668 noop_testMoveFromRootData(); 0669 } 0670 0671 void noop_testModifyInRootData() 0672 { 0673 QTest::addColumn<SignalList>("signalList"); 0674 QTest::addColumn<PersistentChangeList>("changeList"); 0675 0676 noopTest(QStringLiteral("modify01")); 0677 noopTest(QStringLiteral("modify02")); 0678 noopTest(QStringLiteral("modify03")); 0679 noopTest(QStringLiteral("modify04")); 0680 noopTest(QStringLiteral("modify05")); 0681 noopTest(QStringLiteral("modify06")); 0682 noopTest(QStringLiteral("modify07")); 0683 } 0684 0685 void noop_testModifyInTopLevelData() 0686 { 0687 // Same test names etc. 0688 noop_testModifyInRootData(); 0689 } 0690 0691 void noop_testModifyInSecondLevelData() 0692 { 0693 noop_testModifyInRootData(); 0694 } 0695 0696 ProxyModelTest *m_proxyModelTest; 0697 QString m_currentTestFunction; 0698 QSet<QString> m_testNames; 0699 }; 0700 0701 PROXYMODELTESTSUITE_EXPORT uint qHash(const QVariant &var); 0702 0703 /* clang-format off */ 0704 #define PROXYMODELTEST(TestData, TemplateArg, IntermediateProxy, LazyPersistence, Config) \ 0705 if (testObjects.isEmpty() || testObjects.contains(testNum)) { \ 0706 proxyModelTestClass->setTestData(new TestData<TemplateArg>(proxyModelTestClass)); \ 0707 proxyModelTestClass->setUseIntermediateProxy(IntermediateProxy); \ 0708 proxyModelTestClass->setLazyPersistence(LazyPersistence); \ 0709 qDebug() << "\n Running" << proxyModelTestClass->objectName().toLatin1() << testNum << ":\n" \ 0710 << " Source Model: " << #IntermediateProxy << "\n" \ 0711 << " Persistence: " << #LazyPersistence << "\n" Config; \ 0712 result = QTest::qExec(proxyModelTestClass, arguments); \ 0713 if (result != 0) \ 0714 return result; \ 0715 } \ 0716 ++testNum; 0717 0718 #define PROXYMODELTEST_CUSTOM(TestData, IntermediateProxy, LazyPersistence, Config) \ 0719 if (testObjects.isEmpty() || testObjects.contains(testNum)) { \ 0720 proxyModelTestClass->setTestData(TestData); \ 0721 proxyModelTestClass->setUseIntermediateProxy(IntermediateProxy); \ 0722 proxyModelTestClass->setLazyPersistence(LazyPersistence); \ 0723 qDebug() << "\n Running" << proxyModelTestClass->objectName().toLatin1() << testNum << ":\n" \ 0724 << " Source Model: " << #IntermediateProxy << "\n" \ 0725 << " Persistence: " << #LazyPersistence << "\n" Config; \ 0726 result = QTest::qExec(proxyModelTestClass, arguments); \ 0727 if (result != 0) \ 0728 return result; \ 0729 } \ 0730 ++testNum; 0731 0732 // The DynamicTreeModel uses a unique internalId for the first column of each row. 0733 // In the QSortFilterProxyModel the internalId is shared between all rows of the same parent. 0734 // We test the proxy on top of both so that we know it is not using the internalId of its source model 0735 // which will be different each time the test is run. 0736 #define COMPLETETEST(TestData, TemplateArg, Config) \ 0737 PROXYMODELTEST(TestData, TemplateArg, DynamicTree, ImmediatePersistence, Config) \ 0738 PROXYMODELTEST(TestData, TemplateArg, IntermediateProxy, ImmediatePersistence, Config) \ 0739 PROXYMODELTEST(TestData, TemplateArg, DynamicTree, LazyPersistence, Config) \ 0740 PROXYMODELTEST(TestData, TemplateArg, IntermediateProxy, LazyPersistence, Config) 0741 0742 #define PROXYMODELTEST_MAIN(TestClass, Body) \ 0743 int main(int argc, char *argv[]) \ 0744 { \ 0745 QApplication app(argc, argv); \ 0746 QList<int> testObjects; \ 0747 QStringList arguments; \ 0748 bool ok; \ 0749 const auto lst = app.arguments(); \ 0750 for (const QString &arg : lst) { \ 0751 int testObject = arg.toInt(&ok); \ 0752 if (arg == "-count") \ 0753 continue; \ 0754 if (!ok) { \ 0755 arguments.append(arg); \ 0756 continue; \ 0757 } \ 0758 testObjects.append(testObject); \ 0759 } \ 0760 TestClass *proxyModelTestClass = new TestClass(); \ 0761 proxyModelTestClass->setObjectName(#TestClass); \ 0762 int result = 0; \ 0763 int testNum = 1; \ 0764 \ 0765 Body \ 0766 \ 0767 delete proxyModelTestClass; \ 0768 return result; \ 0769 } 0770 0771 /* clang-format on */ 0772 #endif