tests/auto/qitemmodel/tst_qitemmodel.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
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 /****************************************************************************
       
    44 **
       
    45 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
    46 ** All rights reserved.
       
    47 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
    48 **
       
    49 ** This file is part of the test suite of the Qt Toolkit.
       
    50 **
       
    51 ** $LICENSE$
       
    52 **
       
    53 ****************************************************************************/
       
    54 
       
    55 #include <QtTest/QtTest>
       
    56 #include <QtCore>
       
    57 #include <qdebug.h>
       
    58 #include "modelstotest.cpp"
       
    59 #include <QMetaType>
       
    60 
       
    61 Q_DECLARE_METATYPE(QModelIndex)
       
    62 
       
    63 //TESTED_CLASS=
       
    64 //TESTED_FILES=gui/itemviews/qstandarditemmodel.h gui/itemviews/qstandarditemmodel.cpp
       
    65 
       
    66 /*!
       
    67     See modelstotest.cpp for instructions on how to have your model tested with these tests.
       
    68 
       
    69     Each test such as rowCount have a _data() function which populate the QTest data with
       
    70     the tests specified by modelstotest.cpp and any extra data needed for that perticular test.
       
    71 
       
    72     setupWithNoTestData() fills the QTest data with just the tests and is used by most tests.
       
    73 
       
    74     There are some basic qDebug statements sprikled about that might be helpfull for fixing
       
    75     your issues.
       
    76  */
       
    77 class tst_QItemModel : public QObject
       
    78 {
       
    79     Q_OBJECT
       
    80 
       
    81 public:
       
    82     tst_QItemModel() {};
       
    83     virtual ~tst_QItemModel() {};
       
    84 
       
    85 public slots:
       
    86     void init();
       
    87     void cleanup();
       
    88 
       
    89 private slots:
       
    90     void nonDestructiveBasicTest_data();
       
    91     void nonDestructiveBasicTest();
       
    92 
       
    93     void rowCount_data();
       
    94     void rowCount();
       
    95     void columnCount_data();
       
    96     void columnCount();
       
    97 
       
    98     void hasIndex_data();
       
    99     void hasIndex();
       
   100     void index_data();
       
   101     void index();
       
   102 
       
   103     void parent_data();
       
   104     void parent();
       
   105 
       
   106     void data_data();
       
   107     void data();
       
   108 
       
   109     void setData_data();
       
   110     void setData();
       
   111 
       
   112     void setHeaderData_data();
       
   113     void setHeaderData();
       
   114 
       
   115     void remove_data();
       
   116     void remove();
       
   117 
       
   118     void insert_data();
       
   119     void insert();
       
   120 
       
   121     void sort_data();
       
   122     void sort();
       
   123 
       
   124 protected slots:
       
   125     void slot_rowsAboutToRemove(const QModelIndex &parent);
       
   126     void slot_rowsRemoved(const QModelIndex &parent);
       
   127     void slot_columnsAboutToRemove(const QModelIndex &parent);
       
   128     void slot_columnsRemoved(const QModelIndex &parent);
       
   129 
       
   130     void slot_rowsAboutToInserted(const QModelIndex &parent);
       
   131     void slot_rowsInserted(const QModelIndex &parent);
       
   132     void slot_columnsAboutToInserted(const QModelIndex &parent);
       
   133     void slot_columnsInserted(const QModelIndex &parent);
       
   134 private:
       
   135     void setupWithNoTestData();
       
   136     QAbstractItemModel *currentModel;
       
   137     ModelsToTest *testModels;
       
   138 
       
   139     // used by remove()
       
   140     QPersistentModelIndex parentOfRemoved;
       
   141     int afterAboutToRemoveRowCount;
       
   142     int afterRemoveRowCount;
       
   143     int afterAboutToRemoveColumnCount;
       
   144     int afterRemoveColumnCount;
       
   145 
       
   146     // remove() recursive
       
   147     bool removeRecursively;
       
   148 
       
   149     // used by insert()
       
   150     QPersistentModelIndex parentOfInserted;
       
   151     int afterAboutToInsertRowCount;
       
   152     int afterInsertRowCount;
       
   153     int afterAboutToInsertColumnCount;
       
   154     int afterInsertColumnCount;
       
   155 
       
   156     // insert() recursive
       
   157     bool insertRecursively;
       
   158 };
       
   159 
       
   160 void tst_QItemModel::init()
       
   161 {
       
   162     testModels = new ModelsToTest();
       
   163     removeRecursively = false;
       
   164     insertRecursively = false;
       
   165 }
       
   166 
       
   167 void tst_QItemModel::cleanup()
       
   168 {
       
   169     testModels->cleanupTestArea(currentModel);
       
   170     delete testModels;
       
   171     delete currentModel;
       
   172     currentModel = 0;
       
   173 }
       
   174 
       
   175 void tst_QItemModel::setupWithNoTestData()
       
   176 {
       
   177     ModelsToTest modelsToTest;
       
   178     QTest::addColumn<QString>("modelType");
       
   179     QTest::addColumn<bool>("readOnly");
       
   180     QTest::addColumn<bool>("isEmpty");
       
   181     for (int i = 0; i < modelsToTest.tests.size(); ++i) {
       
   182         ModelsToTest::test t = modelsToTest.tests.at(i);
       
   183         bool readOnly = (t.read == ModelsToTest::ReadOnly);
       
   184         bool isEmpty = (t.contains == ModelsToTest::Empty);
       
   185         QTest::newRow(t.modelType.toLatin1().data()) << t.modelType << readOnly << isEmpty;
       
   186     }
       
   187 }
       
   188 
       
   189 void tst_QItemModel::nonDestructiveBasicTest_data()
       
   190 {
       
   191     setupWithNoTestData();
       
   192 }
       
   193 
       
   194 /*!
       
   195     nonDestructiveBasicTest trys to call a number of the basic functions (not all)
       
   196     to make sure the model doesn't segfault, testing the functions that makes sense.
       
   197  */
       
   198 void tst_QItemModel::nonDestructiveBasicTest()
       
   199 {
       
   200     QFETCH(QString, modelType);
       
   201     currentModel = testModels->createModel(modelType);
       
   202 
       
   203     QCOMPARE(currentModel->buddy(QModelIndex()), QModelIndex());
       
   204     currentModel->canFetchMore(QModelIndex());
       
   205     QVERIFY(currentModel->columnCount(QModelIndex()) >= 0);
       
   206     QCOMPARE(currentModel->data(QModelIndex()), QVariant());
       
   207     currentModel->fetchMore(QModelIndex());
       
   208     Qt::ItemFlags flags = currentModel->flags(QModelIndex());
       
   209     QVERIFY(flags == Qt::ItemIsDropEnabled || flags == 0);
       
   210     currentModel->hasChildren(QModelIndex());
       
   211     currentModel->hasIndex(0, 0);
       
   212     currentModel->headerData(0, Qt::Horizontal);
       
   213     currentModel->index(0,0), QModelIndex();
       
   214     currentModel->itemData(QModelIndex());
       
   215     QVariant cache;
       
   216     currentModel->match(QModelIndex(), -1, cache);
       
   217     currentModel->mimeTypes();
       
   218     QCOMPARE(currentModel->parent(QModelIndex()), QModelIndex());
       
   219     QVERIFY(currentModel->rowCount() >= 0);
       
   220     QVariant variant;
       
   221     currentModel->setData(QModelIndex(), variant, -1);
       
   222     currentModel->setHeaderData(-1, Qt::Horizontal, QVariant());
       
   223     currentModel->setHeaderData(0, Qt::Horizontal, QVariant());
       
   224     currentModel->setHeaderData(currentModel->columnCount() + 100, Qt::Horizontal, QVariant());
       
   225     QMap<int, QVariant> roles;
       
   226     currentModel->setItemData(QModelIndex(), roles);
       
   227     currentModel->sibling(0,0,QModelIndex());
       
   228     currentModel->span(QModelIndex());
       
   229     currentModel->supportedDropActions();
       
   230     currentModel->revert();
       
   231     currentModel->submit();
       
   232 }
       
   233 
       
   234 
       
   235 void tst_QItemModel::rowCount_data()
       
   236 {
       
   237     setupWithNoTestData();
       
   238 }
       
   239 
       
   240 /*!
       
   241     Tests model's implimentation of QAbstractItemModel::rowCount() and hasChildren()
       
   242  */
       
   243 void tst_QItemModel::rowCount()
       
   244 {
       
   245     QFETCH(QString, modelType);
       
   246     currentModel = testModels->createModel(modelType);
       
   247 
       
   248     QFETCH(bool, isEmpty);
       
   249     if (isEmpty) {
       
   250         QCOMPARE(currentModel->rowCount(), 0);
       
   251         QCOMPARE(currentModel->hasChildren(), false);
       
   252     }
       
   253     else {
       
   254         QVERIFY(currentModel->rowCount() > 0);
       
   255         QCOMPARE(currentModel->hasChildren(), true);
       
   256     }
       
   257 
       
   258     // check top row
       
   259     QModelIndex topIndex = currentModel->index(0, 0, QModelIndex());
       
   260     int rows = currentModel->rowCount(topIndex);
       
   261     QVERIFY(rows >= 0);
       
   262     if (rows > 0)
       
   263         QCOMPARE(currentModel->hasChildren(topIndex), true);
       
   264     else
       
   265         QCOMPARE(currentModel->hasChildren(topIndex), false);
       
   266 
       
   267     QModelIndex secondLevelIndex = currentModel->index(0, 0, topIndex);
       
   268     if (secondLevelIndex.isValid()) { // not the top level
       
   269         // check a row count where parent is valid
       
   270         rows = currentModel->rowCount(secondLevelIndex);
       
   271         QVERIFY(rows >= 0);
       
   272         if (rows > 0)
       
   273             QCOMPARE(currentModel->hasChildren(secondLevelIndex), true);
       
   274         else
       
   275             QCOMPARE(currentModel->hasChildren(secondLevelIndex), false);
       
   276     }
       
   277 
       
   278     // rowCount is tested more extensivly more later in checkChildren(),
       
   279     // but this catches the big mistakes
       
   280 }
       
   281 
       
   282 void tst_QItemModel::columnCount_data()
       
   283 {
       
   284     setupWithNoTestData();
       
   285 }
       
   286 
       
   287 /*!
       
   288     Tests model's implimentation of QAbstractItemModel::columnCount() and hasChildren()
       
   289  */
       
   290 void tst_QItemModel::columnCount()
       
   291 {
       
   292     QFETCH(QString, modelType);
       
   293     currentModel = testModels->createModel(modelType);
       
   294 
       
   295     QFETCH(bool, isEmpty);
       
   296     if (isEmpty) {
       
   297         QCOMPARE(currentModel->hasChildren(), false);
       
   298     }
       
   299     else {
       
   300         QVERIFY(currentModel->columnCount() > 0);
       
   301         QCOMPARE(currentModel->hasChildren(), true);
       
   302     }
       
   303 
       
   304     // check top row
       
   305     QModelIndex topIndex = currentModel->index(0, 0, QModelIndex());
       
   306     int columns = currentModel->columnCount(topIndex);
       
   307 
       
   308     // check a row count where parent is valid
       
   309     columns = currentModel->columnCount(currentModel->index(0, 0, topIndex));
       
   310     QVERIFY(columns >= 0);
       
   311 
       
   312     // columnCount is tested more extensivly more later in checkChildren(),
       
   313     // but this catches the big mistakes
       
   314 }
       
   315 
       
   316 void tst_QItemModel::hasIndex_data()
       
   317 {
       
   318     setupWithNoTestData();
       
   319 }
       
   320 
       
   321 /*!
       
   322     Tests model's implimentation of QAbstractItemModel::hasIndex()
       
   323  */
       
   324 void tst_QItemModel::hasIndex()
       
   325 {
       
   326     QFETCH(QString, modelType);
       
   327     currentModel = testModels->createModel(modelType);
       
   328 
       
   329     // Make sure that invalid values returns an invalid index
       
   330     QCOMPARE(currentModel->hasIndex(-2, -2), false);
       
   331     QCOMPARE(currentModel->hasIndex(-2, 0), false);
       
   332     QCOMPARE(currentModel->hasIndex(0, -2), false);
       
   333 
       
   334     int rows = currentModel->rowCount();
       
   335     int columns = currentModel->columnCount();
       
   336 
       
   337     QCOMPARE(currentModel->hasIndex(rows, columns), false);
       
   338     QCOMPARE(currentModel->hasIndex(rows+1, columns+1), false);
       
   339 
       
   340     QFETCH(bool, isEmpty);
       
   341     if (isEmpty)
       
   342         return;
       
   343 
       
   344     QCOMPARE(currentModel->hasIndex(0,0), true);
       
   345 
       
   346     // hasIndex is tested more extensivly more later in checkChildren(),
       
   347     // but this catches the big mistakes
       
   348 }
       
   349 
       
   350 void tst_QItemModel::index_data()
       
   351 {
       
   352     setupWithNoTestData();
       
   353 }
       
   354 
       
   355 /*!
       
   356     Tests model's implimentation of QAbstractItemModel::index()
       
   357  */
       
   358 void tst_QItemModel::index()
       
   359 {
       
   360     QFETCH(QString, modelType);
       
   361     currentModel = testModels->createModel(modelType);
       
   362 
       
   363     // Make sure that invalid values returns an invalid index
       
   364     QCOMPARE(currentModel->index(-2, -2), QModelIndex());
       
   365     QCOMPARE(currentModel->index(-2, 0), QModelIndex());
       
   366     QCOMPARE(currentModel->index(0, -2), QModelIndex());
       
   367 
       
   368     QFETCH(bool, isEmpty);
       
   369     if (isEmpty)
       
   370         return;
       
   371 
       
   372     int rows = currentModel->rowCount();
       
   373     int columns = currentModel->columnCount();
       
   374 
       
   375     // Catch off by one errors
       
   376     QCOMPARE(currentModel->index(rows,columns), QModelIndex());
       
   377     QCOMPARE(currentModel->index(0,0).isValid(), true);
       
   378 
       
   379     // Make sure that the same index is always returned
       
   380     QModelIndex a = currentModel->index(0,0);
       
   381     QModelIndex b = currentModel->index(0,0);
       
   382     QVERIFY(a == b);
       
   383 
       
   384     // index is tested more extensivly more later in checkChildren(),
       
   385     // but this catches the big mistakes
       
   386 }
       
   387 
       
   388 
       
   389 void tst_QItemModel::parent_data()
       
   390 {
       
   391     setupWithNoTestData();
       
   392 }
       
   393 
       
   394 /*!
       
   395     A model that returns an index of parent X should also return X when asking
       
   396     for the parent of the index.
       
   397 
       
   398     This recursive function does pretty extensive testing on the whole model in an
       
   399     effort to catch edge cases.
       
   400 
       
   401     This function assumes that rowCount(), columnCount() and index() work.  If they have
       
   402     a bug it will point it out, but the above tests should have already found the basic bugs
       
   403     because it is easier to figure out the problem in those tests then this one.
       
   404  */
       
   405 void checkChildren(QAbstractItemModel *currentModel, const QModelIndex &parent, int currentDepth=0)
       
   406 {
       
   407     QFETCH(bool, readOnly);
       
   408 
       
   409     if (currentModel->canFetchMore(parent))
       
   410         currentModel->fetchMore(parent);
       
   411 
       
   412     int rows = currentModel->rowCount(parent);
       
   413     int columns = currentModel->columnCount(parent);
       
   414 
       
   415     QCOMPARE(rows > 0, (currentModel->hasChildren(parent)));
       
   416 
       
   417     // Some reasuring testing against rows(),columns(), and hasChildren()
       
   418     QVERIFY(rows >= 0);
       
   419     QVERIFY(columns >= 0);
       
   420     if (rows > 0 || columns > 0)
       
   421         QCOMPARE(currentModel->hasChildren(parent), true);
       
   422     else
       
   423         QCOMPARE(currentModel->hasChildren(parent), false);
       
   424 
       
   425     //qDebug() << "parent:" << currentModel->data(parent).toString() << "rows:" << rows
       
   426     //         << "columns:" << columns << "parent column:" << parent.column();
       
   427 
       
   428     QCOMPARE(currentModel->hasIndex(rows+1, 0, parent), false);
       
   429     for (int r = 0; r < rows; ++r) {
       
   430         if (currentModel->canFetchMore(parent))
       
   431             currentModel->fetchMore(parent);
       
   432 
       
   433         QCOMPARE(currentModel->hasIndex(r, columns+1, parent), false);
       
   434         for (int c = 0; c < columns; ++c) {
       
   435             QCOMPARE(currentModel->hasIndex(r, c, parent), true);
       
   436             QModelIndex index = currentModel->index(r, c, parent);
       
   437             QCOMPARE(index.isValid(), true);
       
   438 
       
   439             if (!readOnly)
       
   440                 currentModel->setData(index, "I'm a little tea pot short and stout");
       
   441             QModelIndex modifiedIndex = currentModel->index(r, c, parent);
       
   442             QCOMPARE(index, modifiedIndex);
       
   443 
       
   444             // Make sure we get the same index if we request it twice in a row
       
   445             QModelIndex a = currentModel->index(r, c, parent);
       
   446             QModelIndex b = currentModel->index(r, c, parent);
       
   447             QVERIFY(a == b);
       
   448 
       
   449             // Some basic checking on the index that is returned
       
   450             QVERIFY(index.model() == currentModel);
       
   451             QCOMPARE(index.row(), r);
       
   452             QCOMPARE(index.column(), c);
       
   453             QCOMPARE(currentModel->data(index, Qt::DisplayRole).isValid(), true);
       
   454 
       
   455             // If the next test fails here is some somewhat usefull debug you play with.
       
   456             /*
       
   457             if (currentModel->parent(index) != parent) {
       
   458                 qDebug() << r << c << currentDepth << currentModel->data(index).toString()
       
   459                          << currentModel->data(parent).toString();
       
   460                 qDebug() << index << parent << currentModel->parent(index);
       
   461                 QTreeView view;
       
   462                 view.setModel(currentModel);
       
   463                 view.show();
       
   464                 QTest::qWait(9000);
       
   465             }*/
       
   466             QCOMPARE(currentModel->parent(index), parent);
       
   467 
       
   468             // recursivly go down
       
   469             if (currentModel->hasChildren(index) && currentDepth < 5) {
       
   470                 //qDebug() << r << c << "has children" << currentModel->rowCount(index);
       
   471                 checkChildren(currentModel, index, ++currentDepth);
       
   472                 // Because this is recursive we will return at the first failure rather then
       
   473                 // reporting it over and over
       
   474                 if (QTest::currentTestFailed())
       
   475                     return;
       
   476             }
       
   477 
       
   478             // make sure that after testing the children that the index pointer doesn't change.
       
   479             QModelIndex newerIndex = currentModel->index(r, c, parent);
       
   480             QCOMPARE(index, newerIndex);
       
   481         }
       
   482     }
       
   483 }
       
   484 
       
   485 /*!
       
   486     Tests model's implimentation of QAbstractItemModel::parent()
       
   487  */
       
   488 void tst_QItemModel::parent()
       
   489 {
       
   490     QFETCH(QString, modelType);
       
   491     currentModel = testModels->createModel(modelType);
       
   492 
       
   493     // Make sure the model wont crash and will return an invalid QModelIndex
       
   494     // when asked for the parent of an invalid index.
       
   495     QCOMPARE(currentModel->parent(QModelIndex()), QModelIndex());
       
   496 
       
   497     QFETCH(bool, isEmpty);
       
   498     if (isEmpty)
       
   499         return;
       
   500 
       
   501     // Common error test #1, make sure that a top level index has a parent
       
   502     // that is a invalid QModelIndex.  You model
       
   503     QModelIndex topIndex = currentModel->index(0, 0, QModelIndex());
       
   504     QCOMPARE(currentModel->parent(topIndex), QModelIndex());
       
   505 
       
   506     // Common error test #2, make sure that a second level index has a parent
       
   507     // that is the top level index.
       
   508     if (currentModel->rowCount(topIndex) > 0) {
       
   509         QModelIndex childIndex = currentModel->index(0, 0, topIndex);
       
   510         QCOMPARE(currentModel->parent(childIndex), topIndex);
       
   511     }
       
   512 
       
   513     // Common error test #3, the second colum has the same children
       
   514     // as the first column in a row.
       
   515     QModelIndex topIndex1 = currentModel->index(0, 1, QModelIndex());
       
   516     if (currentModel->rowCount(topIndex1) > 0) {
       
   517         QModelIndex childIndex = currentModel->index(0, 0, topIndex);
       
   518         QModelIndex childIndex1 = currentModel->index(0, 0, topIndex1);
       
   519         QVERIFY(childIndex != childIndex1);
       
   520     }
       
   521 
       
   522     // Full test, walk 10 levels deap through the model making sure that all
       
   523     // parents's children correctly specify their parent
       
   524     QModelIndex top = QModelIndex();
       
   525     checkChildren(currentModel, top);
       
   526 }
       
   527 
       
   528 
       
   529 void tst_QItemModel::data_data()
       
   530 {
       
   531     setupWithNoTestData();
       
   532 }
       
   533 
       
   534 /*!
       
   535     Tests model's implimentation of QAbstractItemModel::data()
       
   536  */
       
   537 void tst_QItemModel::data()
       
   538 {
       
   539     QFETCH(QString, modelType);
       
   540     currentModel = testModels->createModel(modelType);
       
   541 
       
   542     // Invalid index should return an invalid qvariant
       
   543     QVERIFY(!currentModel->data(QModelIndex()).isValid());
       
   544 
       
   545     QFETCH(bool, isEmpty);
       
   546     if (isEmpty)
       
   547         return;
       
   548 
       
   549     // A valid index should have a valid qvariant data
       
   550     QVERIFY(currentModel->index(0,0).isValid());
       
   551 
       
   552     // shouldn't be able to set data on an invalid index
       
   553     QCOMPARE(currentModel->setData(QModelIndex(), "foo", Qt::DisplayRole), false);
       
   554 
       
   555     // General Purpose roles
       
   556     QVariant variant = currentModel->data(currentModel->index(0,0), Qt::ToolTipRole);
       
   557     if (variant.isValid()) {
       
   558         QVERIFY(qVariantCanConvert<QString>(variant));
       
   559     }
       
   560     variant = currentModel->data(currentModel->index(0,0), Qt::StatusTipRole);
       
   561     if (variant.isValid()) {
       
   562         QVERIFY(qVariantCanConvert<QString>(variant));
       
   563     }
       
   564     variant = currentModel->data(currentModel->index(0,0), Qt::WhatsThisRole);
       
   565     if (variant.isValid()) {
       
   566         QVERIFY(qVariantCanConvert<QString>(variant));
       
   567     }
       
   568 
       
   569     variant = currentModel->data(currentModel->index(0,0), Qt::SizeHintRole);
       
   570     if (variant.isValid()) {
       
   571         QVERIFY(qVariantCanConvert<QSize>(variant));
       
   572     }
       
   573 
       
   574 
       
   575     // Appearance roles
       
   576     QVariant fontVariant = currentModel->data(currentModel->index(0,0), Qt::FontRole);
       
   577     if (fontVariant.isValid()) {
       
   578         QVERIFY(qVariantCanConvert<QFont>(fontVariant));
       
   579     }
       
   580 
       
   581     QVariant textAlignmentVariant = currentModel->data(currentModel->index(0,0), Qt::TextAlignmentRole);
       
   582     if (textAlignmentVariant.isValid()) {
       
   583         int alignment = textAlignmentVariant.toInt();
       
   584         QVERIFY(alignment == Qt::AlignLeft ||
       
   585                 alignment == Qt::AlignRight ||
       
   586                 alignment == Qt::AlignHCenter ||
       
   587                 alignment == Qt::AlignJustify);
       
   588     }
       
   589 
       
   590     QVariant colorVariant = currentModel->data(currentModel->index(0,0), Qt::BackgroundColorRole);
       
   591     if (colorVariant.isValid()) {
       
   592         QVERIFY(qVariantCanConvert<QColor>(colorVariant));
       
   593     }
       
   594 
       
   595     colorVariant = currentModel->data(currentModel->index(0,0), Qt::TextColorRole);
       
   596     if (colorVariant.isValid()) {
       
   597         QVERIFY(qVariantCanConvert<QColor>(colorVariant));
       
   598     }
       
   599 
       
   600     QVariant checkStateVariant = currentModel->data(currentModel->index(0,0), Qt::CheckStateRole);
       
   601     if (checkStateVariant.isValid()) {
       
   602         int state = checkStateVariant.toInt();
       
   603         QVERIFY(state == Qt::Unchecked ||
       
   604                 state == Qt::PartiallyChecked ||
       
   605                 state == Qt::Checked);
       
   606     }
       
   607 }
       
   608 
       
   609 void tst_QItemModel::setData_data()
       
   610 {
       
   611     setupWithNoTestData();
       
   612 }
       
   613 
       
   614 /*!
       
   615     Tests model's implimentation of QAbstractItemModel::setData()
       
   616  */
       
   617 void tst_QItemModel::setData()
       
   618 {
       
   619     QFETCH(QString, modelType);
       
   620     currentModel = testModels->createModel(modelType);
       
   621     qRegisterMetaType<QModelIndex>("QModelIndex");
       
   622     QSignalSpy spy(currentModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)));
       
   623     QCOMPARE(currentModel->setData(QModelIndex(), QVariant()), false);
       
   624     QCOMPARE(spy.count(), 0);
       
   625 
       
   626     QFETCH(bool, isEmpty);
       
   627     if (isEmpty)
       
   628         return;
       
   629 
       
   630     QFETCH(bool, readOnly);
       
   631     if (readOnly)
       
   632         return;
       
   633 
       
   634     // Populate the test area so we can chage stuff.  See: cleanup()
       
   635     QModelIndex topIndex = testModels->populateTestArea(currentModel);
       
   636     QVERIFY(currentModel->hasChildren(topIndex));
       
   637     QModelIndex index = currentModel->index(0, 0, topIndex);
       
   638     QVERIFY(index.isValid());
       
   639 
       
   640     spy.clear();
       
   641     QString text = "Index private pointers should always be the same";
       
   642     QCOMPARE(currentModel->setData(index, text, Qt::EditRole), true);
       
   643     QCOMPARE(index.data(Qt::EditRole).toString(), text);
       
   644 
       
   645     // Changing the text shouldn't change the layout, parent, pointer etc.
       
   646     QModelIndex changedIndex = currentModel->index(0, 0, topIndex);
       
   647     QCOMPARE(changedIndex, index);
       
   648     QCOMPARE(spy.count(), 1);
       
   649 }
       
   650 
       
   651 void tst_QItemModel::setHeaderData_data()
       
   652 {
       
   653     setupWithNoTestData();
       
   654 }
       
   655 
       
   656 /*!
       
   657     Tests model's implimentation of QAbstractItemModel::setHeaderData()
       
   658  */
       
   659 void tst_QItemModel::setHeaderData()
       
   660 {
       
   661     QFETCH(QString, modelType);
       
   662     currentModel = testModels->createModel(modelType);
       
   663 
       
   664     QCOMPARE(currentModel->setHeaderData(-1, Qt::Horizontal, QVariant()), false);
       
   665     QCOMPARE(currentModel->setHeaderData(-1, Qt::Vertical, QVariant()), false);
       
   666 
       
   667     QFETCH(bool, isEmpty);
       
   668     if (isEmpty)
       
   669         return;
       
   670 
       
   671     QFETCH(bool, readOnly);
       
   672     if (readOnly)
       
   673         return;
       
   674 
       
   675     // Populate the test area so we can change stuff.  See: cleanup()
       
   676     QModelIndex topIndex = testModels->populateTestArea(currentModel);
       
   677     QVERIFY(currentModel->hasChildren(topIndex));
       
   678     QModelIndex index = currentModel->index(0, 0, topIndex);
       
   679     QVERIFY(index.isValid());
       
   680 
       
   681     qRegisterMetaType<Qt::Orientation>("Qt::Orientation");
       
   682     QSignalSpy spy(currentModel, SIGNAL(headerDataChanged( Qt::Orientation, int , int )));
       
   683 
       
   684     QString text = "Index private pointers should always be the same";
       
   685     int signalCount = 0;
       
   686     for (int i = 0; i < 4; ++i){
       
   687         if(currentModel->setHeaderData(i, Qt::Horizontal, text)) {
       
   688             QCOMPARE(currentModel->headerData(i, Qt::Horizontal).toString(), text);
       
   689             ++signalCount;
       
   690         }
       
   691         if(currentModel->setHeaderData(i, Qt::Vertical, text)) {
       
   692             QCOMPARE(currentModel->headerData(i, Qt::Vertical).toString(), text);
       
   693             ++signalCount;
       
   694         }
       
   695     }
       
   696     QCOMPARE(spy.count(), signalCount);
       
   697 }
       
   698 
       
   699 void tst_QItemModel::sort_data()
       
   700 {
       
   701     setupWithNoTestData();
       
   702 }
       
   703 
       
   704 /*!
       
   705     Tests model's implimentation of QAbstractItemModel::sort()
       
   706  */
       
   707 void tst_QItemModel::sort()
       
   708 {
       
   709     QFETCH(QString, modelType);
       
   710     currentModel = testModels->createModel(modelType);
       
   711 
       
   712     QFETCH(bool, isEmpty);
       
   713     if (isEmpty)
       
   714         return;
       
   715 
       
   716     // Populate the test area so we can chage stuff.  See: cleanup()
       
   717     QPersistentModelIndex topIndex = testModels->populateTestArea(currentModel);
       
   718     QVERIFY(currentModel->hasChildren(topIndex));
       
   719     QModelIndex index = currentModel->index(0, 0, topIndex);
       
   720     QVERIFY(index.isValid());
       
   721     QSignalSpy spy(currentModel, SIGNAL(layoutChanged()));
       
   722     for (int i=-1; i < 10; ++i){
       
   723         currentModel->sort(i);
       
   724         if (index != currentModel->index(0, 0, topIndex)){
       
   725             QVERIFY(spy.count() > 0);
       
   726             index = currentModel->index(0, 0, topIndex);
       
   727             spy.clear();
       
   728         }
       
   729     }
       
   730     currentModel->sort(99999);
       
   731 }
       
   732 
       
   733 /*!
       
   734     Tests model's implimentation of QAbstractItemModel::removeRow() and QAbstractItemModel::removeColumn()
       
   735  */
       
   736 #define START 0
       
   737 #define MIDDLE 6
       
   738 #define END -1
       
   739 #define MANY 9
       
   740 #define ALL -1
       
   741 #define NOSIGNALS 0
       
   742 #define DEFAULTCOUNT 1
       
   743 #define DNS 1 // DefaultNumberOfSignals
       
   744 #define RECURSIVE true
       
   745 #define SUCCESS true
       
   746 #define FAIL false
       
   747 void tst_QItemModel::remove_data()
       
   748 {
       
   749     ModelsToTest modelsToTest;
       
   750     QTest::addColumn<QString>("modelType");
       
   751     QTest::addColumn<bool>("readOnly");
       
   752     QTest::addColumn<bool>("isEmpty");
       
   753 
       
   754     QTest::addColumn<int>("start");
       
   755     QTest::addColumn<int>("count");
       
   756 
       
   757     QTest::addColumn<int>("numberOfRowsAboutToBeRemovedSignals");
       
   758     QTest::addColumn<int>("numberOfColumnsAboutToBeRemovedSignals");
       
   759     QTest::addColumn<int>("numberOfRowsRemovedSignals");
       
   760     QTest::addColumn<int>("numberOfColumnsRemovedSignals");
       
   761 
       
   762     QTest::addColumn<bool>("recursive");
       
   763     QTest::addColumn<int>("recursiveRow");
       
   764     QTest::addColumn<int>("recursiveCount");
       
   765 
       
   766     QTest::addColumn<bool>("shouldSucceed");
       
   767 
       
   768 #define makeTestRow(testName, start, count, sar, srr, sac, src, r, rr, rc, s) \
       
   769         QTest::newRow((t.modelType + testName).toLatin1().data()) << t.modelType << readOnly << isEmpty << \
       
   770         start << count << \
       
   771         sar << srr << sac << src << \
       
   772         r << rr << rc << \
       
   773         s;
       
   774 
       
   775     for (int i = 0; i < modelsToTest.tests.size(); ++i) {
       
   776         ModelsToTest::test t = modelsToTest.tests.at(i);
       
   777         QString name = t.modelType;
       
   778         bool readOnly = (t.read == ModelsToTest::ReadOnly);
       
   779         bool isEmpty = (t.contains == ModelsToTest::Empty);
       
   780 
       
   781         // half these
       
   782         makeTestRow(":one at the start",  START,  DEFAULTCOUNT, DNS, DNS, DNS, DNS, !RECURSIVE, 0, 0, SUCCESS);
       
   783         makeTestRow(":one at the middle", MIDDLE, DEFAULTCOUNT, DNS, DNS, DNS, DNS, !RECURSIVE, 0, 0, SUCCESS);
       
   784         makeTestRow(":one at the end",    END,    DEFAULTCOUNT, DNS, DNS, DNS, DNS, !RECURSIVE, 0, 0, SUCCESS);
       
   785 
       
   786         makeTestRow(":many at the start",  START,  MANY, DNS, DNS, DNS, DNS, !RECURSIVE, 0, 0, SUCCESS);
       
   787         makeTestRow(":many at the middle", MIDDLE, MANY, DNS, DNS, DNS, DNS, !RECURSIVE, 0, 0, SUCCESS);
       
   788         makeTestRow(":many at the end",    END,    MANY, DNS, DNS, DNS, DNS, !RECURSIVE, 0, 0, SUCCESS);
       
   789 
       
   790         makeTestRow(":remove all",        START,  ALL,  DNS, DNS, DNS, DNS, !RECURSIVE, 0, 0, SUCCESS);
       
   791 
       
   792         makeTestRow(":none at the start",  START,  0, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL);
       
   793         makeTestRow(":none at the middle", MIDDLE, 0, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL);
       
   794         makeTestRow(":none at the end",    END,    0, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL);
       
   795 
       
   796         makeTestRow(":invalid start, valid count", -99,  0,    NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL);
       
   797         makeTestRow(":invalid start, valid count", 9999, 0,    NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL);
       
   798         makeTestRow(":invalid start, valid count", -99,  1,    NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL);
       
   799         makeTestRow(":invalid start, valid count", 9999, 1,    NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL);
       
   800         makeTestRow(":invalid start, valid count", -99,  MANY, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL);
       
   801         makeTestRow(":invalid start, valid count", 9999, MANY, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL);
       
   802 
       
   803         makeTestRow(":valid start, invalid count",  START,  -2,   NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL);
       
   804         makeTestRow(":valid start, invalid count",  MIDDLE, -2,   NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL);
       
   805         makeTestRow(":valid start, invalid count",  END,    -2,   NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL);
       
   806         makeTestRow(":valid start, invalid count",  START,  9999, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL);
       
   807         makeTestRow(":valid start, invalid count",  MIDDLE, 9999, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL);
       
   808         makeTestRow(":valid start, invalid count",  END,    9999, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL);
       
   809 
       
   810         // Recursive remove's might assert, havn't decided yet...
       
   811         //makeTestRow(":one at the start recursivly",  START,  DEFAULTCOUNT, 2, DNS, 2, DNS, RECURSIVE, START, DEFAULTCOUNT, FAIL);
       
   812         //makeTestRow(":one at the middle recursivly", MIDDLE, DEFAULTCOUNT, 2, DNS, 2, DNS, RECURSIVE, START, DEFAULTCOUNT, SUCCESS);
       
   813         //makeTestRow(":one at the end recursivly",    END,    DEFAULTCOUNT, 2, DNS, 2, DNS, RECURSIVE, START, DEFAULTCOUNT, SUCCESS);
       
   814     }
       
   815 }
       
   816 
       
   817 void tst_QItemModel::remove()
       
   818 {
       
   819     QFETCH(QString, modelType);
       
   820 
       
   821     currentModel = testModels->createModel(modelType);
       
   822 
       
   823     QFETCH(bool, readOnly);
       
   824     if (readOnly)
       
   825         return;
       
   826 
       
   827     QFETCH(int, start);
       
   828     QFETCH(int, count);
       
   829 
       
   830     QFETCH(bool, recursive);
       
   831     removeRecursively = recursive;
       
   832 
       
   833 /*!
       
   834     Removes count number of rows starting at start
       
   835     if count is -1 it removes all rows
       
   836     if start is -1 then it starts at the last row - count
       
   837  */
       
   838     QFETCH(bool, shouldSucceed);
       
   839 
       
   840     // Populate the test area so we can remove something.  See: cleanup()
       
   841     // parentOfRemoved is stored so that the slots can make sure parentOfRemoved is the index that is emited.
       
   842     parentOfRemoved = testModels->populateTestArea(currentModel);
       
   843 
       
   844     if (count == -1)
       
   845         count = currentModel->rowCount(parentOfRemoved);
       
   846     if (start == -1)
       
   847         start = currentModel->rowCount(parentOfRemoved)-count;
       
   848 
       
   849     if (currentModel->rowCount(parentOfRemoved) == 0 ||
       
   850         currentModel->columnCount(parentOfRemoved) == 0) {
       
   851         qWarning() << "model test area doesn't have any rows or columns, can't fully test remove(). Skipping";
       
   852         return;
       
   853     }
       
   854 
       
   855     //qDebug() << "remove start:" << start << "count:" << count << "rowCount:" << currentModel->rowCount(parentOfRemoved);
       
   856 
       
   857     // When a row or column is removed there should be two signals.
       
   858     // Watch to make sure they are emited and get the row/column count when they do get emited by connecting them to a slot
       
   859     qRegisterMetaType<QModelIndex>("QModelIndex");
       
   860     QSignalSpy columnsAboutToBeRemovedSpy(currentModel, SIGNAL(columnsAboutToBeRemoved( const QModelIndex &, int , int )));
       
   861     QSignalSpy rowsAboutToBeRemovedSpy(currentModel, SIGNAL(rowsAboutToBeRemoved( const QModelIndex &, int , int )));
       
   862     QSignalSpy columnsRemovedSpy(currentModel, SIGNAL(columnsRemoved( const QModelIndex &, int, int )));
       
   863     QSignalSpy rowsRemovedSpy(currentModel, SIGNAL(rowsRemoved( const QModelIndex &, int, int )));
       
   864     QSignalSpy modelResetSpy(currentModel, SIGNAL(modelReset()));
       
   865     QSignalSpy modelLayoutChangedSpy(currentModel, SIGNAL(layoutChanged()));
       
   866 
       
   867     QFETCH(int, numberOfRowsAboutToBeRemovedSignals);
       
   868     QFETCH(int, numberOfColumnsAboutToBeRemovedSignals);
       
   869     QFETCH(int, numberOfRowsRemovedSignals);
       
   870     QFETCH(int, numberOfColumnsRemovedSignals);
       
   871 
       
   872     //
       
   873     // test removeRow()
       
   874     //
       
   875     connect(currentModel, SIGNAL(rowsAboutToBeRemoved( const QModelIndex &, int , int )),
       
   876             this, SLOT(slot_rowsAboutToRemove(const QModelIndex &)));
       
   877     connect(currentModel, SIGNAL(rowsRemoved( const QModelIndex &, int , int )),
       
   878             this, SLOT(slot_rowsRemoved(const QModelIndex &)));
       
   879     int beforeRemoveRowCount = currentModel->rowCount(parentOfRemoved);
       
   880     QPersistentModelIndex dyingIndex = currentModel->index(start + count + 1, 0, parentOfRemoved);
       
   881     QCOMPARE(currentModel->removeRows(start, count, parentOfRemoved), shouldSucceed);
       
   882     currentModel->submit();
       
   883     if (shouldSucceed && dyingIndex.isValid())
       
   884         QCOMPARE(dyingIndex.row(), start + 1);
       
   885 
       
   886     if (rowsAboutToBeRemovedSpy.count() > 0){
       
   887         QList<QVariant> arguments = rowsAboutToBeRemovedSpy.at(0);
       
   888         QModelIndex parent = (qvariant_cast<QModelIndex>(arguments.at(0)));
       
   889         int first = arguments.at(1).toInt();
       
   890         int last = arguments.at(2).toInt();
       
   891         QCOMPARE(first, start);
       
   892         QCOMPARE(last,  start + count - 1);
       
   893         QVERIFY(parentOfRemoved == parent);
       
   894     }
       
   895 
       
   896     if (rowsRemovedSpy.count() > 0){
       
   897         QList<QVariant> arguments = rowsRemovedSpy.at(0);
       
   898         QModelIndex parent = (qvariant_cast<QModelIndex>(arguments.at(0)));
       
   899         int first = arguments.at(1).toInt();
       
   900         int last = arguments.at(2).toInt();
       
   901         QCOMPARE(first, start);
       
   902         QCOMPARE(last,  start + count - 1);
       
   903         QVERIFY(parentOfRemoved == parent);
       
   904     }
       
   905 
       
   906     // Only the row signals should have been emited
       
   907     if (modelResetSpy.count() >= 1 || modelLayoutChangedSpy.count() >=1 ){
       
   908         QCOMPARE(columnsAboutToBeRemovedSpy.count(), 0);
       
   909         QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0);
       
   910         QCOMPARE(columnsRemovedSpy.count(), 0);
       
   911         QCOMPARE(rowsRemovedSpy.count(), 0);
       
   912     }
       
   913     else {
       
   914         QCOMPARE(columnsAboutToBeRemovedSpy.count(), 0);
       
   915         QCOMPARE(rowsAboutToBeRemovedSpy.count(), numberOfRowsAboutToBeRemovedSignals);
       
   916         QCOMPARE(columnsRemovedSpy.count(), 0);
       
   917         QCOMPARE(rowsRemovedSpy.count(), numberOfRowsRemovedSignals);
       
   918     }
       
   919 
       
   920     // The row count should only change *after* rowsAboutToBeRemoved has been emited
       
   921     //qDebug() << beforeRemoveRowCount << afterAboutToRemoveRowCount << afterRemoveRowCount << currentModel->rowCount(parentOfRemoved);
       
   922     if (shouldSucceed) {
       
   923         if (modelResetSpy.count() == 0 && modelLayoutChangedSpy.count() == 0){
       
   924             QCOMPARE(afterAboutToRemoveRowCount, beforeRemoveRowCount);
       
   925             QCOMPARE(afterRemoveRowCount, beforeRemoveRowCount-count-(numberOfRowsRemovedSignals-1));
       
   926         }
       
   927         if (modelResetSpy.count() == 0 )
       
   928             QCOMPARE(currentModel->rowCount(parentOfRemoved), beforeRemoveRowCount-count-(numberOfRowsRemovedSignals-1));
       
   929     }
       
   930     else {
       
   931         if (recursive)
       
   932             QCOMPARE(currentModel->rowCount(parentOfRemoved), beforeRemoveRowCount-1);
       
   933         else
       
   934             QCOMPARE(currentModel->rowCount(parentOfRemoved), beforeRemoveRowCount);
       
   935 
       
   936     }
       
   937     disconnect(currentModel, SIGNAL(rowsAboutToBeRemoved( const QModelIndex &, int , int )),
       
   938             this, SLOT(slot_rowsAboutToRemove(const QModelIndex &)));
       
   939     disconnect(currentModel, SIGNAL(rowsRemoved( const QModelIndex &, int , int )),
       
   940             this, SLOT(slot_rowsRemoved(const QModelIndex &)));
       
   941     modelResetSpy.clear();
       
   942     QCOMPARE(modelResetSpy.count(), 0);
       
   943 
       
   944     //
       
   945     // Test remove column
       
   946     //
       
   947     connect(currentModel, SIGNAL(columnsAboutToBeRemoved( const QModelIndex &, int , int )),
       
   948             this, SLOT(slot_columnsAboutToRemove(const QModelIndex &)));
       
   949     connect(currentModel, SIGNAL(columnsRemoved( const QModelIndex &, int , int )),
       
   950             this, SLOT(slot_columnsRemoved(const QModelIndex &)));
       
   951     int beforeRemoveColumnCount = currentModel->columnCount(parentOfRemoved);
       
   952 
       
   953     // Some models don't let you remove the column, only row
       
   954     if (currentModel->removeColumns(start, count, parentOfRemoved)) {
       
   955         currentModel->submit();
       
   956         // Didn't reset the rows, so they should still be at the same value
       
   957         if (modelResetSpy.count() >= 1 || modelLayoutChangedSpy.count() >= 1){
       
   958             QCOMPARE(columnsAboutToBeRemovedSpy.count(), 0);
       
   959             //QCOMPARE(rowsAboutToBeRemovedSpy.count(), numberOfRowsAboutToBeRemovedSignals);
       
   960             QCOMPARE(columnsRemovedSpy.count(), 0);
       
   961             //QCOMPARE(rowsRemovedSpy.count(), numberOfRowsRemovedSignals);
       
   962         }
       
   963         else {
       
   964             QCOMPARE(columnsAboutToBeRemovedSpy.count(), numberOfColumnsAboutToBeRemovedSignals);
       
   965             QCOMPARE(rowsAboutToBeRemovedSpy.count(), numberOfRowsAboutToBeRemovedSignals);
       
   966             QCOMPARE(columnsRemovedSpy.count(), numberOfColumnsRemovedSignals);
       
   967             QCOMPARE(rowsRemovedSpy.count(), numberOfRowsRemovedSignals);
       
   968         }
       
   969 
       
   970         // The column count should only change *after* rowsAboutToBeRemoved has been emited
       
   971         if (shouldSucceed) {
       
   972             if (modelResetSpy.count() == 0 && modelLayoutChangedSpy.count() == 0){
       
   973                 QCOMPARE(afterAboutToRemoveColumnCount, beforeRemoveColumnCount);
       
   974                 QCOMPARE(afterRemoveColumnCount, beforeRemoveColumnCount-count-(numberOfColumnsRemovedSignals-1));
       
   975             }
       
   976             if (modelResetSpy.count() == 0)
       
   977                 QCOMPARE(currentModel->columnCount(parentOfRemoved), beforeRemoveColumnCount-count-(numberOfColumnsRemovedSignals-1));
       
   978         }
       
   979         else
       
   980             QCOMPARE(currentModel->rowCount(parentOfRemoved), beforeRemoveRowCount);
       
   981     }
       
   982     disconnect(currentModel, SIGNAL(columnsAboutToBeRemoved( const QModelIndex &, int , int )),
       
   983             this, SLOT(slot_columnsAboutToRemove(const QModelIndex &)));
       
   984     disconnect(currentModel, SIGNAL(columnsRemoved( const QModelIndex &, int , int )),
       
   985             this, SLOT(slot_columnsRemoved(const QModelIndex &)));
       
   986 
       
   987     if (columnsAboutToBeRemovedSpy.count() > 0){
       
   988         QList<QVariant> arguments = columnsAboutToBeRemovedSpy.at(0);
       
   989         QModelIndex parent = (qvariant_cast<QModelIndex>(arguments.at(0)));
       
   990         int first = arguments.at(1).toInt();
       
   991         int last = arguments.at(2).toInt();
       
   992         QCOMPARE(first, start);
       
   993         QCOMPARE(last,  start + count - 1);
       
   994         QVERIFY(parentOfRemoved == parent);
       
   995     }
       
   996 
       
   997     if (columnsRemovedSpy.count() > 0){
       
   998         QList<QVariant> arguments = columnsRemovedSpy.at(0);
       
   999         QModelIndex parent = (qvariant_cast<QModelIndex>(arguments.at(0)));
       
  1000         int first = arguments.at(1).toInt();
       
  1001         int last = arguments.at(2).toInt();
       
  1002         QCOMPARE(first, start);
       
  1003         QCOMPARE(last,  start + count - 1);
       
  1004         QVERIFY(parentOfRemoved == parent);
       
  1005     }
       
  1006 
       
  1007     // Cleanup the test area because remove::() is called multiple times in a test
       
  1008     testModels->cleanupTestArea(currentModel);
       
  1009 }
       
  1010 
       
  1011 /*!
       
  1012     Developers like to use the slots to then *do* something on the model so it needs to be
       
  1013     in a working state.
       
  1014  */
       
  1015 void verifyState(QAbstractItemModel *currentModel) {
       
  1016     // Make sure the model isn't confused right now and still knows what is root
       
  1017     if (currentModel->hasChildren()) {
       
  1018         QCOMPARE(currentModel->hasIndex(0, 0), true);
       
  1019         QModelIndex index = currentModel->index(0,0);
       
  1020         QCOMPARE(index.isValid(), true);
       
  1021         QCOMPARE(currentModel->parent(index).isValid(), false);
       
  1022     } else {
       
  1023         QModelIndex index = currentModel->index(0,0);
       
  1024         QCOMPARE(index.isValid(), false);
       
  1025     }
       
  1026 }
       
  1027 
       
  1028 void tst_QItemModel::slot_rowsAboutToRemove(const QModelIndex &parent)
       
  1029 {
       
  1030     QVERIFY(parentOfRemoved == parent);
       
  1031     //qDebug() << "slot_rowsAboutToRemove" << currentModel->rowCount(parent);
       
  1032     afterAboutToRemoveRowCount = currentModel->rowCount(parent);
       
  1033     // hasChildren() should still work
       
  1034     if (afterAboutToRemoveRowCount > 0)
       
  1035         QCOMPARE(currentModel->hasChildren(parent), true);
       
  1036     else
       
  1037         QCOMPARE(currentModel->hasChildren(parent), false);
       
  1038 
       
  1039     verifyState(currentModel);
       
  1040 
       
  1041     // This does happen
       
  1042     if (removeRecursively) {
       
  1043         QFETCH(int, recursiveRow);
       
  1044         QFETCH(int, recursiveCount);
       
  1045         //qDebug() << recursiveRow << recursiveCount;
       
  1046         removeRecursively = false;
       
  1047         QCOMPARE(currentModel->removeRows(recursiveRow, recursiveCount, parent), true);
       
  1048     }
       
  1049 }
       
  1050 
       
  1051 void tst_QItemModel::slot_rowsRemoved(const QModelIndex &parent)
       
  1052 {
       
  1053     QVERIFY(parentOfRemoved == parent);
       
  1054     //qDebug() << "slot_rowsRemoved" << currentModel->rowCount(parent);
       
  1055     afterRemoveRowCount = currentModel->rowCount(parent);
       
  1056     if (afterRemoveRowCount > 0)
       
  1057         QCOMPARE(currentModel->hasChildren(parent), true);
       
  1058     else
       
  1059         QCOMPARE(currentModel->hasChildren(parent), false);
       
  1060 
       
  1061     verifyState(currentModel);
       
  1062 }
       
  1063 
       
  1064 void tst_QItemModel::slot_columnsAboutToRemove(const QModelIndex &parent)
       
  1065 {
       
  1066     QVERIFY(parentOfRemoved == parent);
       
  1067     afterAboutToRemoveColumnCount = currentModel->columnCount(parent);
       
  1068     // hasChildren() should still work
       
  1069     if (afterAboutToRemoveColumnCount > 0 && currentModel->rowCount(parent) > 0)
       
  1070         QCOMPARE(currentModel->hasChildren(parent), true);
       
  1071     else
       
  1072         QCOMPARE(currentModel->hasChildren(parent), false);
       
  1073 
       
  1074     verifyState(currentModel);
       
  1075 }
       
  1076 
       
  1077 void tst_QItemModel::slot_columnsRemoved(const QModelIndex &parent)
       
  1078 {
       
  1079     QVERIFY(parentOfRemoved == parent);
       
  1080     afterRemoveColumnCount = currentModel->columnCount(parent);
       
  1081     if (afterRemoveColumnCount > 0)
       
  1082         QCOMPARE(currentModel->hasChildren(parent), true);
       
  1083     else
       
  1084         QCOMPARE(currentModel->hasChildren(parent), false);
       
  1085 
       
  1086     verifyState(currentModel);
       
  1087 }
       
  1088 
       
  1089 /*!
       
  1090     Tests the model's insertRow/Column()
       
  1091  */
       
  1092 void tst_QItemModel::insert_data()
       
  1093 {
       
  1094     ModelsToTest modelsToTest;
       
  1095     QTest::addColumn<QString>("modelType");
       
  1096     QTest::addColumn<bool>("readOnly");
       
  1097     QTest::addColumn<bool>("isEmpty");
       
  1098 
       
  1099     QTest::addColumn<int>("start");
       
  1100     QTest::addColumn<int>("count");
       
  1101 
       
  1102     QTest::addColumn<int>("numberOfRowsAboutToBeInsertedSignals");
       
  1103     QTest::addColumn<int>("numberOfColumnsAboutToBeInsertedSignals");
       
  1104     QTest::addColumn<int>("numberOfRowsInsertedSignals");
       
  1105     QTest::addColumn<int>("numberOfColumnsInsertedSignals");
       
  1106 
       
  1107     QTest::addColumn<bool>("recursive");
       
  1108     QTest::addColumn<int>("recursiveRow");
       
  1109     QTest::addColumn<int>("recursiveCount");
       
  1110 
       
  1111     QTest::addColumn<bool>("shouldSucceed");
       
  1112 
       
  1113 #define makeTestRow(testName, start, count, sar, srr, sac, src, r, rr, rc, s) \
       
  1114         QTest::newRow((t.modelType + testName).toLatin1().data()) << t.modelType << readOnly << isEmpty << \
       
  1115         start << count << \
       
  1116         sar << srr << sac << src << \
       
  1117         r << rr << rc << \
       
  1118         s;
       
  1119 
       
  1120     for (int i = 0; i < modelsToTest.tests.size(); ++i) {
       
  1121         ModelsToTest::test t = modelsToTest.tests.at(i);
       
  1122         QString name = t.modelType;
       
  1123         bool readOnly = (t.read == ModelsToTest::ReadOnly);
       
  1124         bool isEmpty = (t.contains == ModelsToTest::Empty);
       
  1125 
       
  1126         // half these
       
  1127         makeTestRow(":one at the start",  START,  DEFAULTCOUNT, DNS, DNS, DNS, DNS, !RECURSIVE, 0, 0, SUCCESS);
       
  1128         makeTestRow(":one at the middle", MIDDLE, DEFAULTCOUNT, DNS, DNS, DNS, DNS, !RECURSIVE, 0, 0, SUCCESS);
       
  1129         makeTestRow(":one at the end",    END,    DEFAULTCOUNT, DNS, DNS, DNS, DNS, !RECURSIVE, 0, 0, SUCCESS);
       
  1130 
       
  1131         makeTestRow(":many at the start",  START,  MANY, DNS, DNS, DNS, DNS, !RECURSIVE, 0, 0, SUCCESS);
       
  1132         makeTestRow(":many at the middle", MIDDLE, MANY, DNS, DNS, DNS, DNS, !RECURSIVE, 0, 0, SUCCESS);
       
  1133         makeTestRow(":many at the end",    END,    MANY, DNS, DNS, DNS, DNS, !RECURSIVE, 0, 0, SUCCESS);
       
  1134 
       
  1135         makeTestRow(":add row count",        START,  ALL,  DNS, DNS, DNS, DNS, !RECURSIVE, 0, 0, SUCCESS);
       
  1136 
       
  1137         makeTestRow(":none at the start",  START,  0, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL);
       
  1138         makeTestRow(":none at the middle", MIDDLE, 0, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL);
       
  1139         makeTestRow(":none at the end",    END,    0, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL);
       
  1140 
       
  1141         makeTestRow(":invalid start, valid count", -99,  0,    NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL);
       
  1142         makeTestRow(":invalid start, valid count", 9999, 0,    NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL);
       
  1143         makeTestRow(":invalid start, valid count", -99,  1,    NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL);
       
  1144         makeTestRow(":invalid start, valid count", 9999, 1,    NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL);
       
  1145         makeTestRow(":invalid start, valid count", -99,  MANY, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL);
       
  1146         makeTestRow(":invalid start, valid count", 9999, MANY, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL);
       
  1147 
       
  1148         makeTestRow(":valid start, invalid count",  START,  -2,   NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL);
       
  1149         makeTestRow(":valid start, invalid count",  MIDDLE, -2,   NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL);
       
  1150         makeTestRow(":valid start, invalid count",  END,    -2,   NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL);
       
  1151 
       
  1152         // Recursive insert's might assert, havn't decided yet...
       
  1153         //makeTestRow(":one at the start recursivly",  START,  DEFAULTCOUNT, 2, DNS, 2, DNS, RECURSIVE, START, DEFAULTCOUNT, FAIL);
       
  1154         //makeTestRow(":one at the middle recursivly", MIDDLE, DEFAULTCOUNT, 2, DNS, 2, DNS, RECURSIVE, START, DEFAULTCOUNT, SUCCESS);
       
  1155         //makeTestRow(":one at the end recursivly",    END,    DEFAULTCOUNT, 2, DNS, 2, DNS, RECURSIVE, START, DEFAULTCOUNT, SUCCESS);
       
  1156     }
       
  1157 }
       
  1158 
       
  1159 void tst_QItemModel::insert()
       
  1160 {
       
  1161     QFETCH(QString, modelType);
       
  1162     currentModel = testModels->createModel(modelType);
       
  1163 
       
  1164     QFETCH(bool, readOnly);
       
  1165     if (readOnly)
       
  1166         return;
       
  1167 
       
  1168     QFETCH(int, start);
       
  1169     QFETCH(int, count);
       
  1170 
       
  1171     QFETCH(bool, recursive);
       
  1172     insertRecursively = recursive;
       
  1173 
       
  1174 /*!
       
  1175     Inserts count number of rows starting at start
       
  1176     if count is -1 it inserts all rows
       
  1177     if start is -1 then it starts at the last row - count
       
  1178  */
       
  1179     QFETCH(bool, shouldSucceed);
       
  1180 
       
  1181     // Populate the test area so we can insert something.  See: cleanup()
       
  1182     // parentOfInserted is stored so that the slots can make sure parentOfInserted is the index that is emited.
       
  1183     parentOfInserted = testModels->populateTestArea(currentModel);
       
  1184 
       
  1185     if (count == -1)
       
  1186         count = currentModel->rowCount(parentOfInserted);
       
  1187     if (start == -1)
       
  1188         start = currentModel->rowCount(parentOfInserted)-count;
       
  1189 
       
  1190     if (currentModel->rowCount(parentOfInserted) == 0 ||
       
  1191         currentModel->columnCount(parentOfInserted) == 0) {
       
  1192         qWarning() << "model test area doesn't have any rows, can't fully test insert(). Skipping";
       
  1193         return;
       
  1194     }
       
  1195 
       
  1196     //qDebug() << "insert start:" << start << "count:" << count << "rowCount:" << currentModel->rowCount(parentOfInserted);
       
  1197 
       
  1198     // When a row or column is inserted there should be two signals.
       
  1199     // Watch to make sure they are emited and get the row/column count when they do get emited by connecting them to a slot
       
  1200     qRegisterMetaType<QModelIndex>("QModelIndex");
       
  1201     QSignalSpy columnsAboutToBeInsertedSpy(currentModel, SIGNAL(columnsAboutToBeInserted( const QModelIndex &, int , int )));
       
  1202     QSignalSpy rowsAboutToBeInsertedSpy(currentModel, SIGNAL(rowsAboutToBeInserted( const QModelIndex &, int , int )));
       
  1203     QSignalSpy columnsInsertedSpy(currentModel, SIGNAL(columnsInserted( const QModelIndex &, int, int )));
       
  1204     QSignalSpy rowsInsertedSpy(currentModel, SIGNAL(rowsInserted( const QModelIndex &, int, int )));
       
  1205     QSignalSpy modelResetSpy(currentModel, SIGNAL(modelReset()));
       
  1206     QSignalSpy modelLayoutChangedSpy(currentModel, SIGNAL(layoutChanged()));
       
  1207 
       
  1208     QFETCH(int, numberOfRowsAboutToBeInsertedSignals);
       
  1209     QFETCH(int, numberOfColumnsAboutToBeInsertedSignals);
       
  1210     QFETCH(int, numberOfRowsInsertedSignals);
       
  1211     QFETCH(int, numberOfColumnsInsertedSignals);
       
  1212 
       
  1213     //
       
  1214     // test insertRow()
       
  1215     //
       
  1216     connect(currentModel, SIGNAL(rowsAboutToBeInserted( const QModelIndex &, int , int )),
       
  1217             this, SLOT(slot_rowsAboutToInserted(const QModelIndex &)));
       
  1218     connect(currentModel, SIGNAL(rowsInserted( const QModelIndex &, int , int )),
       
  1219             this, SLOT(slot_rowsInserted(const QModelIndex &)));
       
  1220     int beforeInsertRowCount = currentModel->rowCount(parentOfInserted);
       
  1221     QCOMPARE(currentModel->insertRows(start, count, parentOfInserted), shouldSucceed);
       
  1222     currentModel->submit();
       
  1223 
       
  1224     if (rowsAboutToBeInsertedSpy.count() > 0){
       
  1225         QList<QVariant> arguments = rowsAboutToBeInsertedSpy.at(0);
       
  1226         QModelIndex parent = (qvariant_cast<QModelIndex>(arguments.at(0)));
       
  1227         int first = arguments.at(1).toInt();
       
  1228         int last = arguments.at(2).toInt();
       
  1229         QCOMPARE(first, start);
       
  1230         QCOMPARE(last,  start + count - 1);
       
  1231         QVERIFY(parentOfInserted == parent);
       
  1232     }
       
  1233 
       
  1234     if (rowsInsertedSpy.count() > 0){
       
  1235         QList<QVariant> arguments = rowsInsertedSpy.at(0);
       
  1236         QModelIndex parent = (qvariant_cast<QModelIndex>(arguments.at(0)));
       
  1237         int first = arguments.at(1).toInt();
       
  1238         int last = arguments.at(2).toInt();
       
  1239         QCOMPARE(first, start);
       
  1240         QCOMPARE(last,  start + count - 1);
       
  1241         QVERIFY(parentOfInserted == parent);
       
  1242     }
       
  1243 
       
  1244     // Only the row signals should have been emited
       
  1245     if (modelResetSpy.count() >= 1 || modelLayoutChangedSpy.count() >= 1) {
       
  1246         QCOMPARE(columnsAboutToBeInsertedSpy.count(), 0);
       
  1247         QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0);
       
  1248         QCOMPARE(columnsInsertedSpy.count(), 0);
       
  1249         QCOMPARE(rowsInsertedSpy.count(), 0);
       
  1250     }
       
  1251     else {
       
  1252         QCOMPARE(columnsAboutToBeInsertedSpy.count(), 0);
       
  1253         QCOMPARE(rowsAboutToBeInsertedSpy.count(), numberOfRowsAboutToBeInsertedSignals);
       
  1254         QCOMPARE(columnsInsertedSpy.count(), 0);
       
  1255         QCOMPARE(rowsInsertedSpy.count(), numberOfRowsInsertedSignals);
       
  1256     }
       
  1257     // The row count should only change *after* rowsAboutToBeInserted has been emited
       
  1258     //qDebug() << beforeInsertRowCount << afterAboutToInsertRowCount << afterInsertRowCount << currentModel->rowCount(parentOfInserted);
       
  1259     if (shouldSucceed) {
       
  1260         if (modelResetSpy.count() == 0 && modelLayoutChangedSpy.count() == 0) {
       
  1261             QCOMPARE(afterAboutToInsertRowCount, beforeInsertRowCount);
       
  1262             QCOMPARE(afterInsertRowCount, beforeInsertRowCount+count+(numberOfRowsInsertedSignals-1));
       
  1263         }
       
  1264         if (modelResetSpy.count() == 0)
       
  1265             QCOMPARE(currentModel->rowCount(parentOfInserted), beforeInsertRowCount+count+(numberOfRowsInsertedSignals-1));
       
  1266     }
       
  1267     else {
       
  1268         if (recursive)
       
  1269             QCOMPARE(currentModel->rowCount(parentOfInserted), beforeInsertRowCount+1);
       
  1270         else
       
  1271             QCOMPARE(currentModel->rowCount(parentOfInserted), beforeInsertRowCount);
       
  1272 
       
  1273     }
       
  1274     disconnect(currentModel, SIGNAL(rowsAboutToBeInserted( const QModelIndex &, int , int )),
       
  1275             this, SLOT(slot_rowsAboutToInserted(const QModelIndex &)));
       
  1276     disconnect(currentModel, SIGNAL(rowsInserted( const QModelIndex &, int , int )),
       
  1277             this, SLOT(slot_rowsInserted(const QModelIndex &)));
       
  1278     modelResetSpy.clear();
       
  1279 
       
  1280     //
       
  1281     // Test insertColumn()
       
  1282     //
       
  1283     connect(currentModel, SIGNAL(columnsAboutToBeInserted( const QModelIndex &, int , int )),
       
  1284             this, SLOT(slot_columnsAboutToInserted(const QModelIndex &)));
       
  1285     connect(currentModel, SIGNAL(columnsInserted( const QModelIndex &, int , int )),
       
  1286             this, SLOT(slot_columnsInserted(const QModelIndex &)));
       
  1287     int beforeInsertColumnCount = currentModel->columnCount(parentOfInserted);
       
  1288 
       
  1289     // Some models don't let you insert the column, only row
       
  1290     if (currentModel->insertColumns(start, count, parentOfInserted)) {
       
  1291         currentModel->submit();
       
  1292         if (modelResetSpy.count() >= 1 || modelLayoutChangedSpy.count() >= 1) {
       
  1293             // Didn't reset the rows, so they should still be at the same value
       
  1294             QCOMPARE(columnsAboutToBeInsertedSpy.count(), 0);
       
  1295             //QCOMPARE(rowsAboutToBeInsertedSpy.count(), numberOfRowsAboutToBeInsertedSignals);
       
  1296             QCOMPARE(columnsInsertedSpy.count(), 0);
       
  1297             //QCOMPARE(rowsInsertedSpy.count(), numberOfRowsInsertedSignals);
       
  1298         }
       
  1299         else {
       
  1300             // Didn't reset the rows, so they should still be at the same value
       
  1301             QCOMPARE(columnsAboutToBeInsertedSpy.count(), numberOfColumnsAboutToBeInsertedSignals);
       
  1302             QCOMPARE(rowsAboutToBeInsertedSpy.count(), numberOfRowsAboutToBeInsertedSignals);
       
  1303             QCOMPARE(columnsInsertedSpy.count(), numberOfColumnsInsertedSignals);
       
  1304             QCOMPARE(rowsInsertedSpy.count(), numberOfRowsInsertedSignals);
       
  1305         }
       
  1306         // The column count should only change *after* rowsAboutToBeInserted has been emited
       
  1307         if (shouldSucceed) {
       
  1308             if (modelResetSpy.count() == 0 &&  modelLayoutChangedSpy.count() == 0) {
       
  1309                 QCOMPARE(afterAboutToInsertColumnCount, beforeInsertColumnCount);
       
  1310                 QCOMPARE(afterInsertColumnCount, beforeInsertColumnCount+count+(numberOfColumnsInsertedSignals-1));
       
  1311             }
       
  1312             if (modelResetSpy.count() == 0)
       
  1313                 QCOMPARE(currentModel->columnCount(parentOfInserted), beforeInsertColumnCount+count+(numberOfColumnsInsertedSignals-1));
       
  1314         }
       
  1315         else
       
  1316             QCOMPARE(currentModel->rowCount(parentOfInserted), beforeInsertRowCount);
       
  1317     }
       
  1318     disconnect(currentModel, SIGNAL(columnsAboutToBeInserted( const QModelIndex &, int , int )),
       
  1319             this, SLOT(slot_columnsAboutToInserted(const QModelIndex &)));
       
  1320     disconnect(currentModel, SIGNAL(columnsInserted( const QModelIndex &, int , int )),
       
  1321             this, SLOT(slot_columnsInserted(const QModelIndex &)));
       
  1322 
       
  1323     if (columnsAboutToBeInsertedSpy.count() > 0){
       
  1324         QList<QVariant> arguments = columnsAboutToBeInsertedSpy.at(0);
       
  1325         QModelIndex parent = (qvariant_cast<QModelIndex>(arguments.at(0)));
       
  1326         int first = arguments.at(1).toInt();
       
  1327         int last = arguments.at(2).toInt();
       
  1328         QCOMPARE(first, start);
       
  1329         QCOMPARE(last,  start + count - 1);
       
  1330         QVERIFY(parentOfInserted == parent);
       
  1331     }
       
  1332 
       
  1333     if (columnsInsertedSpy.count() > 0){
       
  1334         QList<QVariant> arguments = columnsInsertedSpy.at(0);
       
  1335         QModelIndex parent = (qvariant_cast<QModelIndex>(arguments.at(0)));
       
  1336         int first = arguments.at(1).toInt();
       
  1337         int last = arguments.at(2).toInt();
       
  1338         QCOMPARE(first, start);
       
  1339         QCOMPARE(last,  start + count - 1);
       
  1340         QVERIFY(parentOfInserted == parent);
       
  1341     }
       
  1342 
       
  1343     // Cleanup the test area because insert::() is called multiple times in a test
       
  1344     testModels->cleanupTestArea(currentModel);
       
  1345 }
       
  1346 
       
  1347 void tst_QItemModel::slot_rowsAboutToInserted(const QModelIndex &parent)
       
  1348 {
       
  1349     QVERIFY(parentOfInserted == parent);
       
  1350     //qDebug() << "slot_rowsAboutToInsert" << currentModel->rowCount(parent);
       
  1351     afterAboutToInsertRowCount = currentModel->rowCount(parent);
       
  1352     bool hasChildren = currentModel->hasChildren(parent);
       
  1353     bool hasDimensions = currentModel->columnCount(parent) > 0 && currentModel->rowCount(parent) > 0;
       
  1354     QCOMPARE(hasChildren, hasDimensions);
       
  1355     verifyState(currentModel);
       
  1356 
       
  1357     // This does happen
       
  1358     if (insertRecursively) {
       
  1359         QFETCH(int, recursiveRow);
       
  1360         QFETCH(int, recursiveCount);
       
  1361         //qDebug() << recursiveRow << recursiveCount;
       
  1362         insertRecursively = false;
       
  1363         QCOMPARE(currentModel->insertRows(recursiveRow, recursiveCount, parent), true);
       
  1364     }
       
  1365 }
       
  1366 
       
  1367 void tst_QItemModel::slot_rowsInserted(const QModelIndex &parent)
       
  1368 {
       
  1369     QVERIFY(parentOfInserted == parent);
       
  1370     afterInsertRowCount = currentModel->rowCount(parent);
       
  1371     bool hasChildren = currentModel->hasChildren(parent);
       
  1372     bool hasDimensions = currentModel->columnCount(parent) > 0 && currentModel->rowCount(parent) > 0;
       
  1373     QCOMPARE(hasChildren, hasDimensions);
       
  1374     verifyState(currentModel);
       
  1375 }
       
  1376 
       
  1377 void tst_QItemModel::slot_columnsAboutToInserted(const QModelIndex &parent)
       
  1378 {
       
  1379     QVERIFY(parentOfInserted == parent);
       
  1380     afterAboutToInsertColumnCount = currentModel->columnCount(parent);
       
  1381     bool hasChildren = currentModel->hasChildren(parent);
       
  1382     bool hasDimensions = currentModel->columnCount(parent) > 0 && currentModel->rowCount(parent) > 0;
       
  1383     QCOMPARE(hasChildren, hasDimensions);
       
  1384     verifyState(currentModel);
       
  1385 }
       
  1386 
       
  1387 void tst_QItemModel::slot_columnsInserted(const QModelIndex &parent)
       
  1388 {
       
  1389     QVERIFY(parentOfInserted == parent);
       
  1390     afterInsertColumnCount = currentModel->columnCount(parent);
       
  1391     bool hasChildren = currentModel->hasChildren(parent);
       
  1392     bool hasDimensions = currentModel->columnCount(parent) > 0 && currentModel->rowCount(parent) > 0;
       
  1393     QCOMPARE(hasChildren, hasDimensions);
       
  1394     verifyState(currentModel);
       
  1395 }
       
  1396 
       
  1397 QTEST_MAIN(tst_QItemModel)
       
  1398 #include "tst_qitemmodel.moc"