File indexing completed on 2024-05-05 05:47:26
0001 /**************************************************************************** 0002 ** 0003 ** Copyright (C) 2010 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 ** No Commercial Usage 0011 ** This file contains pre-release code and may not be distributed. 0012 ** You may use this file in accordance with the terms and conditions 0013 ** contained in the Technology Preview License Agreement accompanying 0014 ** this package. 0015 ** 0016 ** GNU Lesser General Public License Usage 0017 ** Alternatively, this file may be used under the terms of the GNU Lesser 0018 ** General Public License version 2.1 as published by the Free Software 0019 ** Foundation and appearing in the file LICENSE.LGPL included in the 0020 ** packaging of this file. Please review the following information to 0021 ** ensure the GNU Lesser General Public License version 2.1 requirements 0022 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 0023 ** 0024 ** In addition, as a special exception, Nokia gives you certain additional 0025 ** rights. These rights are described in the Nokia Qt LGPL Exception 0026 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 0027 ** 0028 ** If you have questions regarding the use of this file, please contact 0029 ** Nokia at qt-info@nokia.com. 0030 ** 0031 ** 0032 ** 0033 ** 0034 ** 0035 ** 0036 ** 0037 ** 0038 ** $QT_END_LICENSE$ 0039 ** 0040 ****************************************************************************/ 0041 0042 0043 #include "modeltest.h" 0044 0045 #include <QtTest/QtTest> 0046 #undef Q_ASSERT 0047 #define Q_ASSERT QVERIFY 0048 0049 Q_DECLARE_METATYPE ( QModelIndex ) 0050 0051 /*! 0052 Connect to all of the models signals. Whenever anything happens recheck everything. 0053 */ 0054 ModelTest::ModelTest ( QAbstractItemModel *_model, QObject *parent ) : QObject ( parent ), model ( _model ), fetchingMore ( false ) 0055 { 0056 Q_ASSERT ( model ); 0057 0058 connect ( model, SIGNAL ( columnsAboutToBeInserted ( const QModelIndex &, int, int ) ), 0059 this, SLOT ( runAllTests() ) ); 0060 connect ( model, SIGNAL ( columnsAboutToBeRemoved ( const QModelIndex &, int, int ) ), 0061 this, SLOT ( runAllTests() ) ); 0062 connect ( model, SIGNAL ( columnsInserted ( const QModelIndex &, int, int ) ), 0063 this, SLOT ( runAllTests() ) ); 0064 connect ( model, SIGNAL ( columnsRemoved ( const QModelIndex &, int, int ) ), 0065 this, SLOT ( runAllTests() ) ); 0066 connect ( model, SIGNAL ( dataChanged ( const QModelIndex &, const QModelIndex & ) ), 0067 this, SLOT ( runAllTests() ) ); 0068 connect ( model, SIGNAL ( headerDataChanged ( Qt::Orientation, int, int ) ), 0069 this, SLOT ( runAllTests() ) ); 0070 connect ( model, SIGNAL ( layoutAboutToBeChanged () ), this, SLOT ( runAllTests() ) ); 0071 connect ( model, SIGNAL ( layoutChanged () ), this, SLOT ( runAllTests() ) ); 0072 connect ( model, SIGNAL ( modelReset () ), this, SLOT ( runAllTests() ) ); 0073 connect ( model, SIGNAL ( rowsAboutToBeInserted ( const QModelIndex &, int, int ) ), 0074 this, SLOT ( runAllTests() ) ); 0075 connect ( model, SIGNAL ( rowsAboutToBeRemoved ( const QModelIndex &, int, int ) ), 0076 this, SLOT ( runAllTests() ) ); 0077 connect ( model, SIGNAL ( rowsInserted ( const QModelIndex &, int, int ) ), 0078 this, SLOT ( runAllTests() ) ); 0079 connect ( model, SIGNAL ( rowsRemoved ( const QModelIndex &, int, int ) ), 0080 this, SLOT ( runAllTests() ) ); 0081 0082 // Special checks for inserting/removing 0083 connect ( model, SIGNAL ( layoutAboutToBeChanged() ), 0084 this, SLOT ( layoutAboutToBeChanged() ) ); 0085 connect ( model, SIGNAL ( layoutChanged() ), 0086 this, SLOT ( layoutChanged() ) ); 0087 0088 connect ( model, SIGNAL ( rowsAboutToBeInserted ( const QModelIndex &, int, int ) ), 0089 this, SLOT ( rowsAboutToBeInserted ( const QModelIndex &, int, int ) ) ); 0090 connect ( model, SIGNAL ( rowsAboutToBeRemoved ( const QModelIndex &, int, int ) ), 0091 this, SLOT ( rowsAboutToBeRemoved ( const QModelIndex &, int, int ) ) ); 0092 connect ( model, SIGNAL ( rowsInserted ( const QModelIndex &, int, int ) ), 0093 this, SLOT ( rowsInserted ( const QModelIndex &, int, int ) ) ); 0094 connect ( model, SIGNAL ( rowsRemoved ( const QModelIndex &, int, int ) ), 0095 this, SLOT ( rowsRemoved ( const QModelIndex &, int, int ) ) ); 0096 0097 runAllTests(); 0098 } 0099 0100 void ModelTest::runAllTests() 0101 { 0102 if ( fetchingMore ) 0103 return; 0104 nonDestructiveBasicTest(); 0105 rowCount(); 0106 columnCount(); 0107 hasIndex(); 0108 index(); 0109 parent(); 0110 data(); 0111 } 0112 0113 /*! 0114 nonDestructiveBasicTest tries to call a number of the basic functions (not all) 0115 to make sure the model doesn't outright segfault, testing the functions that makes sense. 0116 */ 0117 void ModelTest::nonDestructiveBasicTest() 0118 { 0119 Q_ASSERT ( model->buddy ( QModelIndex() ) == QModelIndex() ); 0120 model->canFetchMore ( QModelIndex() ); 0121 Q_ASSERT ( model->columnCount ( QModelIndex() ) >= 0 ); 0122 Q_ASSERT ( model->data ( QModelIndex() ) == QVariant() ); 0123 fetchingMore = true; 0124 model->fetchMore ( QModelIndex() ); 0125 fetchingMore = false; 0126 Qt::ItemFlags flags = model->flags ( QModelIndex() ); 0127 Q_ASSERT ( flags == Qt::ItemIsDropEnabled || flags == 0 ); 0128 model->hasChildren ( QModelIndex() ); 0129 model->hasIndex ( 0, 0 ); 0130 model->headerData ( 0, Qt::Horizontal ); 0131 model->index ( 0, 0 ); 0132 model->itemData ( QModelIndex() ); 0133 QVariant cache; 0134 model->match ( QModelIndex(), -1, cache ); 0135 model->mimeTypes(); 0136 Q_ASSERT ( model->parent ( QModelIndex() ) == QModelIndex() ); 0137 Q_ASSERT ( model->rowCount() >= 0 ); 0138 QVariant variant; 0139 model->setData ( QModelIndex(), variant, -1 ); 0140 model->setHeaderData ( -1, Qt::Horizontal, QVariant() ); 0141 model->setHeaderData ( 999999, Qt::Horizontal, QVariant() ); 0142 QMap<int, QVariant> roles; 0143 model->sibling ( 0, 0, QModelIndex() ); 0144 model->span ( QModelIndex() ); 0145 model->supportedDropActions(); 0146 } 0147 0148 /*! 0149 Tests model's implementation of QAbstractItemModel::rowCount() and hasChildren() 0150 0151 Models that are dynamically populated are not as fully tested here. 0152 */ 0153 void ModelTest::rowCount() 0154 { 0155 // qDebug() << "rc"; 0156 // check top row 0157 QModelIndex topIndex = model->index ( 0, 0, QModelIndex() ); 0158 int rows = model->rowCount ( topIndex ); 0159 Q_ASSERT ( rows >= 0 ); 0160 if ( rows > 0 ) 0161 Q_ASSERT ( model->hasChildren ( topIndex ) == true ); 0162 0163 QModelIndex secondLevelIndex = model->index ( 0, 0, topIndex ); 0164 if ( secondLevelIndex.isValid() ) { // not the top level 0165 // check a row count where parent is valid 0166 rows = model->rowCount ( secondLevelIndex ); 0167 Q_ASSERT ( rows >= 0 ); 0168 if ( rows > 0 ) 0169 Q_ASSERT ( model->hasChildren ( secondLevelIndex ) == true ); 0170 } 0171 0172 // The models rowCount() is tested more extensively in checkChildren(), 0173 // but this catches the big mistakes 0174 } 0175 0176 /*! 0177 Tests model's implementation of QAbstractItemModel::columnCount() and hasChildren() 0178 */ 0179 void ModelTest::columnCount() 0180 { 0181 // check top row 0182 QModelIndex topIndex = model->index ( 0, 0, QModelIndex() ); 0183 Q_ASSERT ( model->columnCount ( topIndex ) >= 0 ); 0184 0185 // check a column count where parent is valid 0186 QModelIndex childIndex = model->index ( 0, 0, topIndex ); 0187 if ( childIndex.isValid() ) 0188 Q_ASSERT ( model->columnCount ( childIndex ) >= 0 ); 0189 0190 // columnCount() is tested more extensively in checkChildren(), 0191 // but this catches the big mistakes 0192 } 0193 0194 /*! 0195 Tests model's implementation of QAbstractItemModel::hasIndex() 0196 */ 0197 void ModelTest::hasIndex() 0198 { 0199 // qDebug() << "hi"; 0200 // Make sure that invalid values returns an invalid index 0201 Q_ASSERT ( model->hasIndex ( -2, -2 ) == false ); 0202 Q_ASSERT ( model->hasIndex ( -2, 0 ) == false ); 0203 Q_ASSERT ( model->hasIndex ( 0, -2 ) == false ); 0204 0205 int rows = model->rowCount(); 0206 int columns = model->columnCount(); 0207 0208 // check out of bounds 0209 Q_ASSERT ( model->hasIndex ( rows, columns ) == false ); 0210 Q_ASSERT ( model->hasIndex ( rows + 1, columns + 1 ) == false ); 0211 0212 if ( rows > 0 ) 0213 Q_ASSERT ( model->hasIndex ( 0, 0 ) == true ); 0214 0215 // hasIndex() is tested more extensively in checkChildren(), 0216 // but this catches the big mistakes 0217 } 0218 0219 /*! 0220 Tests model's implementation of QAbstractItemModel::index() 0221 */ 0222 void ModelTest::index() 0223 { 0224 // qDebug() << "i"; 0225 // Make sure that invalid values returns an invalid index 0226 Q_ASSERT ( model->index ( -2, -2 ) == QModelIndex() ); 0227 Q_ASSERT ( model->index ( -2, 0 ) == QModelIndex() ); 0228 Q_ASSERT ( model->index ( 0, -2 ) == QModelIndex() ); 0229 0230 int rows = model->rowCount(); 0231 int columns = model->columnCount(); 0232 0233 if ( rows == 0 ) 0234 return; 0235 0236 // Catch off by one errors 0237 Q_ASSERT ( model->index ( rows, columns ) == QModelIndex() ); 0238 Q_ASSERT ( model->index ( 0, 0 ).isValid() == true ); 0239 0240 // Make sure that the same index is *always* returned 0241 QModelIndex a = model->index ( 0, 0 ); 0242 QModelIndex b = model->index ( 0, 0 ); 0243 Q_ASSERT ( a == b ); 0244 0245 // index() is tested more extensively in checkChildren(), 0246 // but this catches the big mistakes 0247 } 0248 0249 /*! 0250 Tests model's implementation of QAbstractItemModel::parent() 0251 */ 0252 void ModelTest::parent() 0253 { 0254 // qDebug() << "p"; 0255 // Make sure the model wont crash and will return an invalid QModelIndex 0256 // when asked for the parent of an invalid index. 0257 Q_ASSERT ( model->parent ( QModelIndex() ) == QModelIndex() ); 0258 0259 if ( model->rowCount() == 0 ) 0260 return; 0261 0262 // Column 0 | Column 1 | 0263 // QModelIndex() | | 0264 // \- topIndex | topIndex1 | 0265 // \- childIndex | childIndex1 | 0266 0267 // Common error test #1, make sure that a top level index has a parent 0268 // that is a invalid QModelIndex. 0269 QModelIndex topIndex = model->index ( 0, 0, QModelIndex() ); 0270 Q_ASSERT ( model->parent ( topIndex ) == QModelIndex() ); 0271 0272 // Common error test #2, make sure that a second level index has a parent 0273 // that is the first level index. 0274 if ( model->rowCount ( topIndex ) > 0 ) { 0275 QModelIndex childIndex = model->index ( 0, 0, topIndex ); 0276 Q_ASSERT ( model->parent ( childIndex ) == topIndex ); 0277 } 0278 0279 // Common error test #3, the second column should NOT have the same children 0280 // as the first column in a row. 0281 // Usually the second column shouldn't have children. 0282 QModelIndex topIndex1 = model->index ( 0, 1, QModelIndex() ); 0283 if ( model->rowCount ( topIndex1 ) > 0 ) { 0284 QModelIndex childIndex = model->index ( 0, 0, topIndex ); 0285 QModelIndex childIndex1 = model->index ( 0, 0, topIndex1 ); 0286 Q_ASSERT ( childIndex != childIndex1 ); 0287 } 0288 0289 // Full test, walk n levels deep through the model making sure that all 0290 // parent's children correctly specify their parent. 0291 checkChildren ( QModelIndex() ); 0292 } 0293 0294 /*! 0295 Called from the parent() test. 0296 0297 A model that returns an index of parent X should also return X when asking 0298 for the parent of the index. 0299 0300 This recursive function does pretty extensive testing on the whole model in an 0301 effort to catch edge cases. 0302 0303 This function assumes that rowCount(), columnCount() and index() already work. 0304 If they have a bug it will point it out, but the above tests should have already 0305 found the basic bugs because it is easier to figure out the problem in 0306 those tests then this one. 0307 */ 0308 void ModelTest::checkChildren ( const QModelIndex &parent, int currentDepth ) 0309 { 0310 // First just try walking back up the tree. 0311 QModelIndex p = parent; 0312 while ( p.isValid() ) 0313 p = p.parent(); 0314 0315 // For models that are dynamically populated 0316 if ( model->canFetchMore ( parent ) ) { 0317 fetchingMore = true; 0318 model->fetchMore ( parent ); 0319 fetchingMore = false; 0320 } 0321 0322 int rows = model->rowCount ( parent ); 0323 int columns = model->columnCount ( parent ); 0324 0325 if ( rows > 0 ) 0326 Q_ASSERT ( model->hasChildren ( parent ) ); 0327 0328 // Some further testing against rows(), columns(), and hasChildren() 0329 Q_ASSERT ( rows >= 0 ); 0330 Q_ASSERT ( columns >= 0 ); 0331 if ( rows > 0 ) 0332 Q_ASSERT ( model->hasChildren ( parent ) == true ); 0333 0334 //qDebug() << "parent:" << model->data(parent).toString() << "rows:" << rows 0335 // << "columns:" << columns << "parent column:" << parent.column(); 0336 0337 Q_ASSERT ( model->hasIndex ( rows + 1, 0, parent ) == false ); 0338 for ( int r = 0; r < rows; ++r ) { 0339 if ( model->canFetchMore ( parent ) ) { 0340 fetchingMore = true; 0341 model->fetchMore ( parent ); 0342 fetchingMore = false; 0343 } 0344 Q_ASSERT ( model->hasIndex ( r, columns + 1, parent ) == false ); 0345 for ( int c = 0; c < columns; ++c ) { 0346 Q_ASSERT ( model->hasIndex ( r, c, parent ) == true ); 0347 QModelIndex index = model->index ( r, c, parent ); 0348 // rowCount() and columnCount() said that it existed... 0349 Q_ASSERT ( index.isValid() == true ); 0350 0351 // index() should always return the same index when called twice in a row 0352 QModelIndex modifiedIndex = model->index ( r, c, parent ); 0353 Q_ASSERT ( index == modifiedIndex ); 0354 0355 // Make sure we get the same index if we request it twice in a row 0356 QModelIndex a = model->index ( r, c, parent ); 0357 QModelIndex b = model->index ( r, c, parent ); 0358 Q_ASSERT ( a == b ); 0359 0360 // Some basic checking on the index that is returned 0361 Q_ASSERT ( index.model() == model ); 0362 Q_ASSERT ( index.row() == r ); 0363 Q_ASSERT ( index.column() == c ); 0364 // While you can technically return a QVariant usually this is a sign 0365 // of an bug in data() Disable if this really is ok in your model. 0366 // Q_ASSERT ( model->data ( index, Qt::DisplayRole ).isValid() == true ); 0367 0368 // If the next test fails here is some somewhat useful debug you play with. 0369 0370 if (model->parent(index) != parent) { 0371 qDebug() << r << c << currentDepth << model->data(index).toString() 0372 << model->data(parent).toString(); 0373 qDebug() << index << parent << model->parent(index); 0374 // And a view that you can even use to show the model. 0375 // QTreeView view; 0376 // view.setModel(model); 0377 // view.show(); 0378 } 0379 0380 // Check that we can get back our real parent. 0381 // qDebug() << model->parent ( index ) << parent ; 0382 Q_ASSERT ( model->parent ( index ) == parent ); 0383 0384 // recursively go down the children 0385 if ( model->hasChildren ( index ) && currentDepth < 10 ) { 0386 //qDebug() << r << c << "has children" << model->rowCount(index); 0387 checkChildren ( index, ++currentDepth ); 0388 }/* else { if (currentDepth >= 10) qDebug() << "checked 10 deep"; };*/ 0389 0390 // make sure that after testing the children that the index doesn't change. 0391 QModelIndex newerIndex = model->index ( r, c, parent ); 0392 Q_ASSERT ( index == newerIndex ); 0393 } 0394 } 0395 } 0396 0397 /*! 0398 Tests model's implementation of QAbstractItemModel::data() 0399 */ 0400 void ModelTest::data() 0401 { 0402 // Invalid index should return an invalid qvariant 0403 Q_ASSERT ( !model->data ( QModelIndex() ).isValid() ); 0404 0405 if ( model->rowCount() == 0 ) 0406 return; 0407 0408 // A valid index should have a valid QVariant data 0409 Q_ASSERT ( model->index ( 0, 0 ).isValid() ); 0410 0411 // shouldn't be able to set data on an invalid index 0412 Q_ASSERT ( model->setData ( QModelIndex(), QLatin1String ( "foo" ), Qt::DisplayRole ) == false ); 0413 0414 // General Purpose roles that should return a QString 0415 QVariant variant = model->data ( model->index ( 0, 0 ), Qt::ToolTipRole ); 0416 if ( variant.isValid() ) { 0417 Q_ASSERT ( variant.canConvert<QString>() ); 0418 } 0419 variant = model->data ( model->index ( 0, 0 ), Qt::StatusTipRole ); 0420 if ( variant.isValid() ) { 0421 Q_ASSERT ( variant.canConvert<QString>() ); 0422 } 0423 variant = model->data ( model->index ( 0, 0 ), Qt::WhatsThisRole ); 0424 if ( variant.isValid() ) { 0425 Q_ASSERT ( variant.canConvert<QString>() ); 0426 } 0427 0428 // General Purpose roles that should return a QSize 0429 variant = model->data ( model->index ( 0, 0 ), Qt::SizeHintRole ); 0430 if ( variant.isValid() ) { 0431 Q_ASSERT ( variant.canConvert<QSize>() ); 0432 } 0433 0434 // General Purpose roles that should return a QFont 0435 QVariant fontVariant = model->data ( model->index ( 0, 0 ), Qt::FontRole ); 0436 if ( fontVariant.isValid() ) { 0437 Q_ASSERT ( fontVariant.canConvert<QFont>() ); 0438 } 0439 0440 // Check that the alignment is one we know about 0441 QVariant textAlignmentVariant = model->data ( model->index ( 0, 0 ), Qt::TextAlignmentRole ); 0442 if ( textAlignmentVariant.isValid() ) { 0443 int alignment = textAlignmentVariant.toInt(); 0444 Q_ASSERT ( alignment == ( alignment & ( Qt::AlignHorizontal_Mask | Qt::AlignVertical_Mask ) ) ); 0445 } 0446 0447 // General Purpose roles that should return a QColor 0448 QVariant colorVariant = model->data ( model->index ( 0, 0 ), Qt::BackgroundColorRole ); 0449 if ( colorVariant.isValid() ) { 0450 Q_ASSERT ( colorVariant.canConvert<QColor>() ); 0451 } 0452 0453 colorVariant = model->data ( model->index ( 0, 0 ), Qt::TextColorRole ); 0454 if ( colorVariant.isValid() ) { 0455 Q_ASSERT ( colorVariant.canConvert<QColor>() ); 0456 } 0457 0458 // Check that the "check state" is one we know about. 0459 QVariant checkStateVariant = model->data ( model->index ( 0, 0 ), Qt::CheckStateRole ); 0460 if ( checkStateVariant.isValid() ) { 0461 int state = checkStateVariant.toInt(); 0462 Q_ASSERT ( state == Qt::Unchecked || 0463 state == Qt::PartiallyChecked || 0464 state == Qt::Checked ); 0465 } 0466 } 0467 0468 /*! 0469 Store what is about to be inserted to make sure it actually happens 0470 0471 \sa rowsInserted() 0472 */ 0473 void ModelTest::rowsAboutToBeInserted ( const QModelIndex &parent, int start, int end ) 0474 { 0475 Q_UNUSED(end); 0476 0477 // qDebug() << "rowsAboutToBeInserted" << "start=" << start << "end=" << end << "parent=" << model->data ( parent ).toString() 0478 // << "current count of parent=" << model->rowCount ( parent ); // << "display of last=" << model->data( model->index(start-1, 0, parent) ); 0479 // qDebug() << model->index(start-1, 0, parent) << model->data( model->index(start-1, 0, parent) ); 0480 Changing c; 0481 c.parent = parent; 0482 c.oldSize = model->rowCount ( parent ); 0483 c.last = model->data ( model->index ( start - 1, 0, parent ) ); 0484 c.next = model->data ( model->index ( start, 0, parent ) ); 0485 insert.push ( c ); 0486 } 0487 0488 /*! 0489 Confirm that what was said was going to happen actually did 0490 0491 \sa rowsAboutToBeInserted() 0492 */ 0493 void ModelTest::rowsInserted ( const QModelIndex & parent, int start, int end ) 0494 { 0495 Changing c = insert.pop(); 0496 Q_ASSERT ( c.parent == parent ); 0497 // qDebug() << "rowsInserted" << "start=" << start << "end=" << end << "oldsize=" << c.oldSize 0498 // << "parent=" << model->data ( parent ).toString() << "current rowcount of parent=" << model->rowCount ( parent ); 0499 0500 // for (int ii=start; ii <= end; ii++) 0501 // { 0502 // qDebug() << "itemWasInserted:" << ii << model->data ( model->index ( ii, 0, parent )); 0503 // } 0504 // qDebug(); 0505 0506 Q_ASSERT ( c.oldSize + ( end - start + 1 ) == model->rowCount ( parent ) ); 0507 Q_ASSERT ( c.last == model->data ( model->index ( start - 1, 0, c.parent ) ) ); 0508 0509 if (c.next != model->data(model->index(end + 1, 0, c.parent))) { 0510 qDebug() << start << end; 0511 for (int i=0; i < model->rowCount(); ++i) 0512 qDebug() << model->index(i, 0).data().toString(); 0513 qDebug() << c.next << model->data(model->index(end + 1, 0, c.parent)); 0514 } 0515 0516 Q_ASSERT ( c.next == model->data ( model->index ( end + 1, 0, c.parent ) ) ); 0517 } 0518 0519 void ModelTest::layoutAboutToBeChanged() 0520 { 0521 for ( int i = 0; i < qBound ( 0, model->rowCount(), 100 ); ++i ) 0522 changing.append ( QPersistentModelIndex ( model->index ( i, 0 ) ) ); 0523 } 0524 0525 void ModelTest::layoutChanged() 0526 { 0527 for ( int i = 0; i < changing.count(); ++i ) { 0528 QPersistentModelIndex p = changing[i]; 0529 Q_ASSERT ( p == model->index ( p.row(), p.column(), p.parent() ) ); 0530 } 0531 changing.clear(); 0532 } 0533 0534 /*! 0535 Store what is about to be inserted to make sure it actually happens 0536 0537 \sa rowsRemoved() 0538 */ 0539 void ModelTest::rowsAboutToBeRemoved ( const QModelIndex &parent, int start, int end ) 0540 { 0541 qDebug() << "ratbr" << parent << start << end; 0542 Changing c; 0543 c.parent = parent; 0544 c.oldSize = model->rowCount ( parent ); 0545 c.last = model->data ( model->index ( start - 1, 0, parent ) ); 0546 c.next = model->data ( model->index ( end + 1, 0, parent ) ); 0547 remove.push ( c ); 0548 } 0549 0550 /*! 0551 Confirm that what was said was going to happen actually did 0552 0553 \sa rowsAboutToBeRemoved() 0554 */ 0555 void ModelTest::rowsRemoved ( const QModelIndex & parent, int start, int end ) 0556 { 0557 qDebug() << "rr" << parent << start << end; 0558 Changing c = remove.pop(); 0559 Q_ASSERT ( c.parent == parent ); 0560 Q_ASSERT ( c.oldSize - ( end - start + 1 ) == model->rowCount ( parent ) ); 0561 Q_ASSERT ( c.last == model->data ( model->index ( start - 1, 0, c.parent ) ) ); 0562 Q_ASSERT ( c.next == model->data ( model->index ( start, 0, c.parent ) ) ); 0563 } 0564 0565 #include "moc_modeltest.cpp"