File indexing completed on 2024-06-09 04:23:55
0001 /* 0002 * SPDX-FileCopyrightText: 2020 boud <boud@valdyas.org> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 #include "TestTagResourceModel.h" 0007 0008 #include <simpletest.h> 0009 #include <QStandardPaths> 0010 #include <QDir> 0011 #include <QVersionNumber> 0012 #include <QDirIterator> 0013 #include <QSqlError> 0014 #include <QSqlQuery> 0015 #include <QAbstractItemModelTester> 0016 0017 #include <kconfig.h> 0018 #include <kconfiggroup.h> 0019 #include <ksharedconfig.h> 0020 0021 #include <KisResourceCacheDb.h> 0022 #include <KisResourceLocator.h> 0023 #include <KisResourceModel.h> 0024 #include <KisTagModel.h> 0025 #include <KisTagResourceModel.h> 0026 #include <KisResourceTypes.h> 0027 0028 #include <DummyResource.h> 0029 #include <ResourceTestHelper.h> 0030 0031 #ifndef FILES_DATA_DIR 0032 #error "FILES_DATA_DIR not set. A directory with the data used for testing installing resources" 0033 #endif 0034 0035 0036 void TestTagResourceModel::initTestCase() 0037 { 0038 ResourceTestHelper::initTestDb(); 0039 ResourceTestHelper::createDummyLoaderRegistry(); 0040 0041 m_srcLocation = QString(FILES_DATA_DIR); 0042 QVERIFY2(QDir(m_srcLocation).exists(), m_srcLocation.toUtf8()); 0043 0044 m_dstLocation = ResourceTestHelper::filesDestDir(); 0045 ResourceTestHelper::cleanDstLocation(m_dstLocation); 0046 0047 KConfigGroup cfg(KSharedConfig::openConfig(), ""); 0048 cfg.writeEntry(KisResourceLocator::resourceLocationKey, m_dstLocation); 0049 0050 m_locator = KisResourceLocator::instance(); 0051 0052 if (!KisResourceCacheDb::initialize(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation))) { 0053 qDebug() << "Could not initialize KisResourceCacheDb on" << QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); 0054 } 0055 QVERIFY(KisResourceCacheDb::isValid()); 0056 0057 KisResourceLocator::LocatorError r = m_locator->initialize(m_srcLocation); 0058 if (!m_locator->errorMessages().isEmpty()) qDebug() << m_locator->errorMessages(); 0059 0060 QVERIFY(r == KisResourceLocator::LocatorError::Ok); 0061 QVERIFY(QDir(m_dstLocation).exists()); 0062 } 0063 0064 void TestTagResourceModel::testWithTagModelTester() 0065 { 0066 KisAllTagResourceModel model(ResourceType::PaintOpPresets); 0067 auto tester = new QAbstractItemModelTester(&model); 0068 Q_UNUSED(tester); 0069 } 0070 0071 0072 void TestTagResourceModel::testRowCount() 0073 { 0074 QSqlQuery q; 0075 QVERIFY(q.prepare("SELECT count(*)\n" 0076 "FROM resource_tags\n" 0077 "WHERE resource_tags.active = 1\n")); 0078 QVERIFY(q.exec()); 0079 q.first(); 0080 int rowCount = q.value(0).toInt(); 0081 QCOMPARE(rowCount, 2); 0082 0083 KisAllTagResourceModel tagResourceModel(ResourceType::PaintOpPresets); 0084 QCOMPARE(tagResourceModel.rowCount(), rowCount); 0085 } 0086 0087 bool testDataInColumnAndRole(KisAllTagResourceModel &tagResourceModel, int columnRole) 0088 { 0089 QModelIndex idx = tagResourceModel.index(0, columnRole); 0090 QVariant data1 = tagResourceModel.data(idx, Qt::DisplayRole); 0091 0092 idx = tagResourceModel.index(0, 0); 0093 QVariant data2 = tagResourceModel.data(idx, Qt::UserRole + columnRole); 0094 bool success = data1 == data2; 0095 if (!success) { 0096 qInfo() << "Column: " << columnRole << "Data from column: " << data1 << "Data from role: " << data2; 0097 } 0098 return success; 0099 } 0100 0101 bool testDataInColumnAndRole(KisAllTagResourceModel &tagResourceModel, int columnRole, QVariant expected) 0102 { 0103 QModelIndex idx = tagResourceModel.index(0, columnRole); 0104 QVariant data = tagResourceModel.data(idx, Qt::DisplayRole); 0105 bool columnSuccess = data == expected; 0106 if (!columnSuccess) { 0107 qInfo() << "Column: " << columnRole << "Expected: " << expected << "Actual: " << data; 0108 } 0109 0110 idx = tagResourceModel.index(0, 0); 0111 data = tagResourceModel.data(idx, Qt::UserRole + columnRole); 0112 bool roleSuccess = data == expected; 0113 if (!roleSuccess) { 0114 qInfo() << "Column: " << columnRole << "Expected: " << expected << "Actual: " << data; 0115 } 0116 return columnSuccess && roleSuccess; 0117 0118 } 0119 0120 void TestTagResourceModel::testData() 0121 { 0122 KisAllTagResourceModel tagResourceModel(ResourceType::PaintOpPresets); 0123 QModelIndex idx = tagResourceModel.index(0, 0); 0124 QVERIFY(idx.isValid()); 0125 0126 // *** columns from ResourceModel, via ResourceQueryMapper *** // 0127 QVERIFY(testDataInColumnAndRole(tagResourceModel, KisAbstractResourceModel::Id, 3)); 0128 QVERIFY(testDataInColumnAndRole(tagResourceModel, KisAbstractResourceModel::StorageId, 1)); 0129 QVERIFY(testDataInColumnAndRole(tagResourceModel, KisAbstractResourceModel::Name, "test0.kpp")); 0130 QVERIFY(testDataInColumnAndRole(tagResourceModel, KisAbstractResourceModel::Filename, "test0.kpp")); 0131 QVERIFY(testDataInColumnAndRole(tagResourceModel, KisAbstractResourceModel::Tooltip, "test0.kpp")); 0132 0133 // Thumbnail -- without checking the value, just if both are the same 0134 QVERIFY(testDataInColumnAndRole(tagResourceModel, KisAbstractResourceModel::Thumbnail)); 0135 // Status -- skip 0136 0137 QVERIFY(testDataInColumnAndRole(tagResourceModel, KisAbstractResourceModel::Location, "")); 0138 QVERIFY(testDataInColumnAndRole(tagResourceModel, KisAbstractResourceModel::ResourceType, ResourceType::PaintOpPresets)); 0139 0140 // Tags -- only in role; there is no column like that, the result in QVariant() 0141 QStringList tagList = tagResourceModel.data(idx, Qt::UserRole + KisAbstractResourceModel::Tags).value<QStringList>(); 0142 QCOMPARE(tagList.count(), 1); 0143 QCOMPARE(tagList[0], "* Favorites"); 0144 0145 // Large Thumbnail -- without checking the value, just if both are the same 0146 QVERIFY(testDataInColumnAndRole(tagResourceModel, KisAbstractResourceModel::LargeThumbnail)); 0147 0148 QVERIFY(testDataInColumnAndRole(tagResourceModel, KisAbstractResourceModel::Dirty, false)); 0149 0150 // MetaData -- only in role; there is no column like that, the result in QVariant() 0151 QMap<QString, QVariant> metadata = tagResourceModel.data(idx, Qt::UserRole + KisAbstractResourceModel::MetaData).value<QMap<QString, QVariant>>(); 0152 QCOMPARE(metadata.count(), 0); 0153 0154 QVERIFY(testDataInColumnAndRole(tagResourceModel, KisAbstractResourceModel::ResourceActive, true)); 0155 QVERIFY(testDataInColumnAndRole(tagResourceModel, KisAbstractResourceModel::StorageActive, true)); 0156 0157 // *** TagResourceModel own columns *** // 0158 QVERIFY(testDataInColumnAndRole(tagResourceModel, KisAllTagResourceModel::TagId, 1)); 0159 QVERIFY(testDataInColumnAndRole(tagResourceModel, KisAllTagResourceModel::ResourceId, 3)); 0160 0161 KisTagSP tag = tagResourceModel.data(idx, Qt::UserRole + KisAllTagResourceModel::Tag).value<KisTagSP>(); 0162 QVERIFY(tag); 0163 QVERIFY(tag->valid()); 0164 QCOMPARE(tag->name(), "* Favorites"); 0165 QCOMPARE(tag->id(), 1); 0166 0167 KoResourceSP resource = tagResourceModel.data(idx, Qt::UserRole + KisAllTagResourceModel::Resource).value<KoResourceSP>(); 0168 QVERIFY(resource); 0169 QVERIFY(resource->valid()); 0170 QCOMPARE(resource->name(), "test0.kpp"); 0171 QCOMPARE(resource->resourceId(), 3); 0172 0173 QVERIFY(testDataInColumnAndRole(tagResourceModel, KisAllTagResourceModel::TagActive, true)); 0174 QVERIFY(testDataInColumnAndRole(tagResourceModel, KisAllTagResourceModel::ResourceActive, true)); 0175 QVERIFY(testDataInColumnAndRole(tagResourceModel, KisAllTagResourceModel::ResourceStorageActive, true)); 0176 0177 QVERIFY(testDataInColumnAndRole(tagResourceModel, KisAllTagResourceModel::ResourceName, "test0.kpp")); 0178 QVERIFY(testDataInColumnAndRole(tagResourceModel, KisAllTagResourceModel::TagName, "* Favorites")); 0179 0180 0181 } 0182 0183 void TestTagResourceModel::testTagResource() 0184 { 0185 KisResourceModel resourceModel(ResourceType::PaintOpPresets); 0186 KoResourceSP resource = resourceModel.resourcesForName("test2.kpp").first(); 0187 Q_ASSERT(resource); 0188 0189 KisTagModel tagModel(ResourceType::PaintOpPresets); 0190 KisTagSP tag = tagModel.tagForIndex(tagModel.index(2, 0)); 0191 Q_ASSERT(tag); 0192 0193 KisAllTagResourceModel tagResourceModel(ResourceType::PaintOpPresets); 0194 if (tagResourceModel.isResourceTagged(tag, resource->resourceId())) { 0195 tagResourceModel.untagResources(tag, { resource->resourceId() }); 0196 } 0197 0198 int rowCount = tagResourceModel.rowCount(); 0199 0200 QVERIFY(tagResourceModel.tagResources(tag, { resource->resourceId() })); 0201 0202 QCOMPARE(tagResourceModel.rowCount(), rowCount + 1); 0203 } 0204 0205 void TestTagResourceModel::testUntagResource() 0206 { 0207 KisResourceModel resourceModel(ResourceType::PaintOpPresets); 0208 KoResourceSP resource = resourceModel.resourcesForName("test1.kpp").first(); 0209 QVERIFY(resource); 0210 0211 KisTagModel tagModel(ResourceType::PaintOpPresets); 0212 KisTagSP tag = tagModel.tagForIndex(tagModel.index(2, 0)); 0213 QVERIFY(tag); 0214 0215 KisAllTagResourceModel tagResourceModel(ResourceType::PaintOpPresets); 0216 0217 if (!tagResourceModel.isResourceTagged(tag, resource->resourceId())) { 0218 tagResourceModel.tagResources(tag, { resource->resourceId() }); 0219 } 0220 0221 int rowCount = tagResourceModel.rowCount(); 0222 tagResourceModel.untagResources(tag, { resource->resourceId() }); 0223 0224 QCOMPARE(tagResourceModel.rowCount(), rowCount - 1); 0225 } 0226 0227 void TestTagResourceModel::testIsResourceTagged() 0228 { 0229 KisResourceModel resourceModel(ResourceType::PaintOpPresets); 0230 KoResourceSP resource = resourceModel.resourcesForName("test2.kpp").first(); 0231 Q_ASSERT(resource); 0232 0233 KisTagModel tagModel(ResourceType::PaintOpPresets); 0234 KisTagSP tag = tagModel.tagForIndex(tagModel.index(2, 0)); 0235 Q_ASSERT(tag); 0236 0237 KisAllTagResourceModel tagResourceModel(ResourceType::PaintOpPresets); 0238 0239 QVERIFY(tagResourceModel.tagResources(tag, { resource->resourceId() })); 0240 QCOMPARE(tagResourceModel.isResourceTagged(tag, resource->resourceId()), true); 0241 0242 resource = resourceModel.resourcesForName("test1.kpp").first(); 0243 QVERIFY(resource); 0244 0245 tag = tagModel.tagForIndex(tagModel.index(2, 0)); 0246 QVERIFY(tag); 0247 0248 tagResourceModel.untagResources(tag, { resource->resourceId() }); 0249 QCOMPARE(tagResourceModel.isResourceTagged(tag, resource->resourceId()), false); 0250 } 0251 0252 void TestTagResourceModel::testFilterTagResource() 0253 { 0254 KisResourceModel resourceModel(ResourceType::PaintOpPresets); 0255 KoResourceSP resource = resourceModel.resourcesForName("test2.kpp").first(); 0256 Q_ASSERT(resource); 0257 0258 KisTagModel tagModel(ResourceType::PaintOpPresets); 0259 KisTagSP tag = tagModel.tagForIndex(tagModel.index(2, 0)); 0260 Q_ASSERT(tag); 0261 0262 KisTagResourceModel tagResourceModel(ResourceType::PaintOpPresets); 0263 QCOMPARE(tagResourceModel.rowCount(), 2); 0264 0265 QVector<int> tagIds; 0266 tagIds << tag->id(); 0267 tagResourceModel.setTagsFilter(tagIds); 0268 0269 QVector<int> resourceIds; 0270 resourceIds << resource->resourceId(); 0271 tagResourceModel.setResourcesFilter(resourceIds); 0272 0273 QCOMPARE(tagResourceModel.rowCount(), 1); 0274 } 0275 0276 0277 void printOutModel(QAbstractItemModel* model) 0278 { 0279 if (model->inherits("KisTagResourceModel")) { 0280 KisTagResourceModel* tagResourceModel = dynamic_cast<KisTagResourceModel*>(model); 0281 if (!tagResourceModel) { 0282 return; 0283 } 0284 for (int i = 0; i < tagResourceModel->rowCount(); i++) { 0285 QModelIndex idx = tagResourceModel->index(i, 0); 0286 qCritical() << "Tag Resource | i: " << i << "| resource id: " << tagResourceModel->data(idx, Qt::UserRole + KisAllTagResourceModel::ResourceId).toInt() 0287 << "| tag id: " << tagResourceModel->data(idx, Qt::UserRole + KisAllTagResourceModel::TagId).toInt() 0288 << "(" << tagResourceModel->data(idx, Qt::UserRole + KisAllTagResourceModel::TagName).toString() << ")"; 0289 } 0290 return; 0291 } 0292 0293 if (model->inherits("KisTagModel")) { 0294 KisTagModel* tagModel = dynamic_cast<KisTagModel*>(model); 0295 if (!tagModel) { 0296 return; 0297 } 0298 for (int i = 0; i < tagModel->rowCount(); i++) { 0299 QModelIndex idx = tagModel->index(i, 0); 0300 qCritical() << "Tag | i: " << i << "| real id: " << tagModel->data(idx, Qt::UserRole + KisAllTagsModel::Id).toInt() 0301 << "| name: " << tagModel->data(idx, Qt::UserRole + KisAllTagsModel::Name).toString(); 0302 } 0303 return; 0304 } 0305 0306 if (model->inherits("KisResourceModel")) { 0307 KisResourceModel* resourceModel = dynamic_cast<KisResourceModel*>(model); 0308 if (!resourceModel) { 0309 return; 0310 } 0311 for (int i = 0; i < resourceModel->rowCount(); i++) { 0312 QModelIndex idx = resourceModel->index(i, 0); 0313 qCritical() << "Resource | i: " << i << "| real id: " << resourceModel->data(idx, Qt::UserRole + KisAllResourcesModel::Id).toInt() 0314 << "| name: " << resourceModel->data(idx, Qt::UserRole + KisAllResourcesModel::Name).toString(); 0315 } 0316 return; 0317 } 0318 0319 } 0320 0321 0322 void TestTagResourceModel::testBeginEndInsert() 0323 { 0324 KisTagResourceModel tagResourceModel(ResourceType::PaintOpPresets); 0325 KisResourceModel resourceModel(ResourceType::PaintOpPresets); 0326 KisTagModel tagModel(ResourceType::PaintOpPresets); 0327 0328 QList<KoResourceSP> resources; 0329 QList<int> resourceIds; 0330 0331 // prepare signal checker 0332 typedef ModelSignalChecker SC; 0333 ModelSignalChecker checker({5, 5, 4, 4}, {5, 5, 5, 5}, {SC::AboutInsert, SC::Insert, SC::AboutInsert, SC::Insert}); 0334 0335 // debug tips: 0336 // to see the content of the signal checker, use: 0337 //checker.printOut(); 0338 // to see the content of the tagResourceModel, use: 0339 //printOutModel(&tagResourceModel); 0340 0341 connect(&tagResourceModel, SIGNAL(rowsAboutToBeInserted(const QModelIndex, int, int)), &checker, SLOT(rowsAboutToBeInserted(const QModelIndex, int, int))); 0342 connect(&tagResourceModel, SIGNAL(rowsAboutToBeRemoved(const QModelIndex, int, int)), &checker, SLOT(rowsAboutToBeRemoved(const QModelIndex, int, int))); 0343 connect(&tagResourceModel, SIGNAL(rowsInserted(const QModelIndex, int, int)), &checker, SLOT(rowsInserted(const QModelIndex, int, int))); 0344 connect(&tagResourceModel, SIGNAL(rowsRemoved(const QModelIndex, int, int)), &checker, SLOT(rowsRemoved(const QModelIndex, int, int))); 0345 0346 // this builds a list of resources 0347 for (int i = 0; i < resourceModel.rowCount(); i++) { 0348 QModelIndex idx = resourceModel.index(i, 0); 0349 if (resources.length() < 4) { // sanity check 0350 resources << resourceModel.resourceForIndex(idx); 0351 resourceIds << resourceModel.data(idx, Qt::UserRole + KisAllResourcesModel::Id).toInt(); 0352 } 0353 } 0354 0355 // //// 0356 tagModel.addTag("Tag1", true, {}); 0357 tagModel.addTag("Tag2", true, {}); 0358 tagModel.addTag("TagSpecial", true, {}); 0359 0360 0361 QList<KisTagSP> tags; 0362 // this builds a list of tags 0363 0364 for (int i = 0; i < tagModel.rowCount(); i++) { 0365 QModelIndex idx = tagModel.index(i, 0); 0366 int realId = tagModel.data(idx, Qt::UserRole + KisAllTagsModel::Id).toInt(); 0367 if (tags.length() < 5 && realId >= 0) { // sanity check 0368 tags << tagModel.tagForIndex(idx); 0369 } 0370 } 0371 0372 QCOMPARE(tags.count(), 4); 0373 QCOMPARE(resources.count(), 3); 0374 0375 0376 // tag assignment to resources: 0377 // other1 - res1 0378 // other2 - res2 0379 // special - res2 0380 // special - res3 0381 // other2 - res3 0382 // special - res1 0383 // other1 - res2 0384 // 0385 // this is done in order for tagging and untagging having to process 0386 // multiple batches of rows 0387 // and not just one consequent group of rows 0388 KisTagSP other1 = tags[1]; 0389 KisTagSP other2 = tags[2]; 0390 KisTagSP special = tags[3]; 0391 0392 // --- tagging 0393 tagResourceModel.tagResources(other1, { resources[0]->resourceId() }); 0394 tagResourceModel.tagResources(other2, { resources[1]->resourceId() }); 0395 0396 tagResourceModel.tagResources(special, { resources[2]->resourceId() }); // <- special 0397 tagResourceModel.tagResources(special, { resources[1]->resourceId() }); // <- special 0398 0399 tagResourceModel.tagResources(other2, { resources[2]->resourceId() }); 0400 0401 tagResourceModel.tagResources(special, { resources[0]->resourceId() }); // <- special 0402 0403 tagResourceModel.tagResources(other1, { resources[1]->resourceId() }); 0404 0405 // --- untagging 0406 0407 checker.reset(); 0408 checker.setInfo({4, 4, 5, 5}, {5, 5, 5, 5}, {SC::AboutRemove, SC::Remove, SC::AboutRemove, SC::Remove}); 0409 0410 tagResourceModel.untagResources(special, QVector<int>() << resourceIds[2] << resourceIds[1] << resourceIds[0]); 0411 0412 QVERIFY2(checker.isCorrect(), "Detected incorrect/unexpected signals sent to views"); 0413 0414 0415 0416 // *** *** // 0417 checker.reset(); 0418 checker.setInfo({5, 5, 4, 4}, {5, 5, 5, 5}, {SC::AboutInsert, SC::Insert, SC::AboutInsert, SC::Insert}); 0419 0420 tagResourceModel.tagResources(special, { resourceIds[2], resourceIds[1], resourceIds[0] }); 0421 0422 QVERIFY2(checker.isCorrect(), "Detected incorrect/unexpected signals sent to views"); 0423 0424 // *** *** // 0425 0426 checker.reset(); 0427 checker.setInfo({4, 4, 5, 5}, {5, 5, 5, 5}, {SC::AboutRemove, SC::Remove, SC::AboutRemove, SC::Remove}); 0428 0429 tagResourceModel.untagResources(special, QVector<int>() << resourceIds[2] << resourceIds[1] << resourceIds[0]); 0430 0431 QVERIFY2(checker.isCorrect(), "Detected incorrect/unexpected signals sent to views"); 0432 0433 // *** *** // 0434 0435 checker.reset(); 0436 checker.setInfo({5, 5, 4, 4}, {5, 5, 5, 5}, {SC::AboutInsert, SC::Insert, SC::AboutInsert, SC::Insert}); 0437 0438 tagResourceModel.tagResources(special, { resourceIds[0], resourceIds[1], resourceIds[2] }); 0439 0440 QVERIFY2(checker.isCorrect(), "Detected incorrect/unexpected signals sent to views"); 0441 0442 // *** *** // 0443 0444 checker.reset(); 0445 checker.setInfo({4, 4, 5, 5}, {5, 5, 5, 5}, {SC::AboutRemove, SC::Remove, SC::AboutRemove, SC::Remove}); 0446 0447 tagResourceModel.untagResources(special, { resourceIds[2], resourceIds[1], resourceIds[0] }); 0448 0449 QVERIFY2(checker.isCorrect(), "Detected incorrect/unexpected signals sent to views"); 0450 0451 // *** *** // 0452 0453 checker.reset(); 0454 checker.setInfo({}, {}, {}); // no signals expected, because all of them are untagged now 0455 0456 tagResourceModel.untagResources(special, { resourceIds[2], resourceIds[1], resourceIds[0] }); 0457 0458 QVERIFY2(checker.isCorrect(), "Detected incorrect/unexpected signals sent to views"); 0459 0460 // *** *** // 0461 0462 checker.reset(); 0463 checker.setInfo({5, 5, 4, 4}, {5, 5, 4, 4}, {SC::AboutInsert, SC::Insert, SC::AboutInsert, SC::Insert}); 0464 0465 tagResourceModel.tagResources(special, { resourceIds[2], resourceIds[0] }); 0466 0467 QVERIFY2(checker.isCorrect(), "Detected incorrect/unexpected signals sent to views"); 0468 0469 // just to clean up space (to have all resources tagged) 0470 checker.reset(); 0471 0472 tagResourceModel.tagResources(special, { resourceIds[2], resourceIds[1], resourceIds[0] }); 0473 0474 // *** *** // 0475 0476 checker.reset(); 0477 checker.setInfo({4, 4, 6, 6}, {4, 4, 6, 6}, {SC::AboutRemove, SC::Remove, SC::AboutRemove, SC::Remove}); 0478 0479 tagResourceModel.untagResources(special, { resourceIds[2], resourceIds[0] }); 0480 0481 QVERIFY2(checker.isCorrect(), "Detected incorrect/unexpected signals sent to views"); 0482 0483 // *** *** // 0484 0485 checker.reset(); 0486 checker.setInfo({4, 4}, {4, 4}, {SC::AboutRemove, SC::Remove}); 0487 0488 tagResourceModel.untagResources(special, { resourceIds[1], resourceIds[0]}); 0489 0490 QVERIFY2(checker.isCorrect(), "Detected incorrect/unexpected signals sent to views"); 0491 0492 // *** *** // 0493 // check adding multiple new tag-resource assignments at once 0494 0495 checker.reset(); 0496 checker.setInfo({6, 6, 9, 9}, {8, 8, 11, 11}, {SC::AboutInsert, SC::Insert, SC::AboutInsert, SC::Insert}); 0497 0498 tagModel.addTag("tagExtra1", true, { resources[2], resources[1], resources[0]}); 0499 tagModel.addTag("tagExtra2", true, {}); 0500 KisTagSP tagExtra1 = tagModel.tagForUrl("tagExtra2"); 0501 tagResourceModel.tagResources(tagExtra1, { resourceIds[2], resourceIds[1], resourceIds[0]}); 0502 0503 0504 QVERIFY2(checker.isCorrect(), "Detected incorrect/unexpected signals sent to views"); 0505 } 0506 0507 void TestTagResourceModel::cleanupTestCase() 0508 { 0509 ResourceTestHelper::rmTestDb(); 0510 ResourceTestHelper::cleanDstLocation(m_dstLocation); 0511 } 0512 0513 #include <kistest.h> 0514 0515 // ***** MODEL SIGNAL CHECKER Function definitions ***** 0516 0517 0518 ModelSignalChecker::ModelSignalChecker(QList<int> _expectedFirsts, QList<int> _expectedLasts, QList<ModelSignalChecker::TYPE> _expectedTypes) 0519 { 0520 setInfo(_expectedFirsts, _expectedLasts, _expectedTypes); 0521 } 0522 0523 void ModelSignalChecker::setInfo(QList<int> _expectedFirsts, QList<int> _expectedLasts, QList<ModelSignalChecker::TYPE> _expectedTypes) 0524 { 0525 KIS_ASSERT(_expectedFirsts.count() == _expectedLasts.count() && _expectedFirsts.count() == _expectedTypes.count() && "Incorrect data supplied to SignalChecker"); 0526 expectedAmount = _expectedFirsts.count(); 0527 0528 expectedFirsts = _expectedFirsts; 0529 expectedLasts = _expectedLasts; 0530 expectedTypes = _expectedTypes; 0531 reset(); 0532 } 0533 0534 void ModelSignalChecker::reset() 0535 { 0536 firsts = QList<int>(); 0537 lasts = QList<int>(); 0538 types = QList<TYPE>(); 0539 amount = 0; 0540 } 0541 0542 bool ModelSignalChecker::isCorrect() { 0543 if (expectedFirsts.count() != firsts.count()) return false; 0544 if (expectedLasts.count() != lasts.count()) return false; 0545 if (expectedTypes.count() != types.count()) return false; 0546 if (expectedAmount != amount) return false; 0547 0548 for (int i = 0; i < firsts.count(); i++) { 0549 if (expectedFirsts[i] != firsts[i]) return false; 0550 } 0551 0552 for (int i = 0; i < lasts.count(); i++) { 0553 if (expectedLasts[i] != lasts[i]) return false; 0554 } 0555 0556 for (int i = 0; i < types.count(); i++) { 0557 if (expectedTypes[i] != types[i]) return false; 0558 } 0559 0560 return true; 0561 } 0562 0563 void ModelSignalChecker::printOut() 0564 { 0565 0566 qCritical() << "*** SignalChecker write out ***"; 0567 0568 int n = qMin(qMin(amount, firsts.count()), qMin(lasts.count(), types.count())); 0569 int nmax = qMax(qMax(amount, firsts.count()), qMax(lasts.count(), types.count())); 0570 if (n != nmax) { 0571 qCritical() << "The amounts differ!" << amount << firsts.count() << lasts.count() << types.count(); 0572 } 0573 0574 for (int i = 0; i < n; i++) { 0575 QString type = "[type]"; 0576 switch(types[i]) { 0577 case AboutInsert: 0578 type = "About Insert"; 0579 break; 0580 case AboutRemove: 0581 type = "About Remove"; 0582 break; 0583 case Insert: 0584 type = "Insert"; 0585 break; 0586 case Remove: 0587 type = "Remove"; 0588 break; 0589 } 0590 qCritical() << i << type << firsts[i] << lasts[i]; 0591 } 0592 0593 qCritical() << "*** SignalChecker write out END ***"; 0594 } 0595 0596 void ModelSignalChecker::rowsAboutToBeInserted(const QModelIndex &parent, int first, int last) 0597 { 0598 Q_UNUSED(parent); 0599 addSignalInfo(first, last, AboutInsert); 0600 } 0601 0602 void ModelSignalChecker::rowsInserted(const QModelIndex &parent, int first, int last) 0603 { 0604 Q_UNUSED(parent); 0605 addSignalInfo(first, last, Insert); 0606 } 0607 0608 void ModelSignalChecker::rowsAboutToBeRemoved(const QModelIndex &parent, int first, int last) 0609 { 0610 Q_UNUSED(parent); 0611 addSignalInfo(first, last, AboutRemove); 0612 } 0613 0614 void ModelSignalChecker::rowsRemoved(const QModelIndex &parent, int first, int last) 0615 { 0616 Q_UNUSED(parent); 0617 addSignalInfo(first, last, Remove); 0618 } 0619 0620 void ModelSignalChecker::addSignalInfo(int first, int last, ModelSignalChecker::TYPE type) 0621 { 0622 amount++; 0623 firsts << first; 0624 lasts << last; 0625 types << type; 0626 } 0627 0628 KISTEST_MAIN(TestTagResourceModel) 0629