~unity-team/unity8/ota9.5

« back to all changes in this revision

Viewing changes to tests/plugins/Utils/modeltest.cpp

  • Committer: Michał Sawicz
  • Date: 2013-06-05 22:03:08 UTC
  • Revision ID: michal.sawicz@canonical.com-20130605220308-yny8fv3futtr04fg
Inital unity8 commit.

Previous history can be found at https://code.launchpad.net/~unity-team/unity/phablet

Show diffs side-by-side

added added

removed removed

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