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 <QtQmlModels/private/qqmlobjectmodel_p.h>
29#include <QtQmlModels/private/qqmlchangeset_p.h>
30#include <QtTest/qsignalspy.h>
31#include <QtTest/qtest.h>
32
33class tst_QQmlObjectModel : public QObject
34{
35 Q_OBJECT
36
37private slots:
38 void changes();
39};
40
41static bool compareItems(QQmlObjectModel *model, const QObjectList &items)
42{
43 for (int i = 0; i < items.count(); ++i) {
44 if (model->get(index: i) != items.at(i))
45 return false;
46 }
47 return true;
48}
49
50static bool verifyChangeSet(const QQmlChangeSet &changeSet, int expectedInserts, int expectedRemoves, bool isMove, int moveId = -1)
51{
52 int actualRemoves = 0;
53 for (const QQmlChangeSet::Change &r : changeSet.removes()) {
54 if (r.isMove() != isMove && (!isMove || moveId == r.moveId))
55 return false;
56 actualRemoves += r.count;
57 }
58
59 int actualInserts = 0;
60 for (const QQmlChangeSet::Change &i : changeSet.inserts()) {
61 if (i.isMove() != isMove && (!isMove || moveId == i.moveId))
62 return false;
63 actualInserts += i.count;
64 }
65
66 return actualRemoves == expectedRemoves && actualInserts == expectedInserts;
67}
68
69Q_DECLARE_METATYPE(QQmlChangeSet)
70
71void tst_QQmlObjectModel::changes()
72{
73 QQmlObjectModel model;
74
75 qRegisterMetaType<QQmlChangeSet>();
76
77 QSignalSpy countSpy(&model, SIGNAL(countChanged()));
78 QSignalSpy childrenSpy(&model, SIGNAL(childrenChanged()));
79 QSignalSpy modelUpdateSpy(&model, SIGNAL(modelUpdated(QQmlChangeSet,bool)));
80
81 int count = 0;
82 int countSignals = 0;
83 int childrenSignals = 0;
84 int modelUpdateSignals = 0;
85
86 QObjectList items;
87 QObject item0, item1, item2, item3;
88
89 // append(item0) -> [item0]
90 model.append(object: &item0); items.append(t: &item0);
91 QCOMPARE(model.count(), ++count);
92 QVERIFY(compareItems(&model, items));
93 QCOMPARE(countSpy.count(), ++countSignals);
94 QCOMPARE(childrenSpy.count(), ++childrenSignals);
95 QCOMPARE(modelUpdateSpy.count(), ++modelUpdateSignals);
96 QVERIFY(verifyChangeSet(modelUpdateSpy.last().first().value<QQmlChangeSet>(), 1, 0, false));
97
98 // insert(0, item1) -> [item1, item0]
99 model.insert(index: 0, object: &item1); items.insert(i: 0, t: &item1);
100 QCOMPARE(model.count(), ++count);
101 QVERIFY(compareItems(&model, items));
102 QCOMPARE(countSpy.count(), ++countSignals);
103 QCOMPARE(childrenSpy.count(), ++childrenSignals);
104 QCOMPARE(modelUpdateSpy.count(), ++modelUpdateSignals);
105 QVERIFY(verifyChangeSet(modelUpdateSpy.last().first().value<QQmlChangeSet>(), 1, 0, false));
106
107 // append(item2) -> [item1, item0, item2]
108 model.append(object: &item2); items.append(t: &item2);
109 QCOMPARE(model.count(), ++count);
110 QVERIFY(compareItems(&model, items));
111 QCOMPARE(countSpy.count(), ++countSignals);
112 QCOMPARE(childrenSpy.count(), ++childrenSignals);
113 QCOMPARE(modelUpdateSpy.count(), ++modelUpdateSignals);
114 QVERIFY(verifyChangeSet(modelUpdateSpy.last().first().value<QQmlChangeSet>(), 1, 0, false));
115
116 // insert(2, item3) -> [item1, item0, item3, item2]
117 model.insert(index: 2, object: &item3); items.insert(i: 2, t: &item3);
118 QCOMPARE(model.count(), ++count);
119 QVERIFY(compareItems(&model, items));
120 QCOMPARE(countSpy.count(), ++countSignals);
121 QCOMPARE(childrenSpy.count(), ++childrenSignals);
122 QCOMPARE(modelUpdateSpy.count(), ++modelUpdateSignals);
123 QVERIFY(verifyChangeSet(modelUpdateSpy.last().first().value<QQmlChangeSet>(), 1, 0, false));
124
125 // move(0, 1) -> [item0, item1, item3, item2]
126 model.move(from: 0, to: 1); items.move(from: 0, to: 1);
127 QCOMPARE(model.count(), count);
128 QVERIFY(compareItems(&model, items));
129 QCOMPARE(countSpy.count(), countSignals);
130 QCOMPARE(childrenSpy.count(), ++childrenSignals);
131 QCOMPARE(modelUpdateSpy.count(), ++modelUpdateSignals);
132 QVERIFY(verifyChangeSet(modelUpdateSpy.last().first().value<QQmlChangeSet>(), 1, 1, true, 1));
133
134 // move(3, 2) -> [item0, item1, item2, item3]
135 model.move(from: 3, to: 2); items.move(from: 3, to: 2);
136 QCOMPARE(model.count(), count);
137 QVERIFY(compareItems(&model, items));
138 QCOMPARE(countSpy.count(), countSignals);
139 QCOMPARE(childrenSpy.count(), ++childrenSignals);
140 QCOMPARE(modelUpdateSpy.count(), ++modelUpdateSignals);
141 QVERIFY(verifyChangeSet(modelUpdateSpy.last().first().value<QQmlChangeSet>(), 1, 1, true, 2));
142
143 // remove(0) -> [item1, item2, item3]
144 model.remove(index: 0); items.removeAt(i: 0);
145 QCOMPARE(model.count(), --count);
146 QVERIFY(compareItems(&model, items));
147 QCOMPARE(countSpy.count(), ++countSignals);
148 QCOMPARE(childrenSpy.count(), ++childrenSignals);
149 QCOMPARE(modelUpdateSpy.count(), ++modelUpdateSignals);
150 QVERIFY(verifyChangeSet(modelUpdateSpy.last().first().value<QQmlChangeSet>(), 0, 1, false));
151
152 // remove(2) -> [item1, item2]
153 model.remove(index: 2); items.removeAt(i: 2);
154 QCOMPARE(model.count(), --count);
155 QVERIFY(compareItems(&model, items));
156 QCOMPARE(countSpy.count(), ++countSignals);
157 QCOMPARE(childrenSpy.count(), ++childrenSignals);
158 QCOMPARE(modelUpdateSpy.count(), ++modelUpdateSignals);
159 QVERIFY(verifyChangeSet(modelUpdateSpy.last().first().value<QQmlChangeSet>(), 0, 1, false));
160
161 // clear() -> []
162 model.clear(); items.clear();
163 QCOMPARE(model.count(), 0);
164 QVERIFY(compareItems(&model, items));
165 QCOMPARE(countSpy.count(), ++countSignals);
166 QCOMPARE(childrenSpy.count(), ++childrenSignals);
167 QCOMPARE(modelUpdateSpy.count(), ++modelUpdateSignals);
168 QVERIFY(verifyChangeSet(modelUpdateSpy.last().first().value<QQmlChangeSet>(), 0, 2, false));
169}
170
171QTEST_MAIN(tst_QQmlObjectModel)
172
173#include "tst_qqmlobjectmodel.moc"
174

source code of qtdeclarative/tests/auto/qml/qqmlobjectmodel/tst_qqmlobjectmodel.cpp