File indexing completed on 2024-06-02 04:17:22
0001 /**************************************************************************** 0002 ** 0003 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 0004 ** All rights reserved. 0005 ** Contact: Nokia Corporation (qt-info@nokia.com) 0006 ** 0007 ** This file is part of the test suite of the Qt Toolkit. 0008 ** 0009 ** $QT_BEGIN_LICENSE:LGPL$ 0010 ** GNU Lesser General Public License Usage 0011 ** This file may be used under the terms of the GNU Lesser General Public 0012 ** License version 2.1 as published by the Free Software Foundation and 0013 ** appearing in the file LICENSE.LGPL included in the packaging of this 0014 ** file. Please review the following information to ensure the GNU Lesser 0015 ** General Public License version 2.1 requirements will be met: 0016 ** https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 0017 ** 0018 ** In addition, as a special exception, Nokia gives you certain additional 0019 ** rights. These rights are described in the Nokia Qt LGPL Exception 0020 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 0021 ** 0022 ** GNU General Public License Usage 0023 ** Alternatively, this file may be used under the terms of the GNU General 0024 ** Public License version 3.0 as published by the Free Software Foundation 0025 ** and appearing in the file LICENSE.GPL included in the packaging of this 0026 ** file. Please review the following information to ensure the GNU General 0027 ** Public License version 3.0 requirements will be met: 0028 ** https://www.gnu.org/copyleft/gpl.html. 0029 ** 0030 ** Other Usage 0031 ** Alternatively, this file may be used in accordance with the terms and 0032 ** conditions contained in a signed written agreement between you and Nokia. 0033 ** 0034 ** 0035 ** 0036 ** 0037 ** 0038 ** $QT_END_LICENSE$ 0039 ** 0040 ****************************************************************************/ 0041 0042 #include "modeltest.h" 0043 0044 // Qt includes 0045 0046 #include <QVariant> 0047 #include <QTest> 0048 0049 // Local includes 0050 0051 #include "digikam_debug.h" 0052 0053 #undef Q_ASSERT 0054 #define Q_ASSERT QVERIFY 0055 0056 Q_DECLARE_METATYPE(QModelIndex) 0057 0058 /** 0059 * Connect to all of the models signals. Whenever anything happens recheck everything. 0060 */ 0061 ModelTest::ModelTest(QAbstractItemModel* const _model, QObject* const parent) 0062 : QObject (parent), 0063 model (_model), 0064 fetchingMore(false) 0065 { 0066 Q_ASSERT(model); 0067 0068 connect(model, SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)), 0069 this, SLOT(runAllTests())); 0070 0071 connect(model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)), 0072 this, SLOT(runAllTests())); 0073 0074 connect(model, SIGNAL(columnsInserted(QModelIndex,int,int)), 0075 this, SLOT(runAllTests())); 0076 0077 connect(model, SIGNAL(columnsRemoved(QModelIndex,int,int)), 0078 this, SLOT(runAllTests())); 0079 0080 connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), 0081 this, SLOT(runAllTests())); 0082 0083 connect(model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)), 0084 this, SLOT(runAllTests())); 0085 0086 connect(model, SIGNAL(layoutAboutToBeChanged()), 0087 this, SLOT(runAllTests())); 0088 0089 connect(model, SIGNAL(layoutChanged()), 0090 this, SLOT(runAllTests())); 0091 0092 connect(model, SIGNAL(modelReset()), 0093 this, SLOT(runAllTests())); 0094 0095 connect(model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), 0096 this, SLOT(runAllTests())); 0097 0098 connect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), 0099 this, SLOT(runAllTests())); 0100 0101 connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)), 0102 this, SLOT(runAllTests())); 0103 0104 connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)), 0105 this, SLOT(runAllTests())); 0106 0107 // Special checks for inserting/removing 0108 0109 connect(model, SIGNAL(layoutAboutToBeChanged()), 0110 this, SLOT(layoutAboutToBeChanged())); 0111 0112 connect(model, SIGNAL(layoutChanged()), 0113 this, SLOT(layoutChanged())); 0114 0115 connect(model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), 0116 this, SLOT(rowsAboutToBeInserted(QModelIndex,int,int))); 0117 0118 connect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), 0119 this, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int))); 0120 0121 connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)), 0122 this, SLOT(rowsInserted(QModelIndex,int,int))); 0123 0124 connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)), 0125 this, SLOT(rowsRemoved(QModelIndex,int,int))); 0126 0127 runAllTests(); 0128 } 0129 0130 void ModelTest::runAllTests() 0131 { 0132 if (fetchingMore) 0133 { 0134 return; 0135 } 0136 0137 nonDestructiveBasicTest(); 0138 rowCount(); 0139 columnCount(); 0140 hasIndex(); 0141 index(); 0142 parent(); 0143 data(); 0144 } 0145 0146 /** 0147 * nonDestructiveBasicTest tries to call a number of the basic functions (not all) 0148 * to make sure the model doesn't outright segfault, testing the functions that makes sense. 0149 */ 0150 void ModelTest::nonDestructiveBasicTest() 0151 { 0152 Q_ASSERT(model->buddy(QModelIndex()) == QModelIndex()); 0153 model->canFetchMore(QModelIndex()); 0154 Q_ASSERT(model->columnCount(QModelIndex()) >= 0); 0155 Q_ASSERT(model->data(QModelIndex()) == QVariant()); 0156 fetchingMore = true; 0157 model->fetchMore(QModelIndex()); 0158 fetchingMore = false; 0159 Qt::ItemFlags flags = model->flags(QModelIndex()); 0160 Q_ASSERT(flags == Qt::ItemIsDropEnabled || flags == 0); 0161 model->hasChildren(QModelIndex()); 0162 model->hasIndex(0, 0); 0163 model->headerData(0, Qt::Horizontal); 0164 model->index(0, 0); 0165 model->itemData(QModelIndex()); 0166 QVariant cache; 0167 model->match(QModelIndex(), -1, cache); 0168 model->mimeTypes(); 0169 Q_ASSERT(model->parent(QModelIndex()) == QModelIndex()); 0170 Q_ASSERT(model->rowCount() >= 0); 0171 QVariant variant; 0172 model->setData(QModelIndex(), variant, -1); 0173 model->setHeaderData(-1, Qt::Horizontal, QVariant()); 0174 model->setHeaderData(999999, Qt::Horizontal, QVariant()); 0175 QMap<int, QVariant> roles; 0176 model->sibling(0, 0, QModelIndex()); 0177 model->span(QModelIndex()); 0178 model->supportedDropActions(); 0179 } 0180 0181 /** 0182 * Tests model's implementation of QAbstractItemModel::rowCount() and hasChildren() 0183 * Models that are dynamically populated are not as fully tested here. 0184 */ 0185 void ModelTest::rowCount() 0186 { 0187 // qCDebug(DIGIKAM_TESTS_LOG) << "rc"; 0188 0189 // check top row 0190 QModelIndex topIndex = model->index(0, 0, QModelIndex()); 0191 int rows = model->rowCount(topIndex); 0192 Q_ASSERT(rows >= 0); 0193 0194 if (rows > 0) 0195 { 0196 Q_ASSERT(model->hasChildren(topIndex) == true); 0197 } 0198 0199 QModelIndex secondLevelIndex = model->index(0, 0, topIndex); 0200 0201 if (secondLevelIndex.isValid()) 0202 { 0203 // not the top level 0204 // check a row count where parent is valid 0205 rows = model->rowCount(secondLevelIndex); 0206 Q_ASSERT(rows >= 0); 0207 0208 if (rows > 0) 0209 { 0210 Q_ASSERT(model->hasChildren(secondLevelIndex) == true); 0211 } 0212 } 0213 0214 // The models rowCount() is tested more extensively in checkChildren(), 0215 // but this catches the big mistakes 0216 } 0217 0218 /** 0219 * Tests model's implementation of QAbstractItemModel::columnCount() and hasChildren() 0220 */ 0221 void ModelTest::columnCount() 0222 { 0223 // check top row 0224 QModelIndex topIndex = model->index(0, 0, QModelIndex()); 0225 Q_ASSERT(model->columnCount(topIndex) >= 0); 0226 0227 // check a column count where parent is valid 0228 QModelIndex childIndex = model->index(0, 0, topIndex); 0229 0230 if (childIndex.isValid()) 0231 { 0232 Q_ASSERT(model->columnCount(childIndex) >= 0); 0233 } 0234 0235 // columnCount() is tested more extensively in checkChildren(), 0236 // but this catches the big mistakes 0237 } 0238 0239 /** 0240 * Tests model's implementation of QAbstractItemModel::hasIndex() 0241 */ 0242 void ModelTest::hasIndex() 0243 { 0244 // qCDebug(DIGIKAM_TESTS_LOG) << "hi"; 0245 // Make sure that invalid values returns an invalid index 0246 Q_ASSERT(model->hasIndex(-2, -2) == false); 0247 Q_ASSERT(model->hasIndex(-2, 0) == false); 0248 Q_ASSERT(model->hasIndex(0, -2) == false); 0249 0250 int rows = model->rowCount(); 0251 int columns = model->columnCount(); 0252 0253 // check out of bounds 0254 Q_ASSERT(model->hasIndex(rows, columns) == false); 0255 Q_ASSERT(model->hasIndex(rows + 1, columns + 1) == false); 0256 0257 if (rows > 0) 0258 { 0259 Q_ASSERT(model->hasIndex(0, 0) == true); 0260 } 0261 0262 // hasIndex() is tested more extensively in checkChildren(), 0263 // but this catches the big mistakes 0264 } 0265 0266 /** 0267 * Tests model's implementation of QAbstractItemModel::index() 0268 */ 0269 void ModelTest::index() 0270 { 0271 // qCDebug(DIGIKAM_TESTS_LOG) << "i"; 0272 // Make sure that invalid values returns an invalid index 0273 Q_ASSERT(model->index(-2, -2) == QModelIndex()); 0274 Q_ASSERT(model->index(-2, 0) == QModelIndex()); 0275 Q_ASSERT(model->index(0, -2) == QModelIndex()); 0276 0277 int rows = model->rowCount(); 0278 int columns = model->columnCount(); 0279 0280 if (rows == 0) 0281 { 0282 return; 0283 } 0284 0285 // Catch off by one errors 0286 Q_ASSERT(model->index(rows, columns) == QModelIndex()); 0287 Q_ASSERT(model->index(0, 0).isValid() == true); 0288 0289 // Make sure that the same index is *always* returned 0290 QModelIndex a = model->index(0, 0); 0291 QModelIndex b = model->index(0, 0); 0292 Q_ASSERT(a == b); 0293 0294 // index() is tested more extensively in checkChildren(), 0295 // but this catches the big mistakes 0296 } 0297 0298 /** 0299 * Tests model's implementation of QAbstractItemModel::parent() 0300 */ 0301 void ModelTest::parent() 0302 { 0303 // qCDebug(DIGIKAM_TESTS_LOG) << "p"; 0304 // Make sure the model wont crash and will return an invalid QModelIndex 0305 // when asked for the parent of an invalid index. 0306 Q_ASSERT(model->parent(QModelIndex()) == QModelIndex()); 0307 0308 if (model->rowCount() == 0) 0309 { 0310 return; 0311 } 0312 0313 // Column 0 | Column 1 | 0314 // QModelIndex() | | 0315 // \- topIndex | topIndex1 | 0316 // \- childIndex | childIndex1 | 0317 0318 // Common error test #1, make sure that a top level index has a parent 0319 // that is a invalid QModelIndex. 0320 QModelIndex topIndex = model->index(0, 0, QModelIndex()); 0321 Q_ASSERT(model->parent(topIndex) == QModelIndex()); 0322 0323 // Common error test #2, make sure that a second level index has a parent 0324 // that is the first level index. 0325 0326 if (model->rowCount(topIndex) > 0) 0327 { 0328 QModelIndex childIndex = model->index(0, 0, topIndex); 0329 Q_ASSERT(model->parent(childIndex) == topIndex); 0330 } 0331 0332 // Common error test #3, the second column should NOT have the same children 0333 // as the first column in a row. 0334 // Usually the second column shouldn't have children. 0335 QModelIndex topIndex1 = model->index(0, 1, QModelIndex()); 0336 0337 if (model->rowCount(topIndex1) > 0) 0338 { 0339 QModelIndex childIndex = model->index(0, 0, topIndex); 0340 QModelIndex childIndex1 = model->index(0, 0, topIndex1); 0341 Q_ASSERT(childIndex != childIndex1); 0342 } 0343 0344 // Full test, walk n levels deep through the model making sure that all 0345 // parent's children correctly specify their parent. 0346 checkChildren(QModelIndex()); 0347 } 0348 0349 /** 0350 * Called from the parent() test. 0351 * 0352 * A model that returns an index of parent X should also return X when asking 0353 * for the parent of the index. 0354 * 0355 * This recursive function does pretty extensive testing on the whole model in an 0356 * effort to catch edge cases. 0357 * 0358 * This function assumes that rowCount(), columnCount() and index() already work. 0359 * If they have a bug it will point it out, but the above tests should have already 0360 * found the basic bugs because it is easier to figure out the problem in 0361 * those tests then this one. 0362 */ 0363 void ModelTest::checkChildren(const QModelIndex& parent, int currentDepth) 0364 { 0365 // First just try walking back up the tree. 0366 QModelIndex p = parent; 0367 0368 while(p.isValid()) 0369 { 0370 p = p.parent(); 0371 } 0372 0373 // For models that are dynamically populated 0374 0375 if (model->canFetchMore(parent)) 0376 { 0377 fetchingMore = true; 0378 model->fetchMore(parent); 0379 fetchingMore = false; 0380 } 0381 0382 int rows = model->rowCount(parent); 0383 int columns = model->columnCount(parent); 0384 0385 if (rows > 0) 0386 { 0387 Q_ASSERT(model->hasChildren(parent)); 0388 } 0389 0390 // Some further testing against rows(), columns(), and hasChildren() 0391 Q_ASSERT(rows >= 0); 0392 Q_ASSERT(columns >= 0); 0393 0394 if (rows > 0) 0395 { 0396 Q_ASSERT(model->hasChildren(parent) == true); 0397 } 0398 0399 //qCDebug(DIGIKAM_TESTS_LOG) << "parent:" << model->data(parent).toString() << "rows:" << rows 0400 // << "columns:" << columns << "parent column:" << parent.column(); 0401 0402 Q_ASSERT(model->hasIndex(rows + 1, 0, parent) == false); 0403 0404 for (int r = 0 ; r < rows ; ++r) 0405 { 0406 if (model->canFetchMore(parent)) 0407 { 0408 fetchingMore = true; 0409 model->fetchMore(parent); 0410 fetchingMore = false; 0411 } 0412 0413 Q_ASSERT(model->hasIndex(r, columns + 1, parent) == false); 0414 0415 for (int c = 0 ; c < columns ; ++c) 0416 { 0417 Q_ASSERT(model->hasIndex(r, c, parent) == true); 0418 QModelIndex index = model->index(r, c, parent); 0419 // rowCount() and columnCount() said that it existed... 0420 Q_ASSERT(index.isValid() == true); 0421 0422 // index() should always return the same index when called twice in a row 0423 QModelIndex modifiedIndex = model->index(r, c, parent); 0424 Q_ASSERT(index == modifiedIndex); 0425 0426 // Make sure we get the same index if we request it twice in a row 0427 QModelIndex a = model->index(r, c, parent); 0428 QModelIndex b = model->index(r, c, parent); 0429 Q_ASSERT(a == b); 0430 0431 // Some basic checking on the index that is returned 0432 Q_ASSERT(index.model() == model); 0433 Q_ASSERT(index.row() == r); 0434 Q_ASSERT(index.column() == c); 0435 // While you can technically return a QVariant usually this is a sign 0436 // of an bug in data() Disable if this really is ok in your model. 0437 // Q_ASSERT(model->data(index, Qt::DisplayRole).isValid() == true); 0438 0439 // If the next test fails here is some somewhat useful debug you play with. 0440 0441 if (model->parent(index) != parent) 0442 { 0443 qCDebug(DIGIKAM_TESTS_LOG) << r << c << currentDepth << model->data(index).toString() 0444 << model->data(parent).toString(); 0445 0446 qCDebug(DIGIKAM_TESTS_LOG) << index << parent << model->parent(index); 0447 // And a view that you can even use to show the model. 0448 // QTreeView view; 0449 // view.setModel(model); 0450 // view.show(); 0451 } 0452 0453 // Check that we can get back our real parent. 0454 // qCDebug(DIGIKAM_TESTS_LOG) << model->parent(index) << parent ; 0455 Q_ASSERT(model->parent(index) == parent); 0456 0457 // recursively go down the children 0458 if (model->hasChildren(index) && currentDepth < 10) 0459 { 0460 //qCDebug(DIGIKAM_TESTS_LOG) << r << c << "has children" << model->rowCount(index); 0461 checkChildren(index, ++currentDepth); 0462 } 0463 /* 0464 * else { if (currentDepth >= 10) qCDebug(DIGIKAM_TESTS_LOG) << "checked 10 deep"; }; 0465 */ 0466 0467 // make sure that after testing the children that the index doesn't change. 0468 QModelIndex newerIndex = model->index(r, c, parent); 0469 Q_ASSERT(index == newerIndex); 0470 } 0471 } 0472 } 0473 0474 /** 0475 * Tests model's implementation of QAbstractItemModel::data() 0476 */ 0477 void ModelTest::data() 0478 { 0479 // Invalid index should return an invalid qvariant 0480 Q_ASSERT(!model->data(QModelIndex()).isValid()); 0481 0482 if (model->rowCount() == 0) 0483 { 0484 return; 0485 } 0486 0487 // A valid index should have a valid QVariant data 0488 Q_ASSERT(model->index(0, 0).isValid()); 0489 0490 // shouldn't be able to set data on an invalid index 0491 Q_ASSERT(model->setData(QModelIndex(), QLatin1String("foo"), Qt::DisplayRole) == false); 0492 0493 // General Purpose roles that should return a QString 0494 QVariant variant = model->data(model->index(0, 0), Qt::ToolTipRole); 0495 0496 if (variant.isValid()) 0497 { 0498 0499 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) 0500 0501 Q_ASSERT(variant.canConvert(QMetaType(QMetaType::QString))); 0502 0503 #else 0504 0505 Q_ASSERT(variant.canConvert(QMetaType::QString)); 0506 0507 #endif 0508 0509 } 0510 0511 variant = model->data(model->index(0, 0), Qt::StatusTipRole); 0512 0513 if (variant.isValid()) 0514 { 0515 0516 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) 0517 0518 Q_ASSERT(variant.canConvert(QMetaType(QMetaType::QString))); 0519 0520 #else 0521 0522 Q_ASSERT(variant.canConvert(QMetaType::QString)); 0523 0524 #endif 0525 0526 } 0527 0528 variant = model->data(model->index(0, 0), Qt::WhatsThisRole); 0529 0530 if (variant.isValid()) 0531 { 0532 0533 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) 0534 0535 Q_ASSERT(variant.canConvert(QMetaType(QMetaType::QString))); 0536 0537 #else 0538 0539 Q_ASSERT(variant.canConvert(QMetaType::QString)); 0540 0541 #endif 0542 0543 } 0544 0545 // General Purpose roles that should return a QSize 0546 variant = model->data(model->index(0, 0), Qt::SizeHintRole); 0547 0548 if (variant.isValid()) 0549 { 0550 0551 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) 0552 0553 Q_ASSERT(variant.canConvert(QMetaType(QMetaType::QSize))); 0554 0555 #else 0556 0557 Q_ASSERT(variant.canConvert(QMetaType::QSize)); 0558 0559 #endif 0560 0561 } 0562 0563 // General Purpose roles that should return a QFont 0564 QVariant fontVariant = model->data(model->index(0, 0), Qt::FontRole); 0565 0566 if (fontVariant.isValid()) 0567 { 0568 0569 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) 0570 0571 Q_ASSERT(fontVariant.canConvert(QMetaType(QMetaType::QFont))); 0572 0573 #else 0574 0575 Q_ASSERT(fontVariant.canConvert(QMetaType::QFont)); 0576 0577 #endif 0578 0579 } 0580 0581 // Check that the alignment is one we know about 0582 QVariant textAlignmentVariant = model->data(model->index(0, 0), Qt::TextAlignmentRole); 0583 0584 if (textAlignmentVariant.isValid()) 0585 { 0586 unsigned int alignment = textAlignmentVariant.toInt(); 0587 Q_ASSERT(alignment ==(alignment &(Qt::AlignHorizontal_Mask | Qt::AlignVertical_Mask))); 0588 } 0589 0590 // General Purpose roles that should return a QColor 0591 QVariant colorVariant = model->data(model->index(0, 0), Qt::BackgroundRole); 0592 0593 if (colorVariant.isValid()) 0594 { 0595 0596 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) 0597 0598 Q_ASSERT(colorVariant.canConvert(QMetaType(QMetaType::QColor))); 0599 0600 #else 0601 0602 Q_ASSERT(colorVariant.canConvert(QMetaType::QColor)); 0603 0604 #endif 0605 0606 } 0607 0608 colorVariant = model->data(model->index(0, 0), Qt::ForegroundRole); 0609 0610 if (colorVariant.isValid()) 0611 { 0612 0613 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) 0614 0615 Q_ASSERT(colorVariant.canConvert(QMetaType(QMetaType::QColor))); 0616 0617 #else 0618 0619 Q_ASSERT(colorVariant.canConvert(QMetaType::QColor)); 0620 0621 #endif 0622 0623 } 0624 0625 // Check that the "check state" is one we know about. 0626 QVariant checkStateVariant = model->data(model->index(0, 0), Qt::CheckStateRole); 0627 0628 if (checkStateVariant.isValid()) 0629 { 0630 int state = checkStateVariant.toInt(); 0631 Q_ASSERT(state == Qt::Unchecked || 0632 state == Qt::PartiallyChecked || 0633 state == Qt::Checked); 0634 } 0635 } 0636 0637 /** 0638 * Store what is about to be inserted to make sure it actually happens 0639 * 0640 * \sa rowsInserted() 0641 */ 0642 void ModelTest::rowsAboutToBeInserted(const QModelIndex& parent, int start, int end) 0643 { 0644 Q_UNUSED(end); 0645 // qCDebug(DIGIKAM_TESTS_LOG) << "rowsAboutToBeInserted" << "start=" << start << "end=" << end << "parent=" << model->data(parent).toString() 0646 // << "current count of parent=" << model->rowCount(parent); // << "display of last=" << model->data( model->index(start-1, 0, parent)); 0647 // qCDebug(DIGIKAM_TESTS_LOG) << model->index(start-1, 0, parent) << model->data( model->index(start-1, 0, parent)); 0648 Changing c; 0649 c.parent = parent; 0650 c.oldSize = model->rowCount(parent); 0651 c.last = model->data(model->index(start - 1, 0, parent)); 0652 c.next = model->data(model->index(start, 0, parent)); 0653 insert.push(c); 0654 } 0655 0656 /** 0657 * Confirm that what was said was going to happen actually did 0658 * 0659 * \sa rowsAboutToBeInserted() 0660 */ 0661 void ModelTest::rowsInserted(const QModelIndex& parent, int start, int end) 0662 { 0663 Changing c = insert.pop(); 0664 Q_ASSERT(c.parent == parent); 0665 // qCDebug(DIGIKAM_TESTS_LOG) << "rowsInserted" << "start=" << start << "end=" << end << "oldsize=" << c.oldSize 0666 // << "parent=" << model->data(parent).toString() << "current rowcount of parent=" << model->rowCount(parent); 0667 0668 // for (int ii=start; ii <= end; ii++) 0669 // { 0670 // qCDebug(DIGIKAM_TESTS_LOG) << "itemWasInserted:" << ii << model->data(model->index(ii, 0, parent)); 0671 // } 0672 // qCDebug(DIGIKAM_TESTS_LOG); 0673 0674 Q_ASSERT(c.oldSize +(end - start + 1) == model->rowCount(parent)); 0675 Q_ASSERT(c.last == model->data(model->index(start - 1, 0, c.parent))); 0676 0677 if (c.next != model->data(model->index(end + 1, 0, c.parent))) 0678 { 0679 qCDebug(DIGIKAM_TESTS_LOG) << start << end; 0680 0681 for (int i = 0 ; i < model->rowCount() ; ++i) 0682 { 0683 qCDebug(DIGIKAM_TESTS_LOG) << model->index(i, 0).data().toString(); 0684 } 0685 0686 qCDebug(DIGIKAM_TESTS_LOG) << c.next << model->data(model->index(end + 1, 0, c.parent)); 0687 } 0688 0689 Q_ASSERT(c.next == model->data(model->index(end + 1, 0, c.parent))); 0690 } 0691 0692 void ModelTest::layoutAboutToBeChanged() 0693 { 0694 for (int i = 0 ; i < qBound(0, model->rowCount(), 100) ; ++i) 0695 { 0696 changing.append(QPersistentModelIndex(model->index(i, 0))); 0697 } 0698 } 0699 0700 void ModelTest::layoutChanged() 0701 { 0702 for (int i = 0 ; i < changing.count() ; ++i) 0703 { 0704 QPersistentModelIndex p = changing[i]; 0705 Q_ASSERT(p == model->index(p.row(), p.column(), p.parent())); 0706 } 0707 0708 changing.clear(); 0709 } 0710 0711 /** 0712 * Store what is about to be inserted to make sure it actually happens 0713 * 0714 * \sa rowsRemoved() 0715 */ 0716 void ModelTest::rowsAboutToBeRemoved(const QModelIndex& parent, int start, int end) 0717 { 0718 qCDebug(DIGIKAM_TESTS_LOG) << "ratbr" << parent << start << end; 0719 Changing c; 0720 c.parent = parent; 0721 c.oldSize = model->rowCount(parent); 0722 c.last = model->data(model->index(start - 1, 0, parent)); 0723 c.next = model->data(model->index(end + 1, 0, parent)); 0724 remove.push(c); 0725 } 0726 0727 /** 0728 * Confirm that what was said was going to happen actually did 0729 * 0730 * \sa rowsAboutToBeRemoved() 0731 */ 0732 void ModelTest::rowsRemoved(const QModelIndex& parent, int start, int end) 0733 { 0734 qCDebug(DIGIKAM_TESTS_LOG) << "rr" << parent << start << end; 0735 Changing c = remove.pop(); 0736 Q_ASSERT(c.parent == parent); 0737 Q_ASSERT(c.oldSize -(end - start + 1) == model->rowCount(parent)); 0738 Q_ASSERT(c.last == model->data(model->index(start - 1, 0, c.parent))); 0739 Q_ASSERT(c.next == model->data(model->index(start, 0, c.parent))); 0740 } 0741 0742 #include "moc_modeltest.cpp"