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