tst_modeltest.cpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. /****************************************************************************
  2. **
  3. ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
  4. ** All rights reserved.
  5. ** Contact: Nokia Corporation (qt-info@nokia.com)
  6. **
  7. ** This file is part of the test suite of the Qt Toolkit.
  8. **
  9. ** This file is free software: you can redistribute it and/or modify
  10. ** it under the terms of the GNU General Public License as published by
  11. ** the Free Software Foundation, either version 3 of the License, or
  12. ** (at your option) any later version.
  13. **
  14. ** $QT_BEGIN_LICENSE:LGPL$
  15. ** GNU Lesser General Public License Usage
  16. ** This file may be used under the terms of the GNU Lesser General Public
  17. ** License version 2.1 as published by the Free Software Foundation and
  18. ** appearing in the file LICENSE.LGPL included in the packaging of this
  19. ** file. Please review the following information to ensure the GNU Lesser
  20. ** General Public License version 2.1 requirements will be met:
  21. ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  22. **
  23. ** In addition, as a special exception, Nokia gives you certain additional
  24. ** rights. These rights are described in the Nokia Qt LGPL Exception
  25. ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
  26. **
  27. ** GNU General Public License Usage
  28. ** Alternatively, this file may be used under the terms of the GNU General
  29. ** Public License version 3.0 as published by the Free Software Foundation
  30. ** and appearing in the file LICENSE.GPL included in the packaging of this
  31. ** file. Please review the following information to ensure the GNU General
  32. ** Public License version 3.0 requirements will be met:
  33. ** http://www.gnu.org/copyleft/gpl.html.
  34. **
  35. ** Other Usage
  36. ** Alternatively, this file may be used in accordance with the terms and
  37. ** conditions contained in a signed written agreement between you and Nokia.
  38. **
  39. **
  40. **
  41. **
  42. **
  43. ** $QT_END_LICENSE$
  44. **
  45. ****************************************************************************/
  46. #include "dynamictreemodel.h"
  47. #include "modeltest.h"
  48. #include <QtGui/QtGui>
  49. #include <QtTest/QtTest>
  50. class tst_ModelTest : public QObject
  51. {
  52. Q_OBJECT
  53. public:
  54. tst_ModelTest() {}
  55. virtual ~tst_ModelTest() {}
  56. public slots:
  57. void initTestCase();
  58. void cleanupTestCase();
  59. void init();
  60. void cleanup();
  61. private slots:
  62. void stringListModel();
  63. void treeWidgetModel();
  64. void standardItemModel();
  65. void testInsertThroughProxy();
  66. void moveSourceItems();
  67. void testResetThroughProxy();
  68. };
  69. void tst_ModelTest::initTestCase()
  70. {
  71. }
  72. void tst_ModelTest::cleanupTestCase()
  73. {
  74. }
  75. void tst_ModelTest::init()
  76. {
  77. }
  78. void tst_ModelTest::cleanup()
  79. {
  80. }
  81. /*
  82. tests
  83. */
  84. void tst_ModelTest::stringListModel()
  85. {
  86. QStringListModel model;
  87. QSortFilterProxyModel proxy;
  88. ModelTest t1( &model );
  89. ModelTest t2( &proxy );
  90. proxy.setSourceModel( &model );
  91. model.setStringList( QStringList() << "2"
  92. << "3"
  93. << "1" );
  94. model.setStringList( QStringList() << "a"
  95. << "e"
  96. << "plop"
  97. << "b"
  98. << "c" );
  99. proxy.setDynamicSortFilter( true );
  100. proxy.setFilterRegExp( QRegExp( "[^b]" ) );
  101. }
  102. void tst_ModelTest::treeWidgetModel()
  103. {
  104. QTreeWidget widget;
  105. ModelTest t1( widget.model() );
  106. QTreeWidgetItem *root = new QTreeWidgetItem( &widget, QStringList( "root" ) );
  107. for ( int i = 0; i < 20; ++i )
  108. {
  109. new QTreeWidgetItem( root, QStringList( QString::number( i ) ) );
  110. }
  111. QTreeWidgetItem *remove = root->child( 2 );
  112. root->removeChild( remove );
  113. QTreeWidgetItem *parent = new QTreeWidgetItem( &widget, QStringList( "parent" ) );
  114. new QTreeWidgetItem( parent, QStringList( "child" ) );
  115. widget.setItemHidden( parent, true );
  116. widget.sortByColumn( 0 );
  117. }
  118. void tst_ModelTest::standardItemModel()
  119. {
  120. QStandardItemModel model( 10, 10 );
  121. QSortFilterProxyModel proxy;
  122. ModelTest t1( &model );
  123. ModelTest t2( &proxy );
  124. proxy.setSourceModel( &model );
  125. model.insertRows( 2, 5 );
  126. model.removeRows( 4, 5 );
  127. model.insertColumns( 2, 5 );
  128. model.removeColumns( 4, 5 );
  129. model.insertRows( 0, 5, model.index( 1, 1 ) );
  130. model.insertColumns( 0, 5, model.index( 1, 3 ) );
  131. }
  132. void tst_ModelTest::testInsertThroughProxy()
  133. {
  134. DynamicTreeModel *model = new DynamicTreeModel( this );
  135. QSortFilterProxyModel *proxy = new QSortFilterProxyModel( this );
  136. proxy->setSourceModel( model );
  137. new ModelTest( proxy, this );
  138. ModelInsertCommand *insertCommand = new ModelInsertCommand( model, this );
  139. insertCommand->setNumCols( 4 );
  140. insertCommand->setStartRow( 0 );
  141. insertCommand->setEndRow( 9 );
  142. // Parent is QModelIndex()
  143. insertCommand->doCommand();
  144. insertCommand = new ModelInsertCommand( model, this );
  145. insertCommand->setNumCols( 4 );
  146. insertCommand->setAncestorRowNumbers( QList<int>() << 5 );
  147. insertCommand->setStartRow( 0 );
  148. insertCommand->setEndRow( 9 );
  149. insertCommand->doCommand();
  150. ModelMoveCommand *moveCommand = new ModelMoveCommand( model, this );
  151. moveCommand->setNumCols( 4 );
  152. moveCommand->setStartRow( 0 );
  153. moveCommand->setEndRow( 0 );
  154. moveCommand->setDestRow( 9 );
  155. moveCommand->setDestAncestors( QList<int>() << 5 );
  156. moveCommand->doCommand();
  157. }
  158. /**
  159. Makes the persistent index list publicly accessible
  160. */
  161. class AccessibleProxyModel : public QSortFilterProxyModel
  162. {
  163. Q_OBJECT
  164. public:
  165. AccessibleProxyModel( QObject *parent = 0 )
  166. : QSortFilterProxyModel( parent ) {}
  167. QModelIndexList persistent()
  168. {
  169. return persistentIndexList();
  170. }
  171. };
  172. class ObservingObject : public QObject
  173. {
  174. Q_OBJECT
  175. public:
  176. ObservingObject( AccessibleProxyModel *proxy, QObject *parent = 0 )
  177. : QObject( parent ), m_proxy( proxy )
  178. {
  179. connect( m_proxy, SIGNAL( layoutAboutToBeChanged() ), SLOT( storePersistent() ) );
  180. connect( m_proxy, SIGNAL( layoutChanged() ), SLOT( checkPersistent() ) );
  181. }
  182. public slots:
  183. void storePersistent( const QModelIndex &parent )
  184. {
  185. for ( int row = 0; row < m_proxy->rowCount( parent ); ++row )
  186. {
  187. QModelIndex proxyIndex = m_proxy->index( row, 0, parent );
  188. QModelIndex sourceIndex = m_proxy->mapToSource( proxyIndex );
  189. Q_ASSERT( proxyIndex.isValid() );
  190. Q_ASSERT( sourceIndex.isValid() );
  191. m_persistentSourceIndexes.append( sourceIndex );
  192. m_persistentProxyIndexes.append( proxyIndex );
  193. if ( m_proxy->hasChildren( proxyIndex ) )
  194. storePersistent( proxyIndex );
  195. }
  196. }
  197. void storePersistent()
  198. {
  199. foreach ( const QModelIndex &idx, m_persistentProxyIndexes )
  200. Q_ASSERT( idx.isValid() ); // This is called from layoutAboutToBeChanged. Persistent indexes should be valid
  201. Q_ASSERT( m_proxy->persistent().isEmpty() );
  202. storePersistent( QModelIndex() );
  203. Q_ASSERT( !m_proxy->persistent().isEmpty() );
  204. }
  205. void checkPersistent()
  206. {
  207. for ( int row = 0; row < m_persistentProxyIndexes.size(); ++row )
  208. {
  209. QModelIndex updatedProxy = m_persistentProxyIndexes.at( row );
  210. QModelIndex updatedSource = m_persistentSourceIndexes.at( row );
  211. }
  212. for ( int row = 0; row < m_persistentProxyIndexes.size(); ++row )
  213. {
  214. QModelIndex updatedProxy = m_persistentProxyIndexes.at( row );
  215. QModelIndex updatedSource = m_persistentSourceIndexes.at( row );
  216. QCOMPARE( m_proxy->mapToSource( updatedProxy ), updatedSource );
  217. }
  218. m_persistentSourceIndexes.clear();
  219. m_persistentProxyIndexes.clear();
  220. }
  221. private:
  222. AccessibleProxyModel *m_proxy;
  223. QList<QPersistentModelIndex> m_persistentSourceIndexes;
  224. QList<QPersistentModelIndex> m_persistentProxyIndexes;
  225. };
  226. void tst_ModelTest::moveSourceItems()
  227. {
  228. DynamicTreeModel *model = new DynamicTreeModel( this );
  229. AccessibleProxyModel *proxy = new AccessibleProxyModel( this );
  230. proxy->setSourceModel( model );
  231. ModelInsertCommand *insertCommand = new ModelInsertCommand( model, this );
  232. insertCommand->setStartRow( 0 );
  233. insertCommand->setEndRow( 2 );
  234. insertCommand->doCommand();
  235. insertCommand = new ModelInsertCommand( model, this );
  236. insertCommand->setAncestorRowNumbers( QList<int>() << 1 );
  237. insertCommand->setStartRow( 0 );
  238. insertCommand->setEndRow( 2 );
  239. insertCommand->doCommand();
  240. ObservingObject observer( proxy );
  241. ModelMoveCommand *moveCommand = new ModelMoveCommand( model, this );
  242. moveCommand->setStartRow( 0 );
  243. moveCommand->setEndRow( 0 );
  244. moveCommand->setDestAncestors( QList<int>() << 1 );
  245. moveCommand->setDestRow( 0 );
  246. moveCommand->doCommand();
  247. }
  248. void tst_ModelTest::testResetThroughProxy()
  249. {
  250. DynamicTreeModel *model = new DynamicTreeModel( this );
  251. ModelInsertCommand *insertCommand = new ModelInsertCommand( model, this );
  252. insertCommand->setStartRow( 0 );
  253. insertCommand->setEndRow( 2 );
  254. insertCommand->doCommand();
  255. QPersistentModelIndex persistent = model->index( 0, 0 );
  256. AccessibleProxyModel *proxy = new AccessibleProxyModel( this );
  257. proxy->setSourceModel( model );
  258. ObservingObject observer( proxy );
  259. observer.storePersistent();
  260. ModelResetCommand *resetCommand = new ModelResetCommand( model, this );
  261. resetCommand->setNumCols( 0 );
  262. resetCommand->doCommand();
  263. }
  264. QTEST_MAIN( tst_ModelTest )
  265. #include "tst_modeltest.moc"