2
* Copyright (C) 2011 Canonical, Ltd.
5
* Florian Boucault <florian.boucault@canonical.com>
7
* This program is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation; version 3.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program. If not, see <http://www.gnu.org/licenses/>.
21
#include "qsortfilterproxymodelqml.h"
22
#include "modeltest.h"
27
#include <QModelIndex>
28
#include <QAbstractListModel>
32
class MockListModel : public QAbstractListModel
37
MockListModel(QObject* parent = 0)
38
: QAbstractListModel(parent)
42
int rowCount(const QModelIndex& /* parent */ = QModelIndex()) const
47
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const
49
if (!index.isValid() || index.row() < 0 || index.row() >= m_list.size() || role != Qt::DisplayRole) {
52
return QVariant(m_list[index.row()]);
55
QHash<int, QByteArray> roleNames() const
60
void setRoles(const QHash<int,QByteArray> &roles) {
64
bool insertRows(int row, int count, const QModelIndex &parent=QModelIndex()) {
65
beginInsertRows(parent, row, row+count-1);
66
for (int i=0; i<count; i++) {
67
m_list.insert(i+row, "test"+i);
73
bool appendRows(QStringList &rows, const QModelIndex &parent=QModelIndex()) {
74
beginInsertRows(parent, rowCount(), rowCount() + rows.count() - 1);
80
bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex()) {
81
beginRemoveRows(parent, row, row+count-1);
82
for (int i=0; i<count; i++) {
91
QHash<int, QByteArray> m_roles;
94
class QSortFilterProxyModelTest : public QObject
100
void initTestCase() {
101
qRegisterMetaType<QModelIndex>("QModelIndex");
104
void testRoleNamesSetAfter()
106
QSortFilterProxyModelQML proxy;
108
QHash<int, QByteArray> roles;
110
proxy.setModel(&model);
114
model.setRoles(roles);
115
QCOMPARE(model.roleNames(), proxy.roleNames());
118
void testRoleNamesSetBefore()
120
QSortFilterProxyModelQML proxy;
122
QHash<int, QByteArray> roles;
126
model.setRoles(roles);
128
proxy.setModel(&model);
129
QCOMPARE(model.roleNames(), proxy.roleNames());
132
void testCountSetAfter()
134
QSortFilterProxyModelQML proxy;
136
model.insertRows(0, 5);
138
QSignalSpy spyOnCountChanged(&proxy, SIGNAL(countChanged()));
140
proxy.setModel(&model);
141
QCOMPARE(proxy.count(), 5);
142
QVERIFY(spyOnCountChanged.count() >= 1);
145
void testCountInsert()
147
QSortFilterProxyModelQML proxy;
150
proxy.setModel(&model);
152
QSignalSpy spyOnCountChanged(&proxy, SIGNAL(countChanged()));
154
model.insertRows(0, 5);
155
QCOMPARE(proxy.count(), 5);
156
QCOMPARE(spyOnCountChanged.count(), 1);
159
void testCountRemove()
161
QSortFilterProxyModelQML proxy;
163
model.insertRows(0, 5);
165
proxy.setModel(&model);
166
QCOMPARE(proxy.count(), 5);
168
QSignalSpy spyOnCountChanged(&proxy, SIGNAL(countChanged()));
170
model.removeRows(0, 3);
171
QCOMPARE(proxy.count(), 2);
172
QCOMPARE(spyOnCountChanged.count(), 1);
175
void testInvertMatch() {
176
QSortFilterProxyModelQML proxy;
179
proxy.setModel(&model);
180
proxy.setDynamicSortFilter(true);
183
rows << "a/foobar/b" << "foobar" << "foobarbaz" << "hello";
184
model.appendRows(rows);
186
// Check that without a filterRegExp all rows are accepted regardless of invertMatch
187
QCOMPARE(model.rowCount(), rows.count());
188
QCOMPARE(proxy.rowCount(), rows.count());
189
for (int i=0; i<rows.count(); i++) {
190
QCOMPARE(proxy.index(i, 0).data().toString(), model.index(i, 0).data().toString());
192
proxy.setInvertMatch(true);
193
QCOMPARE(model.rowCount(), rows.count());
194
QCOMPARE(proxy.rowCount(), rows.count());
195
for (int i=0; i<rows.count(); i++) {
196
QCOMPARE(proxy.index(i, 0).data().toString(), model.index(i, 0).data().toString());
200
// Test non-anchored regexp with invertMatch active
201
proxy.setFilterRegExp("foobar");
202
QCOMPARE(proxy.rowCount(), 1);
203
QCOMPARE(proxy.index(0, 0).data().toString(), rows.last());
205
// Test anchored regexp with invertMatch active
206
proxy.setFilterRegExp("^foobar$");
207
QCOMPARE(proxy.rowCount(), 3);
208
QCOMPARE(proxy.index(0, 0).data().toString(), rows.at(0));
209
QCOMPARE(proxy.index(1, 0).data().toString(), rows.at(2));
210
QCOMPARE(proxy.index(2, 0).data().toString(), rows.at(3));
212
// Test regexp with OR and invertMatch active
213
proxy.setFilterRegExp("foobar|hello");
214
QCOMPARE(proxy.count(), 0);
217
void testNestedProxyRoleNames() {
218
QSortFilterProxyModelQML proxy1, proxy2;
220
QHash<int, QByteArray> roles;
223
model.setRoles(roles);
225
proxy1.setModel(&model);
226
proxy2.setModel(&proxy1);
228
QCOMPARE(proxy2.roleNames(), model.roleNames());
231
void testModelTest() {
232
QSortFilterProxyModelQML proxy;
235
proxy.setModel(&model);
236
proxy.setDynamicSortFilter(true);
239
rows << "a/foobar/b" << "foobar" << "foobarbaz" << "hello";
240
model.appendRows(rows);
242
proxy.setInvertMatch(true);
243
proxy.setFilterRegExp("^foobar$");
245
ModelTest t1(&proxy);
248
void testModelChanged() {
249
QSortFilterProxyModelQML proxy;
250
MockListModel model, model2;
252
QSignalSpy spyOnModelChanged(&proxy, SIGNAL(modelChanged()));
254
proxy.setModel(&model);
255
QCOMPARE(spyOnModelChanged.count(), 1);
257
proxy.setModel(&model2);
258
QCOMPARE(spyOnModelChanged.count(), 2);
260
proxy.setModel(&model);
261
QCOMPARE(spyOnModelChanged.count(), 3);
263
proxy.setModel(&model);
264
QCOMPARE(spyOnModelChanged.count(), 3);
268
QSortFilterProxyModelQML proxy;
269
MockListModel model, model2;
272
rows << "a" << "c" << "b";
273
model.appendRows(rows);
275
proxy.setModel(&model);
278
QCOMPARE(proxy.data(-1, Qt::DisplayRole), QVariant());
279
QCOMPARE(proxy.data(3, Qt::DisplayRole), QVariant());
280
QCOMPARE(proxy.data(0, Qt::DisplayRole - 1), QVariant());
281
QCOMPARE(proxy.data(0, Qt::DisplayRole + 1), QVariant());
282
QCOMPARE(proxy.data(0, Qt::DisplayRole), QVariant("a"));
283
QCOMPARE(proxy.data(1, Qt::DisplayRole), QVariant("b"));
284
QCOMPARE(proxy.data(2, Qt::DisplayRole), QVariant("c"));
288
QTEST_MAIN(QSortFilterProxyModelTest)
290
#include "qsortfilterproxymodeltest.moc"