ctkModelTester.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570
  1. /*=========================================================================
  2. Library: CTK
  3. Copyright (c) Kitware Inc.
  4. Licensed under the Apache License, Version 2.0 (the "License");
  5. you may not use this file except in compliance with the License.
  6. You may obtain a copy of the License at
  7. http://www.commontk.org/LICENSE
  8. Unless required by applicable law or agreed to in writing, software
  9. distributed under the License is distributed on an "AS IS" BASIS,
  10. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. See the License for the specific language governing permissions and
  12. limitations under the License.
  13. =========================================================================*/
  14. // Qt includes
  15. #include <QDebug>
  16. #include <QStack>
  17. // CTK includes
  18. #include "ctkModelTester.h"
  19. //-----------------------------------------------------------------------------
  20. class ctkModelTesterPrivate
  21. {
  22. public:
  23. ctkModelTesterPrivate();
  24. QAbstractItemModel *Model;
  25. bool ThrowOnError;
  26. bool NestedInserts;
  27. bool TestDataEnabled;
  28. struct Change
  29. {
  30. QModelIndex Parent;
  31. Qt::Orientation Orientation;
  32. int Start;
  33. int End;
  34. int Count;
  35. QList<QPersistentModelIndex> Items;
  36. };
  37. QStack<Change> AboutToBeInserted;
  38. QStack<Change> AboutToBeRemoved;
  39. QList<QPersistentModelIndex> LayoutAboutToBeChanged;
  40. };
  41. //-----------------------------------------------------------------------------
  42. // ctkModelTesterPrivate methods
  43. //-----------------------------------------------------------------------------
  44. ctkModelTesterPrivate::ctkModelTesterPrivate()
  45. {
  46. this->Model = 0;
  47. this->ThrowOnError = true;
  48. this->NestedInserts = false;
  49. this->TestDataEnabled = true;
  50. }
  51. //-----------------------------------------------------------------------------
  52. // ctkModelTester methods
  53. //-----------------------------------------------------------------------------
  54. ctkModelTester::ctkModelTester(QObject *_parent)
  55. :QObject(_parent)
  56. , d_ptr(new ctkModelTesterPrivate)
  57. {
  58. }
  59. //-----------------------------------------------------------------------------
  60. ctkModelTester::ctkModelTester(QAbstractItemModel *_model, QObject *_parent)
  61. :QObject(_parent)
  62. , d_ptr(new ctkModelTesterPrivate)
  63. {
  64. this->setModel(_model);
  65. }
  66. //-----------------------------------------------------------------------------
  67. ctkModelTester::~ctkModelTester()
  68. {
  69. }
  70. //-----------------------------------------------------------------------------
  71. void ctkModelTester::setModel(QAbstractItemModel *_model)
  72. {
  73. Q_D(ctkModelTester);
  74. if (d->Model)
  75. {
  76. // disconnect
  77. d->Model->disconnect(this);
  78. d->AboutToBeInserted.clear();
  79. d->AboutToBeRemoved.clear();
  80. d->LayoutAboutToBeChanged.clear();
  81. }
  82. if (_model)
  83. {
  84. connect(_model, SIGNAL(columnsAboutToBeInserted(const QModelIndex &, int, int)),
  85. this, SLOT(onColumnsAboutToBeInserted(const QModelIndex& , int, int)));
  86. connect(_model, SIGNAL(columnsAboutToBeRemoved(const QModelIndex &, int, int)),
  87. this, SLOT(onColumnsAboutToBeRemoved(const QModelIndex& , int, int)));
  88. connect(_model, SIGNAL(columnsInserted(const QModelIndex &, int, int)),
  89. this, SLOT(onColumnsInserted(const QModelIndex& , int, int)));
  90. connect(_model, SIGNAL(columnsRemoved(const QModelIndex &, int, int)),
  91. this, SLOT(onColumnsRemoved(const QModelIndex& , int, int)));
  92. connect(_model, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)),
  93. this, SLOT(onDataChanged(const QModelIndex& , const QModelIndex &)));
  94. connect(_model, SIGNAL(layoutAboutToBeChanged()), this, SLOT(onLayoutAboutToBeChanged()));
  95. connect(_model, SIGNAL(layoutChanged()), this, SLOT(onLayoutChanged()));
  96. connect(_model, SIGNAL(modelAboutToBeReset()), this, SLOT(onModelAboutToBeReset()));
  97. connect(_model, SIGNAL(modelReset()), this, SLOT(onModelReset()));
  98. connect(_model, SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int)),
  99. this, SLOT(onRowsAboutToBeInserted(const QModelIndex& , int, int)));
  100. connect(_model, SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int)),
  101. this, SLOT(onRowsAboutToBeRemoved(const QModelIndex& , int, int)));
  102. connect(_model, SIGNAL(rowsInserted(const QModelIndex &, int, int)),
  103. this, SLOT(onRowsInserted(const QModelIndex& , int, int)));
  104. connect(_model, SIGNAL(rowsRemoved(const QModelIndex &, int, int)),
  105. this, SLOT(onRowsRemoved(const QModelIndex& , int, int)));
  106. }
  107. d->Model = _model;
  108. this->testModel();
  109. }
  110. //-----------------------------------------------------------------------------
  111. QAbstractItemModel* ctkModelTester::model()const
  112. {
  113. Q_D(const ctkModelTester);
  114. return d->Model;
  115. }
  116. //-----------------------------------------------------------------------------
  117. void ctkModelTester::setThrowOnError(bool throwException)
  118. {
  119. Q_D(ctkModelTester);
  120. d->ThrowOnError = throwException;
  121. }
  122. //-----------------------------------------------------------------------------
  123. bool ctkModelTester::throwOnError()const
  124. {
  125. Q_D(const ctkModelTester);
  126. return d->ThrowOnError;
  127. }
  128. //-----------------------------------------------------------------------------
  129. void ctkModelTester::setNestedInserts( bool nestedInsertsValue )
  130. {
  131. Q_D(ctkModelTester);
  132. d->NestedInserts = nestedInsertsValue;
  133. }
  134. //-----------------------------------------------------------------------------
  135. bool ctkModelTester::nestedInserts()const
  136. {
  137. Q_D(const ctkModelTester);
  138. return d->NestedInserts;
  139. }
  140. //-----------------------------------------------------------------------------
  141. void ctkModelTester::setTestDataEnabled( bool enable )
  142. {
  143. Q_D(ctkModelTester);
  144. d->TestDataEnabled = enable;
  145. }
  146. //-----------------------------------------------------------------------------
  147. bool ctkModelTester::testDataEnabled()const
  148. {
  149. Q_D(const ctkModelTester);
  150. return d->TestDataEnabled;
  151. }
  152. //-----------------------------------------------------------------------------
  153. void ctkModelTester::test(bool result, const QString& errorString)const
  154. {
  155. if (result)
  156. {
  157. return;
  158. }
  159. qDebug() << errorString;
  160. if (this->throwOnError())
  161. {
  162. throw errorString;
  163. }
  164. }
  165. //-----------------------------------------------------------------------------
  166. void ctkModelTester::testModelIndex(const QModelIndex& index)const
  167. {
  168. Q_D(const ctkModelTester);
  169. if (!index.isValid())
  170. {// invalid index
  171. this->test(index.model() == 0, "An invalid index can't have a valid model.");
  172. this->test(index.model() != d->Model, "An invalid index can't have a valid model.");
  173. this->test(index.column() == -1, "An invalid index can't have a valid column.");
  174. this->test(index.row() == -1, "An invalid index can't have a valid row.");
  175. this->test(index.parent().isValid() == false, "An invalid index can't have a valid row.");
  176. this->test(index.row() == -1, "An invalid index can't have a valid row.");
  177. for(int i = 0; i < 100; ++i)
  178. {
  179. this->test(index.sibling(i % 10, i / 10).isValid() == false, "An invalid index can't have valid sibling.");
  180. }
  181. }
  182. else
  183. {// valid index
  184. this->test(index.model() == d->Model, "A valid index must have a valid model.");
  185. this->test(index.column() >= 0, "An valid index can't have an invalid column.");
  186. this->test(index.row() >= 0, "An valid index can't have an invalid row.");
  187. this->test(index == index.sibling(index.row(), index.column()), "Index's row and/or column is wrong.");
  188. }
  189. this->testData(index);
  190. this->testParent(index);
  191. }
  192. //-----------------------------------------------------------------------------
  193. void ctkModelTester::testData(const QModelIndex& index)const
  194. {
  195. Q_D(const ctkModelTester);
  196. if (!d->TestDataEnabled)
  197. {
  198. return;
  199. }
  200. if (!index.isValid())
  201. {
  202. this->test(!index.data(Qt::DisplayRole).isValid(),
  203. QString("An invalid index can't have valid data: %1")
  204. .arg(index.data(Qt::DisplayRole).toString()));
  205. }
  206. else
  207. {
  208. this->test(index.data(Qt::DisplayRole).isValid(),
  209. QString("A valid index can't have invalid data: %1, %2, %3")
  210. .arg(index.row()).arg(index.column()).arg(long(index.internalPointer())));
  211. }
  212. }
  213. //-----------------------------------------------------------------------------
  214. void ctkModelTester::testParent(const QModelIndex& vparent)const
  215. {
  216. Q_D(const ctkModelTester);
  217. if (!d->Model->hasChildren(vparent))
  218. {
  219. // it's asking a lot :-)
  220. //this->test(d->Model->columnCount(vparent) <= 0, "A parent with no children can't have a columnCount > 0.");
  221. this->test(d->Model->rowCount(vparent) <= 0, "A parent with no children can't have a rowCount > 0.");
  222. }
  223. else
  224. {
  225. this->test(d->Model->columnCount(vparent) > 0, "A parent with children can't have a columnCount <= 0.");
  226. this->test(d->Model->rowCount(vparent) > 0 || d->Model->canFetchMore(vparent), "A parent with children can't have a rowCount <= 0. or if it does, canFetchMore should return true");
  227. }
  228. if (!vparent.isValid())
  229. {// otherwise there will be an infinite loop
  230. return;
  231. }
  232. for (int i = 0 ; i < d->Model->rowCount(vparent); ++i)
  233. {
  234. for (int j = 0; j < d->Model->columnCount(vparent); ++j)
  235. {
  236. this->test(d->Model->hasIndex(i, j, vparent), "hasIndex should return true for int range {0->rowCount(), 0->columnCount()}");
  237. QModelIndex child = vparent.child(i, j);
  238. this->test(child.parent() == vparent, "A child's parent can't be different from its parent");
  239. this->testModelIndex(child);
  240. }
  241. }
  242. }
  243. //-----------------------------------------------------------------------------
  244. void ctkModelTester::testPersistentModelIndex(const QPersistentModelIndex& index)const
  245. {
  246. Q_D(const ctkModelTester);
  247. //qDebug() << "Test persistent Index: " << index ;
  248. this->test(index.isValid(), "Persistent model index can't be invalid");
  249. // did you forget to call QAbstractItemModel::changePersistentIndex() between
  250. // beginLayoutChanged() and changePersistentIndex() ?
  251. QModelIndex modelIndex = d->Model->index(index.row(), index.column(), index.parent());
  252. this->test(modelIndex == index,
  253. QString("Persistent index (%1, %2) can't be invalid").arg(index.row()).arg(index.column()));
  254. }
  255. //-----------------------------------------------------------------------------
  256. void ctkModelTester::testModel()const
  257. {
  258. Q_D(const ctkModelTester);
  259. if (d->Model == 0)
  260. {
  261. return;
  262. }
  263. for (int i = 0 ; i < d->Model->rowCount(); ++i)
  264. {
  265. for (int j = 0; j < d->Model->columnCount(); ++j)
  266. {
  267. this->test(d->Model->hasIndex(i, j), "hasIndex should return true for int range {0->rowCount(), 0->columnCount()}");
  268. QModelIndex child = d->Model->index(i, j);
  269. this->test(!child.parent().isValid(), "A child's parent can't be different from its parent");
  270. this->testModelIndex(child);
  271. }
  272. }
  273. }
  274. //-----------------------------------------------------------------------------
  275. void ctkModelTester::onColumnsAboutToBeInserted(const QModelIndex & vparent, int start, int end)
  276. {
  277. //qDebug() << "columnsAboutToBeInserted: " << vparent << start << end;
  278. this->onItemsAboutToBeInserted(vparent, Qt::Horizontal, start, end);
  279. }
  280. //-----------------------------------------------------------------------------
  281. void ctkModelTester::onColumnsAboutToBeRemoved(const QModelIndex & vparent, int start, int end)
  282. {
  283. //qDebug() << "columnsAboutToBeRemoved: " << vparent << start << end;
  284. this->onItemsAboutToBeRemoved(vparent, Qt::Horizontal, start, end);
  285. }
  286. //-----------------------------------------------------------------------------
  287. void ctkModelTester::onColumnsInserted(const QModelIndex & vparent, int start, int end)
  288. {
  289. //qDebug() << "columnsInserted: " << vparent << start << end;
  290. this->onItemsInserted(vparent, Qt::Horizontal, start, end);
  291. }
  292. //-----------------------------------------------------------------------------
  293. void ctkModelTester::onColumnsRemoved(const QModelIndex & vparent, int start, int end)
  294. {
  295. //qDebug() << "columnsRemoved: " << vparent << start << end;
  296. this->onItemsRemoved(vparent, Qt::Horizontal, start, end);
  297. }
  298. //-----------------------------------------------------------------------------
  299. void ctkModelTester::onDataChanged(const QModelIndex & topLeft, const QModelIndex & bottomRight)
  300. {
  301. this->test(topLeft.parent() == bottomRight.parent(), "DataChanged support items with the same parent only");
  302. this->test(topLeft.row() >= bottomRight.row(), "topLeft can't have a row lower than bottomRight");
  303. this->test(bottomRight.column() >= topLeft.column(), "topLeft can't have a column lower than bottomRight");
  304. for (int i = topLeft.row(); i <= bottomRight.row(); ++i)
  305. {
  306. for (int j = topLeft.column(); j < bottomRight.column(); ++j)
  307. {
  308. this->test(topLeft.sibling(i,j).isValid(), "Changed data must be valid");
  309. // do the test on the indexes here, it's easier to debug than in testModel();
  310. this->testModelIndex(topLeft.sibling(i,j));
  311. }
  312. }
  313. this->testModel();
  314. }
  315. //-----------------------------------------------------------------------------
  316. void ctkModelTester::onHeaderDataChanged(Qt::Orientation orientation, int first, int last)
  317. {
  318. Q_D(ctkModelTester);
  319. this->test(first <= last, "Changed headers have wrong indexes");
  320. switch (orientation)
  321. {
  322. case Qt::Horizontal:
  323. this->test(d->Model->columnCount() > last, "There is no more horizontal headers than columns.");
  324. break;
  325. case Qt::Vertical:
  326. this->test(d->Model->rowCount() > last, "There is no more vertical headers than rows.");
  327. break;
  328. default:
  329. this->test(orientation == Qt::Horizontal || orientation == Qt::Vertical, "Wrong orientation.");
  330. break;
  331. }
  332. this->testModel();
  333. }
  334. //-----------------------------------------------------------------------------
  335. QList<QPersistentModelIndex> ctkModelTester::persistentModelIndexes(const QModelIndex& index)const
  336. {
  337. Q_D(const ctkModelTester);
  338. QList<QPersistentModelIndex> list;
  339. for (int i = 0; i < d->Model->rowCount(index); ++i)
  340. {
  341. for (int j = 0; j < d->Model->columnCount(index); ++j)
  342. {
  343. QPersistentModelIndex child = d->Model->index(i, j, index);
  344. list.append(child);
  345. list += this->ctkModelTester::persistentModelIndexes(child);
  346. }
  347. }
  348. return list;
  349. }
  350. //-----------------------------------------------------------------------------
  351. void ctkModelTester::onLayoutAboutToBeChanged()
  352. {
  353. Q_D(ctkModelTester);
  354. d->LayoutAboutToBeChanged = this->persistentModelIndexes(QModelIndex());
  355. this->testModel();
  356. }
  357. //-----------------------------------------------------------------------------
  358. void ctkModelTester::onLayoutChanged()
  359. {
  360. Q_D(ctkModelTester);
  361. foreach (const QPersistentModelIndex& index, d->LayoutAboutToBeChanged)
  362. {
  363. this->testPersistentModelIndex(index);
  364. }
  365. d->LayoutAboutToBeChanged.clear();
  366. this->testModel();
  367. }
  368. //-----------------------------------------------------------------------------
  369. void ctkModelTester::onModelAboutToBeReset()
  370. {
  371. this->testModel();
  372. }
  373. //-----------------------------------------------------------------------------
  374. void ctkModelTester::onModelReset()
  375. {
  376. this->testModel();
  377. }
  378. //-----------------------------------------------------------------------------
  379. void ctkModelTester::onRowsAboutToBeInserted(const QModelIndex &vparent, int start, int end)
  380. {
  381. //qDebug() << "rowsAboutToBeInserted: " << vparent << start << end;
  382. this->onItemsAboutToBeInserted(vparent, Qt::Vertical, start, end);
  383. }
  384. //-----------------------------------------------------------------------------
  385. void ctkModelTester::onRowsAboutToBeRemoved(const QModelIndex &vparent, int start, int end)
  386. {
  387. //qDebug() << "rowsAboutToBeRemoved: " << vparent << start << end;
  388. this->onItemsAboutToBeRemoved(vparent, Qt::Vertical, start, end);
  389. }
  390. //-----------------------------------------------------------------------------
  391. void ctkModelTester::onRowsInserted(const QModelIndex & vparent, int start, int end)
  392. {
  393. //qDebug() << "rowsInserted: " << vparent << start << end;
  394. this->onItemsInserted(vparent, Qt::Vertical, start, end);
  395. }
  396. //-----------------------------------------------------------------------------
  397. void ctkModelTester::onRowsRemoved(const QModelIndex & vparent, int start, int end)
  398. {
  399. //qDebug() << "rowsRemoved: " << vparent << start << end;
  400. this->onItemsRemoved(vparent, Qt::Vertical, start, end);
  401. }
  402. //-----------------------------------------------------------------------------
  403. void ctkModelTester::onItemsAboutToBeInserted(const QModelIndex &vparent, Qt::Orientation orientation, int start, int end)
  404. {
  405. Q_D(ctkModelTester);
  406. this->test(start <= end, "Start can't be higher than end");
  407. //Not sure about that
  408. if (!d->NestedInserts)
  409. {
  410. this->test(d->AboutToBeInserted.size() == 0, "While inserting items, you can't insert other items.");
  411. }
  412. //Not sure about that
  413. this->test(d->AboutToBeRemoved.size() == 0, "While removing items, you can't insert other items.");
  414. ctkModelTesterPrivate::Change change;
  415. change.Parent = vparent;
  416. change.Orientation = orientation;
  417. change.Start = start;
  418. change.End = end;
  419. change.Count = (orientation == Qt::Vertical ? d->Model->rowCount(vparent) :d->Model->columnCount(vparent) );
  420. change.Items = this->persistentModelIndexes(vparent);
  421. d->AboutToBeInserted.push(change);
  422. this->testModel();
  423. }
  424. //-----------------------------------------------------------------------------
  425. void ctkModelTester::onItemsAboutToBeRemoved(const QModelIndex &vparent, Qt::Orientation orientation, int start, int end)
  426. {
  427. Q_D(ctkModelTester);
  428. this->test(start <= end, "Start can't be higher than end");
  429. //Not sure about that
  430. this->test(d->AboutToBeInserted.size() == 0, "While inserting items, you can't remove other items.");
  431. //Not sure about that
  432. this->test(d->AboutToBeRemoved.size() == 0, "While removing items, you can't remove other items.");
  433. int count = (orientation == Qt::Vertical ? d->Model->rowCount(vparent) :d->Model->columnCount(vparent) );
  434. this->test(start < count, "Item to remove can't be invalid");
  435. this->test(end < count, "Item to remove can't be invalid");
  436. ctkModelTesterPrivate::Change change;
  437. change.Parent = vparent;
  438. change.Orientation = orientation;
  439. change.Start = start;
  440. change.End = end;
  441. change.Count = count;
  442. for (int i = 0 ; i < count; ++i)
  443. {
  444. QPersistentModelIndex index;
  445. index = (orientation == Qt::Vertical ? d->Model->index(i, 0, vparent) : d->Model->index(0, i, vparent));
  446. this->test(index.isValid(), "Index invalid");
  447. if (orientation == Qt::Vertical && (index.row() < start || index.row() > end))
  448. {
  449. change.Items.append(index);
  450. }
  451. if (orientation == Qt::Horizontal && (index.column() < start || index.column() > end))
  452. {
  453. change.Items.append(index);
  454. }
  455. }
  456. d->AboutToBeRemoved.push(change);
  457. this->testModel();
  458. //qDebug() << "About to be removed: " << start << " " << end <<vparent << count << change.Items.count();
  459. }
  460. //-----------------------------------------------------------------------------
  461. void ctkModelTester::onItemsInserted(const QModelIndex & vparent, Qt::Orientation orientation, int start, int end)
  462. {
  463. Q_D(ctkModelTester);
  464. this->test(start <= end, "Start can't be higher end");
  465. this->test(d->AboutToBeInserted.size() != 0, "rowsInserted() has been emitted, but not rowsAboutToBeInserted.");
  466. //Not sure about that
  467. this->test(d->AboutToBeRemoved.size() == 0, "While removing items, you can't insert other items.");
  468. ctkModelTesterPrivate::Change change = d->AboutToBeInserted.pop();
  469. this->test(change.Parent == vparent, "Parent can't be different");
  470. this->test(change.Orientation == orientation, "Orientation can't be different");
  471. this->test(change.Start == start, "Start can't be different");
  472. this->test(change.End == end, "End can't be different");
  473. int count = (orientation == Qt::Vertical ? d->Model->rowCount(vparent) :d->Model->columnCount(vparent) );
  474. this->test(change.Count < count, "The new count number can't be lower");
  475. this->test(count - change.Count == (end - start + 1) , "The new count number can't be lower");
  476. foreach(const QPersistentModelIndex& index, change.Items)
  477. {
  478. this->testPersistentModelIndex(index);
  479. }
  480. change.Items.clear();
  481. this->testModel();
  482. }
  483. //-----------------------------------------------------------------------------
  484. void ctkModelTester::onItemsRemoved(const QModelIndex & vparent, Qt::Orientation orientation, int start, int end)
  485. {
  486. Q_D(ctkModelTester);
  487. this->test(start <= end, "Start can't be higher end");
  488. this->test(d->AboutToBeRemoved.size() != 0, "rowsRemoved() has been emitted, but not rowsAboutToBeRemoved.");
  489. //Not sure about that
  490. this->test(d->AboutToBeInserted.size() == 0, "While inserted items, you can't remove other items.");
  491. ctkModelTesterPrivate::Change change = d->AboutToBeRemoved.pop();
  492. this->test(change.Parent == vparent, "Parent can't be different");
  493. this->test(change.Orientation == orientation, "Orientation can't be different");
  494. this->test(change.Start == start, "Start can't be different");
  495. this->test(change.End == end, "End can't be different");
  496. int count = (orientation == Qt::Vertical ? d->Model->rowCount(vparent) :d->Model->columnCount(vparent) );
  497. this->test(change.Count > count, "The new count number can't be higher");
  498. this->test(change.Count - count == (end - start + 1) , "The new count number can't be higher");
  499. foreach(const QPersistentModelIndex& index, change.Items)
  500. {
  501. this->testPersistentModelIndex(index);
  502. }
  503. change.Items.clear();
  504. this->testModel();
  505. }