tests/auto/modeltest/modeltest.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the test suite of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 
       
    43 #include <QtGui/QtGui>
       
    44 
       
    45 #include "modeltest.h"
       
    46 
       
    47 #include <QtTest/QtTest>
       
    48 #undef Q_ASSERT
       
    49 #define Q_ASSERT  QVERIFY
       
    50 
       
    51 Q_DECLARE_METATYPE ( QModelIndex )
       
    52 
       
    53 /*!
       
    54     Connect to all of the models signals.  Whenever anything happens recheck everything.
       
    55 */
       
    56 ModelTest::ModelTest ( QAbstractItemModel *_model, QObject *parent ) : QObject ( parent ), model ( _model ), fetchingMore ( false )
       
    57 {
       
    58     Q_ASSERT ( model );
       
    59 
       
    60     connect ( model, SIGNAL ( columnsAboutToBeInserted ( const QModelIndex &, int, int ) ),
       
    61               this, SLOT ( runAllTests() ) );
       
    62     connect ( model, SIGNAL ( columnsAboutToBeRemoved ( const QModelIndex &, int, int ) ),
       
    63               this, SLOT ( runAllTests() ) );
       
    64     connect ( model, SIGNAL ( columnsInserted ( const QModelIndex &, int, int ) ),
       
    65               this, SLOT ( runAllTests() ) );
       
    66     connect ( model, SIGNAL ( columnsRemoved ( const QModelIndex &, int, int ) ),
       
    67               this, SLOT ( runAllTests() ) );
       
    68     connect ( model, SIGNAL ( dataChanged ( const QModelIndex &, const QModelIndex & ) ),
       
    69               this, SLOT ( runAllTests() ) );
       
    70     connect ( model, SIGNAL ( headerDataChanged ( Qt::Orientation, int, int ) ),
       
    71               this, SLOT ( runAllTests() ) );
       
    72     connect ( model, SIGNAL ( layoutAboutToBeChanged () ), this, SLOT ( runAllTests() ) );
       
    73     connect ( model, SIGNAL ( layoutChanged () ), this, SLOT ( runAllTests() ) );
       
    74     connect ( model, SIGNAL ( modelReset () ), this, SLOT ( runAllTests() ) );
       
    75     connect ( model, SIGNAL ( rowsAboutToBeInserted ( const QModelIndex &, int, int ) ),
       
    76               this, SLOT ( runAllTests() ) );
       
    77     connect ( model, SIGNAL ( rowsAboutToBeRemoved ( const QModelIndex &, int, int ) ),
       
    78               this, SLOT ( runAllTests() ) );
       
    79     connect ( model, SIGNAL ( rowsInserted ( const QModelIndex &, int, int ) ),
       
    80               this, SLOT ( runAllTests() ) );
       
    81     connect ( model, SIGNAL ( rowsRemoved ( const QModelIndex &, int, int ) ),
       
    82               this, SLOT ( runAllTests() ) );
       
    83 
       
    84     // Special checks for inserting/removing
       
    85     connect ( model, SIGNAL ( layoutAboutToBeChanged() ),
       
    86               this, SLOT ( layoutAboutToBeChanged() ) );
       
    87     connect ( model, SIGNAL ( layoutChanged() ),
       
    88               this, SLOT ( layoutChanged() ) );
       
    89 
       
    90     connect ( model, SIGNAL ( rowsAboutToBeInserted ( const QModelIndex &, int, int ) ),
       
    91               this, SLOT ( rowsAboutToBeInserted ( const QModelIndex &, int, int ) ) );
       
    92     connect ( model, SIGNAL ( rowsAboutToBeRemoved ( const QModelIndex &, int, int ) ),
       
    93               this, SLOT ( rowsAboutToBeRemoved ( const QModelIndex &, int, int ) ) );
       
    94     connect ( model, SIGNAL ( rowsInserted ( const QModelIndex &, int, int ) ),
       
    95               this, SLOT ( rowsInserted ( const QModelIndex &, int, int ) ) );
       
    96     connect ( model, SIGNAL ( rowsRemoved ( const QModelIndex &, int, int ) ),
       
    97               this, SLOT ( rowsRemoved ( const QModelIndex &, int, int ) ) );
       
    98 
       
    99     runAllTests();
       
   100 }
       
   101 
       
   102 void ModelTest::runAllTests()
       
   103 {
       
   104     if ( fetchingMore )
       
   105         return;
       
   106     nonDestructiveBasicTest();
       
   107     rowCount();
       
   108     columnCount();
       
   109     hasIndex();
       
   110     index();
       
   111     parent();
       
   112     data();
       
   113 }
       
   114 
       
   115 /*!
       
   116     nonDestructiveBasicTest tries to call a number of the basic functions (not all)
       
   117     to make sure the model doesn't outright segfault, testing the functions that makes sense.
       
   118 */
       
   119 void ModelTest::nonDestructiveBasicTest()
       
   120 {
       
   121     Q_ASSERT ( model->buddy ( QModelIndex() ) == QModelIndex() );
       
   122     model->canFetchMore ( QModelIndex() );
       
   123     Q_ASSERT ( model->columnCount ( QModelIndex() ) >= 0 );
       
   124     Q_ASSERT ( model->data ( QModelIndex() ) == QVariant() );
       
   125     fetchingMore = true;
       
   126     model->fetchMore ( QModelIndex() );
       
   127     fetchingMore = false;
       
   128     Qt::ItemFlags flags = model->flags ( QModelIndex() );
       
   129     Q_ASSERT ( flags == Qt::ItemIsDropEnabled || flags == 0 );
       
   130     model->hasChildren ( QModelIndex() );
       
   131     model->hasIndex ( 0, 0 );
       
   132     model->headerData ( 0, Qt::Horizontal );
       
   133     model->index ( 0, 0 );
       
   134     model->itemData ( QModelIndex() );
       
   135     QVariant cache;
       
   136     model->match ( QModelIndex(), -1, cache );
       
   137     model->mimeTypes();
       
   138     Q_ASSERT ( model->parent ( QModelIndex() ) == QModelIndex() );
       
   139     Q_ASSERT ( model->rowCount() >= 0 );
       
   140     QVariant variant;
       
   141     model->setData ( QModelIndex(), variant, -1 );
       
   142     model->setHeaderData ( -1, Qt::Horizontal, QVariant() );
       
   143     model->setHeaderData ( 999999, Qt::Horizontal, QVariant() );
       
   144     QMap<int, QVariant> roles;
       
   145     model->sibling ( 0, 0, QModelIndex() );
       
   146     model->span ( QModelIndex() );
       
   147     model->supportedDropActions();
       
   148 }
       
   149 
       
   150 /*!
       
   151     Tests model's implementation of QAbstractItemModel::rowCount() and hasChildren()
       
   152 
       
   153     Models that are dynamically populated are not as fully tested here.
       
   154  */
       
   155 void ModelTest::rowCount()
       
   156 {
       
   157 //     qDebug() << "rc";
       
   158     // check top row
       
   159     QModelIndex topIndex = model->index ( 0, 0, QModelIndex() );
       
   160     int rows = model->rowCount ( topIndex );
       
   161     Q_ASSERT ( rows >= 0 );
       
   162     if ( rows > 0 )
       
   163         Q_ASSERT ( model->hasChildren ( topIndex ) == true );
       
   164 
       
   165     QModelIndex secondLevelIndex = model->index ( 0, 0, topIndex );
       
   166     if ( secondLevelIndex.isValid() ) { // not the top level
       
   167         // check a row count where parent is valid
       
   168         rows = model->rowCount ( secondLevelIndex );
       
   169         Q_ASSERT ( rows >= 0 );
       
   170         if ( rows > 0 )
       
   171             Q_ASSERT ( model->hasChildren ( secondLevelIndex ) == true );
       
   172     }
       
   173 
       
   174     // The models rowCount() is tested more extensively in checkChildren(),
       
   175     // but this catches the big mistakes
       
   176 }
       
   177 
       
   178 /*!
       
   179     Tests model's implementation of QAbstractItemModel::columnCount() and hasChildren()
       
   180  */
       
   181 void ModelTest::columnCount()
       
   182 {
       
   183     // check top row
       
   184     QModelIndex topIndex = model->index ( 0, 0, QModelIndex() );
       
   185     Q_ASSERT ( model->columnCount ( topIndex ) >= 0 );
       
   186 
       
   187     // check a column count where parent is valid
       
   188     QModelIndex childIndex = model->index ( 0, 0, topIndex );
       
   189     if ( childIndex.isValid() )
       
   190         Q_ASSERT ( model->columnCount ( childIndex ) >= 0 );
       
   191 
       
   192     // columnCount() is tested more extensively in checkChildren(),
       
   193     // but this catches the big mistakes
       
   194 }
       
   195 
       
   196 /*!
       
   197     Tests model's implementation of QAbstractItemModel::hasIndex()
       
   198  */
       
   199 void ModelTest::hasIndex()
       
   200 {
       
   201 //     qDebug() << "hi";
       
   202     // Make sure that invalid values returns an invalid index
       
   203     Q_ASSERT ( model->hasIndex ( -2, -2 ) == false );
       
   204     Q_ASSERT ( model->hasIndex ( -2, 0 ) == false );
       
   205     Q_ASSERT ( model->hasIndex ( 0, -2 ) == false );
       
   206 
       
   207     int rows = model->rowCount();
       
   208     int columns = model->columnCount();
       
   209 
       
   210     // check out of bounds
       
   211     Q_ASSERT ( model->hasIndex ( rows, columns ) == false );
       
   212     Q_ASSERT ( model->hasIndex ( rows + 1, columns + 1 ) == false );
       
   213 
       
   214     if ( rows > 0 )
       
   215         Q_ASSERT ( model->hasIndex ( 0, 0 ) == true );
       
   216 
       
   217     // hasIndex() is tested more extensively in checkChildren(),
       
   218     // but this catches the big mistakes
       
   219 }
       
   220 
       
   221 /*!
       
   222     Tests model's implementation of QAbstractItemModel::index()
       
   223  */
       
   224 void ModelTest::index()
       
   225 {
       
   226 //     qDebug() << "i";
       
   227     // Make sure that invalid values returns an invalid index
       
   228     Q_ASSERT ( model->index ( -2, -2 ) == QModelIndex() );
       
   229     Q_ASSERT ( model->index ( -2, 0 ) == QModelIndex() );
       
   230     Q_ASSERT ( model->index ( 0, -2 ) == QModelIndex() );
       
   231 
       
   232     int rows = model->rowCount();
       
   233     int columns = model->columnCount();
       
   234 
       
   235     if ( rows == 0 )
       
   236         return;
       
   237 
       
   238     // Catch off by one errors
       
   239     Q_ASSERT ( model->index ( rows, columns ) == QModelIndex() );
       
   240     Q_ASSERT ( model->index ( 0, 0 ).isValid() == true );
       
   241 
       
   242     // Make sure that the same index is *always* returned
       
   243     QModelIndex a = model->index ( 0, 0 );
       
   244     QModelIndex b = model->index ( 0, 0 );
       
   245     Q_ASSERT ( a == b );
       
   246 
       
   247     // index() is tested more extensively in checkChildren(),
       
   248     // but this catches the big mistakes
       
   249 }
       
   250 
       
   251 /*!
       
   252     Tests model's implementation of QAbstractItemModel::parent()
       
   253  */
       
   254 void ModelTest::parent()
       
   255 {
       
   256 //     qDebug() << "p";
       
   257     // Make sure the model wont crash and will return an invalid QModelIndex
       
   258     // when asked for the parent of an invalid index.
       
   259     Q_ASSERT ( model->parent ( QModelIndex() ) == QModelIndex() );
       
   260 
       
   261     if ( model->rowCount() == 0 )
       
   262         return;
       
   263 
       
   264     // Column 0                | Column 1    |
       
   265     // QModelIndex()           |             |
       
   266     //    \- topIndex          | topIndex1   |
       
   267     //         \- childIndex   | childIndex1 |
       
   268 
       
   269     // Common error test #1, make sure that a top level index has a parent
       
   270     // that is a invalid QModelIndex.
       
   271     QModelIndex topIndex = model->index ( 0, 0, QModelIndex() );
       
   272     Q_ASSERT ( model->parent ( topIndex ) == QModelIndex() );
       
   273 
       
   274     // Common error test #2, make sure that a second level index has a parent
       
   275     // that is the first level index.
       
   276     if ( model->rowCount ( topIndex ) > 0 ) {
       
   277         QModelIndex childIndex = model->index ( 0, 0, topIndex );
       
   278         Q_ASSERT ( model->parent ( childIndex ) == topIndex );
       
   279     }
       
   280 
       
   281     // Common error test #3, the second column should NOT have the same children
       
   282     // as the first column in a row.
       
   283     // Usually the second column shouldn't have children.
       
   284     QModelIndex topIndex1 = model->index ( 0, 1, QModelIndex() );
       
   285     if ( model->rowCount ( topIndex1 ) > 0 ) {
       
   286         QModelIndex childIndex = model->index ( 0, 0, topIndex );
       
   287         QModelIndex childIndex1 = model->index ( 0, 0, topIndex1 );
       
   288         Q_ASSERT ( childIndex != childIndex1 );
       
   289     }
       
   290 
       
   291     // Full test, walk n levels deep through the model making sure that all
       
   292     // parent's children correctly specify their parent.
       
   293     checkChildren ( QModelIndex() );
       
   294 }
       
   295 
       
   296 /*!
       
   297     Called from the parent() test.
       
   298 
       
   299     A model that returns an index of parent X should also return X when asking
       
   300     for the parent of the index.
       
   301 
       
   302     This recursive function does pretty extensive testing on the whole model in an
       
   303     effort to catch edge cases.
       
   304 
       
   305     This function assumes that rowCount(), columnCount() and index() already work.
       
   306     If they have a bug it will point it out, but the above tests should have already
       
   307     found the basic bugs because it is easier to figure out the problem in
       
   308     those tests then this one.
       
   309  */
       
   310 void ModelTest::checkChildren ( const QModelIndex &parent, int currentDepth )
       
   311 {
       
   312     // First just try walking back up the tree.
       
   313     QModelIndex p = parent;
       
   314     while ( p.isValid() )
       
   315         p = p.parent();
       
   316 
       
   317     // For models that are dynamically populated
       
   318     if ( model->canFetchMore ( parent ) ) {
       
   319         fetchingMore = true;
       
   320         model->fetchMore ( parent );
       
   321         fetchingMore = false;
       
   322     }
       
   323 
       
   324     int rows = model->rowCount ( parent );
       
   325     int columns = model->columnCount ( parent );
       
   326 
       
   327     if ( rows > 0 )
       
   328         Q_ASSERT ( model->hasChildren ( parent ) );
       
   329 
       
   330     // Some further testing against rows(), columns(), and hasChildren()
       
   331     Q_ASSERT ( rows >= 0 );
       
   332     Q_ASSERT ( columns >= 0 );
       
   333     if ( rows > 0 )
       
   334         Q_ASSERT ( model->hasChildren ( parent ) == true );
       
   335 
       
   336     //qDebug() << "parent:" << model->data(parent).toString() << "rows:" << rows
       
   337     //         << "columns:" << columns << "parent column:" << parent.column();
       
   338 
       
   339     Q_ASSERT ( model->hasIndex ( rows + 1, 0, parent ) == false );
       
   340     for ( int r = 0; r < rows; ++r ) {
       
   341         if ( model->canFetchMore ( parent ) ) {
       
   342             fetchingMore = true;
       
   343             model->fetchMore ( parent );
       
   344             fetchingMore = false;
       
   345         }
       
   346         Q_ASSERT ( model->hasIndex ( r, columns + 1, parent ) == false );
       
   347         for ( int c = 0; c < columns; ++c ) {
       
   348             Q_ASSERT ( model->hasIndex ( r, c, parent ) == true );
       
   349             QModelIndex index = model->index ( r, c, parent );
       
   350             // rowCount() and columnCount() said that it existed...
       
   351             Q_ASSERT ( index.isValid() == true );
       
   352 
       
   353             // index() should always return the same index when called twice in a row
       
   354             QModelIndex modifiedIndex = model->index ( r, c, parent );
       
   355             Q_ASSERT ( index == modifiedIndex );
       
   356 
       
   357             // Make sure we get the same index if we request it twice in a row
       
   358             QModelIndex a = model->index ( r, c, parent );
       
   359             QModelIndex b = model->index ( r, c, parent );
       
   360             Q_ASSERT ( a == b );
       
   361 
       
   362             // Some basic checking on the index that is returned
       
   363             Q_ASSERT ( index.model() == model );
       
   364             Q_ASSERT ( index.row() == r );
       
   365             Q_ASSERT ( index.column() == c );
       
   366             // While you can technically return a QVariant usually this is a sign
       
   367             // of an bug in data()  Disable if this really is ok in your model.
       
   368 //            Q_ASSERT ( model->data ( index, Qt::DisplayRole ).isValid() == true );
       
   369 
       
   370             // If the next test fails here is some somewhat useful debug you play with.
       
   371 
       
   372             if (model->parent(index) != parent) {
       
   373                 qDebug() << r << c << currentDepth << model->data(index).toString()
       
   374                          << model->data(parent).toString();
       
   375                 qDebug() << index << parent << model->parent(index);
       
   376 //                 And a view that you can even use to show the model.
       
   377 //                 QTreeView view;
       
   378 //                 view.setModel(model);
       
   379 //                 view.show();
       
   380             }
       
   381 
       
   382             // Check that we can get back our real parent.
       
   383 //             qDebug() << model->parent ( index ) << parent ;
       
   384             Q_ASSERT ( model->parent ( index ) == parent );
       
   385 
       
   386             // recursively go down the children
       
   387             if ( model->hasChildren ( index ) && currentDepth < 10 ) {
       
   388                 //qDebug() << r << c << "has children" << model->rowCount(index);
       
   389                 checkChildren ( index, ++currentDepth );
       
   390             }/* else { if (currentDepth >= 10) qDebug() << "checked 10 deep"; };*/
       
   391 
       
   392             // make sure that after testing the children that the index doesn't change.
       
   393             QModelIndex newerIndex = model->index ( r, c, parent );
       
   394             Q_ASSERT ( index == newerIndex );
       
   395         }
       
   396     }
       
   397 }
       
   398 
       
   399 /*!
       
   400     Tests model's implementation of QAbstractItemModel::data()
       
   401  */
       
   402 void ModelTest::data()
       
   403 {
       
   404     // Invalid index should return an invalid qvariant
       
   405     Q_ASSERT ( !model->data ( QModelIndex() ).isValid() );
       
   406 
       
   407     if ( model->rowCount() == 0 )
       
   408         return;
       
   409 
       
   410     // A valid index should have a valid QVariant data
       
   411     Q_ASSERT ( model->index ( 0, 0 ).isValid() );
       
   412 
       
   413     // shouldn't be able to set data on an invalid index
       
   414     Q_ASSERT ( model->setData ( QModelIndex(), QLatin1String ( "foo" ), Qt::DisplayRole ) == false );
       
   415 
       
   416     // General Purpose roles that should return a QString
       
   417     QVariant variant = model->data ( model->index ( 0, 0 ), Qt::ToolTipRole );
       
   418     if ( variant.isValid() ) {
       
   419         Q_ASSERT ( qVariantCanConvert<QString> ( variant ) );
       
   420     }
       
   421     variant = model->data ( model->index ( 0, 0 ), Qt::StatusTipRole );
       
   422     if ( variant.isValid() ) {
       
   423         Q_ASSERT ( qVariantCanConvert<QString> ( variant ) );
       
   424     }
       
   425     variant = model->data ( model->index ( 0, 0 ), Qt::WhatsThisRole );
       
   426     if ( variant.isValid() ) {
       
   427         Q_ASSERT ( qVariantCanConvert<QString> ( variant ) );
       
   428     }
       
   429 
       
   430     // General Purpose roles that should return a QSize
       
   431     variant = model->data ( model->index ( 0, 0 ), Qt::SizeHintRole );
       
   432     if ( variant.isValid() ) {
       
   433         Q_ASSERT ( qVariantCanConvert<QSize> ( variant ) );
       
   434     }
       
   435 
       
   436     // General Purpose roles that should return a QFont
       
   437     QVariant fontVariant = model->data ( model->index ( 0, 0 ), Qt::FontRole );
       
   438     if ( fontVariant.isValid() ) {
       
   439         Q_ASSERT ( qVariantCanConvert<QFont> ( fontVariant ) );
       
   440     }
       
   441 
       
   442     // Check that the alignment is one we know about
       
   443     QVariant textAlignmentVariant = model->data ( model->index ( 0, 0 ), Qt::TextAlignmentRole );
       
   444     if ( textAlignmentVariant.isValid() ) {
       
   445         int alignment = textAlignmentVariant.toInt();
       
   446         Q_ASSERT ( alignment == ( alignment & ( Qt::AlignHorizontal_Mask | Qt::AlignVertical_Mask ) ) );
       
   447     }
       
   448 
       
   449     // General Purpose roles that should return a QColor
       
   450     QVariant colorVariant = model->data ( model->index ( 0, 0 ), Qt::BackgroundColorRole );
       
   451     if ( colorVariant.isValid() ) {
       
   452         Q_ASSERT ( qVariantCanConvert<QColor> ( colorVariant ) );
       
   453     }
       
   454 
       
   455     colorVariant = model->data ( model->index ( 0, 0 ), Qt::TextColorRole );
       
   456     if ( colorVariant.isValid() ) {
       
   457         Q_ASSERT ( qVariantCanConvert<QColor> ( colorVariant ) );
       
   458     }
       
   459 
       
   460     // Check that the "check state" is one we know about.
       
   461     QVariant checkStateVariant = model->data ( model->index ( 0, 0 ), Qt::CheckStateRole );
       
   462     if ( checkStateVariant.isValid() ) {
       
   463         int state = checkStateVariant.toInt();
       
   464         Q_ASSERT ( state == Qt::Unchecked ||
       
   465                    state == Qt::PartiallyChecked ||
       
   466                    state == Qt::Checked );
       
   467     }
       
   468 }
       
   469 
       
   470 /*!
       
   471     Store what is about to be inserted to make sure it actually happens
       
   472 
       
   473     \sa rowsInserted()
       
   474  */
       
   475 void ModelTest::rowsAboutToBeInserted ( const QModelIndex &parent, int start, int end )
       
   476 {
       
   477 //     Q_UNUSED(end);
       
   478     qDebug() << "rowsAboutToBeInserted" << "start=" << start << "end=" << end << "parent=" << model->data ( parent ).toString()
       
   479     << "current count of parent=" << model->rowCount ( parent ); // << "display of last=" << model->data( model->index(start-1, 0, parent) );
       
   480 //     qDebug() << model->index(start-1, 0, parent) << model->data( model->index(start-1, 0, parent) );
       
   481     Changing c;
       
   482     c.parent = parent;
       
   483     c.oldSize = model->rowCount ( parent );
       
   484     c.last = model->data ( model->index ( start - 1, 0, parent ) );
       
   485     c.next = model->data ( model->index ( start, 0, parent ) );
       
   486     insert.push ( c );
       
   487 }
       
   488 
       
   489 /*!
       
   490     Confirm that what was said was going to happen actually did
       
   491 
       
   492     \sa rowsAboutToBeInserted()
       
   493  */
       
   494 void ModelTest::rowsInserted ( const QModelIndex & parent, int start, int end )
       
   495 {
       
   496     Changing c = insert.pop();
       
   497     Q_ASSERT ( c.parent == parent );
       
   498     qDebug() << "rowsInserted"  << "start=" << start << "end=" << end << "oldsize=" << c.oldSize
       
   499     << "parent=" << model->data ( parent ).toString() << "current rowcount of parent=" << model->rowCount ( parent );
       
   500 
       
   501     for (int ii=start; ii <= end; ii++)
       
   502     {
       
   503       qDebug() << "itemWasInserted:" << ii << model->data ( model->index ( ii, 0, parent ));
       
   504     }
       
   505     qDebug();
       
   506 
       
   507     Q_ASSERT ( c.oldSize + ( end - start + 1 ) == model->rowCount ( parent ) );
       
   508     Q_ASSERT ( c.last == model->data ( model->index ( start - 1, 0, c.parent ) ) );
       
   509 
       
   510     if (c.next != model->data(model->index(end + 1, 0, c.parent))) {
       
   511         qDebug() << start << end;
       
   512         for (int i=0; i < model->rowCount(); ++i)
       
   513             qDebug() << model->index(i, 0).data().toString();
       
   514         qDebug() << c.next << model->data(model->index(end + 1, 0, c.parent));
       
   515     }
       
   516 
       
   517     Q_ASSERT ( c.next == model->data ( model->index ( end + 1, 0, c.parent ) ) );
       
   518 }
       
   519 
       
   520 void ModelTest::layoutAboutToBeChanged()
       
   521 {
       
   522     for ( int i = 0; i < qBound ( 0, model->rowCount(), 100 ); ++i )
       
   523         changing.append ( QPersistentModelIndex ( model->index ( i, 0 ) ) );
       
   524 }
       
   525 
       
   526 void ModelTest::layoutChanged()
       
   527 {
       
   528     for ( int i = 0; i < changing.count(); ++i ) {
       
   529         QPersistentModelIndex p = changing[i];
       
   530         Q_ASSERT ( p == model->index ( p.row(), p.column(), p.parent() ) );
       
   531     }
       
   532     changing.clear();
       
   533 }
       
   534 
       
   535 /*!
       
   536     Store what is about to be inserted to make sure it actually happens
       
   537 
       
   538     \sa rowsRemoved()
       
   539  */
       
   540 void ModelTest::rowsAboutToBeRemoved ( const QModelIndex &parent, int start, int end )
       
   541 {
       
   542 qDebug() << "ratbr" << parent << start << end;
       
   543     Changing c;
       
   544     c.parent = parent;
       
   545     c.oldSize = model->rowCount ( parent );
       
   546     c.last = model->data ( model->index ( start - 1, 0, parent ) );
       
   547     c.next = model->data ( model->index ( end + 1, 0, parent ) );
       
   548     remove.push ( c );
       
   549 }
       
   550 
       
   551 /*!
       
   552     Confirm that what was said was going to happen actually did
       
   553 
       
   554     \sa rowsAboutToBeRemoved()
       
   555  */
       
   556 void ModelTest::rowsRemoved ( const QModelIndex & parent, int start, int end )
       
   557 {
       
   558   qDebug() << "rr" << parent << start << end;
       
   559     Changing c = remove.pop();
       
   560     Q_ASSERT ( c.parent == parent );
       
   561     Q_ASSERT ( c.oldSize - ( end - start + 1 ) == model->rowCount ( parent ) );
       
   562     Q_ASSERT ( c.last == model->data ( model->index ( start - 1, 0, c.parent ) ) );
       
   563     Q_ASSERT ( c.next == model->data ( model->index ( start, 0, c.parent ) ) );
       
   564 }
       
   565 
       
   566