]> cloud.milkyroute.net Git - dolphin.git/blob - src/tests/kitemsettest.cpp
Merge branch 'Applications/18.04'
[dolphin.git] / src / tests / kitemsettest.cpp
1 /***************************************************************************
2 * Copyright (C) 2013 by Frank Reininghaus <frank78ac@googlemail.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 "kitemviews/kitemset.h"
21
22 #include <QTest>
23
24 Q_DECLARE_METATYPE(KItemRangeList)
25
26 /**
27 * Converts a KItemRangeList to a KItemSet.
28 */
29 KItemSet KItemRangeList2KItemSet(const KItemRangeList& itemRanges)
30 {
31 KItemSet result;
32 foreach (const KItemRange& range, itemRanges) {
33 for (int i = range.index; i < range.index + range.count; ++i) {
34 result.insert(i);
35 }
36 }
37 return result;
38 }
39
40 /**
41 * Converts a KItemRangeList to a QSet<int>.
42 */
43 QSet<int> KItemRangeList2QSet(const KItemRangeList& itemRanges)
44 {
45 QSet<int> result;
46 foreach (const KItemRange& range, itemRanges) {
47 for (int i = range.index; i < range.index + range.count; ++i) {
48 result.insert(i);
49 }
50 }
51 return result;
52 }
53
54 /**
55 * Converts a KItemRangeList to a QVector<int>.
56 */
57 QVector<int> KItemRangeList2QVector(const KItemRangeList& itemRanges)
58 {
59 QVector<int> result;
60 foreach (const KItemRange& range, itemRanges) {
61 for (int i = range.index; i < range.index + range.count; ++i) {
62 result.append(i);
63 }
64 }
65 return result;
66 }
67
68 /**
69 * Converts a KItemSet to a QSet<int>.
70 */
71 static QSet<int> KItemSet2QSet(const KItemSet& itemSet)
72 {
73 QSet<int> result;
74 for (int i : itemSet) {
75 result.insert(i);
76 }
77
78 // Check that the conversion was successful.
79 Q_ASSERT(itemSet.count() == result.count());
80
81 for (int i : itemSet) {
82 Q_ASSERT(result.contains(i));
83 }
84
85 foreach (int i, result) {
86 Q_ASSERT(itemSet.contains(i));
87 }
88
89 return result;
90 }
91
92
93 /**
94 * The main test class.
95 */
96 class KItemSetTest : public QObject
97 {
98 Q_OBJECT
99
100 private slots:
101 void initTestCase();
102
103 void testConstruction_data();
104 void testConstruction();
105 void testIterators_data();
106 void testIterators();
107 void testFind_data();
108 void testFind();
109 void testChangingOneItem_data();
110 void testChangingOneItem();
111 void testAddSets_data();
112 void testAddSets();
113 /*
114 void testSubtractSets_data();
115 void testSubtractSets();
116 */
117 void testSymmetricDifference_data();
118 void testSymmetricDifference();
119
120 private:
121 QHash<const char*, KItemRangeList> m_testCases;
122 };
123
124 void KItemSetTest::initTestCase()
125 {
126 m_testCases.insert("empty", KItemRangeList());
127 m_testCases.insert("[0]", KItemRangeList() << KItemRange(0, 1));
128 m_testCases.insert("[1]", KItemRangeList() << KItemRange(1, 1));
129 m_testCases.insert("[1, 2]", KItemRangeList() << KItemRange(1, 2));
130 m_testCases.insert("[1, 2] [5]", KItemRangeList() << KItemRange(1, 2) << KItemRange(5, 1));
131 m_testCases.insert("[1] [4, 5]", KItemRangeList() << KItemRange(1, 1) << KItemRange(4, 2));
132 m_testCases.insert("[1, 2] [4, 5]", KItemRangeList() << KItemRange(1, 2) << KItemRange(4, 2));
133 m_testCases.insert("[1, 5]", KItemRangeList() << KItemRange(1, 5));
134 m_testCases.insert("[1, 2] [4, 5] [7] [9, 10] [13] [20, 25] [30]",
135 KItemRangeList() << KItemRange(1, 2) << KItemRange(4, 2) << KItemRange(7, 1) << KItemRange(9, 2) << KItemRange(20, 6) << KItemRange(30, 1));
136 m_testCases.insert("[-10, -1]", KItemRangeList() << KItemRange(-10, 10));
137 m_testCases.insert("[-10, 0]", KItemRangeList() << KItemRange(-10, 11));
138 m_testCases.insert("[-10, 1]", KItemRangeList() << KItemRange(-10, 12));
139 m_testCases.insert("[0, 9]", KItemRangeList() << KItemRange(0, 10));
140 m_testCases.insert("[0, 19]", KItemRangeList() << KItemRange(0, 10));
141 }
142
143 void KItemSetTest::testConstruction_data()
144 {
145 QTest::addColumn<KItemRangeList>("itemRanges");
146
147 QHash<const char*, KItemRangeList>::const_iterator it = m_testCases.constBegin();
148 const QHash<const char*, KItemRangeList>::const_iterator end = m_testCases.constEnd();
149
150 while (it != end) {
151 QTest::newRow(it.key()) << it.value();
152 ++it;
153 }
154 }
155
156 void KItemSetTest::testConstruction()
157 {
158 QFETCH(KItemRangeList, itemRanges);
159
160 KItemSet itemSet = KItemRangeList2KItemSet(itemRanges);
161 QSet<int> itemsQSet = KItemRangeList2QSet(itemRanges);
162
163 QVERIFY(itemSet.isValid());
164 QVERIFY(itemSet.count() == itemsQSet.count());
165 QCOMPARE(KItemSet2QSet(itemSet), itemsQSet);
166
167 // Test copy constructor.
168 KItemSet copy(itemSet);
169 QCOMPARE(itemSet, copy);
170 copy.clear();
171 QVERIFY(itemSet != copy || itemSet.isEmpty());
172
173 // Clear the set.
174 itemSet.clear();
175 QVERIFY(itemSet.isEmpty());
176 QCOMPARE(itemSet.count(), 0);
177 }
178
179 void KItemSetTest::testIterators_data()
180 {
181 QTest::addColumn<KItemRangeList>("itemRanges");
182
183 QHash<const char*, KItemRangeList>::const_iterator it = m_testCases.constBegin();
184 const QHash<const char*, KItemRangeList>::const_iterator end = m_testCases.constEnd();
185
186 while (it != end) {
187 QTest::newRow(it.key()) << it.value();
188 ++it;
189 }
190 }
191
192 /**
193 * Verify that the iterators work exactly like their counterparts for the
194 * equivalent QVector<int>.
195 */
196 void KItemSetTest::testIterators()
197 {
198 QFETCH(KItemRangeList, itemRanges);
199
200 KItemSet itemSet = KItemRangeList2KItemSet(itemRanges);
201 QVector<int> itemsQVector = KItemRangeList2QVector(itemRanges);
202
203 QVERIFY(itemSet.isValid());
204 QVERIFY(itemSet.count() == itemsQVector.count());
205
206 if (itemSet.count() == 0) {
207 QVERIFY(itemSet.isEmpty());
208 QVERIFY(itemSet.begin() == itemSet.end());
209 QVERIFY(itemSet.constBegin() == itemSet.constEnd());
210 } else {
211 QVERIFY(!itemSet.isEmpty());
212 QVERIFY(itemSet.begin() != itemSet.end());
213 QVERIFY(itemSet.constBegin() != itemSet.constEnd());
214
215 const int min = itemsQVector.first();
216 const int max = itemsQVector.last();
217
218 QCOMPARE(*itemSet.begin(), min);
219 QCOMPARE(*itemSet.constBegin(), min);
220 QCOMPARE(itemSet.first(), min);
221
222 QCOMPARE(*(--itemSet.end()), max);
223 QCOMPARE(*(--itemSet.constEnd()), max);
224 QCOMPARE(itemSet.last(), max);
225 }
226
227 // Test iterating using the different iterators.
228 QVector<int> testQVector;
229 for (KItemSet::iterator it = itemSet.begin(), end = itemSet.end(); it != end; ++it) {
230 testQVector.append(*it);
231 }
232 QCOMPARE(testQVector, itemsQVector);
233
234 testQVector.clear();
235 for (KItemSet::const_iterator it = itemSet.constBegin(), end = itemSet.constEnd(); it != end; ++it) {
236 testQVector.append(*it);
237 }
238 QCOMPARE(testQVector, itemsQVector);
239
240 testQVector.clear();
241 for (int i : itemSet) {
242 testQVector.append(i);
243 }
244 QCOMPARE(testQVector, itemsQVector);
245
246 // Verify that both variants of the (const)iterator's operator++ and
247 // operator-- functions behave exactly like their QVector equivalents.
248 KItemSet::iterator it1 = itemSet.begin();
249 KItemSet::iterator it2 = itemSet.begin();
250 KItemSet::const_iterator constIt1 = itemSet.constBegin();
251 KItemSet::const_iterator constIt2 = itemSet.constBegin();
252 QVector<int>::iterator vectorIt1 = itemsQVector.begin();
253 QVector<int>::iterator vectorIt2 = itemsQVector.begin();
254 QVector<int>::const_iterator vectorConstIt1 = itemsQVector.constBegin();
255 QVector<int>::const_iterator vectorConstIt2 = itemsQVector.constBegin();
256
257 while (it1 != itemSet.end()) {
258 if (it1 != --itemSet.end()) {
259 QCOMPARE(*(++it1), *(++vectorIt1));
260 QCOMPARE(*(++constIt1), *(++vectorConstIt1));
261 } else {
262 QCOMPARE(++it1, itemSet.end());
263 QCOMPARE(++vectorIt1, itemsQVector.end());
264 QCOMPARE(++constIt1, itemSet.constEnd());
265 QCOMPARE(++vectorConstIt1, itemsQVector.constEnd());
266 }
267
268 QCOMPARE(*(it2++), *(vectorIt2++));
269 QCOMPARE(*(constIt2++), *(vectorConstIt2++));
270
271 QCOMPARE(it1, it2);
272 QCOMPARE(constIt1, constIt2);
273 QCOMPARE(KItemSet::const_iterator(it1), constIt1);
274 }
275
276 QCOMPARE(it1, itemSet.end());
277 QCOMPARE(it2, itemSet.end());
278 QCOMPARE(constIt1, itemSet.constEnd());
279 QCOMPARE(constIt2, itemSet.constEnd());
280 QCOMPARE(vectorIt1, itemsQVector.end());
281 QCOMPARE(vectorIt2, itemsQVector.end());
282 QCOMPARE(vectorConstIt1, itemsQVector.constEnd());
283 QCOMPARE(vectorConstIt2, itemsQVector.constEnd());
284
285 while (it1 != itemSet.begin()) {
286 QCOMPARE(*(--it1), *(--vectorIt1));
287 QCOMPARE(*(--constIt1), *(--vectorConstIt1));
288
289 if (it2 != itemSet.end()) {
290 QCOMPARE(*(it2--), *(vectorIt2--));
291 QCOMPARE(*(constIt2--), *(vectorConstIt2--));
292 } else {
293 QCOMPARE(it2--, itemSet.end());
294 QCOMPARE(vectorIt2--, itemsQVector.end());
295 QCOMPARE(constIt2--, itemSet.constEnd());
296 QCOMPARE(vectorConstIt2--, itemsQVector.constEnd());
297 }
298
299 QCOMPARE(it1, it2);
300 QCOMPARE(constIt1, constIt2);
301 QCOMPARE(KItemSet::const_iterator(it1), constIt1);
302 }
303
304 QCOMPARE(it1, itemSet.begin());
305 QCOMPARE(it2, itemSet.begin());
306 QCOMPARE(constIt1, itemSet.constBegin());
307 QCOMPARE(constIt2, itemSet.constBegin());
308 QCOMPARE(vectorIt1, itemsQVector.begin());
309 QCOMPARE(vectorIt2, itemsQVector.begin());
310 QCOMPARE(vectorConstIt1, itemsQVector.constBegin());
311 QCOMPARE(vectorConstIt2, itemsQVector.constBegin());
312 }
313
314 void KItemSetTest::testFind_data()
315 {
316 QTest::addColumn<KItemRangeList>("itemRanges");
317
318 QHash<const char*, KItemRangeList>::const_iterator it = m_testCases.constBegin();
319 const QHash<const char*, KItemRangeList>::const_iterator end = m_testCases.constEnd();
320
321 while (it != end) {
322 QTest::newRow(it.key()) << it.value();
323 ++it;
324 }
325 }
326
327 /**
328 * Test all functions that find items:
329 * contais(int), find(int), constFind(int)
330 */
331 void KItemSetTest::testFind()
332 {
333 QFETCH(KItemRangeList, itemRanges);
334
335 KItemSet itemSet = KItemRangeList2KItemSet(itemRanges);
336 QSet<int> itemsQSet = KItemRangeList2QSet(itemRanges);
337
338 QVERIFY(itemSet.isValid());
339 QVERIFY(itemSet.count() == itemsQSet.count());
340
341 // Find the minimum and maximum items.
342 int min;
343 int max;
344
345 if (itemSet.count() == 0) {
346 // Use some arbitrary values for the upcoming tests.
347 min = 0;
348 max = 5;
349 } else {
350 min = *itemSet.begin();
351 max = *(--itemSet.end());
352 }
353
354 // Test contains(int), find(int), and constFind(int)
355 // for items between min - 2 and max + 2.
356 for (int i = min - 2; i <= max + 2; ++i) {
357 const KItemSet::iterator it = itemSet.find(i);
358 const KItemSet::const_iterator constIt = itemSet.constFind(i);
359 QCOMPARE(KItemSet::const_iterator(it), constIt);
360
361 if (itemsQSet.contains(i)) {
362 QVERIFY(itemSet.contains(i));
363 QCOMPARE(*it, i);
364 QCOMPARE(*constIt, i);
365 } else {
366 QVERIFY(!itemSet.contains(i));
367 QCOMPARE(it, itemSet.end());
368 QCOMPARE(constIt, itemSet.constEnd());
369 }
370 }
371 }
372
373 void KItemSetTest::testChangingOneItem_data()
374 {
375 QTest::addColumn<KItemRangeList>("itemRanges");
376
377 QHash<const char*, KItemRangeList>::const_iterator it = m_testCases.constBegin();
378 const QHash<const char*, KItemRangeList>::const_iterator end = m_testCases.constEnd();
379
380 while (it != end) {
381 QTest::newRow(it.key()) << it.value();
382 ++it;
383 }
384 }
385
386 /**
387 * Test all functions that change a single item:
388 * insert(int), remove(int), erase(KItemSet::iterator)
389 */
390 void KItemSetTest::testChangingOneItem()
391 {
392 QFETCH(KItemRangeList, itemRanges);
393
394 KItemSet itemSet = KItemRangeList2KItemSet(itemRanges);
395 QSet<int> itemsQSet = KItemRangeList2QSet(itemRanges);
396
397 QVERIFY(itemSet.isValid());
398 QVERIFY(itemSet.count() == itemsQSet.count());
399
400 // Find the minimum and maximum items.
401 int min;
402 int max;
403
404 if (itemSet.count() == 0) {
405 // Use some arbitrary values for the upcoming tests.
406 min = 0;
407 max = 5;
408 } else {
409 min = *itemSet.begin();
410 max = *(--itemSet.end());
411 }
412
413 // Test insert(int), remove(int), and erase(KItemSet::iterator)
414 // for items between min - 2 and max + 2.
415 for (int i = min - 2; i <= max + 2; ++i) {
416
417 // Test insert(int).
418 {
419 KItemSet tmp(itemSet);
420 const KItemSet::iterator insertedIt = tmp.insert(i);
421 QCOMPARE(*insertedIt, i);
422
423 QVERIFY(tmp.isValid());
424 QVERIFY(tmp.contains(i));
425
426 QSet<int> expectedQSet = itemsQSet;
427 expectedQSet.insert(i);
428 QCOMPARE(KItemSet2QSet(tmp), expectedQSet);
429
430 if (!itemSet.contains(i)) {
431 QVERIFY(itemSet != tmp);
432 QCOMPARE(tmp.count(), itemSet.count() + 1);
433 } else {
434 QCOMPARE(itemSet, tmp);
435 }
436
437 QCOMPARE(i, *tmp.find(i));
438 QCOMPARE(i, *tmp.constFind(i));
439
440 // Erase the new item and check that we get the old KItemSet back.
441 tmp.erase(tmp.find(i));
442 QVERIFY(tmp.isValid());
443 QVERIFY(!tmp.contains(i));
444
445 if (!itemSet.contains(i)) {
446 QCOMPARE(itemSet, tmp);
447 }
448
449 expectedQSet.remove(i);
450 QCOMPARE(KItemSet2QSet(tmp), expectedQSet);
451 }
452
453 // Test remove(int).
454 {
455 KItemSet tmp(itemSet);
456 const bool removed = tmp.remove(i);
457
458 QCOMPARE(removed, itemSet.contains(i));
459
460 QVERIFY(tmp.isValid());
461 QVERIFY(!tmp.contains(i));
462
463 QSet<int> expectedQSet = itemsQSet;
464 expectedQSet.remove(i);
465 QCOMPARE(KItemSet2QSet(tmp), expectedQSet);
466
467 if (itemSet.contains(i)) {
468 QVERIFY(itemSet != tmp);
469 QCOMPARE(tmp.count(), itemSet.count() - 1);
470 } else {
471 QCOMPARE(itemSet, tmp);
472 }
473
474 QCOMPARE(tmp.end(), tmp.find(i));
475 QCOMPARE(tmp.constEnd(), tmp.constFind(i));
476 }
477
478 // Test erase(KItemSet::iterator).
479 if (itemSet.contains(i)) {
480 KItemSet tmp(itemSet);
481 KItemSet::iterator it = tmp.find(i);
482 it = tmp.erase(it);
483
484 QVERIFY(tmp.isValid());
485 QVERIFY(!tmp.contains(i));
486
487 QSet<int> expectedQSet = itemsQSet;
488 expectedQSet.remove(i);
489 QCOMPARE(KItemSet2QSet(tmp), expectedQSet);
490
491 if (itemSet.contains(i)) {
492 QVERIFY(itemSet != tmp);
493 QCOMPARE(tmp.count(), itemSet.count() - 1);
494 } else {
495 QCOMPARE(itemSet, tmp);
496 }
497
498 QCOMPARE(tmp.end(), tmp.find(i));
499 QCOMPARE(tmp.constEnd(), tmp.constFind(i));
500
501 // Check the returen value, now contained in 'it'.
502 if (i == max) {
503 QCOMPARE(it, tmp.end());
504 } else {
505 // it now points to the next item.
506 QVERIFY(tmp.contains(*it));
507 for (int j = i; j < *it; ++j) {
508 QVERIFY(!tmp.contains(j));
509 }
510 }
511 }
512 }
513
514 // Clear the set.
515 itemSet.clear();
516 QVERIFY(itemSet.isEmpty());
517 QCOMPARE(itemSet.count(), 0);
518 }
519
520 void KItemSetTest::testAddSets_data()
521 {
522 QTest::addColumn<KItemRangeList>("itemRanges1");
523 QTest::addColumn<KItemRangeList>("itemRanges2");
524
525 QHash<const char*, KItemRangeList>::const_iterator it1 = m_testCases.constBegin();
526 const QHash<const char*, KItemRangeList>::const_iterator end = m_testCases.constEnd();
527
528 while (it1 != end) {
529 QHash<const char*, KItemRangeList>::const_iterator it2 = m_testCases.constBegin();
530
531 while (it2 != end) {
532 QByteArray name = it1.key() + QByteArray(" + ") + it2.key();
533 QTest::newRow(name) << it1.value() << it2.value();
534 ++it2;
535 }
536
537 ++it1;
538 }
539 }
540
541 void KItemSetTest::testAddSets()
542 {
543 QFETCH(KItemRangeList, itemRanges1);
544 QFETCH(KItemRangeList, itemRanges2);
545
546 KItemSet itemSet1 = KItemRangeList2KItemSet(itemRanges1);
547 QSet<int> itemsQSet1 = KItemRangeList2QSet(itemRanges1);
548
549 KItemSet itemSet2 = KItemRangeList2KItemSet(itemRanges2);
550 QSet<int> itemsQSet2 = KItemRangeList2QSet(itemRanges2);
551
552 KItemSet sum = itemSet1 + itemSet2;
553 QSet<int> sumQSet = itemsQSet1 + itemsQSet2;
554
555 QCOMPARE(sum.count(), sumQSet.count());
556 QCOMPARE(KItemSet2QSet(sum), sumQSet);
557 }
558
559 void KItemSetTest::testSymmetricDifference_data()
560 {
561 QTest::addColumn<KItemRangeList>("itemRanges1");
562 QTest::addColumn<KItemRangeList>("itemRanges2");
563
564 QHash<const char*, KItemRangeList>::const_iterator it1 = m_testCases.constBegin();
565 const QHash<const char*, KItemRangeList>::const_iterator end = m_testCases.constEnd();
566
567 while (it1 != end) {
568 QHash<const char*, KItemRangeList>::const_iterator it2 = m_testCases.constBegin();
569
570 while (it2 != end) {
571 QByteArray name = it1.key() + QByteArray(" ^ ") + it2.key();
572 QTest::newRow(name) << it1.value() << it2.value();
573 ++it2;
574 }
575
576 ++it1;
577 }
578 }
579
580 void KItemSetTest::testSymmetricDifference()
581 {
582 QFETCH(KItemRangeList, itemRanges1);
583 QFETCH(KItemRangeList, itemRanges2);
584
585 KItemSet itemSet1 = KItemRangeList2KItemSet(itemRanges1);
586 QSet<int> itemsQSet1 = KItemRangeList2QSet(itemRanges1);
587
588 KItemSet itemSet2 = KItemRangeList2KItemSet(itemRanges2);
589 QSet<int> itemsQSet2 = KItemRangeList2QSet(itemRanges2);
590
591 KItemSet symmetricDifference = itemSet1 ^ itemSet2;
592 QSet<int> symmetricDifferenceQSet = (itemsQSet1 - itemsQSet2) + (itemsQSet2 - itemsQSet1);
593
594 QCOMPARE(symmetricDifference.count(), symmetricDifferenceQSet.count());
595 QCOMPARE(KItemSet2QSet(symmetricDifference), symmetricDifferenceQSet);
596
597 // Check commutativity.
598 QCOMPARE(itemSet2 ^ itemSet1, symmetricDifference);
599
600 // Some more checks:
601 // itemSet1 ^ symmetricDifference == itemSet2,
602 // itemSet2 ^ symmetricDifference == itemSet1.
603 QCOMPARE(itemSet1 ^ symmetricDifference, itemSet2);
604 QCOMPARE(itemSet2 ^ symmetricDifference, itemSet1);
605 }
606
607
608 QTEST_GUILESS_MAIN(KItemSetTest)
609
610 #include "kitemsettest.moc"