]> cloud.milkyroute.net Git - dolphin.git/blob - src/tests/kfileitemmodeltest.cpp
Fix for KFileItemModel::expansionLevelsCompare
[dolphin.git] / src / tests / kfileitemmodeltest.cpp
1 /***************************************************************************
2 * Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com> *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
18 ***************************************************************************/
19
20 #include <qtest_kde.h>
21
22 #include <KDirLister>
23 #include "kitemviews/kfileitemmodel.h"
24 #include "testdir.h"
25
26 namespace {
27 const int DefaultTimeout = 5000;
28 };
29
30 Q_DECLARE_METATYPE(KItemRangeList)
31
32 class KFileItemModelTest : public QObject
33 {
34 Q_OBJECT
35
36 private slots:
37 void init();
38 void cleanup();
39
40 void testDefaultRoles();
41 void testDefaultSortRole();
42 void testDefaultGroupRole();
43 void testNewItems();
44 void testModelConsistencyWhenInsertingItems();
45 void testItemRangeConsistencyWhenInsertingItems();
46
47 void testExpansionLevelsCompare_data();
48 void testExpansionLevelsCompare();
49
50 private:
51 bool isModelConsistent() const;
52
53 private:
54 KFileItemModel* m_model;
55 KDirLister* m_dirLister;
56 TestDir* m_testDir;
57 };
58
59 void KFileItemModelTest::init()
60 {
61 qRegisterMetaType<KItemRangeList>("KItemRangeList");
62 qRegisterMetaType<KFileItemList>("KFileItemList");
63
64 m_testDir = new TestDir();
65 m_dirLister = new KDirLister();
66 m_model = new KFileItemModel(m_dirLister);
67 }
68
69 void KFileItemModelTest::cleanup()
70 {
71 delete m_model;
72 m_model = 0;
73
74 delete m_dirLister;
75 m_dirLister = 0;
76
77 delete m_testDir;
78 m_testDir = 0;
79 }
80
81 void KFileItemModelTest::testDefaultRoles()
82 {
83 const QSet<QByteArray> roles = m_model->roles();
84 QCOMPARE(roles.count(), 2);
85 QVERIFY(roles.contains("name"));
86 QVERIFY(roles.contains("isDir"));
87 }
88
89 void KFileItemModelTest::testDefaultSortRole()
90 {
91 QCOMPARE(m_model->sortRole(), QByteArray("name"));
92
93 QStringList files;
94 files << "c.txt" << "a.txt" << "b.txt";
95
96 m_testDir->createFiles(files);
97
98 m_dirLister->openUrl(m_testDir->url());
99 QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsInserted(KItemRangeList)), DefaultTimeout));
100
101 QCOMPARE(m_model->count(), 3);
102 QCOMPARE(m_model->data(0)["name"].toString(), QString("a.txt"));
103 QCOMPARE(m_model->data(1)["name"].toString(), QString("b.txt"));
104 QCOMPARE(m_model->data(2)["name"].toString(), QString("c.txt"));
105 }
106
107 void KFileItemModelTest::testDefaultGroupRole()
108 {
109 QVERIFY(m_model->groupRole().isEmpty());
110 }
111
112 void KFileItemModelTest::testNewItems()
113 {
114 QStringList files;
115 files << "a.txt" << "b.txt" << "c.txt";
116 m_testDir->createFiles(files);
117
118 m_dirLister->openUrl(m_testDir->url());
119 QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsInserted(KItemRangeList)), DefaultTimeout));
120
121 QCOMPARE(m_model->count(), 3);
122
123 QVERIFY(isModelConsistent());
124 }
125
126 void KFileItemModelTest::testModelConsistencyWhenInsertingItems()
127 {
128 QSKIP("Temporary disabled", SkipSingle);
129
130 // KFileItemModel prevents that inserting a punch of items sequentially
131 // results in an itemsInserted()-signal for each item. Instead internally
132 // a timeout is given that collects such operations and results in only
133 // one itemsInserted()-signal. However in this test we want to stress
134 // KFileItemModel to do a lot of insert operation and hence decrease
135 // the timeout to 1 millisecond.
136 m_model->m_minimumUpdateIntervalTimer->setInterval(1);
137
138 m_testDir->createFile("1");
139 m_dirLister->openUrl(m_testDir->url());
140 QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsInserted(KItemRangeList)), DefaultTimeout));
141 QCOMPARE(m_model->count(), 1);
142
143 // Insert 10 items for 20 times. After each insert operation the model consistency
144 // is checked.
145 QSet<int> insertedItems;
146 for (int i = 0; i < 20; ++i) {
147 QSignalSpy spy(m_model, SIGNAL(itemsInserted(KItemRangeList)));
148
149 for (int j = 0; j < 10; ++j) {
150 int itemName = qrand();
151 while (insertedItems.contains(itemName)) {
152 itemName = qrand();
153 }
154 insertedItems.insert(itemName);
155
156 m_testDir->createFile(QString::number(itemName));
157 }
158
159 m_dirLister->updateDirectory(m_testDir->url());
160 if (spy.count() == 0) {
161 QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsInserted(KItemRangeList)), DefaultTimeout));
162 }
163
164 QVERIFY(isModelConsistent());
165 }
166
167 QCOMPARE(m_model->count(), 201);
168 }
169
170 void KFileItemModelTest::testItemRangeConsistencyWhenInsertingItems()
171 {
172 QStringList files;
173 files << "B" << "E" << "G";
174 m_testDir->createFiles(files);
175
176 // Due to inserting the 3 items one item-range with index == 0 and
177 // count == 3 must be given
178 QSignalSpy spy1(m_model, SIGNAL(itemsInserted(KItemRangeList)));
179 m_dirLister->openUrl(m_testDir->url());
180 QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsInserted(KItemRangeList)), DefaultTimeout));
181
182 QCOMPARE(spy1.count(), 1);
183 QList<QVariant> arguments = spy1.takeFirst();
184 KItemRangeList itemRangeList = arguments.at(0).value<KItemRangeList>();
185 QCOMPARE(itemRangeList.count(), 1);
186 KItemRange itemRange = itemRangeList.first();
187 QCOMPARE(itemRange.index, 0);
188 QCOMPARE(itemRange.count, 3);
189
190 // The indexes of the item-ranges must always be related to the model before
191 // the items have been inserted. Having:
192 // 0 1 2
193 // B E G
194 // and inserting A, C, D, F the resulting model will be:
195 // 0 1 2 3 4 5 6
196 // A B C D E F G
197 // and the item-ranges must be:
198 // index: 0, count: 1 for A
199 // index: 1, count: 2 for B, C
200 // index: 2, count: 1 for G
201
202 files.clear();
203 files << "A" << "C" << "D" << "F";
204 m_testDir->createFiles(files);
205
206 QSignalSpy spy2(m_model, SIGNAL(itemsInserted(KItemRangeList)));
207 m_dirLister->updateDirectory(m_testDir->url());
208 QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsInserted(KItemRangeList)), DefaultTimeout));
209
210 QCOMPARE(spy2.count(), 1);
211 arguments = spy2.takeFirst();
212 itemRangeList = arguments.at(0).value<KItemRangeList>();
213 QCOMPARE(itemRangeList.count(), 3);
214 QCOMPARE(itemRangeList.at(0).index, 0);
215 QCOMPARE(itemRangeList.at(0).count, 1);
216 QCOMPARE(itemRangeList.at(1).index, 1);
217 QCOMPARE(itemRangeList.at(1).count, 2);
218 QCOMPARE(itemRangeList.at(2).index, 2);
219 QCOMPARE(itemRangeList.at(2).count, 1);
220 }
221
222 void KFileItemModelTest::testExpansionLevelsCompare_data()
223 {
224 QTest::addColumn<QString>("urlA");
225 QTest::addColumn<QString>("urlB");
226 QTest::addColumn<int>("result");
227
228 QTest::newRow("Equal") << "/a/b" << "/a/b" << 0;
229 QTest::newRow("Sub path: A < B") << "/a/b" << "/a/b/c" << -1;
230 QTest::newRow("Sub path: A > B") << "/a/b/c" << "/a/b" << +1;
231 QTest::newRow("Same level: /a/1 < /a-1/1") << "/a/1" << "/a-1/1" << -1;
232 }
233
234 void KFileItemModelTest::testExpansionLevelsCompare()
235 {
236 QFETCH(QString, urlA);
237 QFETCH(QString, urlB);
238 QFETCH(int, result);
239
240 const KFileItem a(KUrl(urlA), QString(), mode_t(-1));
241 const KFileItem b(KUrl(urlB), QString(), mode_t(-1));
242 QCOMPARE(m_model->expansionLevelsCompare(a, b), result);
243 }
244
245 bool KFileItemModelTest::isModelConsistent() const
246 {
247 for (int i = 0; i < m_model->count(); ++i) {
248 const KFileItem item = m_model->fileItem(i);
249 if (item.isNull()) {
250 qWarning() << "Item" << i << "is null";
251 return false;
252 }
253
254 const int itemIndex = m_model->index(item);
255 if (itemIndex != i) {
256 qWarning() << "Item" << i << "has a wrong index:" << itemIndex;
257 return false;
258 }
259 }
260
261 return true;
262 }
263
264 QTEST_KDEMAIN(KFileItemModelTest, NoGUI)
265
266 #include "kfileitemmodeltest.moc"