File indexing completed on 2024-06-02 04:17:22

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