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

source code of qtremoteobjects/tests/auto/modelview/modeltest.cpp