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#include <qtest.h>
29#include <private/qqmllistcompositor_p.h>
30
31template<typename T, int N> int lengthOf(const T (&)[N]) { return N; }
32
33typedef QQmlListCompositor C;
34
35struct Range
36{
37 Range() {}
38 Range(void *list, int index, int count, int flags)
39 : list(list), index(index), count(count), flags(flags) {}
40 void *list;
41 int index;
42 int count;
43 int flags;
44};
45
46template <typename T> struct Array
47{
48 Array() : array(nullptr) {}
49 template<int N> Array(const T (&array)[N]) : array(array), count(N) {}
50
51 T operator [](int index) const { return array[index]; }
52
53 const T *array;
54 int count = 0;
55};
56
57typedef Array<int> IndexArray;
58typedef Array<const void *> ListArray;
59
60typedef QVector<QQmlListCompositor::Remove> RemoveList;
61typedef QVector<QQmlListCompositor::Insert> InsertList;
62typedef QVector<QQmlListCompositor::Change> ChangeList;
63
64typedef QVector<Range> RangeList;
65
66Q_DECLARE_METATYPE(RangeList)
67Q_DECLARE_METATYPE(RemoveList)
68Q_DECLARE_METATYPE(InsertList)
69Q_DECLARE_METATYPE(ChangeList)
70Q_DECLARE_METATYPE(void *)
71Q_DECLARE_METATYPE(IndexArray)
72Q_DECLARE_METATYPE(ListArray)
73Q_DECLARE_METATYPE(C::Group)
74
75QT_BEGIN_NAMESPACE
76bool operator ==(const C::Change &left, const C::Change &right)
77{
78 return left.index[3] == right.index[3]
79 && left.index[2] == right.index[2]
80 && left.index[1] == right.index[1]
81 && left.index[0] == right.index[0]
82 && left.count == right.count
83 && left.groups() == right.groups()
84 && left.inCache() == right.inCache()
85 && (left.moveId == -1) == (right.moveId == -1);
86}
87QT_END_NAMESPACE
88
89static const C::Group Visible = C::Group(2);
90static const C::Group Selection = C::Group(3);
91
92class tst_qqmllistcompositor : public QObject
93{
94 Q_OBJECT
95
96 enum {
97 VisibleFlag = 0x04,
98 SelectionFlag = 0x08
99 };
100
101 void populateChange(
102 C::Change &change, int sIndex, int vIndex, int dIndex, int cIndex, int count, int flags, int moveId)
103 {
104 change.index[Selection] = sIndex;
105 change.index[Visible] = vIndex;
106 change.index[C::Default] = dIndex;
107 change.index[C::Cache] = cIndex;
108 change.count = count;
109 change.flags = flags;
110 change.moveId = moveId;
111 }
112
113 C::Remove Remove(
114 int sIndex, int vIndex, int dIndex, int cIndex, int count, int flags, int moveId = -1)
115 {
116 C::Remove remove;
117 populateChange(change&: remove, sIndex, vIndex, dIndex, cIndex, count, flags, moveId);
118 return remove;
119 }
120
121 C::Insert Insert(
122 int sIndex, int vIndex, int dIndex, int cIndex, int count, int flags, int moveId = -1)
123 {
124 C::Insert insert;
125 populateChange(change&: insert, sIndex, vIndex, dIndex, cIndex, count, flags, moveId);
126 return insert;
127 }
128
129 C::Change Change(
130 int sIndex, int vIndex, int dIndex, int cIndex, int count, int flags, int moveId = -1)
131 {
132 C::Change change;
133 populateChange(change, sIndex, vIndex, dIndex, cIndex, count, flags, moveId);
134 return change;
135 }
136
137private slots:
138 void find_data();
139 void find();
140 void findInsertPosition_data();
141 void findInsertPosition();
142 void insert();
143 void clearFlags_data();
144 void clearFlags();
145 void setFlags_data();
146 void setFlags();
147 void move_data();
148 void move();
149 void moveFromEnd();
150 void clear();
151 void listItemsInserted_data();
152 void listItemsInserted();
153 void listItemsRemoved_data();
154 void listItemsRemoved();
155 void listItemsMoved_data();
156 void listItemsMoved();
157 void listItemsChanged_data();
158 void listItemsChanged();
159 void compositorDebug();
160 void changeDebug();
161 void groupDebug();
162};
163
164void tst_qqmllistcompositor::find_data()
165{
166 QTest::addColumn<RangeList>(name: "ranges");
167 QTest::addColumn<C::Group>(name: "startGroup");
168 QTest::addColumn<int>(name: "startIndex");
169 QTest::addColumn<C::Group>(name: "group");
170 QTest::addColumn<int>(name: "index");
171 QTest::addColumn<int>(name: "selectionIndex");
172 QTest::addColumn<int>(name: "visibleIndex");
173 QTest::addColumn<int>(name: "defaultIndex");
174 QTest::addColumn<int>(name: "cacheIndex");
175 QTest::addColumn<uint>(name: "rangeFlags");
176 QTest::addColumn<int>(name: "rangeIndex");
177
178 int listA; void *a = &listA;
179
180 QTest::newRow(dataTag: "Start")
181 << (RangeList()
182 << Range(a, 0, 1, int(C::PrependFlag | SelectionFlag | C::DefaultFlag | C::CacheFlag))
183 << Range(a, 1, 1, int(C::AppendFlag | C::PrependFlag | C::CacheFlag))
184 << Range(nullptr, 0, 1, int(VisibleFlag| C::CacheFlag)))
185 << C::Cache << 2
186 << Selection << 0
187 << 0 << 0 << 0 << 0
188 << uint(C::PrependFlag | SelectionFlag | C::DefaultFlag | C::CacheFlag) << 0;
189}
190
191void tst_qqmllistcompositor::find()
192{
193 QFETCH(RangeList, ranges);
194 QFETCH(C::Group, startGroup);
195 QFETCH(int, startIndex);
196 QFETCH(C::Group, group);
197 QFETCH(int, index);
198 QFETCH(int, cacheIndex);
199 QFETCH(int, defaultIndex);
200 QFETCH(int, visibleIndex);
201 QFETCH(int, selectionIndex);
202 QFETCH(uint, rangeFlags);
203 QFETCH(int, rangeIndex);
204
205 QQmlListCompositor compositor;
206 compositor.setGroupCount(4);
207 compositor.setDefaultGroups(VisibleFlag | C::DefaultFlag);
208
209 foreach (const Range &range, ranges)
210 compositor.append(list: range.list, index: range.index, count: range.count, flags: range.flags);
211
212 compositor.find(group: startGroup, index: startIndex);
213
214 QQmlListCompositor::iterator it = compositor.find(group, index);
215 QCOMPARE(it.index[C::Cache], cacheIndex);
216 QCOMPARE(it.index[C::Default], defaultIndex);
217 QCOMPARE(it.index[Visible], visibleIndex);
218 QCOMPARE(it.index[Selection], selectionIndex);
219 QCOMPARE(it->flags, rangeFlags);
220 QCOMPARE(it->index, rangeIndex);
221}
222
223void tst_qqmllistcompositor::findInsertPosition_data()
224{
225 QTest::addColumn<RangeList>(name: "ranges");
226 QTest::addColumn<C::Group>(name: "group");
227 QTest::addColumn<int>(name: "index");
228 QTest::addColumn<int>(name: "selectionIndex");
229 QTest::addColumn<int>(name: "visibleIndex");
230 QTest::addColumn<int>(name: "defaultIndex");
231 QTest::addColumn<int>(name: "cacheIndex");
232 QTest::addColumn<uint>(name: "rangeFlags");
233 QTest::addColumn<int>(name: "rangeIndex");
234
235 int listA; void *a = &listA;
236
237 QTest::newRow(dataTag: "Start")
238 << (RangeList()
239 << Range(a, 0, 1, int(C::PrependFlag | SelectionFlag | C::DefaultFlag | C::CacheFlag))
240 << Range(a, 1, 1, int(C::AppendFlag | C::PrependFlag | C::CacheFlag))
241 << Range(nullptr, 0, 1, int(VisibleFlag| C::CacheFlag)))
242 << Selection << 0
243 << 0 << 0 << 0 << 0
244 << uint(C::PrependFlag | SelectionFlag | C::DefaultFlag | C::CacheFlag) << 0;
245 QTest::newRow(dataTag: "1")
246 << (RangeList()
247 << Range(a, 0, 1, int(C::PrependFlag | SelectionFlag | C::DefaultFlag | C::CacheFlag))
248 << Range(a, 1, 1, int(C::AppendFlag | C::PrependFlag | C::CacheFlag))
249 << Range(nullptr, 0, 1, int(VisibleFlag| C::CacheFlag)))
250 << Selection << 1
251 << 1 << 1 << 1 << 3
252 << uint(0) << 0;
253}
254
255void tst_qqmllistcompositor::findInsertPosition()
256{
257 QFETCH(RangeList, ranges);
258 QFETCH(C::Group, group);
259 QFETCH(int, index);
260 QFETCH(int, cacheIndex);
261 QFETCH(int, defaultIndex);
262 QFETCH(int, visibleIndex);
263 QFETCH(int, selectionIndex);
264 QFETCH(uint, rangeFlags);
265 QFETCH(int, rangeIndex);
266
267 QQmlListCompositor compositor;
268 compositor.setGroupCount(4);
269 compositor.setDefaultGroups(VisibleFlag | C::DefaultFlag);
270
271 foreach (const Range &range, ranges)
272 compositor.append(list: range.list, index: range.index, count: range.count, flags: range.flags);
273
274 QQmlListCompositor::insert_iterator it = compositor.findInsertPosition(group, index);
275
276 QCOMPARE(it.index[C::Cache], cacheIndex);
277 QCOMPARE(it.index[C::Default], defaultIndex);
278 QCOMPARE(it.index[Visible], visibleIndex);
279 QCOMPARE(it.index[Selection], selectionIndex);
280 QCOMPARE(it->flags, rangeFlags);
281 QCOMPARE(it->index, rangeIndex);
282}
283
284void tst_qqmllistcompositor::insert()
285{
286 QQmlListCompositor compositor;
287 compositor.setGroupCount(4);
288 compositor.setDefaultGroups(VisibleFlag | C::DefaultFlag);
289
290 C::iterator it;
291
292 int listA; int *a = &listA;
293 int listB; int *b = &listB;
294 int listC; int *c = &listC;
295
296 {
297 compositor.append(list: a, index: 0, count: 12, flags: C::AppendFlag | C::PrependFlag | C::DefaultFlag);
298 const int indexes[] = {0,1,2,3,4,5,6,7,8,9,10,11};
299 const int *lists[] = {a,a,a,a,a,a,a,a,a,a, a, a};
300 QCOMPARE(compositor.count(C::Default), lengthOf(indexes));
301 for (int i = 0; i < lengthOf(indexes); ++i) {
302 it = compositor.find(group: C::Default, index: i);
303 QCOMPARE(it.list<int>(), lists[i]);
304 if (lists[i]) QCOMPARE(it.modelIndex(), indexes[i]);
305 }
306 } {
307 compositor.append(list: b, index: 4, count: 4, flags: C::DefaultFlag);
308 const int indexes[] = {0,1,2,3,4,5,6,7,8,9,10,11,4,5,6,7};
309 const int *lists[] = {a,a,a,a,a,a,a,a,a,a, a, a,b,b,b,b};
310 QCOMPARE(compositor.count(C::Default), lengthOf(indexes));
311 for (int i = 0; i < lengthOf(indexes); ++i) {
312 it = compositor.find(group: C::Default, index: i);
313 QCOMPARE(it.list<int>(), lists[i]);
314 if (lists[i]) QCOMPARE(it.modelIndex(), indexes[i]);
315 }
316 } { // Insert at end.
317 compositor.insert(
318 group: C::Default, before: 16, list: c, index: 2, count: 2, flags: C::DefaultFlag);
319 const int indexes[] = {0,1,2,3,4,5,6,7,8,9,10,11,4,5,6,7,2,3};
320 const int *lists[] = {a,a,a,a,a,a,a,a,a,a, a, a,b,b,b,b,c,c};
321 QCOMPARE(compositor.count(C::Default), lengthOf(indexes));
322 for (int i = 0; i < lengthOf(indexes); ++i) {
323 it = compositor.find(group: C::Default, index: i);
324 QCOMPARE(it.list<int>(), lists[i]);
325 if (lists[i]) QCOMPARE(it.modelIndex(), indexes[i]);
326 }
327 } { // Insert at start
328 compositor.insert(
329 group: C::Default, before: 0, list: c, index: 6, count: 4, flags: C::DefaultFlag);
330 const int indexes[] = {6,7,8,9,0,1,2,3,4,5,6,7,8,9,10,11,4,5,6,7,2,3};
331 const int *lists[] = {c,c,c,c,a,a,a,a,a,a,a,a,a,a, a, a,b,b,b,b,c,c};
332 for (int i = 0; i < lengthOf(indexes); ++i) {
333 it = compositor.find(group: C::Default, index: i);
334 QCOMPARE(it.list<int>(), lists[i]);
335 if (lists[i]) QCOMPARE(it.modelIndex(), indexes[i]);
336 }
337 } { // Insert after static range.
338 compositor.insert(
339 group: C::Default, before: 4, list: b, index: 0, count: 8, flags: C::AppendFlag | C::PrependFlag | C::DefaultFlag);
340 const int indexes[] = {6,7,8,9,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,8,9,10,11,4,5,6,7,2,3};
341 const int *lists[] = {c,c,c,c,b,b,b,b,b,b,b,b,a,a,a,a,a,a,a,a,a,a, a, a,b,b,b,b,c,c};
342 QCOMPARE(compositor.count(C::Default), lengthOf(indexes));
343 for (int i = 0; i < lengthOf(indexes); ++i) {
344 it = compositor.find(group: C::Default, index: i);
345 QCOMPARE(it.list<int>(), lists[i]);
346 if (lists[i]) QCOMPARE(it.modelIndex(), indexes[i]);
347 }
348 } { // Insert at end of dynamic range.
349 compositor.insert(
350 group: C::Default, before: 12, list: c, index: 0, count: 4, flags: C::AppendFlag | C::PrependFlag | C::DefaultFlag);
351 const int indexes[] = {6,7,8,9,0,1,2,3,4,5,6,7,0,1,2,3,0,1,2,3,4,5,6,7,8,9,10,11,4,5,6,7,2,3};
352 const int *lists[] = {c,c,c,c,b,b,b,b,b,b,b,b,c,c,c,c,a,a,a,a,a,a,a,a,a,a, a, a,b,b,b,b,c,c};
353 QCOMPARE(compositor.count(C::Default), lengthOf(indexes));
354 for (int i = 0; i < lengthOf(indexes); ++i) {
355 it = compositor.find(group: C::Default, index: i);
356 QCOMPARE(it.list<int>(), lists[i]);
357 if (lists[i]) QCOMPARE(it.modelIndex(), indexes[i]);
358 }
359 } { // Insert into range.
360 compositor.insert(
361 group: C::Default, before: 8, list: c, index: 0, count: 4, flags: C::AppendFlag | C::PrependFlag | C::DefaultFlag);
362 const int indexes[] = {6,7,8,9,0,1,2,3,0,1,2,3,4,5,6,7,0,1,2,3,0,1,2,3,4,5,6,7,8,9,10,11,4,5,6,7,2,3};
363 const int *lists[] = {c,c,c,c,b,b,b,b,c,c,c,c,b,b,b,b,c,c,c,c,a,a,a,a,a,a,a,a,a,a, a, a,b,b,b,b,c,c};
364 QCOMPARE(compositor.count(C::Default), lengthOf(indexes));
365 for (int i = 0; i < lengthOf(indexes); ++i) {
366 it = compositor.find(group: C::Default, index: i);
367 QCOMPARE(it.list<int>(), lists[i]);
368 if (lists[i]) QCOMPARE(it.modelIndex(), indexes[i]);
369 }
370 }
371}
372
373void tst_qqmllistcompositor::clearFlags_data()
374{
375 QTest::addColumn<RangeList>(name: "ranges");
376 QTest::addColumn<C::Group>(name: "group");
377 QTest::addColumn<int>(name: "index");
378 QTest::addColumn<int>(name: "count");
379 QTest::addColumn<int>(name: "flags");
380 QTest::addColumn<RemoveList>(name: "expectedRemoves");
381 QTest::addColumn<IndexArray>(name: "cacheIndexes");
382 QTest::addColumn<ListArray>(name: "cacheLists");
383 QTest::addColumn<IndexArray>(name: "defaultIndexes");
384 QTest::addColumn<ListArray>(name: "defaultLists");
385 QTest::addColumn<IndexArray>(name: "visibleIndexes");
386 QTest::addColumn<ListArray>(name: "visibleLists");
387 QTest::addColumn<IndexArray>(name: "selectionIndexes");
388 QTest::addColumn<ListArray>(name: "selectionLists");
389
390 int listA; void *a = &listA;
391
392 { static const int cacheIndexes[] = {0,1,2,3,4,5,6,7,8,9,10,11,0,0,0,0};
393 static const void *cacheLists[] = {a,a,a,a,a,a,a,a,a,a, a, a,nullptr,nullptr,nullptr,nullptr};
394 static const int defaultIndexes[] = {0,1,2,3,4,5,6,7,8,9,10,11,0,0,0,0};
395 static const void *defaultLists[] = {a,a,a,a,a,a,a,a,a,a, a, a,nullptr,nullptr,nullptr,nullptr};
396 static const int visibleIndexes[] = {0,1,2,3,4,5,6,7,8,9,10,11,0,0,0,0};
397 static const void *visibleLists[] = {a,a,a,a,a,a,a,a,a,a, a, a,nullptr,nullptr,nullptr,nullptr};
398 static const int selectionIndexes[] = {0,1,4,5,6,7,8,9,10,11,0,0,0,0};
399 static const void *selectionLists[] = {a,a,a,a,a,a,a,a, a, a,nullptr,nullptr,nullptr,nullptr};
400 QTest::newRow(dataTag: "Default, 2, 2, Selection")
401 << (RangeList()
402 << Range(a, 0, 12, int(C::AppendFlag | C::PrependFlag | SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag))
403 << Range(nullptr, 0, 4, int(SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag)))
404 << C::Default << 2 << 2 << int(SelectionFlag)
405 << (RemoveList()
406 << Remove(sIndex: 2, vIndex: 2, dIndex: 2, cIndex: 2, count: 2, flags: SelectionFlag | C::CacheFlag))
407 << IndexArray(cacheIndexes) << ListArray(cacheLists)
408 << IndexArray(defaultIndexes) << ListArray(defaultLists)
409 << IndexArray(visibleIndexes) << ListArray(visibleLists)
410 << IndexArray(selectionIndexes) << ListArray(selectionLists);
411 } { static const int cacheIndexes[] = {0,1,2,3,4,5,6,7,8,9,10,11,0,0,0,0};
412 static const void *cacheLists[] = {a,a,a,a,a,a,a,a,a,a, a, a,nullptr,nullptr,nullptr,nullptr};
413 static const int defaultIndexes[] = {0,1,2,3,4,5,6,7,8,9,10,11,0,0,0,0};
414 static const void *defaultLists[] = {a,a,a,a,a,a,a,a,a,a, a, a,nullptr,nullptr,nullptr,nullptr};
415 static const int visibleIndexes[] = {0,2,3,5,6,7,8,9,10,11,0,0,0,0};
416 static const void *visibleLists[] = {a,a,a,a,a,a,a,a, a, a,nullptr,nullptr,nullptr,nullptr};
417 static const int selectionIndexes[] = {0,1,4,5,6,7,8,9,10,11,0,0,0,0};
418 static const void *selectionLists[] = {a,a,a,a,a,a,a,a, a, a,nullptr,nullptr,nullptr,nullptr};
419 QTest::newRow(dataTag: "Selection, 1, 2, Visible")
420 << (RangeList()
421 << Range(a, 0, 2, int(C::PrependFlag | SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag))
422 << Range(a, 2, 2, int(C::PrependFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag))
423 << Range(a, 4, 8, int(C::AppendFlag | C::PrependFlag | SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag))
424 << Range(nullptr, 0, 4, int(SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag)))
425 << Selection << 1 << 2 << int(VisibleFlag)
426 << (RemoveList()
427 << Remove(sIndex: 1, vIndex: 1, dIndex: 1, cIndex: 1, count: 1, flags: VisibleFlag | C::CacheFlag)
428 << Remove(sIndex: 2, vIndex: 3, dIndex: 4, cIndex: 4, count: 1, flags: VisibleFlag | C::CacheFlag))
429 << IndexArray(cacheIndexes) << ListArray(cacheLists)
430 << IndexArray(defaultIndexes) << ListArray(defaultLists)
431 << IndexArray(visibleIndexes) << ListArray(visibleLists)
432 << IndexArray(selectionIndexes) << ListArray(selectionLists);
433 } { static const int cacheIndexes[] = {0,1,2,3,4,5,6,7,8,9,10,11,0,0,0,0};
434 static const void *cacheLists[] = {a,a,a,a,a,a,a,a,a,a, a, a,nullptr,nullptr,nullptr,nullptr};
435 static const int defaultIndexes[] = {0,1,2,3,4,5,6,7,8,9,10,11,0,0,0};
436 static const void *defaultLists[] = {a,a,a,a,a,a,a,a,a,a, a, a,nullptr,nullptr,nullptr};
437 static const int visibleIndexes[] = {0,2,3,5,6,7,8,9,10,11,0,0,0};
438 static const void *visibleLists[] = {a,a,a,a,a,a,a,a, a, a,nullptr,nullptr,nullptr};
439 static const int selectionIndexes[] = {0,1,4,5,6,7,8,9,10,11,0,0,0};
440 static const void *selectionLists[] = {a,a,a,a,a,a,a,a, a, a,nullptr,nullptr,nullptr};
441 QTest::newRow(dataTag: "Default, 13, 1, Prepend | Selection | Visible | Default")
442 << (RangeList()
443 << Range(a, 0, 1, int(C::PrependFlag | SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag))
444 << Range(a, 1, 1, int(C::PrependFlag | SelectionFlag | C::DefaultFlag | C::CacheFlag))
445 << Range(a, 2, 2, int(C::PrependFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag))
446 << Range(a, 4, 1, int(C::PrependFlag | SelectionFlag | C::DefaultFlag | C::CacheFlag))
447 << Range(a, 5, 7, int(C::AppendFlag | C::PrependFlag | SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag))
448 << Range(nullptr, 0, 4, int(SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag)))
449 << C::Default << 13 << 1 << int(C::PrependFlag | SelectionFlag | VisibleFlag | C::DefaultFlag)
450 << (RemoveList()
451 << Remove(sIndex: 11, vIndex: 11, dIndex: 13, cIndex: 13, count: 1, flags: SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag))
452 << IndexArray(cacheIndexes) << ListArray(cacheLists)
453 << IndexArray(defaultIndexes) << ListArray(defaultLists)
454 << IndexArray(visibleIndexes) << ListArray(visibleLists)
455 << IndexArray(selectionIndexes) << ListArray(selectionLists);
456 } { static const int cacheIndexes[] = {0,1,2,3,4,5,6,7,8,9,10,0};
457 static const void *cacheLists[] = {a,a,a,a,a,a,a,a,a,a, a,nullptr};
458 static const int defaultIndexes[] = {0,1,2,3,4,5,6,7,8,9,10,11,0,0,0};
459 static const void *defaultLists[] = {a,a,a,a,a,a,a,a,a,a, a, a,nullptr,nullptr,nullptr};
460 static const int visibleIndexes[] = {0,2,3,5,6,7,8,9,10,11,0,0,0};
461 static const void *visibleLists[] = {a,a,a,a,a,a,a,a, a, a,nullptr,nullptr,nullptr};
462 static const int selectionIndexes[] = {0,1,4,5,6,7,8,9,10,11,0,0,0};
463 static const void *selectionLists[] = {a,a,a,a,a,a,a,a, a, a,nullptr,nullptr,nullptr};
464 QTest::newRow(dataTag: "Cache, 11, 4, Cache")
465 << (RangeList()
466 << Range(a, 0, 1, int(C::PrependFlag | SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag))
467 << Range(a, 1, 1, int(C::PrependFlag | SelectionFlag | C::DefaultFlag | C::CacheFlag))
468 << Range(a, 2, 2, int(C::PrependFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag))
469 << Range(a, 4, 1, int(C::PrependFlag | SelectionFlag | C::DefaultFlag | C::CacheFlag))
470 << Range(a, 5, 7, int(C::AppendFlag | C::PrependFlag | SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag))
471 << Range(nullptr, 0, 1, int(C::CacheFlag))
472 << Range(nullptr, 0, 3, int(SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag)))
473 << C::Cache << 11 << 4 << int(C::CacheFlag)
474 << (RemoveList())
475 << IndexArray(cacheIndexes) << ListArray(cacheLists)
476 << IndexArray(defaultIndexes) << ListArray(defaultLists)
477 << IndexArray(visibleIndexes) << ListArray(visibleLists)
478 << IndexArray(selectionIndexes) << ListArray(selectionLists);
479 } { static const int cacheIndexes[] = {0,1,2,3,4,5,6,7,8,9,10,0};
480 static const void *cacheLists[] = {a,a,a,a,a,a,a,a,a,a, a,nullptr};
481 static const int defaultIndexes[] = {0,1,2,3,4,5,6,7,8,9,10,0};
482 static const void *defaultLists[] = {a,a,a,a,a,a,a,a,a,a, a,nullptr};
483 static const int visibleIndexes[] = {0,2,3,5,6,7,8,9,10,0};
484 static const void *visibleLists[] = {a,a,a,a,a,a,a,a, a,nullptr};
485 static const int selectionIndexes[] = {0,1,4,5,6,7,8,9,10,0};
486 static const void *selectionLists[] = {a,a,a,a,a,a,a,a, a,nullptr};
487 QTest::newRow(dataTag: "Default, 11, 3, Default | Visible | Selection")
488 << (RangeList()
489 << Range(a, 0, 1, int(C::PrependFlag | SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag))
490 << Range(a, 1, 1, int(C::PrependFlag | SelectionFlag | C::DefaultFlag | C::CacheFlag))
491 << Range(a, 2, 2, int(C::PrependFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag))
492 << Range(a, 4, 1, int(C::PrependFlag | SelectionFlag | C::DefaultFlag | C::CacheFlag))
493 << Range(a, 5, 6, int(C::PrependFlag | SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag))
494 << Range(a, 11, 1, int(C::AppendFlag | C::PrependFlag | SelectionFlag | VisibleFlag | C::DefaultFlag))
495 << Range(nullptr, 0, 2, int(SelectionFlag | VisibleFlag | C::DefaultFlag))
496 << Range(nullptr, 0, 1, int(SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag)))
497 << C::Default << 11 << 3 << int(C::DefaultFlag | VisibleFlag| SelectionFlag)
498 << (RemoveList()
499 << Remove(sIndex: 9, vIndex: 9, dIndex: 11, cIndex: 11, count: 1, flags: SelectionFlag | VisibleFlag | C::DefaultFlag)
500 << Remove(sIndex: 9, vIndex: 9, dIndex: 11, cIndex: 11, count: 2, flags: SelectionFlag | VisibleFlag | C::DefaultFlag))
501 << IndexArray(cacheIndexes) << ListArray(cacheLists)
502 << IndexArray(defaultIndexes) << ListArray(defaultLists)
503 << IndexArray(visibleIndexes) << ListArray(visibleLists)
504 << IndexArray(selectionIndexes) << ListArray(selectionLists);
505 }
506}
507
508void tst_qqmllistcompositor::clearFlags()
509{
510 QFETCH(RangeList, ranges);
511 QFETCH(C::Group, group);
512 QFETCH(int, index);
513 QFETCH(int, count);
514 QFETCH(int, flags);
515 QFETCH(RemoveList, expectedRemoves);
516 QFETCH(IndexArray, cacheIndexes);
517 QFETCH(ListArray, cacheLists);
518 QFETCH(IndexArray, defaultIndexes);
519 QFETCH(ListArray, defaultLists);
520 QFETCH(IndexArray, visibleIndexes);
521 QFETCH(ListArray, visibleLists);
522 QFETCH(IndexArray, selectionIndexes);
523 QFETCH(ListArray, selectionLists);
524
525 QQmlListCompositor compositor;
526 compositor.setGroupCount(4);
527 compositor.setDefaultGroups(VisibleFlag | C::DefaultFlag);
528
529 foreach (const Range &range, ranges)
530 compositor.append(list: range.list, index: range.index, count: range.count, flags: range.flags);
531
532 QVector<C::Remove> removes;
533 compositor.clearFlags(fromGroup: group, from: index, count, flags, removals: &removes);
534
535 QCOMPARE(removes, expectedRemoves);
536
537 QCOMPARE(compositor.count(C::Cache), cacheIndexes.count);
538 for (int i = 0; i < cacheIndexes.count; ++i) {
539 C::iterator it = compositor.find(group: C::Cache, index: i);
540 QCOMPARE(it->list, cacheLists[i]);
541 if (cacheLists[i])
542 QCOMPARE(it.modelIndex(), cacheIndexes[i]);
543 }
544 QCOMPARE(compositor.count(C::Default), defaultIndexes.count);
545 for (int i = 0; i < defaultIndexes.count; ++i) {
546 C::iterator it = compositor.find(group: C::Default, index: i);
547 QCOMPARE(it->list, defaultLists[i]);
548 if (defaultLists[i])
549 QCOMPARE(it.modelIndex(), defaultIndexes[i]);
550 }
551 QCOMPARE(compositor.count(Visible), visibleIndexes.count);
552 for (int i = 0; i < visibleIndexes.count; ++i) {
553 C::iterator it = compositor.find(group: Visible, index: i);
554 QCOMPARE(it->list, visibleLists[i]);
555 if (visibleLists[i])
556 QCOMPARE(it.modelIndex(), visibleIndexes[i]);
557 }
558 QCOMPARE(compositor.count(Selection), selectionIndexes.count);
559 for (int i = 0; i < selectionIndexes.count; ++i) {
560 C::iterator it = compositor.find(group: Selection, index: i);
561 QCOMPARE(it->list, selectionLists[i]);
562 if (selectionLists[i])
563 QCOMPARE(it.modelIndex(), selectionIndexes[i]);
564 }
565}
566
567void tst_qqmllistcompositor::setFlags_data()
568{
569 QTest::addColumn<RangeList>(name: "ranges");
570 QTest::addColumn<C::Group>(name: "group");
571 QTest::addColumn<int>(name: "index");
572 QTest::addColumn<int>(name: "count");
573 QTest::addColumn<int>(name: "flags");
574 QTest::addColumn<InsertList>(name: "expectedInserts");
575 QTest::addColumn<IndexArray>(name: "cacheIndexes");
576 QTest::addColumn<ListArray>(name: "cacheLists");
577 QTest::addColumn<IndexArray>(name: "defaultIndexes");
578 QTest::addColumn<ListArray>(name: "defaultLists");
579 QTest::addColumn<IndexArray>(name: "visibleIndexes");
580 QTest::addColumn<ListArray>(name: "visibleLists");
581 QTest::addColumn<IndexArray>(name: "selectionIndexes");
582 QTest::addColumn<ListArray>(name: "selectionLists");
583
584 int listA; void *a = &listA;
585
586 { static const int cacheIndexes[] = {0,0,0,0};
587 static const void *cacheLists[] = {nullptr,nullptr,nullptr,nullptr};
588 static const int defaultIndexes[] = {0,1,2,3,4,5,6,7,8,9,10,11};
589 static const void *defaultLists[] = {a,a,a,a,a,a,a,a,a,a, a, a};
590 QTest::newRow(dataTag: "Default, 2, 2, Default")
591 << (RangeList()
592 << Range(a, 0, 12, C::DefaultFlag)
593 << Range(nullptr, 0, 4, C::CacheFlag))
594 << C::Default << 2 << 2 << int(C::DefaultFlag)
595 << (InsertList())
596 << IndexArray(cacheIndexes) << ListArray(cacheLists)
597 << IndexArray(defaultIndexes) << ListArray(defaultLists)
598 << IndexArray() << ListArray()
599 << IndexArray() << ListArray();
600 } { static const int cacheIndexes[] = {0,0,0,0};
601 static const void *cacheLists[] = {nullptr,nullptr,nullptr,nullptr};
602 static const int defaultIndexes[] = {0,1,2,3,4,5,6,7,8,9,10,11};
603 static const void *defaultLists[] = {a,a,a,a,a,a,a,a,a,a, a, a};
604 static const int visibleIndexes[] = {2,3};
605 static const void *visibleLists[] = {a,a};
606 QTest::newRow(dataTag: "Default, 2, 2, Visible")
607 << (RangeList()
608 << Range(a, 0, 12, C::DefaultFlag)
609 << Range(nullptr, 0, 4, C::CacheFlag))
610 << C::Default << 2 << 2 << int(VisibleFlag)
611 << (InsertList()
612 << Insert(sIndex: 0, vIndex: 0, dIndex: 2, cIndex: 0, count: 2, flags: VisibleFlag))
613 << IndexArray(cacheIndexes) << ListArray(cacheLists)
614 << IndexArray(defaultIndexes) << ListArray(defaultLists)
615 << IndexArray(visibleIndexes) << ListArray(visibleLists)
616 << IndexArray() << ListArray();
617 } { static const int cacheIndexes[] = {3,6,0,0,0,0};
618 static const void *cacheLists[] = {a,a,nullptr,nullptr,nullptr,nullptr};
619 static const int defaultIndexes[] = {0,1,2,3,4,5,6,7,8,9,10,11};
620 static const void *defaultLists[] = {a,a,a,a,a,a,a,a,a,a, a, a};
621 static const int visibleIndexes[] = {2,3,6,7};
622 static const void *visibleLists[] = {a,a,a,a};
623 static const int selectionIndexes[] = {3,6};
624 static const void *selectionLists[] = {a,a};
625 QTest::newRow(dataTag: "Visible, 1, 2, Selection | Cache")
626 << (RangeList()
627 << Range(a, 0, 2, C::DefaultFlag)
628 << Range(a, 2, 2, VisibleFlag | C::DefaultFlag)
629 << Range(a, 4, 2, C::DefaultFlag)
630 << Range(a, 6, 2, VisibleFlag | C::DefaultFlag)
631 << Range(a, 8, 4, C::DefaultFlag)
632 << Range(nullptr, 0, 4, C::CacheFlag))
633 << Visible << 1 << 2 << int(SelectionFlag | C::CacheFlag)
634 << (InsertList()
635 << Insert(sIndex: 0, vIndex: 1, dIndex: 3, cIndex: 0, count: 1, flags: SelectionFlag | C::CacheFlag)
636 << Insert(sIndex: 1, vIndex: 2, dIndex: 6, cIndex: 1, count: 1, flags: SelectionFlag | C::CacheFlag))
637 << IndexArray(cacheIndexes) << ListArray(cacheLists)
638 << IndexArray(defaultIndexes) << ListArray(defaultLists)
639 << IndexArray(visibleIndexes) << ListArray(visibleLists)
640 << IndexArray(selectionIndexes) << ListArray(selectionLists);
641 } { static const int cacheIndexes[] = {3,6,0,0,0,0};
642 static const void *cacheLists[] = {a,a,nullptr,nullptr,nullptr,nullptr};
643 static const int defaultIndexes[] = {0,1,2,3,4,5,6,7,8,9,10,11};
644 static const void *defaultLists[] = {a,a,a,a,a,a,a,a,a,a, a, a};
645 static const int visibleIndexes[] = {2,3,6,7,0};
646 static const void *visibleLists[] = {a,a,a,a,nullptr};
647 static const int selectionIndexes[] = {3,6};
648 static const void *selectionLists[] = {a,a};
649 QTest::newRow(dataTag: "Cache, 3, 1, Visible")
650 << (RangeList()
651 << Range(a, 0, 2, C::DefaultFlag)
652 << Range(a, 2, 1, VisibleFlag | C::DefaultFlag)
653 << Range(a, 3, 1, SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag)
654 << Range(a, 4, 2, C::DefaultFlag)
655 << Range(a, 6, 1, SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag)
656 << Range(a, 7, 1, VisibleFlag | C::DefaultFlag)
657 << Range(a, 8, 4, C::DefaultFlag)
658 << Range(nullptr, 0, 4, C::CacheFlag))
659 << C::Cache << 3 << 1 << int(VisibleFlag)
660 << (InsertList()
661 << Insert(sIndex: 2, vIndex: 4, dIndex: 12, cIndex: 3, count: 1, flags: VisibleFlag | C::CacheFlag))
662 << IndexArray(cacheIndexes) << ListArray(cacheLists)
663 << IndexArray(defaultIndexes) << ListArray(defaultLists)
664 << IndexArray(visibleIndexes) << ListArray(visibleLists)
665 << IndexArray(selectionIndexes) << ListArray(selectionLists);
666 } { static const int cacheIndexes[] = {0,1,2,3,4,5,6,7,8,9,10,11};
667 static const void *cacheLists[] = {a,a,a,a,a,a,a,a,a,a, a, a};
668 static const int defaultIndexes[] = {0,1,2,3,4,5,6,7,8,9,10,11};
669 static const void *defaultLists[] = {a,a,a,a,a,a,a,a,a,a, a, a};
670 static const int visibleIndexes[] = {0,1,3,4,5,6,7,8,9,10,11};
671 static const void *visibleLists[] = {a,a,a,a,a,a,a,a,a, a, a};
672 static const int selectionIndexes[] = {2,6,7,8,9};
673 static const void *selectionLists[] = {a,a,a,a,a};
674 QTest::newRow(dataTag: "Existing flag, sparse selection")
675 << (RangeList()
676 << Range(a, 0, 2, C::PrependFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag)
677 << Range(a, 2, 1, C::PrependFlag | SelectionFlag | C::DefaultFlag | C::CacheFlag)
678 << Range(a, 3, 3, C::PrependFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag)
679 << Range(a, 6, 4, C::PrependFlag | SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag)
680 << Range(a,10, 2, C::AppendFlag | C::PrependFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag))
681 << C::Cache << 3 << 1 << int(VisibleFlag)
682 << InsertList()
683 << IndexArray(cacheIndexes) << ListArray(cacheLists)
684 << IndexArray(defaultIndexes) << ListArray(defaultLists)
685 << IndexArray(visibleIndexes) << ListArray(visibleLists)
686 << IndexArray(selectionIndexes) << ListArray(selectionLists);
687 }
688}
689
690void tst_qqmllistcompositor::setFlags()
691{
692 QFETCH(RangeList, ranges);
693 QFETCH(C::Group, group);
694 QFETCH(int, index);
695 QFETCH(int, count);
696 QFETCH(int, flags);
697 QFETCH(InsertList, expectedInserts);
698 QFETCH(IndexArray, cacheIndexes);
699 QFETCH(ListArray, cacheLists);
700 QFETCH(IndexArray, defaultIndexes);
701 QFETCH(ListArray, defaultLists);
702 QFETCH(IndexArray, visibleIndexes);
703 QFETCH(ListArray, visibleLists);
704 QFETCH(IndexArray, selectionIndexes);
705 QFETCH(ListArray, selectionLists);
706
707 QQmlListCompositor compositor;
708 compositor.setGroupCount(4);
709 compositor.setDefaultGroups(VisibleFlag | C::DefaultFlag);
710
711 foreach (const Range &range, ranges)
712 compositor.append(list: range.list, index: range.index, count: range.count, flags: range.flags);
713
714 QVector<C::Insert> inserts;
715 compositor.setFlags(fromGroup: group, from: index, count, flags, inserts: &inserts);
716
717 QCOMPARE(inserts, expectedInserts);
718
719 QCOMPARE(compositor.count(C::Cache), cacheIndexes.count);
720 for (int i = 0; i < cacheIndexes.count; ++i) {
721 C::iterator it = compositor.find(group: C::Cache, index: i);
722 QCOMPARE(it->list, cacheLists[i]);
723 if (cacheLists[i])
724 QCOMPARE(it.modelIndex(), cacheIndexes[i]);
725 }
726 QCOMPARE(compositor.count(C::Default), defaultIndexes.count);
727 for (int i = 0; i < defaultIndexes.count; ++i) {
728 C::iterator it = compositor.find(group: C::Default, index: i);
729 QCOMPARE(it->list, defaultLists[i]);
730 if (defaultLists[i])
731 QCOMPARE(it.modelIndex(), defaultIndexes[i]);
732 }
733 QCOMPARE(compositor.count(Visible), visibleIndexes.count);
734 for (int i = 0; i < visibleIndexes.count; ++i) {
735 C::iterator it = compositor.find(group: Visible, index: i);
736 QCOMPARE(it->list, visibleLists[i]);
737 if (visibleLists[i])
738 QCOMPARE(it.modelIndex(), visibleIndexes[i]);
739 }
740 QCOMPARE(compositor.count(Selection), selectionIndexes.count);
741 for (int i = 0; i < selectionIndexes.count; ++i) {
742 C::iterator it = compositor.find(group: Selection, index: i);
743 QCOMPARE(it->list, selectionLists[i]);
744 if (selectionLists[i])
745 QCOMPARE(it.modelIndex(), selectionIndexes[i]);
746 }
747}
748
749void tst_qqmllistcompositor::move_data()
750{
751 QTest::addColumn<RangeList>(name: "ranges");
752 QTest::addColumn<C::Group>(name: "fromGroup");
753 QTest::addColumn<int>(name: "from");
754 QTest::addColumn<C::Group>(name: "toGroup");
755 QTest::addColumn<int>(name: "to");
756 QTest::addColumn<int>(name: "count");
757 QTest::addColumn<RemoveList>(name: "expectedRemoves");
758 QTest::addColumn<InsertList>(name: "expectedInserts");
759 QTest::addColumn<IndexArray>(name: "cacheIndexes");
760 QTest::addColumn<ListArray>(name: "cacheLists");
761 QTest::addColumn<IndexArray>(name: "defaultIndexes");
762 QTest::addColumn<ListArray>(name: "defaultLists");
763 QTest::addColumn<IndexArray>(name: "visibleIndexes");
764 QTest::addColumn<ListArray>(name: "visibleLists");
765 QTest::addColumn<IndexArray>(name: "selectionIndexes");
766 QTest::addColumn<ListArray>(name: "selectionLists");
767
768 int listA; void *a = &listA;
769 int listB; void *b = &listB;
770 int listC; void *c = &listC;
771
772 { static const int cacheIndexes[] = {0,0,0,0,2,3};
773 static const void *cacheLists[] = {nullptr,nullptr,nullptr,nullptr,c,c};
774 static const int defaultIndexes[] = {0,0,1,2,3,4,5,0,1,2,3,4,5,1,2,3,0,1,2,3,4,5};
775 static const void *defaultLists[] = {nullptr,a,a,a,a,a,a,b,b,b,b,b,b,nullptr,nullptr,nullptr,c,c,c,c,c,c};
776 QTest::newRow(dataTag: "15, 0, 1")
777 << (RangeList()
778 << Range(a, 0, 6, C::DefaultFlag)
779 << Range(b, 0, 6, C::AppendFlag | C::PrependFlag | C::DefaultFlag)
780 << Range(nullptr, 0, 4, C::DefaultFlag | C::CacheFlag)
781 << Range(c, 0, 2, C::PrependFlag | C::DefaultFlag)
782 << Range(c, 2, 2, C::PrependFlag | C::DefaultFlag | C::CacheFlag)
783 << Range(c, 4, 2, C::AppendFlag | C::PrependFlag | C::DefaultFlag))
784 << C::Default << 15 << C::Default << 0 << 1
785 << (RemoveList()
786 << Remove(sIndex: 0, vIndex: 0, dIndex: 15, cIndex: 3, count: 1, flags: C::DefaultFlag | C::CacheFlag, moveId: 0))
787 << (InsertList()
788 << Insert(sIndex: 0, vIndex: 0, dIndex: 0, cIndex: 0, count: 1, flags: C::DefaultFlag | C::CacheFlag, moveId: 0))
789 << IndexArray(cacheIndexes) << ListArray(cacheLists)
790 << IndexArray(defaultIndexes) << ListArray(defaultLists)
791 << IndexArray() << ListArray()
792 << IndexArray() << ListArray();
793 } { static const int cacheIndexes[] = {0,0,0,0,2,3};
794 static const void *cacheLists[] = {nullptr,nullptr,nullptr,nullptr,c,c};
795 static const int defaultIndexes[] = {0,1,0,1,2,3,4,5,0,1,2,3,4,5,2,3,0,1,2,3,4,5};
796 static const void *defaultLists[] = {nullptr,nullptr,a,a,a,a,a,a,b,b,b,b,b,b,nullptr,nullptr,c,c,c,c,c,c};
797 QTest::newRow(dataTag: "15, 1, 1")
798 << (RangeList()
799 << Range(nullptr, 0, 1, C::DefaultFlag | C::CacheFlag)
800 << Range(a, 0, 6, C::DefaultFlag)
801 << Range(b, 0, 6, C::AppendFlag | C::PrependFlag | C::DefaultFlag)
802 << Range(nullptr, 0, 3, C::DefaultFlag | C::CacheFlag)
803 << Range(c, 0, 2, C::PrependFlag | C::DefaultFlag)
804 << Range(c, 2, 2, C::PrependFlag | C::DefaultFlag | C::CacheFlag)
805 << Range(c, 4, 2, C::AppendFlag | C::PrependFlag | C::DefaultFlag))
806 << C::Default << 15 << C::Default << 1 << 1
807 << (RemoveList()
808 << Remove(sIndex: 0, vIndex: 0, dIndex: 15, cIndex: 3, count: 1, flags: C::DefaultFlag | C::CacheFlag, moveId: 0))
809 << (InsertList()
810 << Insert(sIndex: 0, vIndex: 0, dIndex: 1, cIndex: 1, count: 1, flags: C::DefaultFlag | C::CacheFlag, moveId: 0))
811 << IndexArray(cacheIndexes) << ListArray(cacheLists)
812 << IndexArray(defaultIndexes) << ListArray(defaultLists)
813 << IndexArray() << ListArray()
814 << IndexArray() << ListArray();
815 } { static const int cacheIndexes[] = {0,0,0,0,2,3};
816 static const void *cacheLists[] = {nullptr,nullptr,nullptr,nullptr,c,c};
817 static const int defaultIndexes[] = {0,1,2,0,1,3,4,5,0,1,2,3,4,5,2,3,0,1,2,3,4,5};
818 static const void *defaultLists[] = {a,a,a,nullptr,nullptr,a,a,a,b,b,b,b,b,b,nullptr,nullptr,c,c,c,c,c,c};
819 QTest::newRow(dataTag: "0, 3, 2")
820 << (RangeList()
821 << Range(nullptr, 0, 2, C::DefaultFlag | C::CacheFlag)
822 << Range(a, 0, 6, C::DefaultFlag)
823 << Range(b, 0, 6, C::AppendFlag | C::PrependFlag | C::DefaultFlag)
824 << Range(nullptr, 0, 2, C::DefaultFlag | C::CacheFlag)
825 << Range(c, 0, 2, C::PrependFlag | C::DefaultFlag)
826 << Range(c, 2, 2, C::PrependFlag | C::DefaultFlag | C::CacheFlag)
827 << Range(c, 4, 2, C::AppendFlag | C::PrependFlag | C::DefaultFlag))
828 << C::Default << 0 << C::Default << 3 << 2
829 << (RemoveList()
830 << Remove(sIndex: 0, vIndex: 0, dIndex: 0, cIndex: 0, count: 2, flags: C::DefaultFlag | C::CacheFlag, moveId: 0))
831 << (InsertList()
832 << Insert(sIndex: 0, vIndex: 0, dIndex: 3, cIndex: 0, count: 2, flags: C::DefaultFlag | C::CacheFlag, moveId: 0))
833 << IndexArray(cacheIndexes) << ListArray(cacheLists)
834 << IndexArray(defaultIndexes) << ListArray(defaultLists)
835 << IndexArray() << ListArray()
836 << IndexArray() << ListArray();
837 } { static const int cacheIndexes[] = {0,0,0,0,2,3};
838 static const void *cacheLists[] = {nullptr,nullptr,nullptr,nullptr,c,c};
839 static const int defaultIndexes[] = {0,5,0,1,2,3,4,5,0,1,0,1,2,2,3,3,4,1,2,3,4,5};
840 static const void *defaultLists[] = {a,a,b,b,b,b,b,b,nullptr,nullptr,c,a,a,nullptr,nullptr,a,a,c,c,c,c,c};
841 QTest::newRow(dataTag: "7, 1, 10")
842 << (RangeList()
843 << Range(a, 0, 3, C::DefaultFlag)
844 << Range(nullptr, 0, 2, C::DefaultFlag | C::CacheFlag)
845 << Range(a, 3, 3, C::DefaultFlag)
846 << Range(b, 0, 6, C::AppendFlag | C::PrependFlag | C::DefaultFlag)
847 << Range(nullptr, 0, 2, C::DefaultFlag | C::CacheFlag)
848 << Range(c, 0, 2, C::PrependFlag | C::DefaultFlag)
849 << Range(c, 2, 2, C::PrependFlag | C::DefaultFlag | C::CacheFlag)
850 << Range(c, 4, 2, C::AppendFlag | C::PrependFlag | C::DefaultFlag))
851 << C::Default << 7 << C::Default << 1 << 10
852 << (RemoveList()
853 << Remove(sIndex: 0, vIndex: 0, dIndex: 7, cIndex: 2, count: 1, flags: C::DefaultFlag, moveId: 0)
854 << Remove(sIndex: 0, vIndex: 0, dIndex: 7, cIndex: 2, count: 6, flags: C::DefaultFlag, moveId: 1)
855 << Remove(sIndex: 0, vIndex: 0, dIndex: 7, cIndex: 2, count: 2, flags: C::DefaultFlag | C::CacheFlag, moveId: 2)
856 << Remove(sIndex: 0, vIndex: 0, dIndex: 7, cIndex: 2, count: 1, flags: C::DefaultFlag, moveId: 3))
857 << (InsertList()
858 << Insert(sIndex: 0, vIndex: 0, dIndex: 1, cIndex: 0, count: 1, flags: C::DefaultFlag, moveId: 0)
859 << Insert(sIndex: 0, vIndex: 0, dIndex: 2, cIndex: 0, count: 6, flags: C::DefaultFlag, moveId: 1)
860 << Insert(sIndex: 0, vIndex: 0, dIndex: 8, cIndex: 0, count: 2, flags: C::DefaultFlag | C::CacheFlag, moveId: 2)
861 << Insert(sIndex: 0, vIndex: 0, dIndex: 10, cIndex: 2, count: 1, flags: C::DefaultFlag, moveId: 3))
862 << IndexArray(cacheIndexes) << ListArray(cacheLists)
863 << IndexArray(defaultIndexes) << ListArray(defaultLists)
864 << IndexArray() << ListArray()
865 << IndexArray() << ListArray();
866 } { static const int cacheIndexes[] = {0,0,0,0,3,2};
867 static const void *cacheLists[] = {nullptr,nullptr,nullptr,nullptr,c,c};
868 static const int defaultIndexes[] = {0,5,0,1,2,3,4,5,0,1,0,1,2,2,3,3,4,3,4,5,1,2};
869 static const void *defaultLists[] = {a,a,b,b,b,b,b,b,nullptr,nullptr,c,a,a,nullptr,nullptr,a,a,c,c,c,c,c};
870 QTest::newRow(dataTag: "17, 20, 2")
871 << (RangeList()
872 << Range(a, 0, 1, C::DefaultFlag)
873 << Range(a, 5, 1, C::DefaultFlag)
874 << Range(b, 0, 6, C::DefaultFlag)
875 << Range(nullptr, 0, 2, C::DefaultFlag | C::CacheFlag)
876 << Range(c, 0, 1, C::DefaultFlag)
877 << Range(a, 1, 2, C::DefaultFlag)
878 << Range(nullptr, 0, 2, C::DefaultFlag | C::CacheFlag)
879 << Range(a, 3, 2, C::DefaultFlag)
880 << Range(b, 0, 6, C::AppendFlag | C::PrependFlag)
881 << Range(c, 0, 1, C::PrependFlag)
882 << Range(c, 1, 1, C::PrependFlag | C::DefaultFlag)
883 << Range(c, 2, 2, C::PrependFlag | C::DefaultFlag | C::CacheFlag)
884 << Range(c, 4, 2, C::AppendFlag | C::PrependFlag | C::DefaultFlag))
885 << C::Default << 17 << C::Default << 20 << 2
886 << (RemoveList()
887 << Remove(sIndex: 0, vIndex: 0, dIndex: 17, cIndex: 4, count: 1, flags: C::DefaultFlag, moveId: 0)
888 << Remove(sIndex: 0, vIndex: 0, dIndex: 17, cIndex: 4, count: 1, flags: C::DefaultFlag | C::CacheFlag, moveId: 1))
889 << (InsertList()
890 << Insert(sIndex: 0, vIndex: 0, dIndex: 20, cIndex: 5, count: 1, flags: C::DefaultFlag, moveId: 0)
891 << Insert(sIndex: 0, vIndex: 0, dIndex: 21, cIndex: 5, count: 1, flags: C::DefaultFlag | C::CacheFlag, moveId: 1))
892 << IndexArray(cacheIndexes) << ListArray(cacheLists)
893 << IndexArray(defaultIndexes) << ListArray(defaultLists)
894 << IndexArray() << ListArray()
895 << IndexArray() << ListArray();
896 } { static const int cacheIndexes[] = {8,9,10,4,11,0,1,2,3,5,6,7};
897 static const void *cacheLists[] = {a,a, a,a, a,a,a,a,a,a,a,a};
898 static const int defaultIndexes[] = {8,9,10,4,11,0,1,2,3,5,6,7};
899 static const void *defaultLists[] = {a,a, a,a, a,a,a,a,a,a,a,a};
900 static const int visibleIndexes[] = {8,9,10,4,11,0,1,2,3,5,6,7};
901 static const void *visibleLists[] = {a,a, a,a, a,a,a,a,a,a,a,a};
902 QTest::newRow(dataTag: "3, 4, 5")
903 << (RangeList()
904 << Range(a, 8, 4, VisibleFlag | C::DefaultFlag | C::CacheFlag)
905 << Range(a, 0, 2, C::PrependFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag)
906 << Range(a, 2, 1, C::PrependFlag)
907 << Range(a, 2, 1, VisibleFlag | C::DefaultFlag | C::CacheFlag)
908 << Range(a, 3, 5, C::PrependFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag)
909 << Range(a, 8, 4, C::AppendFlag | C::PrependFlag))
910 << C::Default << 3 << C::Default << 4 << 5
911 << (RemoveList()
912 << Remove(sIndex: 0, vIndex: 3, dIndex: 3, cIndex: 3, count: 1, flags: VisibleFlag | C::DefaultFlag | C::CacheFlag, moveId: 0)
913 << Remove(sIndex: 0, vIndex: 3, dIndex: 3, cIndex: 3, count: 2, flags: VisibleFlag | C::DefaultFlag | C::CacheFlag, moveId: 1)
914 << Remove(sIndex: 0, vIndex: 3, dIndex: 3, cIndex: 3, count: 1, flags: VisibleFlag | C::DefaultFlag | C::CacheFlag, moveId: 2)
915 << Remove(sIndex: 0, vIndex: 3, dIndex: 3, cIndex: 3, count: 1, flags: VisibleFlag | C::DefaultFlag | C::CacheFlag, moveId: 3))
916 << (InsertList()
917 << Insert(sIndex: 0, vIndex: 4, dIndex: 4, cIndex: 4, count: 1, flags: VisibleFlag | C::DefaultFlag | C::CacheFlag, moveId: 0)
918 << Insert(sIndex: 0, vIndex: 5, dIndex: 5, cIndex: 5, count: 2, flags: VisibleFlag | C::DefaultFlag | C::CacheFlag, moveId: 1)
919 << Insert(sIndex: 0, vIndex: 7, dIndex: 7, cIndex: 7, count: 1, flags: VisibleFlag | C::DefaultFlag | C::CacheFlag, moveId: 2)
920 << Insert(sIndex: 0, vIndex: 8, dIndex: 8, cIndex: 8, count: 1, flags: VisibleFlag | C::DefaultFlag | C::CacheFlag, moveId: 3))
921 << IndexArray(cacheIndexes) << ListArray(cacheLists)
922 << IndexArray(defaultIndexes) << ListArray(defaultLists)
923 << IndexArray(visibleIndexes) << ListArray(visibleLists)
924 << IndexArray() << ListArray();
925 } { static const int cacheIndexes[] = {0,1};
926 static const void *cacheLists[] = {a,a};
927 static const int defaultIndexes[] = {0,1};
928 static const void *defaultLists[] = {a,a};
929 QTest::newRow(dataTag: "0, 1, 1")
930 << (RangeList()
931 << Range(a, 0, 1, C::PrependFlag)
932 << Range(a, 1, 1, C::PrependFlag | C::DefaultFlag | C::CacheFlag)
933 << Range(a, 2, 0, C::AppendFlag | C::PrependFlag)
934 << Range(a, 0, 1, C::DefaultFlag | C::CacheFlag))
935 << C::Default << 0 << C::Default << 1 << 1
936 << (RemoveList()
937 << Remove(sIndex: 0, vIndex: 0, dIndex: 0, cIndex: 0, count: 1, flags: C::DefaultFlag | C::CacheFlag, moveId: 0))
938 << (InsertList()
939 << Insert(sIndex: 0, vIndex: 0, dIndex: 1, cIndex: 1, count: 1, flags: C::DefaultFlag | C::CacheFlag, moveId: 0))
940 << IndexArray(cacheIndexes) << ListArray(cacheLists)
941 << IndexArray(defaultIndexes) << ListArray(defaultLists)
942 << IndexArray() << ListArray()
943 << IndexArray() << ListArray();
944 } { static const int cacheIndexes[] = {1,2,3,4,5,6,0,8,9};
945 static const void *cacheLists[] = {a,a,a,a,a,a,a,a,a};
946 static const int defaultIndexes[] = {1,2,3,4,5,6,0,8,9};
947 static const void *defaultLists[] = {a,a,a,a,a,a,a,a,a};
948 static const int visibleIndexes[] = {0,7,10};
949 static const void *visibleLists[] = {a,a, a};
950 QTest::newRow(dataTag: "0, 6, 3")
951 << (RangeList()
952 << Range(a, 0, 1, C::PrependFlag)
953 << Range(a, 1, 6, C::PrependFlag | C::DefaultFlag | C::CacheFlag)
954 << Range(a, 0, 1, VisibleFlag | C::DefaultFlag | C::CacheFlag)
955 << Range(a, 7, 1, VisibleFlag)
956 << Range(a,10, 1, VisibleFlag)
957 << Range(a, 7, 1, C::PrependFlag)
958 << Range(a, 8, 2, C::AppendFlag | C::PrependFlag | C::DefaultFlag | C::CacheFlag))
959 << Visible << 0 << C::Default << 6 << 3
960 << (RemoveList()
961 << Remove(sIndex: 0, vIndex: 0, dIndex: 6, cIndex: 6, count: 1, flags: VisibleFlag | C::DefaultFlag | C::CacheFlag, moveId: 0)
962 << Remove(sIndex: 0, vIndex: 0, dIndex: 6, cIndex: 6, count: 1, flags: VisibleFlag, moveId: 1)
963 << Remove(sIndex: 0, vIndex: 0, dIndex: 6, cIndex: 6, count: 1, flags: VisibleFlag, moveId: 2))
964 << (InsertList()
965 << Insert(sIndex: 0, vIndex: 0, dIndex: 6, cIndex: 6, count: 1, flags: VisibleFlag | C::DefaultFlag | C::CacheFlag, moveId: 0)
966 << Insert(sIndex: 0, vIndex: 1, dIndex: 7, cIndex: 7, count: 1, flags: VisibleFlag, moveId: 1)
967 << Insert(sIndex: 0, vIndex: 2, dIndex: 7, cIndex: 7, count: 1, flags: VisibleFlag, moveId: 2))
968 << IndexArray(cacheIndexes) << ListArray(cacheLists)
969 << IndexArray(defaultIndexes) << ListArray(defaultLists)
970 << IndexArray(visibleIndexes) << ListArray(visibleLists)
971 << IndexArray() << ListArray();
972 }
973}
974
975void tst_qqmllistcompositor::move()
976{
977 QFETCH(RangeList, ranges);
978 QFETCH(C::Group, fromGroup);
979 QFETCH(int, from);
980 QFETCH(C::Group, toGroup);
981 QFETCH(int, to);
982 QFETCH(int, count);
983 QFETCH(RemoveList, expectedRemoves);
984 QFETCH(InsertList, expectedInserts);
985 QFETCH(IndexArray, cacheIndexes);
986 QFETCH(ListArray, cacheLists);
987 QFETCH(IndexArray, defaultIndexes);
988 QFETCH(ListArray, defaultLists);
989 QFETCH(IndexArray, visibleIndexes);
990 QFETCH(ListArray, visibleLists);
991 QFETCH(IndexArray, selectionIndexes);
992 QFETCH(ListArray, selectionLists);
993
994 QQmlListCompositor compositor;
995 compositor.setGroupCount(4);
996 compositor.setDefaultGroups(VisibleFlag | C::DefaultFlag);
997
998 foreach (const Range &range, ranges)
999 compositor.append(list: range.list, index: range.index, count: range.count, flags: range.flags);
1000
1001 QVector<C::Remove> removes;
1002 QVector<C::Insert> inserts;
1003 compositor.move(fromGroup, from, toGroup, to, count, group: fromGroup, removals: &removes, inserts: &inserts);
1004
1005 QCOMPARE(removes, expectedRemoves);
1006 QCOMPARE(inserts, expectedInserts);
1007
1008 QCOMPARE(compositor.count(C::Cache), cacheIndexes.count);
1009 for (int i = 0; i < cacheIndexes.count; ++i) {
1010 C::iterator it = compositor.find(group: C::Cache, index: i);
1011 QCOMPARE(it->list, cacheLists[i]);
1012 if (cacheLists[i])
1013 QCOMPARE(it.modelIndex(), cacheIndexes[i]);
1014 }
1015 QCOMPARE(compositor.count(C::Default), defaultIndexes.count);
1016 for (int i = 0; i < defaultIndexes.count; ++i) {
1017 C::iterator it = compositor.find(group: C::Default, index: i);
1018 QCOMPARE(it->list, defaultLists[i]);
1019 if (defaultLists[i])
1020 QCOMPARE(it.modelIndex(), defaultIndexes[i]);
1021 }
1022 QCOMPARE(compositor.count(Visible), visibleIndexes.count);
1023 for (int i = 0; i < visibleIndexes.count; ++i) {
1024 C::iterator it = compositor.find(group: Visible, index: i);
1025 QCOMPARE(it->list, visibleLists[i]);
1026 if (visibleLists[i])
1027 QCOMPARE(it.modelIndex(), visibleIndexes[i]);
1028 }
1029 QCOMPARE(compositor.count(Selection), selectionIndexes.count);
1030 for (int i = 0; i < selectionIndexes.count; ++i) {
1031 C::iterator it = compositor.find(group: Selection, index: i);
1032 QCOMPARE(it->list, selectionLists[i]);
1033 if (selectionLists[i])
1034 QCOMPARE(it.modelIndex(), selectionIndexes[i]);
1035 }
1036}
1037
1038void tst_qqmllistcompositor::moveFromEnd()
1039{
1040 int listA; void *a = &listA;
1041
1042 QQmlListCompositor compositor;
1043 compositor.append(list: a, index: 0, count: 1, flags: C::AppendFlag | C::PrependFlag | C::DefaultFlag);
1044
1045 // Moving an item anchors it to that position.
1046 compositor.move(fromGroup: C::Default, from: 0, toGroup: C::Default, to: 0, count: 1, group: C::Default);
1047
1048 // The existing item is anchored at 0 so prepending an item to the source will append it here
1049 QVector<C::Insert> inserts;
1050 compositor.listItemsInserted(list: a, index: 0, count: 1, inserts: &inserts);
1051
1052 QCOMPARE(inserts.count(), 1);
1053 QCOMPARE(inserts.at(0).index[1], 1);
1054 QCOMPARE(inserts.at(0).count, 1);
1055
1056 C::iterator it;
1057 it = compositor.find(group: C::Default, index: 0);
1058 QCOMPARE(it.modelIndex(), 1);
1059
1060 it = compositor.find(group: C::Default, index: 1);
1061 QCOMPARE(it.modelIndex(), 0);
1062}
1063
1064void tst_qqmllistcompositor::clear()
1065{
1066 QQmlListCompositor compositor;
1067 compositor.setGroupCount(4);
1068 compositor.setDefaultGroups(VisibleFlag | C::DefaultFlag);
1069
1070 int listA; void *a = &listA;
1071 int listB; void *b = &listB;
1072
1073 compositor.append(list: a, index: 0, count: 8, flags: C::AppendFlag | C::PrependFlag | VisibleFlag | C::DefaultFlag);
1074 compositor.append(list: b, index: 4, count: 5, flags: VisibleFlag | C::DefaultFlag);
1075 compositor.append(list: nullptr, index: 0, count: 3, flags: VisibleFlag | C::DefaultFlag | C::CacheFlag);
1076
1077 QCOMPARE(compositor.count(C::Default), 16);
1078 QCOMPARE(compositor.count(Visible), 16);
1079 QCOMPARE(compositor.count(C::Cache), 3);
1080
1081 compositor.clear();
1082 QCOMPARE(compositor.count(C::Default), 0);
1083 QCOMPARE(compositor.count(Visible), 0);
1084 QCOMPARE(compositor.count(C::Cache), 0);
1085}
1086
1087void tst_qqmllistcompositor::listItemsInserted_data()
1088{
1089 QTest::addColumn<RangeList>(name: "ranges");
1090 QTest::addColumn<void *>(name: "list");
1091 QTest::addColumn<int>(name: "index");
1092 QTest::addColumn<int>(name: "count");
1093 QTest::addColumn<InsertList>(name: "expectedInserts");
1094 QTest::addColumn<IndexArray>(name: "cacheIndexes");
1095 QTest::addColumn<IndexArray>(name: "defaultIndexes");
1096 QTest::addColumn<IndexArray>(name: "visibleIndexes");
1097 QTest::addColumn<IndexArray>(name: "selectionIndexes");
1098
1099 int listA; void *a = &listA;
1100 int listB; void *b = &listB;
1101
1102 { static const int defaultIndexes[] = {/*A*/0,1,5,6,/*B*/0,1,2,3,/*A*/2,3,4};
1103 QTest::newRow(dataTag: "A 10, 2")
1104 << (RangeList()
1105 << Range(a, 0, 2, C::PrependFlag | C::DefaultFlag)
1106 << Range(a, 2, 3, C::PrependFlag)
1107 << Range(a, 5, 2, C::AppendFlag | C::PrependFlag | C::DefaultFlag)
1108 << Range(b, 0, 4, C::DefaultFlag)
1109 << Range(a, 2, 3, C::DefaultFlag))
1110 << a << 10 << 2
1111 << InsertList()
1112 << IndexArray()
1113 << IndexArray(defaultIndexes)
1114 << IndexArray()
1115 << IndexArray();
1116 } { static const int defaultIndexes[] = {/*A*/0,1,5,6,/*B*/0,1,2,3,/*A*/2,3,4};
1117 QTest::newRow(dataTag: "B 10, 2")
1118 << (RangeList()
1119 << Range(a, 0, 2, C::PrependFlag | C::DefaultFlag)
1120 << Range(a, 2, 3, C::PrependFlag)
1121 << Range(a, 5, 2, C::AppendFlag | C::PrependFlag | C::DefaultFlag)
1122 << Range(b, 0, 4, C::DefaultFlag)
1123 << Range(a, 2, 3, C::DefaultFlag))
1124 << b << 10 << 2
1125 << InsertList()
1126 << IndexArray()
1127 << IndexArray(defaultIndexes)
1128 << IndexArray()
1129 << IndexArray();
1130 } { static const int defaultIndexes[] = {/*A*/0,1,2,3,7,8,/*B*/0,1,2,3,/*A*/4,5,6};
1131 static const int visibleIndexes[] = {/*A*/0,1};
1132 QTest::newRow(dataTag: "A 0, 2")
1133 << (RangeList()
1134 << Range(a, 0, 2, C::PrependFlag | C::DefaultFlag)
1135 << Range(a, 2, 3, C::PrependFlag)
1136 << Range(a, 5, 2, C::AppendFlag | C::PrependFlag | C::DefaultFlag)
1137 << Range(b, 0, 4, C::DefaultFlag)
1138 << Range(a, 2, 3, C::DefaultFlag))
1139 << a << 0 << 2
1140 << (InsertList()
1141 << Insert(sIndex: 0, vIndex: 0, dIndex: 0, cIndex: 0, count: 2, flags: VisibleFlag | C::DefaultFlag))
1142 << IndexArray()
1143 << IndexArray(defaultIndexes)
1144 << IndexArray(visibleIndexes)
1145 << IndexArray();
1146 } { static const int defaultIndexes[] = {/*A*/0,1,2,3,5,8,9,/*B*/0,1,2,3,/*A*/4,6,7};
1147 static const int visibleIndexes[] = {/*A*/0,1,5};
1148 QTest::newRow(dataTag: "A 5, 1")
1149 << (RangeList()
1150 << Range(a, 0, 2, C::PrependFlag | VisibleFlag | C::DefaultFlag)
1151 << Range(a, 2, 2, C::PrependFlag | C::DefaultFlag)
1152 << Range(a, 4, 3, C::PrependFlag)
1153 << Range(a, 7, 2, C::AppendFlag | C::PrependFlag | C::DefaultFlag)
1154 << Range(b, 0, 4, C::DefaultFlag)
1155 << Range(a, 4, 3, C::DefaultFlag))
1156 << a << 5 << 1
1157 << (InsertList()
1158 << Insert(sIndex: 0, vIndex: 2, dIndex: 4, cIndex: 0, count: 1, flags: VisibleFlag | C::DefaultFlag))
1159 << IndexArray()
1160 << IndexArray(defaultIndexes)
1161 << IndexArray(visibleIndexes)
1162 << IndexArray();
1163 } { static const int defaultIndexes[] = {/*A*/0,1,2,3,5,8,9,10,11,/*B*/0,1,2,3,/*A*/4,6,7};
1164 static const int visibleIndexes[] = {/*A*/0,1,5,10,11};
1165 QTest::newRow(dataTag: "A 10, 2")
1166 << (RangeList()
1167 << Range(a, 0, 2, C::PrependFlag | VisibleFlag | C::DefaultFlag)
1168 << Range(a, 2, 2, C::PrependFlag | C::DefaultFlag)
1169 << Range(a, 4, 1, C::PrependFlag)
1170 << Range(a, 5, 1, C::PrependFlag | VisibleFlag | C::DefaultFlag)
1171 << Range(a, 6, 2, C::PrependFlag)
1172 << Range(a, 8, 2, C::AppendFlag | C::PrependFlag | C::DefaultFlag)
1173 << Range(b, 0, 4, C::DefaultFlag)
1174 << Range(a, 4, 1, C::DefaultFlag)
1175 << Range(a, 6, 2, C::DefaultFlag))
1176 << a << 10 << 2
1177 << (InsertList()
1178 << Insert(sIndex: 0, vIndex: 3, dIndex: 7, cIndex: 0, count: 2, flags: VisibleFlag | C::DefaultFlag))
1179 << IndexArray()
1180 << IndexArray(defaultIndexes)
1181 << IndexArray(visibleIndexes)
1182 << IndexArray();
1183 } { static const int cacheIndexes[] = {/*A*/0,1,-1,-1,-1,2,5,6,7,8,9};
1184 static const int defaultIndexes[] = {/*A*/0,1,2,3,4,5,6,7,8,9};
1185 static const int visibleIndexes[] = {/*A*/3,4};
1186 QTest::newRow(dataTag: "Insert after remove")
1187 << (RangeList()
1188 << Range(a, 0, 2, C::PrependFlag | C::DefaultFlag | C::CacheFlag)
1189 << Range(a, 2, 3, C::CacheFlag)
1190 << Range(a, 2, 6, C::AppendFlag | C::PrependFlag | C::DefaultFlag | C::CacheFlag))
1191 << a << 3 << 2
1192 << (InsertList()
1193 << Insert(sIndex: 0, vIndex: 0, dIndex: 3, cIndex: 6, count: 2, flags: VisibleFlag | C::DefaultFlag))
1194 << IndexArray(cacheIndexes)
1195 << IndexArray(defaultIndexes)
1196 << IndexArray(visibleIndexes)
1197 << IndexArray();
1198 } { static const int cacheIndexes[] = {/*A*/0,1,2,3,4};
1199 static const int defaultIndexes[] = {/*A*/0,1,2,3,4,5,6};
1200 static const int visibleIndexes[] = {/*A*/0,1,2,3,4,5,6};
1201 QTest::newRow(dataTag: "Consecutive appends")
1202 << (RangeList()
1203 << Range(a, 0, 5, C::PrependFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag)
1204 << Range(a, 5, 1, C::PrependFlag | VisibleFlag | C::DefaultFlag)
1205 << Range(a, 6, 0, C::AppendFlag | VisibleFlag | C::PrependFlag | C::DefaultFlag | C::CacheFlag))
1206 << a << 6 << 1
1207 << (InsertList()
1208 << Insert(sIndex: 0, vIndex: 6, dIndex: 6, cIndex: 5, count: 1, flags: VisibleFlag | C::DefaultFlag))
1209 << IndexArray(cacheIndexes)
1210 << IndexArray(defaultIndexes)
1211 << IndexArray(visibleIndexes)
1212 << IndexArray();
1213 }
1214}
1215
1216void tst_qqmllistcompositor::listItemsInserted()
1217{
1218 QFETCH(RangeList, ranges);
1219 QFETCH(void *, list);
1220 QFETCH(int, index);
1221 QFETCH(int, count);
1222 QFETCH(InsertList, expectedInserts);
1223 QFETCH(IndexArray, cacheIndexes);
1224 QFETCH(IndexArray, defaultIndexes);
1225 QFETCH(IndexArray, visibleIndexes);
1226 QFETCH(IndexArray, selectionIndexes);
1227
1228 QQmlListCompositor compositor;
1229 compositor.setGroupCount(4);
1230 compositor.setDefaultGroups(VisibleFlag | C::DefaultFlag);
1231
1232 foreach (const Range &range, ranges)
1233 compositor.append(list: range.list, index: range.index, count: range.count, flags: range.flags);
1234
1235 QVector<C::Insert> inserts;
1236 compositor.listItemsInserted(list, index, count, inserts: &inserts);
1237
1238 QCOMPARE(inserts, expectedInserts);
1239
1240 QCOMPARE(compositor.count(C::Cache), cacheIndexes.count);
1241 for (int i = 0; i < cacheIndexes.count; ++i) {
1242 if (cacheIndexes[i] != -1) {
1243 QCOMPARE(compositor.find(C::Cache, i).modelIndex(), cacheIndexes[i]);
1244 }
1245 }
1246 QCOMPARE(compositor.count(C::Default), defaultIndexes.count);
1247 for (int i = 0; i < defaultIndexes.count; ++i) {
1248 if (defaultIndexes[i] != -1) {
1249 QCOMPARE(compositor.find(C::Default, i).modelIndex(), defaultIndexes[i]);
1250 }
1251 }
1252 QCOMPARE(compositor.count(Visible), visibleIndexes.count);
1253 for (int i = 0; i < visibleIndexes.count; ++i) {
1254 if (visibleIndexes[i] != -1) {
1255 QCOMPARE(compositor.find(Visible, i).modelIndex(), visibleIndexes[i]);
1256 }
1257 }
1258 QCOMPARE(compositor.count(Selection), selectionIndexes.count);
1259 for (int i = 0; i < selectionIndexes.count; ++i) {
1260 if (selectionIndexes[i] != -1) {
1261 QCOMPARE(compositor.find(Selection, i).modelIndex(), selectionIndexes[i]);
1262 }
1263 }
1264}
1265
1266void tst_qqmllistcompositor::listItemsRemoved_data()
1267{
1268 QTest::addColumn<RangeList>(name: "ranges");
1269 QTest::addColumn<void *>(name: "list");
1270 QTest::addColumn<int>(name: "index");
1271 QTest::addColumn<int>(name: "count");
1272 QTest::addColumn<RemoveList>(name: "expectedRemoves");
1273 QTest::addColumn<IndexArray>(name: "cacheIndexes");
1274 QTest::addColumn<IndexArray>(name: "defaultIndexes");
1275 QTest::addColumn<IndexArray>(name: "visibleIndexes");
1276 QTest::addColumn<IndexArray>(name: "selectionIndexes");
1277
1278 int listA; void *a = &listA;
1279 int listB; void *b = &listB;
1280
1281 { static const int defaultIndexes[] = {/*A*/0,1,5,6,/*B*/0,1,2,3,/*A*/2,3,4};
1282 QTest::newRow(dataTag: "12, 2")
1283 << (RangeList()
1284 << Range(a, 0, 2, C::PrependFlag | C::DefaultFlag)
1285 << Range(a, 2, 3, C::PrependFlag)
1286 << Range(a, 5, 2, C::AppendFlag | C::PrependFlag | C::DefaultFlag)
1287 << Range(b, 0, 4, C::DefaultFlag)
1288 << Range(a, 2, 3, C::DefaultFlag))
1289 << a << 12 << 2
1290 << RemoveList()
1291 << IndexArray()
1292 << IndexArray(defaultIndexes)
1293 << IndexArray()
1294 << IndexArray();
1295 } { static const int defaultIndexes[] = {/*A*/0,1,/*B*/0,1,2,3,/*A*/2,3};
1296 QTest::newRow(dataTag: "4, 3")
1297 << (RangeList()
1298 << Range(a, 0, 2, C::PrependFlag | C::DefaultFlag)
1299 << Range(a, 2, 3, C::PrependFlag)
1300 << Range(a, 5, 2, C::AppendFlag | C::PrependFlag | C::DefaultFlag)
1301 << Range(b, 0, 4, C::DefaultFlag)
1302 << Range(a, 2, 3, C::DefaultFlag))
1303 << a << 4 << 3
1304 << (RemoveList()
1305 << Remove(sIndex: 0, vIndex: 0, dIndex: 2, cIndex: 0, count: 2, flags: C::DefaultFlag)
1306 << Remove(sIndex: 0, vIndex: 0, dIndex: 8, cIndex: 0, count: 1, flags: C::DefaultFlag))
1307 << IndexArray()
1308 << IndexArray(defaultIndexes)
1309 << IndexArray()
1310 << IndexArray();
1311 } { static const int cacheIndexes[] = {/*A*/0,1,-1,-1,-1,2,-1,-1,3,4,5};
1312 static const int defaultIndexes[] = {/*A*/0,1,2,3,4,5};
1313 QTest::newRow(dataTag: "Remove after remove")
1314 << (RangeList()
1315 << Range(a, 0, 2, C::PrependFlag | C::DefaultFlag | C::CacheFlag)
1316 << Range(a, 2, 3, C::CacheFlag)
1317 << Range(a, 2, 6, C::AppendFlag | C::PrependFlag | C::DefaultFlag | C::CacheFlag))
1318 << a << 3 << 2
1319 << (RemoveList()
1320 << Remove(sIndex: 0, vIndex: 0, dIndex: 3, cIndex: 6, count: 2, flags: C::DefaultFlag | C::CacheFlag))
1321 << IndexArray(cacheIndexes)
1322 << IndexArray(defaultIndexes)
1323 << IndexArray()
1324 << IndexArray();
1325 } { static const int cacheIndexes[] = {/*A*/-1,-1,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1};
1326 static const int defaultIndexes[] = {/*A*/0,1,2,3,4,5,6};
1327 QTest::newRow(dataTag: "Sparse remove")
1328 << (RangeList()
1329 << Range(a, 0, 2, C::CacheFlag)
1330 << Range(a, 0, 1, C::DefaultFlag | C::CacheFlag)
1331 << Range(a, 0, 1, C::CacheFlag)
1332 << Range(a, 1, 5, C::DefaultFlag | C::CacheFlag)
1333 << Range(a, 0, 1, C::CacheFlag)
1334 << Range(a, 6, 2, C::DefaultFlag | C::CacheFlag)
1335 << Range(a, 0, 1, C::CacheFlag)
1336 << Range(a, 8, 3, C::DefaultFlag | C::CacheFlag)
1337 << Range(a, 0, 1, C::CacheFlag)
1338 << Range(a, 11, 1, C::DefaultFlag | C::CacheFlag)
1339 << Range(a, 12, 5, C::DefaultFlag))
1340 << a << 1 << 10
1341 << (RemoveList()
1342 << Remove(sIndex: 0, vIndex: 0, dIndex: 1, cIndex: 4, count: 5, flags: C::DefaultFlag | C::CacheFlag)
1343 << Remove(sIndex: 0, vIndex: 0, dIndex: 1,cIndex: 10, count: 2, flags: C::DefaultFlag | C::CacheFlag)
1344 << Remove(sIndex: 0, vIndex: 0, dIndex: 1,cIndex: 13, count: 3, flags: C::DefaultFlag | C::CacheFlag))
1345 << IndexArray(cacheIndexes)
1346 << IndexArray(defaultIndexes)
1347 << IndexArray()
1348 << IndexArray();
1349 }
1350}
1351
1352void tst_qqmllistcompositor::listItemsRemoved()
1353{
1354 QFETCH(RangeList, ranges);
1355 QFETCH(void *, list);
1356 QFETCH(int, index);
1357 QFETCH(int, count);
1358 QFETCH(RemoveList, expectedRemoves);
1359 QFETCH(IndexArray, cacheIndexes);
1360 QFETCH(IndexArray, defaultIndexes);
1361 QFETCH(IndexArray, visibleIndexes);
1362 QFETCH(IndexArray, selectionIndexes);
1363
1364 QQmlListCompositor compositor;
1365 compositor.setGroupCount(4);
1366 compositor.setDefaultGroups(VisibleFlag | C::DefaultFlag);
1367
1368 foreach (const Range &range, ranges)
1369 compositor.append(list: range.list, index: range.index, count: range.count, flags: range.flags);
1370
1371 QVector<C::Remove> removes;
1372 compositor.listItemsRemoved(list, index, count, removals: &removes);
1373
1374 QCOMPARE(removes, expectedRemoves);
1375
1376 QCOMPARE(compositor.count(C::Cache), cacheIndexes.count);
1377 for (int i = 0; i < cacheIndexes.count; ++i) {
1378 if (cacheIndexes[i] != -1) {
1379 QCOMPARE(compositor.find(C::Cache, i).modelIndex(), cacheIndexes[i]);
1380 }
1381 }
1382 QCOMPARE(compositor.count(C::Default), defaultIndexes.count);
1383 for (int i = 0; i < defaultIndexes.count; ++i) {
1384 if (defaultIndexes[i] != -1) {
1385 QCOMPARE(compositor.find(C::Default, i).modelIndex(), defaultIndexes[i]);
1386 }
1387 }
1388 QCOMPARE(compositor.count(Visible), visibleIndexes.count);
1389 for (int i = 0; i < visibleIndexes.count; ++i) {
1390 if (visibleIndexes[i] != -1) {
1391 QCOMPARE(compositor.find(Visible, i).modelIndex(), visibleIndexes[i]);
1392 }
1393 }
1394 QCOMPARE(compositor.count(Selection), selectionIndexes.count);
1395 for (int i = 0; i < selectionIndexes.count; ++i) {
1396 if (selectionIndexes[i] != -1) {
1397 QCOMPARE(compositor.find(Selection, i).modelIndex(), selectionIndexes[i]);
1398 }
1399 }
1400}
1401
1402void tst_qqmllistcompositor::listItemsMoved_data()
1403{
1404 QTest::addColumn<RangeList>(name: "ranges");
1405 QTest::addColumn<void *>(name: "list");
1406 QTest::addColumn<int>(name: "from");
1407 QTest::addColumn<int>(name: "to");
1408 QTest::addColumn<int>(name: "count");
1409 QTest::addColumn<RemoveList>(name: "expectedRemoves");
1410 QTest::addColumn<InsertList>(name: "expectedInserts");
1411 QTest::addColumn<IndexArray>(name: "cacheIndexes");
1412 QTest::addColumn<IndexArray>(name: "defaultIndexes");
1413 QTest::addColumn<IndexArray>(name: "visibleIndexes");
1414 QTest::addColumn<IndexArray>(name: "selectionIndexes");
1415
1416 int listA; void *a = &listA;
1417 int listB; void *b = &listB;
1418
1419 { static const int defaultIndexes[] = {/*A*/0,2,3,4,/*B*/0,1,2,3,/*A*/5,6,1};
1420 QTest::newRow(dataTag: "4, 1, 3")
1421 << (RangeList()
1422 << Range(a, 0, 2, C::PrependFlag | C::DefaultFlag)
1423 << Range(a, 2, 3, C::PrependFlag)
1424 << Range(a, 5, 2, C::AppendFlag | C::PrependFlag | C::DefaultFlag)
1425 << Range(b, 0, 4, C::DefaultFlag)
1426 << Range(a, 2, 3, C::DefaultFlag))
1427 << a << 4 << 1 << 3
1428 << (RemoveList()
1429 << Remove(sIndex: 0, vIndex: 0, dIndex: 2, cIndex: 0, count: 2, flags: C::DefaultFlag, moveId: 0))
1430 << (InsertList()
1431 << Insert(sIndex: 0, vIndex: 0, dIndex: 1, cIndex: 0, count: 2, flags: C::DefaultFlag, moveId: 0))
1432 << IndexArray()
1433 << IndexArray(defaultIndexes)
1434 << IndexArray()
1435 << IndexArray();
1436 } { static const int defaultIndexes[] = {/*A*/1,2,3,6,/*B*/0,1,2,3,/*A*/4,5,0};
1437 QTest::newRow(dataTag: "0, 6, 1")
1438 << (RangeList()
1439 << Range(a, 0, 1, C::PrependFlag | C::DefaultFlag)
1440 << Range(a, 1, 1, C::PrependFlag)
1441 << Range(a, 2, 3, C::PrependFlag | C::DefaultFlag)
1442 << Range(a, 5, 2, C::PrependFlag)
1443 << Range(a, 7, 0, C::AppendFlag | C::PrependFlag | C::DefaultFlag)
1444 << Range(b, 0, 4, C::DefaultFlag)
1445 << Range(a, 5, 2, C::DefaultFlag)
1446 << Range(a, 1, 1, C::DefaultFlag))
1447 << a << 0 << 6 << 1
1448 << (RemoveList()
1449 << Remove(sIndex: 0, vIndex: 0, dIndex: 0, cIndex: 0, count: 1, flags: C::DefaultFlag, moveId: 0))
1450 << (InsertList()
1451 << Insert(sIndex: 0, vIndex: 0, dIndex: 3, cIndex: 0, count: 1, flags: C::DefaultFlag, moveId: 0))
1452 << IndexArray()
1453 << IndexArray(defaultIndexes)
1454 << IndexArray()
1455 << IndexArray();
1456 } { static const int cacheIndexes[] = {/*A*/0,1,3,4};
1457 static const int defaultIndexes[] = {/*A*/0,1,2,3,4,5,6,7};
1458 QTest::newRow(dataTag: "6, 2, 1")
1459 << (RangeList()
1460 << Range(a, 0, 4, C::PrependFlag | C::DefaultFlag | C::CacheFlag)
1461 << Range(a, 4, 4, C::AppendFlag | C::PrependFlag | C::DefaultFlag))
1462 << a << 6 << 2 << 1
1463 << (RemoveList()
1464 << Remove(sIndex: 0, vIndex: 0, dIndex: 6, cIndex: 4, count: 1, flags: C::DefaultFlag, moveId: 0))
1465 << (InsertList()
1466 << Insert(sIndex: 0, vIndex: 0, dIndex: 2, cIndex: 2, count: 1, flags: C::DefaultFlag, moveId: 0))
1467 << IndexArray(cacheIndexes)
1468 << IndexArray(defaultIndexes)
1469 << IndexArray()
1470 << IndexArray();
1471 } { static const int cacheIndexes[] = {/*A*/0,1,-1,-1,-1,2,3,4,5,6,7};
1472 static const int defaultIndexes[] = {/*A*/0,1,2,3,4,5,6,7};
1473 QTest::newRow(dataTag: "Move after remove")
1474 << (RangeList()
1475 << Range(a, 0, 2, C::PrependFlag | C::DefaultFlag | C::CacheFlag)
1476 << Range(a, 2, 3, C::CacheFlag)
1477 << Range(a, 2, 6, C::AppendFlag | C::PrependFlag | C::DefaultFlag | C::CacheFlag))
1478 << a << 4 << 2 << 2
1479 << (RemoveList()
1480 << Remove(sIndex: 0, vIndex: 0, dIndex: 4, cIndex: 7, count: 2, flags: C::DefaultFlag | C::CacheFlag, moveId: 0))
1481 << (InsertList()
1482 << Insert(sIndex: 0, vIndex: 0, dIndex: 2, cIndex: 5, count: 2, flags: C::DefaultFlag | C::CacheFlag, moveId: 0))
1483 << IndexArray(cacheIndexes)
1484 << IndexArray(defaultIndexes)
1485 << IndexArray()
1486 << IndexArray();
1487 } { static const int cacheIndexes[] = {/*A*/0,1,5,6,7,8,9,10,11,12};
1488 static const int defaultIndexes[] = {/*A*/0,1,2,3,4,5,6,7,8,9,10,11,12};
1489 QTest::newRow(dataTag: "Move merge tail")
1490 << (RangeList()
1491 << Range(a, 0, 10, C::PrependFlag | C::DefaultFlag | C::CacheFlag)
1492 << Range(a, 10, 3, C::PrependFlag | C::DefaultFlag)
1493 << Range(a, 13, 0, C::AppendFlag | C::PrependFlag | C::DefaultFlag | C::CacheFlag))
1494 << a << 8 << 0 << 5
1495 << (RemoveList()
1496 << Remove(sIndex: 0, vIndex: 0, dIndex: 8, cIndex: 8, count: 2, flags: C::DefaultFlag | C::CacheFlag, moveId: 0)
1497 << Remove(sIndex: 0, vIndex: 0, dIndex: 8, cIndex: 8, count: 3, flags: C::DefaultFlag, moveId: 1))
1498 << (InsertList()
1499 << Insert(sIndex: 0, vIndex: 0, dIndex: 0, cIndex: 0, count: 2, flags: C::DefaultFlag | C::CacheFlag, moveId: 0)
1500 << Insert(sIndex: 0, vIndex: 0, dIndex: 2, cIndex: 2, count: 3, flags: C::DefaultFlag, moveId: 1))
1501 << IndexArray(cacheIndexes)
1502 << IndexArray(defaultIndexes)
1503 << IndexArray()
1504 << IndexArray();
1505 } { static const int cacheIndexes[] = {/*A*/0,1,2,3};
1506 static const int defaultIndexes[] = {/*A*/0,1,2,3};
1507 static const int selectionIndexes[] = {/*A*/3};
1508 QTest::newRow(dataTag: "Move selection")
1509 << (RangeList()
1510 << Range(a, 0, 2, C::PrependFlag | C::DefaultFlag | C::CacheFlag)
1511 << Range(a, 2, 1, C::PrependFlag | SelectionFlag | C::DefaultFlag | C::CacheFlag)
1512 << Range(a, 3, 1, C::AppendFlag | C::PrependFlag | C::DefaultFlag | C::CacheFlag))
1513 << a << 2 << 3 << 1
1514 << (RemoveList()
1515 << Remove(sIndex: 0, vIndex: 0, dIndex: 2, cIndex: 2, count: 1, flags: C::PrependFlag | SelectionFlag | C::DefaultFlag | C::CacheFlag, moveId: 0))
1516 << (InsertList()
1517 << Insert(sIndex: 0, vIndex: 0, dIndex: 3, cIndex: 3, count: 1, flags: C::PrependFlag | SelectionFlag | C::DefaultFlag | C::CacheFlag, moveId: 0))
1518 << IndexArray(cacheIndexes)
1519 << IndexArray(defaultIndexes)
1520 << IndexArray()
1521 << IndexArray(selectionIndexes);
1522 } { static const int cacheIndexes[] = {/*A*/0,1,2,3,4,5,8,9};
1523 static const int defaultIndexes[] = {/*A*/0,1,2,3,4,5,6,7,8,9,10,11};
1524 QTest::newRow(dataTag: "move mixed cached items")
1525 << (RangeList()
1526 << Range(a, 0, 1, C::PrependFlag | C::DefaultFlag | C::CacheFlag)
1527 << Range(a, 1, 2, C::PrependFlag | C::DefaultFlag)
1528 << Range(a, 3, 7, C::PrependFlag | C::DefaultFlag | C::CacheFlag)
1529 << Range(a, 10, 2, C::PrependFlag | C::DefaultFlag))
1530 << a << 1 << 6 << 3
1531 << (RemoveList()
1532 << Remove(sIndex: 0, vIndex: 0, dIndex: 1, cIndex: 1, count: 2, flags: C::PrependFlag | C::DefaultFlag, moveId: 0)
1533 << Remove(sIndex: 0, vIndex: 0, dIndex: 1, cIndex: 1, count: 1, flags: C::PrependFlag | C::DefaultFlag | C::CacheFlag, moveId: 1))
1534 << (InsertList()
1535 << Insert(sIndex: 0, vIndex: 0, dIndex: 6, cIndex: 6, count: 2, flags: C::PrependFlag | C::DefaultFlag, moveId: 0)
1536 << Insert(sIndex: 0, vIndex: 0, dIndex: 8, cIndex: 6, count: 1, flags: C::PrependFlag | C::DefaultFlag | C::CacheFlag, moveId: 1))
1537 << IndexArray(cacheIndexes)
1538 << IndexArray(defaultIndexes)
1539 << IndexArray()
1540 << IndexArray();
1541 }
1542}
1543
1544void tst_qqmllistcompositor::listItemsMoved()
1545{
1546 QFETCH(RangeList, ranges);
1547 QFETCH(void *, list);
1548 QFETCH(int, from);
1549 QFETCH(int, to);
1550 QFETCH(int, count);
1551 QFETCH(RemoveList, expectedRemoves);
1552 QFETCH(InsertList, expectedInserts);
1553 QFETCH(IndexArray, cacheIndexes);
1554 QFETCH(IndexArray, defaultIndexes);
1555 QFETCH(IndexArray, visibleIndexes);
1556 QFETCH(IndexArray, selectionIndexes);
1557
1558 QQmlListCompositor compositor;
1559 compositor.setGroupCount(4);
1560 compositor.setDefaultGroups(VisibleFlag | C::DefaultFlag);
1561
1562 foreach (const Range &range, ranges)
1563 compositor.append(list: range.list, index: range.index, count: range.count, flags: range.flags);
1564
1565 QVector<C::Remove> removes;
1566 QVector<C::Insert> inserts;
1567 compositor.listItemsMoved(list, from, to, count, removals: &removes, inserts: &inserts);
1568
1569 QCOMPARE(removes, expectedRemoves);
1570 QCOMPARE(inserts, expectedInserts);
1571
1572 QCOMPARE(compositor.count(C::Cache), cacheIndexes.count);
1573 for (int i = 0; i < cacheIndexes.count; ++i) {
1574 if (cacheIndexes[i] != -1) {
1575 QCOMPARE(compositor.find(C::Cache, i).modelIndex(), cacheIndexes[i]);
1576 }
1577 }
1578 QCOMPARE(compositor.count(C::Default), defaultIndexes.count);
1579 for (int i = 0; i < defaultIndexes.count; ++i) {
1580 if (defaultIndexes[i] != -1) {
1581 QCOMPARE(compositor.find(C::Default, i).modelIndex(), defaultIndexes[i]);
1582 }
1583 }
1584 QCOMPARE(compositor.count(Visible), visibleIndexes.count);
1585 for (int i = 0; i < visibleIndexes.count; ++i) {
1586 if (visibleIndexes[i] != -1) {
1587 QCOMPARE(compositor.find(Visible, i).modelIndex(), visibleIndexes[i]);
1588 }
1589 }
1590 QCOMPARE(compositor.count(Selection), selectionIndexes.count);
1591 for (int i = 0; i < selectionIndexes.count; ++i) {
1592 if (selectionIndexes[i] != -1) {
1593 QCOMPARE(compositor.find(Selection, i).modelIndex(), selectionIndexes[i]);
1594 }
1595 }
1596}
1597
1598void tst_qqmllistcompositor::listItemsChanged_data()
1599{
1600 QTest::addColumn<RangeList>(name: "ranges");
1601 QTest::addColumn<void *>(name: "list");
1602 QTest::addColumn<int>(name: "index");
1603 QTest::addColumn<int>(name: "count");
1604 QTest::addColumn<ChangeList>(name: "expectedChanges");
1605
1606 int listA; void *a = &listA;
1607 int listB; void *b = &listB;
1608
1609 QTest::newRow(dataTag: "overlapping")
1610 << (RangeList()
1611 << Range(a, 0, 2, C::PrependFlag | C::DefaultFlag)
1612 << Range(a, 2, 3, C::PrependFlag)
1613 << Range(a, 5, 2, C::AppendFlag | C::PrependFlag | C::DefaultFlag)
1614 << Range(b, 0, 4, C::DefaultFlag)
1615 << Range(a, 2, 3, C::DefaultFlag))
1616 << a << 3 << 4
1617 << (ChangeList()
1618 << Change(sIndex: 0, vIndex: 0, dIndex: 2, cIndex: 0, count: 2, flags: C::DefaultFlag)
1619 << Change(sIndex: 0, vIndex: 0, dIndex: 9, cIndex: 0, count: 2, flags: C::DefaultFlag));
1620 QTest::newRow(dataTag: "Change after remove")
1621 << (RangeList()
1622 << Range(a, 0, 2, C::PrependFlag | C::DefaultFlag | C::CacheFlag)
1623 << Range(a, 2, 3, C::CacheFlag)
1624 << Range(a, 2, 6, C::AppendFlag | C::PrependFlag | C::DefaultFlag | C::CacheFlag))
1625 << a << 3 << 2
1626 << (ChangeList()
1627 << Change(sIndex: 0, vIndex: 0, dIndex: 3, cIndex: 6, count: 2, flags: C::DefaultFlag | C::CacheFlag));
1628}
1629
1630void tst_qqmllistcompositor::listItemsChanged()
1631{
1632 QFETCH(RangeList, ranges);
1633 QFETCH(void *, list);
1634 QFETCH(int, index);
1635 QFETCH(int, count);
1636 QFETCH(ChangeList, expectedChanges);
1637
1638 QQmlListCompositor compositor;
1639 compositor.setGroupCount(4);
1640 compositor.setDefaultGroups(VisibleFlag | C::DefaultFlag);
1641
1642 foreach (const Range &range, ranges)
1643 compositor.append(list: range.list, index: range.index, count: range.count, flags: range.flags);
1644
1645 QVector<C::Change> changes;
1646 compositor.listItemsChanged(list, index, count, changes: &changes);
1647
1648 QCOMPARE(changes, expectedChanges);
1649}
1650
1651void tst_qqmllistcompositor::compositorDebug()
1652{
1653 void *a = (void *)0xa0;
1654 void *b = (void *)0xb0;
1655
1656 QQmlListCompositor compositor;
1657 compositor.setGroupCount(4);
1658 compositor.setDefaultGroups(VisibleFlag | C::DefaultFlag);
1659 compositor.append(list: a, index: 0, count: 2, flags: C::PrependFlag | C::DefaultFlag);
1660 compositor.append(list: a, index: 2, count: 3, flags: C::PrependFlag);
1661 compositor.append(list: a, index: 5, count: 2, flags: C::AppendFlag | C::PrependFlag | C::DefaultFlag);
1662 compositor.append(list: b, index: 0, count: 4, flags: C::DefaultFlag);
1663 compositor.append(list: a, index: 2, count: 3, flags: C::DefaultFlag);
1664
1665 QTest::ignoreMessage(type: QtDebugMsg,
1666 message: "QQmlListCompositor(00110\n"
1667 " 0 0 0 0 Range(0xa0 0 2 00P000000000D0\n"
1668 " 0 0 2 0 Range(0xa0 2 3 00P00000000000\n"
1669 " 0 0 2 0 Range(0xa0 5 2 0AP000000000D0\n"
1670 " 0 0 4 0 Range(0xb0 0 4 000000000000D0\n"
1671 " 0 0 8 0 Range(0xa0 2 3 000000000000D0)");
1672 qDebug() << compositor;
1673
1674 compositor.setFlags(fromGroup: C::Default, from: 5, count: 2, flags: SelectionFlag);
1675
1676 QTest::ignoreMessage(type: QtDebugMsg,
1677 message: "QQmlListCompositor(20110\n"
1678 " 0 0 0 0 Range(0xa0 0 2 00P000000000D0\n"
1679 " 0 0 2 0 Range(0xa0 2 3 00P00000000000\n"
1680 " 0 0 2 0 Range(0xa0 5 2 0AP000000000D0\n"
1681 " 0 0 4 0 Range(0xb0 0 1 000000000000D0\n"
1682 " 0 0 5 0 Range(0xb0 1 2 000000000010D0\n"
1683 " 2 0 7 0 Range(0xb0 3 1 000000000000D0\n"
1684 " 2 0 8 0 Range(0xa0 2 3 000000000000D0)");
1685 qDebug() << compositor;
1686}
1687
1688void tst_qqmllistcompositor::changeDebug()
1689{
1690 void *a = (void *)0xa0;
1691 void *b = (void *)0xb0;
1692
1693 QQmlListCompositor compositor;
1694 compositor.setGroupCount(4);
1695 compositor.setDefaultGroups(VisibleFlag | C::DefaultFlag);
1696 compositor.append(list: a, index: 0, count: 2, flags: C::PrependFlag | C::DefaultFlag);
1697 compositor.append(list: a, index: 2, count: 3, flags: C::PrependFlag);
1698 compositor.append(list: a, index: 5, count: 2, flags: C::AppendFlag | C::PrependFlag | C::DefaultFlag);
1699 compositor.append(list: b, index: 0, count: 1, flags: C::DefaultFlag);
1700 compositor.append(list: b, index: 1, count: 2, flags: SelectionFlag | C::DefaultFlag);
1701 compositor.append(list: b, index: 3, count: 1, flags: C::DefaultFlag);
1702 compositor.append(list: a, index: 2, count: 3, flags: C::DefaultFlag);
1703
1704
1705 QTest::ignoreMessage(type: QtDebugMsg, message: "Change(-1 2 000000010D0 2 0 7 0)");
1706 qDebug() << QQmlListCompositor::Change(compositor.find(group: C::Default, index: 7), 2, SelectionFlag | C::DefaultFlag);
1707 QTest::ignoreMessage(type: QtDebugMsg, message: "Remove(9 4 000000000D0 10 0)");
1708 qDebug() << QQmlListCompositor::Remove(compositor.find(group: C::Default, index: 10), 4, C::DefaultFlag, 9);
1709 QTest::ignoreMessage(type: QtDebugMsg, message: "Insert(9 4 000000000D0 3 0)");
1710 qDebug() << QQmlListCompositor::Insert(compositor.find(group: C::Default, index: 3), 4, C::DefaultFlag, 9);
1711}
1712
1713void tst_qqmllistcompositor::groupDebug()
1714{
1715 QTest::ignoreMessage(type: QtDebugMsg, message: "Default");
1716 qDebug() << C::Default;
1717 QTest::ignoreMessage(type: QtDebugMsg, message: "Cache");
1718 qDebug() << C::Cache;
1719 QTest::ignoreMessage(type: QtDebugMsg, message: "Group3");
1720 qDebug() << Selection;
1721}
1722
1723QTEST_MAIN(tst_qqmllistcompositor)
1724
1725#include "tst_qqmllistcompositor.moc"
1726
1727
1728

source code of qtdeclarative/tests/auto/qml/qqmllistcompositor/tst_qqmllistcompositor.cpp