1
/****************************************************************************
3
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4
** Contact: http://www.qt-project.org/legal
6
** This file is part of the test suite of the Qt Toolkit.
8
** $QT_BEGIN_LICENSE:LGPL$
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 Digia. For licensing terms and
14
** conditions see http://qt.digia.com/licensing. For further information
15
** use the contact form at http://qt.digia.com/contact-us.
17
** GNU Lesser General Public License Usage
18
** Alternatively, this file may be used under the terms of the GNU Lesser
19
** General Public License version 2.1 as published by the Free Software
20
** Foundation and appearing in the file LICENSE.LGPL included in the
21
** packaging of this file. Please review the following information to
22
** ensure the GNU Lesser General Public License version 2.1 requirements
23
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25
** In addition, as a special exception, Digia gives you certain additional
26
** rights. These rights are described in the Digia Qt LGPL Exception
27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29
** GNU General Public License Usage
30
** Alternatively, this file may be used under the terms of the GNU
31
** General Public License version 3.0 as published by the Free Software
32
** Foundation and appearing in the file LICENSE.GPL included in the
33
** packaging of this file. Please review the following information to
34
** ensure the GNU General Public License version 3.0 requirements will be
35
** met: http://www.gnu.org/copyleft/gpl.html.
40
****************************************************************************/
41
#include "../../shared/util.h"
42
#include "../shared/visualtestutil.h"
43
#include "../shared/viewtestutil.h"
46
#include <QtTest/QSignalSpy>
47
#include <QtQml/qqmlengine.h>
48
#include <QtQml/qqmlcomponent.h>
49
#include <QtQml/qqmlcontext.h>
50
#include <QtQml/qqmlexpression.h>
51
#include <QtQml/qqmlincubator.h>
52
#include <QtQuick/qquickview.h>
53
#include <private/qquicklistview_p.h>
54
#include <QtQuick/private/qquicktext_p.h>
55
#include <QtQuick/private/qquickvisualdatamodel_p.h>
56
#include <private/qqmlvaluetype_p.h>
57
#include <private/qquickchangeset_p.h>
58
#include <private/qqmlengine_p.h>
60
#include <QtGui/qstandarditemmodel.h>
62
using namespace QQuickVisualTestUtil;
63
using namespace QQuickViewTestUtil;
65
template <typename T, int N> int lengthOf(const T (&)[N]) { return N; }
67
static void initStandardTreeModel(QStandardItemModel *model)
70
item = new QStandardItem(QLatin1String("Row 1 Item"));
71
model->insertRow(0, item);
73
item = new QStandardItem(QLatin1String("Row 2 Item"));
74
item->setCheckable(true);
75
model->insertRow(1, item);
77
QStandardItem *childItem = new QStandardItem(QLatin1String("Row 2 Child Item"));
78
item->setChild(0, childItem);
80
item = new QStandardItem(QLatin1String("Row 3 Item"));
81
item->setIcon(QIcon());
82
model->insertRow(2, item);
85
class SingleRoleModel : public QAbstractItemModel
88
Q_PROPERTY(QStringList values READ getList WRITE setList)
92
Node(const QString &display = QString()) : branch(0), display(display) {}
98
Branch(Branch *parent = 0) : parent(parent) {}
99
~Branch() { foreach (const Node &child, children) delete child.branch; }
100
int indexOf(Branch *branch) const {
101
for (int i = 0; i < children.count(); ++i) {
102
if (children.at(i).branch == branch)
108
QVector<Node> children;
112
SingleRoleModel(const QStringList &list = QStringList(), const QByteArray &role = "name", QObject *parent = 0)
113
: QAbstractItemModel(parent) {
114
QHash<int, QByteArray> roles;
115
roles.insert(Qt::DisplayRole , role);
117
foreach (const QString &string, list)
118
trunk.children.append(Node(string));
120
~SingleRoleModel() {}
122
Branch *branchForIndex(const QModelIndex &index) const {
123
return index.isValid()
124
? static_cast<Branch *>(index.internalPointer())->children.at(index.row()).branch
125
: const_cast<Branch *>(&trunk);
128
Branch *createBranchForIndex(const QModelIndex &index) const {
129
if (index.isValid()) {
130
Branch * const parentBranch = static_cast<Branch *>(index.internalPointer());
131
Node &node = parentBranch->children[index.row()];
133
node.branch = new Branch(parentBranch);
136
return const_cast<Branch *>(&trunk);
140
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const {
141
if (row < 0 || column != 0)
142
return QModelIndex();
143
Branch * const branch = branchForIndex(parent);
144
return branch && row < branch->children.count()
145
? createIndex(row, column, branch)
149
QModelIndex parent(const QModelIndex &child) const {
150
Branch * const branch = static_cast<Branch *>(child.internalPointer());
151
return branch->parent
152
? createIndex(branch->parent->indexOf(branch), 0, branch->parent)
156
int rowCount(const QModelIndex &parent) const {
157
Branch * const branch = branchForIndex(parent);
158
return branch ? branch->children.count() : 0;
161
int columnCount(const QModelIndex &parent) const {
162
Branch * const branch = branchForIndex(parent);
163
return branch ? 1 : 0;
166
QVariant data(const QModelIndex &index, int role) const {
167
return index.isValid() && role == Qt::DisplayRole
168
? static_cast<Branch *>(index.internalPointer())->children.at(index.row()).display
172
void insert(const QModelIndex &parent, int index, const QStringList &data) {
173
beginInsertRows(parent, index, index + data.count() - 1);
174
Branch * const branch = createBranchForIndex(parent);
175
for (int i = 0; i < data.count(); ++i)
176
branch->children.insert(index + i, Node(data.at(i)));
180
void remove(const QModelIndex &parent, int index, int count) {
181
beginRemoveRows(parent, index, index + count - 1);
182
Branch * const branch = branchForIndex(parent);
183
for (int i = 0; i < count; ++i) {
184
delete branch->children.at(index).branch;
185
branch->children.remove(index);
190
void move(const QModelIndex &fromParent, int from, const QModelIndex &toParent, int to, int count) {
191
beginMoveRows(fromParent, from, from + count - 1, toParent, to);
192
Branch * const fromBranch = branchForIndex(fromParent);
193
Branch * const toBranch = createBranchForIndex(toParent);
195
if (fromBranch == toBranch) {
196
qquickmodelviewstestutil_move(from, to, count, &fromBranch->children);
198
for (int i = 0; i < count; ++i) {
199
Node node = fromBranch->children.at(from);
200
fromBranch->children.remove(from);
202
node.branch->parent = toBranch;
203
toBranch->children.insert(to + i, node);
210
void emitMove(int sourceFirst, int sourceLast, int destinationChild) {
211
emit beginMoveRows(QModelIndex(), sourceFirst, sourceLast, QModelIndex(), destinationChild);
215
QStringList getList() const {
217
foreach (const Node &node, trunk.children)
218
list.append(node.display);
222
void setList(const QStringList &l) {
223
if (trunk.children.count() > 0) {
224
beginRemoveRows(QModelIndex(), 0, trunk.children.count() - 1);
225
foreach (const Node &child, trunk.children) delete child.branch;
226
trunk.children.clear();
230
beginInsertRows(QModelIndex(), 0, l.count() -1);
231
foreach (const QString &string, l)
232
trunk.children.append(Node(string));
237
QString at(int index) const { return trunk.children.at(index).display; }
240
void set(int idx, QString string) {
241
trunk.children[idx].display = string;
242
emit dataChanged(createIndex(idx, 0, &trunk), createIndex(idx, 0, &trunk));
249
class StandardItem : public QObject, public QStandardItem
252
Q_PROPERTY(QString text READ readText WRITE setText)
255
QString readText() const { return text(); }
256
void writeText(const QString &text) { setText(text); }
259
class StandardItemModel : public QStandardItemModel
262
Q_PROPERTY(QQmlListProperty<StandardItem> items READ items CONSTANT)
263
Q_CLASSINFO("DefaultProperty", "items")
265
QQmlListProperty<StandardItem> items() { return QQmlListProperty<StandardItem>(this, 0, append, 0, 0, 0); }
267
static void append(QQmlListProperty<StandardItem> *property, StandardItem *item)
269
static_cast<QStandardItemModel *>(property->object)->appendRow(item);
273
class DataSubObject : public QObject
277
Q_PROPERTY(QString subName READ subName WRITE setSubName NOTIFY subNameChanged)
280
DataSubObject(QObject *parent=0) : QObject(parent) {}
282
QString subName() const { return m_subName; }
283
void setSubName(const QString &name) {
284
if (name != m_subName) {
286
emit subNameChanged();
291
void subNameChanged();
297
class DataObject : public QObject
301
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
302
Q_PROPERTY(QString color READ color WRITE setColor NOTIFY colorChanged)
303
Q_PROPERTY(QObject *object READ object)
306
DataObject(QObject *parent=0) : QObject(parent) {}
307
DataObject(const QString &name, const QString &color, QObject *parent=0)
308
: QObject(parent), m_name(name), m_color(color), m_object(new DataSubObject(this)) { }
311
QString name() const { return m_name; }
312
void setName(const QString &name) {
313
if (name != m_name) {
319
QString color() const { return m_color; }
320
void setColor(const QString &color) {
321
if (color != m_color) {
327
QObject *object() const { return m_object; }
328
void setSubName(const QString &sn) {
329
m_object->setSubName(sn);
339
DataSubObject *m_object;
342
class ItemRequester : public QObject
346
ItemRequester(QObject *parent = 0)
351
, indexInitialized(-1)
356
QQuickItem *itemInitialized;
357
QQuickItem *itemCreated;
358
QQuickItem *itemDestroyed;
359
int indexInitialized;
363
void initItem(int index, QQuickItem *item)
365
itemInitialized = item;
366
indexInitialized = index;
369
void createdItem(int index, QQuickItem *item)
372
indexCreated = index;
375
void destroyingItem(QQuickItem *item)
377
itemDestroyed = item;
381
QML_DECLARE_TYPE(SingleRoleModel)
382
QML_DECLARE_TYPE(DataObject)
383
QML_DECLARE_TYPE(StandardItem)
384
QML_DECLARE_TYPE(StandardItemModel)
386
class tst_qquickvisualdatamodel : public QQmlDataTest
390
tst_qquickvisualdatamodel();
394
void cleanupTestCase();
396
void updateLayout_data();
398
void childChanged_data();
400
void noDelegate_data();
402
void itemsDestroyed_data();
403
void itemsDestroyed();
404
void objectListModel();
406
void modelProperties();
407
void packagesDestroyed();
408
void qaimRowsMoved();
409
void qaimRowsMoved_data();
410
void subtreeRowsMoved();
412
void hasModelChildren();
420
void invalidGroups();
422
void onChanged_data();
425
void incompleteModel();
430
void warnings_data();
432
void invalidAttachment();
433
void asynchronousInsert_data();
434
void asynchronousInsert();
435
void asynchronousRemove_data();
436
void asynchronousRemove();
437
void asynchronousMove();
438
void asynchronousMove_data();
439
void asynchronousCancel();
440
void invalidContext();
443
template <int N> void groups_verify(
444
const SingleRoleModel &model,
445
QQuickItem *contentItem,
446
const int (&mIndex)[N],
447
const int (&iIndex)[N],
448
const int (&vIndex)[N],
449
const int (&sIndex)[N],
450
const bool (&vMember)[N],
451
const bool (&sMember)[N]);
453
template <int N> void get_verify(
454
const SingleRoleModel &model,
455
QQuickVisualDataModel *visualModel,
456
QQuickVisualDataGroup *visibleItems,
457
QQuickVisualDataGroup *selectedItems,
458
const int (&mIndex)[N],
459
const int (&iIndex)[N],
460
const int (&vIndex)[N],
461
const int (&sIndex)[N],
462
const bool (&vMember)[N],
463
const bool (&sMember)[N]);
466
QQmlIncubationController controller;
470
Q_DECLARE_METATYPE(QQuickChangeSet)
472
template <typename T> static T evaluate(QObject *scope, const QString &expression)
474
QQmlExpression expr(qmlContext(scope), scope, expression);
475
T result = expr.evaluate().value<T>();
477
qWarning() << expr.error().toString();
481
template <> void evaluate<void>(QObject *scope, const QString &expression)
483
QQmlExpression expr(qmlContext(scope), scope, expression);
486
qWarning() << expr.error().toString();
489
void tst_qquickvisualdatamodel::initTestCase()
491
QQmlDataTest::initTestCase();
492
qRegisterMetaType<QQuickChangeSet>();
494
qmlRegisterType<SingleRoleModel>("tst_qquickvisualdatamodel", 1, 0, "SingleRoleModel");
495
qmlRegisterType<DataObject>("tst_qquickvisualdatamodel", 1, 0, "DataObject");
496
qmlRegisterType<StandardItem>("tst_qquickvisualdatamodel", 1, 0, "StandardItem");
497
qmlRegisterType<StandardItemModel>("tst_qquickvisualdatamodel", 1, 0, "StandardItemModel");
499
engine.setIncubationController(&controller);
502
void tst_qquickvisualdatamodel::cleanupTestCase()
506
tst_qquickvisualdatamodel::tst_qquickvisualdatamodel()
510
void tst_qquickvisualdatamodel::rootIndex()
513
QQmlComponent c(&engine, testFileUrl("visualdatamodel.qml"));
515
QStandardItemModel model;
516
initStandardTreeModel(&model);
518
engine.rootContext()->setContextProperty("myModel", &model);
520
QQuickVisualDataModel *obj = qobject_cast<QQuickVisualDataModel*>(c.create());
523
QMetaObject::invokeMethod(obj, "setRoot");
524
QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == model.index(0,0));
526
QMetaObject::invokeMethod(obj, "setRootToParent");
527
QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == QModelIndex());
529
QMetaObject::invokeMethod(obj, "setRoot");
530
QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == model.index(0,0));
531
model.clear(); // will emit modelReset()
532
QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == QModelIndex());
537
void tst_qquickvisualdatamodel::updateLayout_data()
539
QTest::addColumn<QUrl>("source");
541
QTest::newRow("item delegate") << testFileUrl("datalist.qml");
542
QTest::newRow("package delegate") << testFileUrl("datalist-package.qml");
545
void tst_qquickvisualdatamodel::updateLayout()
547
QFETCH(QUrl, source);
551
QStandardItemModel model;
552
initStandardTreeModel(&model);
554
view.rootContext()->setContextProperty("myModel", &model);
556
view.setSource(source);
558
QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
559
QVERIFY(listview != 0);
561
QQuickItem *contentItem = listview->contentItem();
562
QVERIFY(contentItem != 0);
564
QQuickText *name = findItem<QQuickText>(contentItem, "display", 0);
566
QCOMPARE(name->text(), QString("Row 1 Item"));
567
name = findItem<QQuickText>(contentItem, "display", 1);
569
QCOMPARE(name->text(), QString("Row 2 Item"));
570
name = findItem<QQuickText>(contentItem, "display", 2);
572
QCOMPARE(name->text(), QString("Row 3 Item"));
574
model.invisibleRootItem()->sortChildren(0, Qt::DescendingOrder);
576
name = findItem<QQuickText>(contentItem, "display", 0);
578
QCOMPARE(name->text(), QString("Row 3 Item"));
579
name = findItem<QQuickText>(contentItem, "display", 1);
581
QCOMPARE(name->text(), QString("Row 2 Item"));
582
name = findItem<QQuickText>(contentItem, "display", 2);
584
QCOMPARE(name->text(), QString("Row 1 Item"));
587
void tst_qquickvisualdatamodel::childChanged_data()
589
QTest::addColumn<QUrl>("source");
591
QTest::newRow("item delegate") << testFileUrl("datalist.qml");
592
QTest::newRow("package delegate") << testFileUrl("datalist-package.qml");
595
void tst_qquickvisualdatamodel::childChanged()
597
QFETCH(QUrl, source);
601
QStandardItemModel model;
602
initStandardTreeModel(&model);
604
view.rootContext()->setContextProperty("myModel", &model);
606
view.setSource(source);
608
QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
609
QVERIFY(listview != 0);
611
QQuickItem *contentItem = listview->contentItem();
612
QVERIFY(contentItem != 0);
614
QQuickVisualDataModel *vdm = listview->findChild<QQuickVisualDataModel*>("visualModel");
615
vdm->setRootIndex(QVariant::fromValue(model.indexFromItem(model.item(1,0))));
616
QCOMPARE(listview->count(), 1);
618
QQuickText *name = findItem<QQuickText>(contentItem, "display", 0);
620
QCOMPARE(name->text(), QString("Row 2 Child Item"));
622
model.item(1,0)->child(0,0)->setText("Row 2 updated child");
624
name = findItem<QQuickText>(contentItem, "display", 0);
626
QCOMPARE(name->text(), QString("Row 2 updated child"));
628
model.item(1,0)->appendRow(new QStandardItem(QLatin1String("Row 2 Child Item 2")));
629
QCOMPARE(listview->count(), 2);
631
name = findItem<QQuickText>(contentItem, "display", 1);
633
QCOMPARE(name->text(), QString("Row 2 Child Item 2"));
635
model.item(1,0)->takeRow(1);
636
name = findItem<QQuickText>(contentItem, "display", 1);
639
vdm->setRootIndex(QVariant::fromValue(QModelIndex()));
640
QCOMPARE(listview->count(), 3);
641
name = findItem<QQuickText>(contentItem, "display", 0);
643
QCOMPARE(name->text(), QString("Row 1 Item"));
644
name = findItem<QQuickText>(contentItem, "display", 1);
646
QCOMPARE(name->text(), QString("Row 2 Item"));
647
name = findItem<QQuickText>(contentItem, "display", 2);
649
QCOMPARE(name->text(), QString("Row 3 Item"));
652
void tst_qquickvisualdatamodel::objectListModel()
656
QList<QObject*> dataList;
657
dataList.append(new DataObject("Item 1", "red"));
658
dataList.append(new DataObject("Item 2", "green"));
659
dataList.append(new DataObject("Item 3", "blue"));
660
dataList.append(new DataObject("Item 4", "yellow"));
662
QQmlContext *ctxt = view.rootContext();
663
ctxt->setContextProperty("myModel", QVariant::fromValue(dataList));
665
view.setSource(testFileUrl("objectlist.qml"));
667
QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
668
QVERIFY(listview != 0);
670
QQuickItem *contentItem = listview->contentItem();
671
QVERIFY(contentItem != 0);
673
QQuickText *name = findItem<QQuickText>(contentItem, "name", 0);
674
QCOMPARE(name->text(), QString("Item 1"));
675
QCOMPARE(name->property("modelName").toString(), QString("Item 1"));
677
QQuickText *section = findItem<QQuickText>(contentItem, "section", 0);
678
QCOMPARE(section->text(), QString("Item 1"));
680
dataList[0]->setProperty("name", QLatin1String("Changed"));
681
QCOMPARE(name->text(), QString("Changed"));
682
QCOMPARE(name->property("modelName").toString(), QString("Changed"));
684
// Test resolving nested section property
685
DataObject *obj = static_cast<DataObject*>(dataList[0]);
686
obj->setSubName("SubItem 1");
688
QMetaObject::invokeMethod(listview, "changeSectionProperty");
689
section = findItem<QQuickText>(contentItem, "section", 0);
690
QCOMPARE(section->text(), QString("SubItem 1"));
693
void tst_qquickvisualdatamodel::singleRole()
695
QStringList list = QStringList() << "one" << "two" << "three" << "four";
699
SingleRoleModel model(list);
701
QQmlContext *ctxt = view.rootContext();
702
ctxt->setContextProperty("myModel", &model);
704
view.setSource(testFileUrl("singlerole1.qml"));
706
QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
707
QVERIFY(listview != 0);
709
QQuickItem *contentItem = listview->contentItem();
710
QVERIFY(contentItem != 0);
712
QQuickText *name = findItem<QQuickText>(contentItem, "name", 1);
713
QCOMPARE(name->text(), QString("two"));
715
model.set(1, "Changed");
716
QCOMPARE(name->text(), QString("Changed"));
721
SingleRoleModel model(list);
723
QQmlContext *ctxt = view.rootContext();
724
ctxt->setContextProperty("myModel", &model);
726
view.setSource(testFileUrl("singlerole2.qml"));
728
QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
729
QVERIFY(listview != 0);
731
QQuickItem *contentItem = listview->contentItem();
732
QVERIFY(contentItem != 0);
734
QQuickText *name = findItem<QQuickText>(contentItem, "name", 1);
735
QCOMPARE(name->text(), QString("two"));
737
model.set(1, "Changed");
738
QCOMPARE(name->text(), QString("Changed"));
743
SingleRoleModel model(list, "modelData");
745
QQmlContext *ctxt = view.rootContext();
746
ctxt->setContextProperty("myModel", &model);
748
view.setSource(testFileUrl("singlerole2.qml"));
750
QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
751
QVERIFY(listview != 0);
753
QQuickItem *contentItem = listview->contentItem();
754
QVERIFY(contentItem != 0);
756
QQuickText *name = findItem<QQuickText>(contentItem, "name", 1);
757
QCOMPARE(name->text(), QString("two"));
759
model.set(1, "Changed");
760
QCOMPARE(name->text(), QString("Changed"));
764
void tst_qquickvisualdatamodel::modelProperties()
769
SingleRoleModel model(QStringList() << "one" << "two" << "three" << "four");
771
QQmlContext *ctxt = view.rootContext();
772
ctxt->setContextProperty("myModel", &model);
774
view.setSource(testFileUrl("modelproperties.qml"));
776
QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
777
QVERIFY(listview != 0);
779
QQuickItem *contentItem = listview->contentItem();
780
QVERIFY(contentItem != 0);
782
QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", 1);
784
QCOMPARE(delegate->property("test1").toString(),QString("two"));
785
QCOMPARE(delegate->property("test2").toString(),QString("two"));
786
QCOMPARE(delegate->property("test3").toString(),QString("two"));
787
QCOMPARE(delegate->property("test4").toString(),QString("two"));
788
QVERIFY(!delegate->property("test9").isValid());
789
QCOMPARE(delegate->property("test5").toString(),QString(""));
790
QVERIFY(delegate->property("test6").value<QObject*>() != 0);
791
QCOMPARE(delegate->property("test7").toInt(),1);
792
QCOMPARE(delegate->property("test8").toInt(),1);
798
QList<QObject*> dataList;
799
dataList.append(new DataObject("Item 1", "red"));
800
dataList.append(new DataObject("Item 2", "green"));
801
dataList.append(new DataObject("Item 3", "blue"));
802
dataList.append(new DataObject("Item 4", "yellow"));
804
QQmlContext *ctxt = view.rootContext();
805
ctxt->setContextProperty("myModel", QVariant::fromValue(dataList));
807
view.setSource(testFileUrl("modelproperties.qml"));
809
QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
810
QVERIFY(listview != 0);
812
QQuickItem *contentItem = listview->contentItem();
813
QVERIFY(contentItem != 0);
815
QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", 1);
817
QCOMPARE(delegate->property("test1").toString(),QString("Item 2"));
818
QCOMPARE(delegate->property("test2").toString(),QString("Item 2"));
819
QVERIFY(qobject_cast<DataObject*>(delegate->property("test3").value<QObject*>()) != 0);
820
QVERIFY(qobject_cast<DataObject*>(delegate->property("test4").value<QObject*>()) != 0);
821
QCOMPARE(delegate->property("test5").toString(),QString("Item 2"));
822
QCOMPARE(delegate->property("test9").toString(),QString("Item 2"));
823
QVERIFY(delegate->property("test6").value<QObject*>() != 0);
824
QCOMPARE(delegate->property("test7").toInt(),1);
825
QCOMPARE(delegate->property("test8").toInt(),1);
831
DataObject object("Item 1", "red");
833
QQmlContext *ctxt = view.rootContext();
834
ctxt->setContextProperty("myModel", &object);
836
view.setSource(testFileUrl("modelproperties.qml"));
838
QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
839
QVERIFY(listview != 0);
841
QQuickItem *contentItem = listview->contentItem();
842
QVERIFY(contentItem != 0);
844
QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", 0);
846
QCOMPARE(delegate->property("test1").toString(),QString("Item 1"));
847
QCOMPARE(delegate->property("test2").toString(),QString("Item 1"));
848
QVERIFY(qobject_cast<DataObject*>(delegate->property("test3").value<QObject*>()) != 0);
849
QVERIFY(qobject_cast<DataObject*>(delegate->property("test4").value<QObject*>()) != 0);
850
QCOMPARE(delegate->property("test5").toString(),QString("Item 1"));
851
QCOMPARE(delegate->property("test9").toString(),QString("Item 1"));
852
QVERIFY(delegate->property("test6").value<QObject*>() != 0);
853
QCOMPARE(delegate->property("test7").toInt(), 0);
854
QCOMPARE(delegate->property("test8").toInt(), 0);
860
QStandardItemModel model;
861
initStandardTreeModel(&model);
863
view.rootContext()->setContextProperty("myModel", &model);
865
QUrl source(testFileUrl("modelproperties2.qml"));
868
QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":13: ReferenceError: modelData is not defined");
869
QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":13: ReferenceError: modelData is not defined");
870
QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":13: ReferenceError: modelData is not defined");
871
QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":11: ReferenceError: modelData is not defined");
872
QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":11: ReferenceError: modelData is not defined");
873
QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":11: ReferenceError: modelData is not defined");
874
QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":17: TypeError: Cannot read property 'display' of undefined");
875
QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":17: TypeError: Cannot read property 'display' of undefined");
876
QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":17: TypeError: Cannot read property 'display' of undefined");
878
view.setSource(source);
880
QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
881
QVERIFY(listview != 0);
883
QQuickItem *contentItem = listview->contentItem();
884
QVERIFY(contentItem != 0);
886
QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", 1);
888
QCOMPARE(delegate->property("test1").toString(),QString("Row 2 Item"));
889
QCOMPARE(delegate->property("test2").toString(),QString("Row 2 Item"));
890
QVERIFY(!delegate->property("test3").isValid());
891
QVERIFY(!delegate->property("test4").isValid());
892
QVERIFY(!delegate->property("test5").isValid());
893
QVERIFY(!delegate->property("test9").isValid());
894
QVERIFY(delegate->property("test6").value<QObject*>() != 0);
895
QCOMPARE(delegate->property("test7").toInt(),1);
896
QCOMPARE(delegate->property("test8").toInt(),1);
898
//### should also test QStringList and QVariantList
901
void tst_qquickvisualdatamodel::noDelegate_data()
903
QTest::addColumn<QUrl>("source");
905
QTest::newRow("item delegate") << testFileUrl("datalist.qml");
906
QTest::newRow("package delegate") << testFileUrl("datalist-package.qml");
909
void tst_qquickvisualdatamodel::noDelegate()
911
QFETCH(QUrl, source);
915
QStandardItemModel model;
916
initStandardTreeModel(&model);
918
view.rootContext()->setContextProperty("myModel", &model);
920
view.setSource(source);
922
QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
923
QVERIFY(listview != 0);
925
QQuickVisualDataModel *vdm = listview->findChild<QQuickVisualDataModel*>("visualModel");
927
QCOMPARE(vdm->count(), 3);
930
QCOMPARE(vdm->count(), 0);
933
void tst_qquickvisualdatamodel::itemsDestroyed_data()
935
QTest::addColumn<QUrl>("source");
937
QTest::newRow("listView") << testFileUrl("itemsDestroyed_listView.qml");
938
QTest::newRow("package") << testFileUrl("itemsDestroyed_package.qml");
939
QTest::newRow("pathView") << testFileUrl("itemsDestroyed_pathView.qml");
940
QTest::newRow("repeater") << testFileUrl("itemsDestroyed_repeater.qml");
943
void tst_qquickvisualdatamodel::itemsDestroyed()
945
QFETCH(QUrl, source);
947
QQmlGuard<QQuickItem> delegate;
951
QStandardItemModel model;
952
initStandardTreeModel(&model);
953
view.rootContext()->setContextProperty("myModel", &model);
954
view.setSource(source);
957
QVERIFY(QTest::qWaitForWindowExposed(&view));
959
QVERIFY(delegate = findItem<QQuickItem>(view.contentItem(), "delegate", 1));
961
QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
965
void tst_qquickvisualdatamodel::packagesDestroyed()
968
for (int i=0; i<30; i++)
969
list << (QLatin1String("item ") + i);
970
SingleRoleModel model(list);
973
view.rootContext()->setContextProperty("testModel", &model);
975
QString filename(testFile("packageView.qml"));
976
view.setSource(QUrl::fromLocalFile(filename));
978
qApp->processEvents();
980
QQuickListView *leftview = findItem<QQuickListView>(view.rootObject(), "leftList");
981
QTRY_VERIFY(leftview != 0);
983
QQuickListView *rightview = findItem<QQuickListView>(view.rootObject(), "rightList");
984
QTRY_VERIFY(rightview != 0);
986
QQuickItem *leftContent = leftview->contentItem();
987
QTRY_VERIFY(leftContent != 0);
989
QQuickItem *rightContent = rightview->contentItem();
990
QTRY_VERIFY(rightContent != 0);
992
QCOMPARE(leftview->currentIndex(), 0);
993
QCOMPARE(rightview->currentIndex(), 0);
995
rightview->setCurrentIndex(20);
996
QTRY_COMPARE(rightview->contentY(), 100.0);
998
QQmlGuard<QQuickItem> left;
999
QQmlGuard<QQuickItem> right;
1001
QVERIFY(findItem<QQuickItem>(leftContent, "wrapper", 1));
1002
QVERIFY(findItem<QQuickItem>(rightContent, "wrapper", 1));
1004
QVERIFY(left = findItem<QQuickItem>(leftContent, "wrapper", 19));
1005
QVERIFY(right = findItem<QQuickItem>(rightContent, "wrapper", 19));
1007
rightview->setCurrentIndex(0);
1008
QCOMPARE(rightview->currentIndex(), 0);
1010
QTRY_COMPARE(rightview->contentY(), 0.0);
1011
QCoreApplication::sendPostedEvents();
1016
QVERIFY(left = findItem<QQuickItem>(leftContent, "wrapper", 1));
1017
QVERIFY(right = findItem<QQuickItem>(rightContent, "wrapper", 1));
1019
rightview->setCurrentIndex(20);
1020
QTRY_COMPARE(rightview->contentY(), 100.0);
1025
QVERIFY(findItem<QQuickItem>(leftContent, "wrapper", 19));
1026
QVERIFY(findItem<QQuickItem>(rightContent, "wrapper", 19));
1028
leftview->setCurrentIndex(20);
1029
QTRY_COMPARE(leftview->contentY(), 100.0);
1035
void tst_qquickvisualdatamodel::qaimRowsMoved()
1037
// Test parameters passed in QAIM::rowsMoved() signal are converted correctly
1038
// when translated to (from, to count) semantics.
1039
QFETCH(int, sourceFirst);
1040
QFETCH(int, sourceLast);
1041
QFETCH(int, destinationChild);
1042
QFETCH(int, expectFrom);
1043
QFETCH(int, expectTo);
1044
QFETCH(int, expectCount);
1047
QQmlComponent c(&engine, testFileUrl("visualdatamodel.qml"));
1050
for (int i=0; i<30; i++)
1051
list << (QLatin1String("item ") + i);
1052
SingleRoleModel model(list);
1053
engine.rootContext()->setContextProperty("myModel", &model);
1055
QQuickVisualDataModel *obj = qobject_cast<QQuickVisualDataModel*>(c.create());
1058
QSignalSpy spy(obj, SIGNAL(modelUpdated(QQuickChangeSet,bool)));
1059
model.emitMove(sourceFirst, sourceLast, destinationChild);
1060
QCOMPARE(spy.count(), 1);
1062
QCOMPARE(spy[0].count(), 2);
1063
QQuickChangeSet changeSet = spy[0][0].value<QQuickChangeSet>();
1064
QCOMPARE(changeSet.removes().count(), 1);
1065
QCOMPARE(changeSet.removes().at(0).index, expectFrom);
1066
QCOMPARE(changeSet.removes().at(0).count, expectCount);
1067
QCOMPARE(changeSet.inserts().count(), 1);
1068
QCOMPARE(changeSet.inserts().at(0).index, expectTo);
1069
QCOMPARE(changeSet.inserts().at(0).count, expectCount);
1070
QCOMPARE(changeSet.removes().at(0).moveId, changeSet.inserts().at(0).moveId);
1071
QCOMPARE(spy[0][1].toBool(), false);
1076
void tst_qquickvisualdatamodel::qaimRowsMoved_data()
1078
QTest::addColumn<int>("sourceFirst");
1079
QTest::addColumn<int>("sourceLast");
1080
QTest::addColumn<int>("destinationChild");
1081
QTest::addColumn<int>("expectFrom");
1082
QTest::addColumn<int>("expectTo");
1083
QTest::addColumn<int>("expectCount");
1085
QTest::newRow("move 1 forward")
1089
QTest::newRow("move 1 backwards")
1093
QTest::newRow("move multiple forwards")
1097
QTest::newRow("move multiple forwards, with same to")
1101
QTest::newRow("move multiple backwards")
1106
void tst_qquickvisualdatamodel::subtreeRowsMoved()
1108
SingleRoleModel model(QStringList() << "one" << "two" << "three" << "four");
1109
model.insert(model.index(0, 0), 0, QStringList() << "a" << "b" << "c" << "d" << "e");
1110
model.insert(model.index(2, 0), 0, QStringList() << "A" << "B" << "C");
1113
engine.rootContext()->setContextProperty("myModel", &model);
1115
QQmlComponent component(&engine, testFileUrl("visualdatamodel.qml"));
1117
QScopedPointer<QObject> object(component.create());
1118
QQuickVisualDataModel *vdm = qobject_cast<QQuickVisualDataModel*>(object.data());
1121
QSignalSpy spy(vdm, SIGNAL(modelUpdated(QQuickChangeSet,bool)));
1122
QQuickChangeSet changeSet;
1124
QCOMPARE(vdm->count(), 4);
1126
// Move items from the current root index to a sub tree.
1127
model.move(QModelIndex(), 1, model.index(0, 0), 3, 2);
1128
QCOMPARE(vdm->count(), 2);
1129
QCOMPARE(spy.count(), 1);
1130
changeSet = spy.last().at(0).value<QQuickChangeSet>();
1131
QCOMPARE(changeSet.removes().count(), 1);
1132
QCOMPARE(changeSet.removes().at(0).index, 1);
1133
QCOMPARE(changeSet.removes().at(0).count, 2);
1134
QCOMPARE(changeSet.inserts().count(), 0);
1136
// Move items from a sub tree to the current root index.
1137
model.move(model.index(0, 0), 4, QModelIndex(), 2, 1);
1138
QCOMPARE(vdm->count(), 3);
1139
QCOMPARE(spy.count(), 2);
1140
changeSet = spy.last().at(0).value<QQuickChangeSet>();
1141
QCOMPARE(changeSet.removes().count(), 0);
1142
QCOMPARE(changeSet.inserts().count(), 1);
1143
QCOMPARE(changeSet.inserts().at(0).index, 2);
1144
QCOMPARE(changeSet.inserts().at(0).count, 1);
1146
vdm->setRootIndex(QVariant::fromValue(model.index(2, 0)));
1147
QCOMPARE(vdm->rootIndex().value<QModelIndex>(), model.index(2, 0));
1148
QCOMPARE(vdm->count(), 3);
1149
QCOMPARE(spy.count(), 4);
1150
changeSet = spy.at(2).at(0).value<QQuickChangeSet>();
1151
QCOMPARE(changeSet.removes().count(), 1);
1152
QCOMPARE(changeSet.removes().at(0).index, 0);
1153
QCOMPARE(changeSet.removes().at(0).count, 3);
1154
changeSet = spy.last().at(0).value<QQuickChangeSet>();
1155
QCOMPARE(changeSet.inserts().count(), 1);
1156
QCOMPARE(changeSet.inserts().at(0).index, 0);
1157
QCOMPARE(changeSet.inserts().at(0).count, 3);
1159
// Move the current root index without changing its parent.
1160
model.move(QModelIndex(), 2, QModelIndex(), 0, 1);
1161
QCOMPARE(vdm->rootIndex().value<QModelIndex>(), model.index(0, 0));
1162
QCOMPARE(vdm->count(), 3);
1163
QCOMPARE(spy.count(), 4);
1165
// Move the current root index, changing its parent.
1166
model.move(QModelIndex(), 0, model.index(1, 0), 0, 1);
1167
QCOMPARE(vdm->rootIndex().value<QModelIndex>(), model.index(0, 0, model.index(0, 0)));
1168
QCOMPARE(vdm->count(), 3);
1169
QCOMPARE(spy.count(), 4);
1171
model.insert(model.index(0, 0), 0, QStringList() << "new1" << "new2");
1172
QCOMPARE(vdm->rootIndex().value<QModelIndex>(), model.index(2, 0, model.index(0, 0)));
1173
QCOMPARE(vdm->count(), 3);
1174
QCOMPARE(spy.count(), 4);
1176
model.remove(model.index(0, 0), 1, 1);
1177
QCOMPARE(vdm->rootIndex().value<QModelIndex>(), model.index(1, 0, model.index(0, 0)));
1178
QCOMPARE(vdm->count(), 3);
1179
QCOMPARE(spy.count(), 4);
1181
model.remove(model.index(0, 0), 1, 1);
1182
QCOMPARE(vdm->rootIndex().value<QModelIndex>(), QModelIndex());
1183
QCOMPARE(vdm->count(), 0);
1184
QCOMPARE(spy.count(), 5);
1185
changeSet = spy.last().at(0).value<QQuickChangeSet>();
1186
QCOMPARE(changeSet.removes().count(), 1);
1187
QCOMPARE(changeSet.removes().at(0).index, 0);
1188
QCOMPARE(changeSet.removes().at(0).count, 3);
1189
QCOMPARE(changeSet.inserts().count(), 0);
1191
vdm->setRootIndex(QVariant::fromValue(QModelIndex()));
1192
QCOMPARE(vdm->rootIndex().value<QModelIndex>(), QModelIndex());
1193
QCOMPARE(vdm->count(), 2);
1194
QCOMPARE(spy.count(), 6);
1195
changeSet = spy.last().at(0).value<QQuickChangeSet>();
1196
QCOMPARE(changeSet.removes().count(), 0);
1197
QCOMPARE(changeSet.inserts().count(), 1);
1198
QCOMPARE(changeSet.inserts().at(0).index, 0);
1199
QCOMPARE(changeSet.inserts().at(0).count, 2);
1202
void tst_qquickvisualdatamodel::watchedRoles()
1205
for (int i = 0; i < 30; i++)
1206
model.addItem("Item" + QString::number(i), "");
1209
engine.rootContext()->setContextProperty("myModel", &model);
1211
QQmlComponent component(&engine, testFileUrl("visualdatamodel.qml"));
1213
QScopedPointer<QObject> object(component.create());
1214
QQuickVisualDataModel *vdm = qobject_cast<QQuickVisualDataModel*>(object.data());
1217
// VisualDataModel doesn't initialize model data until the first item is requested.
1218
QQuickItem *item = vdm->item(0);
1221
QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); // Ensure released items are deleted before test exits.
1223
QSignalSpy spy(vdm, SIGNAL(modelUpdated(QQuickChangeSet,bool)));
1224
QQuickChangeSet changeSet;
1226
QCOMPARE(vdm->count(), 30);
1228
emit model.dataChanged(model.index(0), model.index(4));
1229
QCOMPARE(spy.count(), 0);
1231
emit model.dataChanged(model.index(0), model.index(4), QVector<int>() << QaimModel::Name);
1232
QCOMPARE(spy.count(), 0);
1234
emit model.dataChanged(model.index(0), model.index(4), QVector<int>() << QaimModel::Number);
1235
QCOMPARE(spy.count(), 0);
1237
vdm->setWatchedRoles(QList<QByteArray>() << "name" << "dummy");
1239
emit model.dataChanged(model.index(0), model.index(4));
1240
QCOMPARE(spy.count(), 1);
1241
changeSet = spy.last().at(0).value<QQuickChangeSet>();
1242
QCOMPARE(changeSet.changes().at(0).index, 0);
1243
QCOMPARE(changeSet.changes().at(0).count, 5);
1245
emit model.dataChanged(model.index(1), model.index(6), QVector<int>() << QaimModel::Name);
1246
QCOMPARE(spy.count(), 2);
1247
changeSet = spy.last().at(0).value<QQuickChangeSet>();
1248
QCOMPARE(changeSet.changes().at(0).index, 1);
1249
QCOMPARE(changeSet.changes().at(0).count, 6);
1251
emit model.dataChanged(model.index(8), model.index(8), QVector<int>() << QaimModel::Number);
1252
QCOMPARE(spy.count(), 2);
1254
vdm->setWatchedRoles(QList<QByteArray>() << "number" << "dummy");
1256
emit model.dataChanged(model.index(0), model.index(4));
1257
QCOMPARE(spy.count(), 3);
1258
changeSet = spy.last().at(0).value<QQuickChangeSet>();
1259
QCOMPARE(changeSet.changes().at(0).index, 0);
1260
QCOMPARE(changeSet.changes().at(0).count, 5);
1262
emit model.dataChanged(model.index(1), model.index(6), QVector<int>() << QaimModel::Name);
1263
QCOMPARE(spy.count(), 3);
1265
emit model.dataChanged(model.index(8), model.index(8), QVector<int>() << QaimModel::Number);
1266
QCOMPARE(spy.count(), 4);
1267
changeSet = spy.last().at(0).value<QQuickChangeSet>();
1268
QCOMPARE(changeSet.changes().at(0).index, 8);
1269
QCOMPARE(changeSet.changes().at(0).count, 1);
1271
vdm->setWatchedRoles(QList<QByteArray>() << "number" << "name");
1273
emit model.dataChanged(model.index(0), model.index(4));
1274
QCOMPARE(spy.count(), 5);
1275
changeSet = spy.last().at(0).value<QQuickChangeSet>();
1276
QCOMPARE(changeSet.changes().at(0).index, 0);
1277
QCOMPARE(changeSet.changes().at(0).count, 5);
1279
emit model.dataChanged(model.index(1), model.index(6), QVector<int>() << QaimModel::Name);
1280
QCOMPARE(spy.count(), 6);
1281
changeSet = spy.last().at(0).value<QQuickChangeSet>();
1282
QCOMPARE(changeSet.changes().at(0).index, 1);
1283
QCOMPARE(changeSet.changes().at(0).count, 6);
1285
emit model.dataChanged(model.index(8), model.index(8), QVector<int>() << QaimModel::Number);
1286
QCOMPARE(spy.count(), 7);
1287
changeSet = spy.last().at(0).value<QQuickChangeSet>();
1288
QCOMPARE(changeSet.changes().at(0).index, 8);
1289
QCOMPARE(changeSet.changes().at(0).count, 1);
1292
void tst_qquickvisualdatamodel::hasModelChildren()
1294
SingleRoleModel model(QStringList() << "one" << "two" << "three" << "four");
1295
model.insert(model.index(0, 0), 0, QStringList() << "a" << "b" << "c" << "d" << "e");
1296
model.insert(model.index(2, 0), 0, QStringList() << "A" << "B" << "C");
1299
engine.rootContext()->setContextProperty("myModel", &model);
1301
QQmlComponent component(&engine, testFileUrl("visualdatamodel.qml"));
1303
QScopedPointer<QObject> object(component.create());
1304
QQuickVisualDataModel *vdm = qobject_cast<QQuickVisualDataModel*>(object.data());
1307
QCOMPARE(vdm->count(), 4);
1309
QQuickItem *item = 0;
1311
item = vdm->item(0);
1313
QCOMPARE(item->property("modelChildren").toBool(), true);
1316
item = vdm->item(1);
1318
QCOMPARE(item->property("modelChildren").toBool(), false);
1321
item = vdm->item(2);
1323
QCOMPARE(item->property("modelChildren").toBool(), true);
1326
item = vdm->item(3);
1328
QCOMPARE(item->property("modelChildren").toBool(), false);
1330
QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); // Ensure released items are deleted before test exits.
1332
QCOMPARE(vdm->stringValue(0, QLatin1String("hasModelChildren")), QVariant(true).toString());
1333
QCOMPARE(vdm->stringValue(1, QLatin1String("hasModelChildren")), QVariant(false).toString());
1334
QCOMPARE(vdm->stringValue(2, QLatin1String("hasModelChildren")), QVariant(true).toString());
1335
QCOMPARE(vdm->stringValue(3, QLatin1String("hasModelChildren")), QVariant(false).toString());
1337
QCOMPARE(evaluate<bool>(vdm, "items.get(0).model.hasModelChildren"), true);
1338
QCOMPARE(evaluate<bool>(vdm, "items.get(1).model.hasModelChildren"), false);
1339
QCOMPARE(evaluate<bool>(vdm, "items.get(2).model.hasModelChildren"), true);
1340
QCOMPARE(evaluate<bool>(vdm, "items.get(3).model.hasModelChildren"), false);
1343
void tst_qquickvisualdatamodel::setValue()
1345
QStandardItemModel model;
1346
initStandardTreeModel(&model);
1349
engine.rootContext()->setContextProperty("myModel", &model);
1351
QQmlComponent component(&engine, testFileUrl("visualdatamodel.qml"));
1353
QScopedPointer<QObject> object(component.create());
1354
QQuickVisualDataModel *vdm = qobject_cast<QQuickVisualDataModel*>(object.data());
1357
QCOMPARE(vdm->count(), 3);
1359
QQuickItem *item = 0;
1361
item = vdm->item(0);
1363
QCOMPARE(evaluate<QString>(item, "display"), QString("Row 1 Item"));
1364
evaluate<void>(item, "display = 'Changed Item 1'");
1365
QCOMPARE(evaluate<QString>(item, "display"), QString("Changed Item 1"));
1366
QCOMPARE(model.item(0)->text(), QString("Changed Item 1"));
1370
QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); // Ensure released items are deleted before test exits.
1373
void tst_qquickvisualdatamodel::remove_data()
1375
QTest::addColumn<QUrl>("source");
1376
QTest::addColumn<QString>("package delegate");
1378
QTest::newRow("item delegate")
1379
<< testFileUrl("groups.qml")
1381
QTest::newRow("package")
1382
<< testFileUrl("groups-package.qml")
1383
<< QString("package.");
1386
void tst_qquickvisualdatamodel::remove()
1390
SingleRoleModel model(QStringList()
1404
QQmlContext *ctxt = view.rootContext();
1405
ctxt->setContextProperty("myModel", &model);
1407
view.setSource(testFileUrl("groups.qml"));
1409
QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
1410
QVERIFY(listview != 0);
1412
QQuickItem *contentItem = listview->contentItem();
1413
QVERIFY(contentItem != 0);
1415
QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel *>(qvariant_cast<QObject *>(listview->model()));
1416
QVERIFY(visualModel);
1419
QCOMPARE(listview->count(), 12);
1420
QCOMPARE(visualModel->items()->count(), 12);
1421
static const int mIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1422
static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1424
for (int i = 0; i < lengthOf(mIndex); ++i) {
1425
QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1427
QCOMPARE(delegate->property("test1").toString(), model.at(mIndex[i]));
1428
QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
1429
QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
1432
evaluate<void>(visualModel, "items.remove(2)");
1433
QCOMPARE(listview->count(), 11);
1434
QCOMPARE(visualModel->items()->count(), 11);
1435
static const int mIndex[] = { 0, 1, 3, 4, 5, 6, 7, 8, 9,10,11 };
1436
static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10 };
1438
for (int i = 0; i < lengthOf(mIndex); ++i) {
1439
QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1441
QCOMPARE(delegate->property("test1").toString(), model.at(mIndex[i]));
1442
QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
1443
QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
1446
evaluate<void>(visualModel, "items.remove(1, 4)");
1447
QCOMPARE(listview->count(), 7);
1448
QCOMPARE(visualModel->items()->count(), 7);
1449
static const int mIndex[] = { 0, 6, 7, 8, 9,10,11 };
1450
static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6 };
1452
for (int i = 0; i < lengthOf(mIndex); ++i) {
1453
QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1455
QCOMPARE(delegate->property("test1").toString(), model.at(mIndex[i]));
1456
QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
1457
QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
1460
QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: remove: index out of range");
1461
evaluate<void>(visualModel, "items.remove(-8, 4)");
1462
QCOMPARE(listview->count(), 7);
1463
QCOMPARE(visualModel->items()->count(), 7);
1465
QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: remove: index out of range");
1466
evaluate<void>(visualModel, "items.remove(12, 2)");
1467
QCOMPARE(listview->count(), 7);
1468
QCOMPARE(visualModel->items()->count(), 7);
1470
QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: remove: invalid count");
1471
evaluate<void>(visualModel, "items.remove(5, 3)");
1472
QCOMPARE(listview->count(), 7);
1473
QCOMPARE(visualModel->items()->count(), 7);
1475
QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: remove: invalid count");
1476
evaluate<void>(visualModel, "items.remove(5, -2)");
1477
QCOMPARE(listview->count(), 7);
1478
QCOMPARE(visualModel->items()->count(), 7);
1482
void tst_qquickvisualdatamodel::move_data()
1484
QTest::addColumn<QUrl>("source");
1485
QTest::addColumn<QString>("package delegate");
1487
QTest::newRow("item delegate")
1488
<< testFileUrl("groups.qml")
1490
QTest::newRow("package")
1491
<< testFileUrl("groups-package.qml")
1492
<< QString("package.");
1495
void tst_qquickvisualdatamodel::move()
1499
SingleRoleModel model(QStringList()
1513
QQmlContext *ctxt = view.rootContext();
1514
ctxt->setContextProperty("myModel", &model);
1516
view.setSource(testFileUrl("groups.qml"));
1518
QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
1519
QVERIFY(listview != 0);
1521
QQuickItem *contentItem = listview->contentItem();
1522
QVERIFY(contentItem != 0);
1524
QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel *>(qvariant_cast<QObject *>(listview->model()));
1525
QVERIFY(visualModel);
1528
QCOMPARE(listview->count(), 12);
1529
QCOMPARE(visualModel->items()->count(), 12);
1530
static const int mIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1531
static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1533
for (int i = 0; i < lengthOf(mIndex); ++i) {
1534
QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1536
QCOMPARE(delegate->property("test1").toString(), model.at(mIndex[i]));
1537
QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
1538
QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
1541
evaluate<void>(visualModel, "items.move(2, 4)");
1542
QCOMPARE(listview->count(), 12);
1543
QCOMPARE(visualModel->items()->count(), 12);
1544
static const int mIndex[] = { 0, 1, 3, 4, 2, 5, 6, 7, 8, 9,10,11 };
1545
static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1547
for (int i = 0; i < lengthOf(mIndex); ++i) {
1548
QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1550
QCOMPARE(delegate->property("test1").toString(), model.at(mIndex[i]));
1551
QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
1552
QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
1555
evaluate<void>(visualModel, "items.move(4, 2)");
1556
QCOMPARE(listview->count(), 12);
1557
QCOMPARE(visualModel->items()->count(), 12);
1558
static const int mIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1559
static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1561
for (int i = 0; i < lengthOf(mIndex); ++i) {
1562
QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1564
QCOMPARE(delegate->property("test1").toString(), model.at(mIndex[i]));
1565
QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
1566
QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
1569
evaluate<void>(visualModel, "items.move(8, 0, 4)");
1570
QCOMPARE(listview->count(), 12);
1571
QCOMPARE(visualModel->items()->count(), 12);
1572
static const int mIndex[] = { 8, 9,10,11, 0, 1, 2, 3, 4, 5, 6, 7 };
1573
static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1575
for (int i = 0; i < lengthOf(mIndex); ++i) {
1576
QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1578
QCOMPARE(delegate->property("test1").toString(), model.at(mIndex[i]));
1579
QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
1580
QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
1583
evaluate<void>(visualModel, "items.move(3, 4, 5)");
1584
QCOMPARE(listview->count(), 12);
1585
QCOMPARE(visualModel->items()->count(), 12);
1586
static const int mIndex[] = { 8, 9,10,4, 11, 0, 1, 2, 3, 5, 6, 7 };
1587
static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1589
for (int i = 0; i < lengthOf(mIndex); ++i) {
1590
QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1592
QCOMPARE(delegate->property("test1").toString(), model.at(mIndex[i]));
1593
QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
1594
QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
1597
QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: invalid count");
1598
evaluate<void>(visualModel, "items.move(5, 2, -2)");
1599
QCOMPARE(listview->count(), 12);
1600
QCOMPARE(visualModel->items()->count(), 12);
1602
QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: from index out of range");
1603
evaluate<void>(visualModel, "items.move(-6, 2, 1)");
1604
QCOMPARE(listview->count(), 12);
1605
QCOMPARE(visualModel->items()->count(), 12);
1607
QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: from index out of range");
1608
evaluate<void>(visualModel, "items.move(15, 2, 1)");
1609
QCOMPARE(listview->count(), 12);
1610
QCOMPARE(visualModel->items()->count(), 12);
1612
QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: from index out of range");
1613
evaluate<void>(visualModel, "items.move(11, 1, 3)");
1614
QCOMPARE(listview->count(), 12);
1615
QCOMPARE(visualModel->items()->count(), 12);
1617
QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: to index out of range");
1618
evaluate<void>(visualModel, "items.move(2, -5, 1)");
1619
QCOMPARE(listview->count(), 12);
1620
QCOMPARE(visualModel->items()->count(), 12);
1622
QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: to index out of range");
1623
evaluate<void>(visualModel, "items.move(2, 14, 1)");
1624
QCOMPARE(listview->count(), 12);
1625
QCOMPARE(visualModel->items()->count(), 12);
1627
QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: to index out of range");
1628
evaluate<void>(visualModel, "items.move(2, 11, 4)");
1629
QCOMPARE(listview->count(), 12);
1630
QCOMPARE(visualModel->items()->count(), 12);
1634
void tst_qquickvisualdatamodel::groups_data()
1636
QTest::addColumn<QUrl>("source");
1637
QTest::addColumn<QString>("part");
1639
QTest::newRow("item delegate")
1640
<< testFileUrl("groups.qml")
1642
QTest::newRow("package")
1643
<< testFileUrl("groups-package.qml")
1644
<< QString("visualModel.parts.package.");
1647
template <int N> void tst_qquickvisualdatamodel::groups_verify(
1648
const SingleRoleModel &model,
1649
QQuickItem *contentItem,
1650
const int (&mIndex)[N],
1651
const int (&iIndex)[N],
1652
const int (&vIndex)[N],
1653
const int (&sIndex)[N],
1654
const bool (&vMember)[N],
1655
const bool (&sMember)[N])
1658
for (int i = 0; i < N; ++i) {
1659
QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1661
QCOMPARE(evaluate<QString>(delegate, "test1"), model.at(mIndex[i]));
1662
QCOMPARE(evaluate<int>(delegate, "test2") , mIndex[i]);
1663
QCOMPARE(evaluate<int>(delegate, "test3") , iIndex[i]);
1664
QCOMPARE(evaluate<bool>(delegate, "test4"), true);
1665
QCOMPARE(evaluate<int>(delegate, "test5") , vIndex[i]);
1666
QCOMPARE(evaluate<bool>(delegate, "test6"), vMember[i]);
1667
QCOMPARE(evaluate<int>(delegate, "test7") , sIndex[i]);
1668
QCOMPARE(evaluate<bool>(delegate, "test8"), sMember[i]);
1669
QCOMPARE(evaluate<QStringList>(delegate, "test9").contains("items") , bool(true));
1670
QCOMPARE(evaluate<QStringList>(delegate, "test9").contains("visible") , bool(vMember[i]));
1671
QCOMPARE(evaluate<QStringList>(delegate, "test9").contains("selected"), bool(sMember[i]));
1676
#define VERIFY_GROUPS \
1677
groups_verify(model, contentItem, mIndex, iIndex, vIndex, sIndex, vMember, sMember); \
1681
void tst_qquickvisualdatamodel::groups()
1683
QFETCH(QUrl, source);
1684
QFETCH(QString, part);
1688
SingleRoleModel model(QStringList()
1702
QQmlContext *ctxt = view.rootContext();
1703
ctxt->setContextProperty("myModel", &model);
1705
view.setSource(source);
1707
QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
1708
QVERIFY(listview != 0);
1710
QQuickItem *contentItem = listview->contentItem();
1711
QVERIFY(contentItem != 0);
1713
QQuickVisualDataModel *visualModel = listview->findChild<QQuickVisualDataModel *>("visualModel");
1714
QVERIFY(visualModel);
1716
QQuickVisualDataGroup *visibleItems = listview->findChild<QQuickVisualDataGroup *>("visibleItems");
1717
QVERIFY(visibleItems);
1719
QQuickVisualDataGroup *selectedItems = listview->findChild<QQuickVisualDataGroup *>("selectedItems");
1720
QVERIFY(selectedItems);
1722
const bool f = false;
1723
const bool t = true;
1726
QCOMPARE(listview->count(), 12);
1727
QCOMPARE(visualModel->items()->count(), 12);
1728
QCOMPARE(visibleItems->count(), 12);
1729
QCOMPARE(selectedItems->count(), 0);
1730
static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1731
static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1732
static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1733
static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
1734
static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1735
static const bool sMember[] = { f, f, f, f, f, f, f, f, f, f, f, f };
1738
evaluate<void>(visualModel, "items.addGroups(8, \"selected\")");
1739
QCOMPARE(listview->count(), 12);
1740
QCOMPARE(visualModel->items()->count(), 12);
1741
QCOMPARE(visibleItems->count(), 12);
1742
QCOMPARE(selectedItems->count(), 1);
1743
static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1744
static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1745
static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1746
static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
1747
static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 };
1748
static const bool sMember[] = { f, f, f, f, f, f, f, f, t, f, f, f };
1751
evaluate<void>(visualModel, "items.addGroups(6, 4, [\"visible\", \"selected\"])");
1752
QCOMPARE(listview->count(), 12);
1753
QCOMPARE(visualModel->items()->count(), 12);
1754
QCOMPARE(visibleItems->count(), 12);
1755
QCOMPARE(selectedItems->count(), 4);
1756
static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1757
static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1758
static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1759
static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
1760
static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 4 };
1761
static const bool sMember[] = { f, f, f, f, f, f, t, t, t, t, f, f };
1764
evaluate<void>(visualModel, "items.setGroups(2, [\"items\", \"selected\"])");
1765
QCOMPARE(listview->count(), 12);
1766
QCOMPARE(visualModel->items()->count(), 12);
1767
QCOMPARE(visibleItems->count(), 11);
1768
QCOMPARE(selectedItems->count(), 5);
1769
static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1770
static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1771
static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9,10 };
1772
static const bool vMember[] = { t, t, f, t, t, t, t, t, t, t, t, t };
1773
static const int sIndex [] = { 0, 0, 0, 1, 1, 1, 1, 2, 3, 4, 5, 5 };
1774
static const bool sMember[] = { f, f, t, f, f, f, t, t, t, t, f, f };
1777
evaluate<void>(selectedItems, "setGroups(0, 3, \"items\")");
1778
QCOMPARE(listview->count(), 12);
1779
QCOMPARE(visualModel->items()->count(), 12);
1780
QCOMPARE(visibleItems->count(), 9);
1781
QCOMPARE(selectedItems->count(), 2);
1782
static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1783
static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1784
static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 5, 5, 6, 7, 8 };
1785
static const bool vMember[] = { t, t, f, t, t, t, f, f, t, t, t, t };
1786
static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 };
1787
static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f };
1790
QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: addGroups: invalid count");
1791
evaluate<void>(visualModel, "items.addGroups(11, -4, \"items\")");
1792
QCOMPARE(listview->count(), 12);
1793
QCOMPARE(visualModel->items()->count(), 12);
1794
QCOMPARE(visibleItems->count(), 9);
1795
QCOMPARE(selectedItems->count(), 2);
1797
QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: addGroups: index out of range");
1798
evaluate<void>(visualModel, "items.addGroups(-1, 3, \"items\")");
1799
QCOMPARE(listview->count(), 12);
1800
QCOMPARE(visualModel->items()->count(), 12);
1801
QCOMPARE(visibleItems->count(), 9);
1802
QCOMPARE(selectedItems->count(), 2);
1804
QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: addGroups: index out of range");
1805
evaluate<void>(visualModel, "items.addGroups(14, 3, \"items\")");
1806
QCOMPARE(listview->count(), 12);
1807
QCOMPARE(visualModel->items()->count(), 12);
1808
QCOMPARE(visibleItems->count(), 9);
1809
QCOMPARE(selectedItems->count(), 2);
1811
QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: addGroups: invalid count");
1812
evaluate<void>(visualModel, "items.addGroups(11, 5, \"items\")");
1813
QCOMPARE(listview->count(), 12);
1814
QCOMPARE(visualModel->items()->count(), 12);
1815
QCOMPARE(visibleItems->count(), 9);
1816
QCOMPARE(selectedItems->count(), 2);
1818
QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: setGroups: invalid count");
1819
evaluate<void>(visualModel, "items.setGroups(11, -4, \"items\")");
1820
QCOMPARE(listview->count(), 12);
1821
QCOMPARE(visualModel->items()->count(), 12);
1822
QCOMPARE(visibleItems->count(), 9);
1823
QCOMPARE(selectedItems->count(), 2);
1825
QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: setGroups: index out of range");
1826
evaluate<void>(visualModel, "items.setGroups(-1, 3, \"items\")");
1827
QCOMPARE(listview->count(), 12);
1828
QCOMPARE(visualModel->items()->count(), 12);
1829
QCOMPARE(visibleItems->count(), 9);
1830
QCOMPARE(selectedItems->count(), 2);
1832
QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: setGroups: index out of range");
1833
evaluate<void>(visualModel, "items.setGroups(14, 3, \"items\")");
1834
QCOMPARE(listview->count(), 12);
1835
QCOMPARE(visualModel->items()->count(), 12);
1836
QCOMPARE(visibleItems->count(), 9);
1837
QCOMPARE(selectedItems->count(), 2);
1839
QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: setGroups: invalid count");
1840
evaluate<void>(visualModel, "items.setGroups(11, 5, \"items\")");
1841
QCOMPARE(listview->count(), 12);
1842
QCOMPARE(visualModel->items()->count(), 12);
1843
QCOMPARE(visibleItems->count(), 9);
1844
QCOMPARE(selectedItems->count(), 2);
1846
QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: removeGroups: invalid count");
1847
evaluate<void>(visualModel, "items.removeGroups(11, -4, \"items\")");
1848
QCOMPARE(listview->count(), 12);
1849
QCOMPARE(visualModel->items()->count(), 12);
1851
QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: removeGroups: index out of range");
1852
evaluate<void>(visualModel, "items.removeGroups(-1, 3, \"items\")");
1853
QCOMPARE(listview->count(), 12);
1854
QCOMPARE(visualModel->items()->count(), 12);
1855
QCOMPARE(visibleItems->count(), 9);
1856
QCOMPARE(selectedItems->count(), 2);
1858
QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: removeGroups: index out of range");
1859
evaluate<void>(visualModel, "items.removeGroups(14, 3, \"items\")");
1860
QCOMPARE(listview->count(), 12);
1861
QCOMPARE(visualModel->items()->count(), 12);
1862
QCOMPARE(visibleItems->count(), 9);
1863
QCOMPARE(selectedItems->count(), 2);
1865
QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: removeGroups: invalid count");
1866
evaluate<void>(visualModel, "items.removeGroups(11, 5, \"items\")");
1867
QCOMPARE(listview->count(), 12);
1868
QCOMPARE(visualModel->items()->count(), 12);
1869
QCOMPARE(visibleItems->count(), 9);
1870
QCOMPARE(selectedItems->count(), 2);
1872
evaluate<void>(visualModel, part + "filterOnGroup = \"visible\"");
1873
QCOMPARE(listview->count(), 9);
1874
QCOMPARE(visualModel->items()->count(), 12);
1875
QCOMPARE(visibleItems->count(), 9);
1876
QCOMPARE(selectedItems->count(), 2);
1877
QCOMPARE(evaluate<QString>(visualModel, part + "filterOnGroup"), QString("visible"));
1879
evaluate<void>(visualModel, part + "filterOnGroup = \"selected\"");
1880
QCOMPARE(listview->count(), 2);
1881
QCOMPARE(visualModel->items()->count(), 12);
1882
QCOMPARE(visibleItems->count(), 9);
1883
QCOMPARE(selectedItems->count(), 2);
1884
QCOMPARE(evaluate<QString>(visualModel, part + "filterOnGroup"), QString("selected"));
1886
evaluate<void>(visualModel, part + "filterOnGroup = undefined");
1887
QCOMPARE(listview->count(), 12);
1888
QCOMPARE(visualModel->items()->count(), 12);
1889
QCOMPARE(visibleItems->count(), 9);
1890
QCOMPARE(selectedItems->count(), 2);
1891
QCOMPARE(evaluate<QString>(visualModel, part + "filterOnGroup"), QString("items"));
1893
QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", 5);
1896
evaluate<void>(delegate, "hide()");
1897
QCOMPARE(listview->count(), 12);
1898
QCOMPARE(visualModel->items()->count(), 12);
1899
QCOMPARE(visibleItems->count(), 8);
1900
QCOMPARE(selectedItems->count(), 2);
1901
static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1902
static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1903
static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 6, 7 };
1904
static const bool vMember[] = { t, t, f, t, t, f, f, f, t, t, t, t };
1905
static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 };
1906
static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f };
1909
QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", 5);
1912
evaluate<void>(delegate, "select()");
1913
QCOMPARE(listview->count(), 12);
1914
QCOMPARE(visualModel->items()->count(), 12);
1915
QCOMPARE(visibleItems->count(), 8);
1916
QCOMPARE(selectedItems->count(), 3);
1917
static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1918
static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1919
static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 6, 7 };
1920
static const bool vMember[] = { t, t, f, t, t, f, f, f, t, t, t, t };
1921
static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 3, 3 };
1922
static const bool sMember[] = { f, f, f, f, f, t, f, f, t, t, f, f };
1925
evaluate<void>(visualModel, "items.move(2, 6, 3)");
1926
QCOMPARE(listview->count(), 12);
1927
QCOMPARE(visualModel->items()->count(), 12);
1928
QCOMPARE(visibleItems->count(), 8);
1929
QCOMPARE(selectedItems->count(), 3);
1930
static const int mIndex [] = { 0, 1, 5, 6, 7, 8, 2, 3, 4, 9,10,11 };
1931
static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1932
static const int vIndex [] = { 0, 1, 2, 2, 2, 2, 3, 3, 4, 5, 6, 7 };
1933
static const bool vMember[] = { t, t, f, f, f, t, f, t, t, t, t, t };
1934
static const int sIndex [] = { 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3 };
1935
static const bool sMember[] = { f, f, t, f, f, t, f, f, f, t, f, f };
1940
template <int N> void tst_qquickvisualdatamodel::get_verify(
1941
const SingleRoleModel &model,
1942
QQuickVisualDataModel *visualModel,
1943
QQuickVisualDataGroup *visibleItems,
1944
QQuickVisualDataGroup *selectedItems,
1945
const int (&mIndex)[N],
1946
const int (&iIndex)[N],
1947
const int (&vIndex)[N],
1948
const int (&sIndex)[N],
1949
const bool (&vMember)[N],
1950
const bool (&sMember)[N])
1953
for (int i = 0; i < N; ++i) {
1954
QCOMPARE(evaluate<QString>(visualModel, QString("items.get(%1).model.name").arg(i)), model.at(mIndex[i]));
1955
QCOMPARE(evaluate<QString>(visualModel, QString("items.get(%1).model.modelData").arg(i)), model.at(mIndex[i]));
1956
QCOMPARE(evaluate<int>(visualModel, QString("items.get(%1).model.index").arg(i)), mIndex[i]);
1957
QCOMPARE(evaluate<int>(visualModel, QString("items.get(%1).itemsIndex").arg(i)), iIndex[i]);
1958
QCOMPARE(evaluate<bool>(visualModel, QString("items.get(%1).inItems").arg(i)), true);
1959
QCOMPARE(evaluate<int>(visualModel, QString("items.get(%1).visibleIndex").arg(i)), vIndex[i]);
1960
QCOMPARE(evaluate<bool>(visualModel, QString("items.get(%1).inVisible").arg(i)), vMember[i]);
1961
QCOMPARE(evaluate<int>(visualModel, QString("items.get(%1).selectedIndex").arg(i)), sIndex[i]);
1962
QCOMPARE(evaluate<bool>(visualModel, QString("items.get(%1).inSelected").arg(i)), sMember[i]);
1963
QCOMPARE(evaluate<bool>(visualModel, QString("contains(items.get(%1).groups, \"items\")").arg(i)), true);
1964
QCOMPARE(evaluate<bool>(visualModel, QString("contains(items.get(%1).groups, \"visible\")").arg(i)), vMember[i]);
1965
QCOMPARE(evaluate<bool>(visualModel, QString("contains(items.get(%1).groups, \"selected\")").arg(i)), sMember[i]);
1968
QCOMPARE(evaluate<QString>(visibleItems, QString("get(%1).model.name").arg(vIndex[i])), model.at(mIndex[i]));
1969
QCOMPARE(evaluate<QString>(visibleItems, QString("get(%1).model.modelData").arg(vIndex[i])), model.at(mIndex[i]));
1970
QCOMPARE(evaluate<int>(visibleItems, QString("get(%1).model.index").arg(vIndex[i])), mIndex[i]);
1971
QCOMPARE(evaluate<int>(visibleItems, QString("get(%1).itemsIndex").arg(vIndex[i])), iIndex[i]);
1972
QCOMPARE(evaluate<bool>(visibleItems, QString("get(%1).inItems").arg(vIndex[i])), true);
1973
QCOMPARE(evaluate<int>(visibleItems, QString("get(%1).visibleIndex").arg(vIndex[i])), vIndex[i]);
1974
QCOMPARE(evaluate<bool>(visibleItems, QString("get(%1).inVisible").arg(vIndex[i])), vMember[i]);
1975
QCOMPARE(evaluate<int>(visibleItems, QString("get(%1).selectedIndex").arg(vIndex[i])), sIndex[i]);
1976
QCOMPARE(evaluate<bool>(visibleItems, QString("get(%1).inSelected").arg(vIndex[i])), sMember[i]);
1978
QCOMPARE(evaluate<bool>(visibleItems, QString("contains(get(%1).groups, \"items\")").arg(vIndex[i])), true);
1979
QCOMPARE(evaluate<bool>(visibleItems, QString("contains(get(%1).groups, \"visible\")").arg(vIndex[i])), vMember[i]);
1980
QCOMPARE(evaluate<bool>(visibleItems, QString("contains(get(%1).groups, \"selected\")").arg(vIndex[i])), sMember[i]);
1983
QCOMPARE(evaluate<QString>(selectedItems, QString("get(%1).model.name").arg(sIndex[i])), model.at(mIndex[i]));
1984
QCOMPARE(evaluate<QString>(selectedItems, QString("get(%1).model.modelData").arg(sIndex[i])), model.at(mIndex[i]));
1985
QCOMPARE(evaluate<int>(selectedItems, QString("get(%1).model.index").arg(sIndex[i])), mIndex[i]);
1986
QCOMPARE(evaluate<int>(selectedItems, QString("get(%1).itemsIndex").arg(sIndex[i])), iIndex[i]);
1987
QCOMPARE(evaluate<bool>(selectedItems, QString("get(%1).inItems").arg(sIndex[i])), true);
1988
QCOMPARE(evaluate<int>(selectedItems, QString("get(%1).visibleIndex").arg(sIndex[i])), vIndex[i]);
1989
QCOMPARE(evaluate<bool>(selectedItems, QString("get(%1).inVisible").arg(sIndex[i])), vMember[i]);
1990
QCOMPARE(evaluate<int>(selectedItems, QString("get(%1).selectedIndex").arg(sIndex[i])), sIndex[i]);
1991
QCOMPARE(evaluate<bool>(selectedItems, QString("get(%1).inSelected").arg(sIndex[i])), sMember[i]);
1992
QCOMPARE(evaluate<bool>(selectedItems, QString("contains(get(%1).groups, \"items\")").arg(sIndex[i])), true);
1993
QCOMPARE(evaluate<bool>(selectedItems, QString("contains(get(%1).groups, \"visible\")").arg(sIndex[i])), vMember[i]);
1994
QCOMPARE(evaluate<bool>(selectedItems, QString("contains(get(%1).groups, \"selected\")").arg(sIndex[i])), sMember[i]);
2000
#define VERIFY_GET \
2001
get_verify(model, visualModel, visibleItems, selectedItems, mIndex, iIndex, vIndex, sIndex, vMember, sMember); \
2004
void tst_qquickvisualdatamodel::get()
2008
SingleRoleModel model(QStringList()
2022
QQmlContext *ctxt = view.rootContext();
2023
ctxt->setContextProperty("myModel", &model);
2025
view.setSource(testFileUrl("groups.qml"));
2027
QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
2028
QVERIFY(listview != 0);
2030
QQuickItem *contentItem = listview->contentItem();
2031
QVERIFY(contentItem != 0);
2033
QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel *>(qvariant_cast<QObject *>(listview->model()));
2034
QVERIFY(visualModel);
2036
QQuickVisualDataGroup *visibleItems = visualModel->findChild<QQuickVisualDataGroup *>("visibleItems");
2037
QVERIFY(visibleItems);
2039
QQuickVisualDataGroup *selectedItems = visualModel->findChild<QQuickVisualDataGroup *>("selectedItems");
2040
QVERIFY(selectedItems);
2042
QV8Engine *v8Engine = QQmlEnginePrivate::getV8Engine(ctxt->engine());
2045
const bool f = false;
2046
const bool t = true;
2049
QCOMPARE(listview->count(), 12);
2050
QCOMPARE(visualModel->items()->count(), 12);
2051
QCOMPARE(visibleItems->count(), 12);
2052
QCOMPARE(selectedItems->count(), 0);
2053
static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
2054
static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
2055
static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
2056
static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
2057
static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2058
static const bool sMember[] = { f, f, f, f, f, f, f, f, f, f, f, f };
2061
evaluate<void>(visualModel, "items.addGroups(8, \"selected\")");
2062
QCOMPARE(listview->count(), 12);
2063
QCOMPARE(visualModel->items()->count(), 12);
2064
QCOMPARE(visibleItems->count(), 12);
2065
QCOMPARE(selectedItems->count(), 1);
2066
static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
2067
static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
2068
static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
2069
static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
2070
static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 };
2071
static const bool sMember[] = { f, f, f, f, f, f, f, f, t, f, f, f };
2074
evaluate<void>(visualModel, "items.addGroups(6, 4, [\"visible\", \"selected\"])");
2075
QCOMPARE(listview->count(), 12);
2076
QCOMPARE(visualModel->items()->count(), 12);
2077
QCOMPARE(visibleItems->count(), 12);
2078
QCOMPARE(selectedItems->count(), 4);
2079
static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
2080
static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
2081
static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
2082
static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
2083
static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 4 };
2084
static const bool sMember[] = { f, f, f, f, f, f, t, t, t, t, f, f };
2087
evaluate<void>(visualModel, "items.setGroups(2, [\"items\", \"selected\"])");
2088
QCOMPARE(listview->count(), 12);
2089
QCOMPARE(visualModel->items()->count(), 12);
2090
QCOMPARE(visibleItems->count(), 11);
2091
QCOMPARE(selectedItems->count(), 5);
2092
static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
2093
static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
2094
static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9,10 };
2095
static const bool vMember[] = { t, t, f, t, t, t, t, t, t, t, t, t };
2096
static const int sIndex [] = { 0, 0, 0, 1, 1, 1, 1, 2, 3, 4, 5, 5 };
2097
static const bool sMember[] = { f, f, t, f, f, f, t, t, t, t, f, f };
2100
evaluate<void>(selectedItems, "setGroups(0, 3, \"items\")");
2101
QCOMPARE(listview->count(), 12);
2102
QCOMPARE(visualModel->items()->count(), 12);
2103
QCOMPARE(visibleItems->count(), 9);
2104
QCOMPARE(selectedItems->count(), 2);
2105
static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
2106
static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
2107
static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 5, 5, 6, 7, 8 };
2108
static const bool vMember[] = { t, t, f, t, t, t, f, f, t, t, t, t };
2109
static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 };
2110
static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f };
2113
evaluate<void>(visualModel, "items.get(5).inVisible = false");
2114
QCOMPARE(listview->count(), 12);
2115
QCOMPARE(visualModel->items()->count(), 12);
2116
QCOMPARE(visibleItems->count(), 8);
2117
QCOMPARE(selectedItems->count(), 2);
2118
static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
2119
static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
2120
static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 6, 7 };
2121
static const bool vMember[] = { t, t, f, t, t, f, f, f, t, t, t, t };
2122
static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 };
2123
static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f };
2126
evaluate<void>(visualModel, "items.get(5).inSelected = true");
2127
QCOMPARE(listview->count(), 12);
2128
QCOMPARE(visualModel->items()->count(), 12);
2129
QCOMPARE(visibleItems->count(), 8);
2130
QCOMPARE(selectedItems->count(), 3);
2131
static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
2132
static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
2133
static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 6, 7 };
2134
static const bool vMember[] = { t, t, f, t, t, f, f, f, t, t, t, t };
2135
static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 3, 3 };
2136
static const bool sMember[] = { f, f, f, f, f, t, f, f, t, t, f, f };
2139
evaluate<void>(visualModel, "items.get(5).groups = [\"visible\", \"items\"]");
2140
QCOMPARE(listview->count(), 12);
2141
QCOMPARE(visualModel->items()->count(), 12);
2142
QCOMPARE(visibleItems->count(), 9);
2143
QCOMPARE(selectedItems->count(), 2);
2144
static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
2145
static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
2146
static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 5, 5, 6, 7, 8 };
2147
static const bool vMember[] = { t, t, f, t, t, t, f, f, t, t, t, t };
2148
static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 };
2149
static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f };
2154
void tst_qquickvisualdatamodel::invalidGroups()
2156
QUrl source = testFileUrl("groups-invalid.qml");
2157
QTest::ignoreMessage(QtWarningMsg, (source.toString() + ":12:9: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("Group names must start with a lower case letter")).toUtf8());
2159
QQmlComponent component(&engine, source);
2160
QScopedPointer<QObject> object(component.create());
2163
QCOMPARE(evaluate<int>(object.data(), "groups.length"), 4);
2164
QCOMPARE(evaluate<QString>(object.data(), "groups[0].name"), QString("items"));
2165
QCOMPARE(evaluate<QString>(object.data(), "groups[1].name"), QString("persistedItems"));
2166
QCOMPARE(evaluate<QString>(object.data(), "groups[2].name"), QString("visible"));
2167
QCOMPARE(evaluate<QString>(object.data(), "groups[3].name"), QString("selected"));
2170
void tst_qquickvisualdatamodel::onChanged_data()
2172
QTest::addColumn<QString>("expression");
2173
QTest::addColumn<QStringList>("tests");
2175
QTest::newRow("item appended")
2176
<< QString("listModel.append({\"number\": \"five\"})")
2178
<< "verify(vm.removed, [], [], [])"
2179
<< "verify(vm.inserted, [4], [1], [undefined])"
2180
<< "verify(vi.removed, [], [], [])"
2181
<< "verify(vi.inserted, [4], [1], [undefined])"
2182
<< "verify(si.removed, [], [], [])"
2183
<< "verify(si.inserted, [], [], [])");
2184
QTest::newRow("item prepended")
2185
<< QString("listModel.insert(0, {\"number\": \"five\"})")
2187
<< "verify(vm.removed, [], [], [])"
2188
<< "verify(vm.inserted, [0], [1], [undefined])"
2189
<< "verify(vi.removed, [], [], [])"
2190
<< "verify(vi.inserted, [0], [1], [undefined])"
2191
<< "verify(si.removed, [], [], [])"
2192
<< "verify(si.inserted, [], [], [])");
2193
QTest::newRow("item inserted")
2194
<< QString("listModel.insert(2, {\"number\": \"five\"})")
2196
<< "verify(vm.removed, [], [], [])"
2197
<< "verify(vm.inserted, [2], [1], [undefined])"
2198
<< "verify(vi.removed, [], [], [])"
2199
<< "verify(vi.inserted, [2], [1], [undefined])"
2200
<< "verify(si.removed, [], [], [])"
2201
<< "verify(si.inserted, [], [], [])");
2203
QTest::newRow("item removed tail")
2204
<< QString("listModel.remove(3)")
2206
<< "verify(vm.removed, [3], [1], [undefined])"
2207
<< "verify(vm.inserted, [], [], [])"
2208
<< "verify(vi.removed, [3], [1], [undefined])"
2209
<< "verify(vi.inserted, [], [], [])"
2210
<< "verify(si.removed, [], [], [])"
2211
<< "verify(si.inserted, [], [], [])");
2212
QTest::newRow("item removed head")
2213
<< QString("listModel.remove(0)")
2215
<< "verify(vm.removed, [0], [1], [undefined])"
2216
<< "verify(vm.inserted, [], [], [])"
2217
<< "verify(vi.removed, [0], [1], [undefined])"
2218
<< "verify(vi.inserted, [], [], [])"
2219
<< "verify(si.removed, [], [], [])"
2220
<< "verify(si.inserted, [], [], [])");
2221
QTest::newRow("item removed middle")
2222
<< QString("listModel.remove(1)")
2224
<< "verify(vm.removed, [1], [1], [undefined])"
2225
<< "verify(vm.inserted, [], [], [])"
2226
<< "verify(vi.removed, [1], [1], [undefined])"
2227
<< "verify(vi.inserted, [], [], [])"
2228
<< "verify(si.removed, [], [], [])"
2229
<< "verify(si.inserted, [], [], [])");
2232
QTest::newRow("item moved from tail")
2233
<< QString("listModel.move(3, 0, 1)")
2235
<< "verify(vm.removed, [3], [1], [vm.inserted[0].moveId])"
2236
<< "verify(vm.inserted, [0], [1], [vm.removed[0].moveId])"
2237
<< "verify(vi.removed, [3], [1], [vi.inserted[0].moveId])"
2238
<< "verify(vi.inserted, [0], [1], [vi.removed[0].moveId])"
2239
<< "verify(si.removed, [], [], [])"
2240
<< "verify(si.inserted, [], [], [])");
2241
QTest::newRow("item moved from head")
2242
<< QString("listModel.move(0, 2, 2)")
2244
<< "verify(vm.removed, [0], [2], [vm.inserted[0].moveId])"
2245
<< "verify(vm.inserted, [2], [2], [vm.removed[0].moveId])"
2246
<< "verify(vi.removed, [0], [2], [vi.inserted[0].moveId])"
2247
<< "verify(vi.inserted, [2], [2], [vi.removed[0].moveId])"
2248
<< "verify(si.removed, [], [], [])"
2249
<< "verify(si.inserted, [], [], [])");
2251
QTest::newRow("groups changed")
2252
<< QString("items.setGroups(1, 2, [\"items\", \"selected\"])")
2254
<< "verify(vm.inserted, [], [], [])"
2255
<< "verify(vm.removed, [], [], [])"
2256
<< "verify(vi.removed, [1], [2], [undefined])"
2257
<< "verify(vi.inserted, [], [], [])"
2258
<< "verify(si.removed, [], [], [])"
2259
<< "verify(si.inserted, [0], [2], [undefined])");
2261
QTest::newRow("multiple removes")
2262
<< QString("{ vi.remove(1, 1); "
2263
"vi.removeGroups(0, 2, \"items\") }")
2265
<< "verify(vm.removed, [0, 1], [1, 1], [undefined, undefined])"
2266
<< "verify(vm.inserted, [], [], [])"
2267
<< "verify(vi.removed, [1], [1], [undefined])"
2268
<< "verify(vi.inserted, [], [], [])"
2269
<< "verify(si.removed, [], [], [])"
2270
<< "verify(si.inserted, [], [], [])");
2273
void tst_qquickvisualdatamodel::onChanged()
2275
QFETCH(QString, expression);
2276
QFETCH(QStringList, tests);
2278
QQmlComponent component(&engine, testFileUrl("onChanged.qml"));
2279
QScopedPointer<QObject> object(component.create());
2282
evaluate<void>(object.data(), expression);
2284
foreach (const QString &test, tests) {
2285
bool passed = evaluate<bool>(object.data(), test);
2292
void tst_qquickvisualdatamodel::create()
2296
SingleRoleModel model(QStringList()
2318
QQmlContext *ctxt = view.rootContext();
2319
ctxt->setContextProperty("myModel", &model);
2321
view.setSource(testFileUrl("create.qml"));
2323
QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
2324
QVERIFY(listview != 0);
2326
QQuickItem *contentItem = listview->contentItem();
2327
QVERIFY(contentItem != 0);
2329
QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel *>(qvariant_cast<QObject *>(listview->model()));
2330
QVERIFY(visualModel);
2332
QCOMPARE(listview->count(), 20);
2334
QQmlGuard<QQuickItem> delegate;
2336
// persistedItems.includeByDefault is true, so all items belong to persistedItems initially.
2337
QVERIFY(delegate = findItem<QQuickItem>(contentItem, "delegate", 1));
2338
QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
2340
// changing include by default doesn't remove persistance.
2341
evaluate<void>(visualModel, "persistedItems.includeByDefault = false");
2342
QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
2344
// removing from persistedItems does.
2345
evaluate<void>(visualModel, "persistedItems.remove(0, 20)");
2346
QCOMPARE(listview->count(), 20);
2347
QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), false);
2349
// Request an item instantiated by the view.
2350
QVERIFY(delegate = qobject_cast<QQuickItem *>(evaluate<QObject *>(visualModel, "items.create(1)")));
2351
QCOMPARE(delegate.data(), findItem<QQuickItem>(contentItem, "delegate", 1));
2352
QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
2353
QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 1);
2355
evaluate<void>(delegate, "VisualDataModel.inPersistedItems = false");
2356
QCOMPARE(listview->count(), 20);
2357
QCoreApplication::sendPostedEvents(delegate, QEvent::DeferredDelete);
2359
QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), false);
2360
QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 0);
2362
// Request an item not instantiated by the view.
2363
QVERIFY(!findItem<QQuickItem>(contentItem, "delegate", 15));
2364
QVERIFY(delegate = qobject_cast<QQuickItem *>(evaluate<QObject *>(visualModel, "items.create(15)")));
2365
QCOMPARE(delegate.data(), findItem<QQuickItem>(contentItem, "delegate", 15));
2366
QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
2367
QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 1);
2369
evaluate<void>(visualModel, "persistedItems.remove(0)");
2370
QCoreApplication::sendPostedEvents(delegate, QEvent::DeferredDelete);
2372
QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 0);
2374
// Request an item not instantiated by the view, then scroll the view so it will request it.
2375
QVERIFY(!findItem<QQuickItem>(contentItem, "delegate", 16));
2376
QVERIFY(delegate = qobject_cast<QQuickItem *>(evaluate<QObject *>(visualModel, "items.create(16)")));
2377
QCOMPARE(delegate.data(), findItem<QQuickItem>(contentItem, "delegate", 16));
2378
QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
2379
QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 1);
2381
evaluate<void>(listview, "positionViewAtIndex(19, ListView.End)");
2382
QCOMPARE(listview->count(), 20);
2383
evaluate<void>(delegate, "VisualDataModel.groups = [\"items\"]");
2384
QCoreApplication::sendPostedEvents(delegate, QEvent::DeferredDelete);
2386
QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), false);
2387
QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 0);
2389
// Request and release an item instantiated by the view, then scroll the view so it releases it.
2390
QVERIFY(findItem<QQuickItem>(contentItem, "delegate", 17));
2391
QVERIFY(delegate = qobject_cast<QQuickItem *>(evaluate<QObject *>(visualModel, "items.create(17)")));
2392
QCOMPARE(delegate.data(), findItem<QQuickItem>(contentItem, "delegate", 17));
2393
QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
2394
QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 1);
2396
evaluate<void>(visualModel, "items.removeGroups(17, \"persistedItems\")");
2397
QCoreApplication::sendPostedEvents(delegate, QEvent::DeferredDelete);
2399
QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), false);
2400
QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 0);
2401
evaluate<void>(listview, "positionViewAtIndex(1, ListView.Beginning)");
2402
QCOMPARE(listview->count(), 20);
2403
QCoreApplication::sendPostedEvents(delegate, QEvent::DeferredDelete);
2406
// Adding an item to the persistedItems group won't instantiate it, but if later requested by
2407
// the view it will be persisted.
2408
evaluate<void>(visualModel, "items.addGroups(18, \"persistedItems\")");
2409
QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 1);
2410
QVERIFY(!findItem<QQuickItem>(contentItem, "delegate", 18));
2411
evaluate<void>(listview, "positionViewAtIndex(19, ListView.End)");
2412
QCOMPARE(listview->count(), 20);
2413
QVERIFY(delegate = findItem<QQuickItem>(contentItem, "delegate", 18));
2414
QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
2415
QCoreApplication::sendPostedEvents(delegate, QEvent::DeferredDelete);
2417
evaluate<void>(listview, "positionViewAtIndex(1, ListView.Beginning)");
2418
QCOMPARE(listview->count(), 20);
2419
QCoreApplication::sendPostedEvents(delegate, QEvent::DeferredDelete);
2422
// Remove an uninstantiated but cached item from the persistedItems group.
2423
evaluate<void>(visualModel, "items.addGroups(19, \"persistedItems\")");
2424
QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 2);
2425
QVERIFY(!findItem<QQuickItem>(contentItem, "delegate", 19));
2426
// Store a reference to the item so it is retained in the cache.
2427
evaluate<void>(visualModel, "persistentHandle = items.get(19)");
2428
QCOMPARE(evaluate<bool>(visualModel, "persistentHandle.inPersistedItems"), true);
2429
evaluate<void>(visualModel, "items.removeGroups(19, \"persistedItems\")");
2430
QCOMPARE(evaluate<bool>(visualModel, "persistentHandle.inPersistedItems"), false);
2433
void tst_qquickvisualdatamodel::incompleteModel()
2435
// VisualDataModel is first populated in componentComplete. Verify various functions are
2436
// harmlessly ignored until then.
2438
QQmlComponent component(&engine);
2439
component.setData("import QtQuick 2.0\n VisualDataModel {}", testFileUrl(""));
2441
QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
2443
QQuickVisualDataModel *model = qobject_cast<QQuickVisualDataModel *>(object.data());
2446
QSignalSpy itemsSpy(model->items(), SIGNAL(countChanged()));
2447
QSignalSpy persistedItemsSpy(model->items(), SIGNAL(countChanged()));
2449
evaluate<void>(model, "items.removeGroups(0, items.count, \"items\")");
2450
QCOMPARE(itemsSpy.count(), 0);
2451
QCOMPARE(persistedItemsSpy.count(), 0);
2453
evaluate<void>(model, "items.setGroups(0, items.count, \"persistedItems\")");
2454
QCOMPARE(itemsSpy.count(), 0);
2455
QCOMPARE(persistedItemsSpy.count(), 0);
2457
evaluate<void>(model, "items.addGroups(0, items.count, \"persistedItems\")");
2458
QCOMPARE(itemsSpy.count(), 0);
2459
QCOMPARE(persistedItemsSpy.count(), 0);
2461
evaluate<void>(model, "items.remove(0, items.count)");
2462
QCOMPARE(itemsSpy.count(), 0);
2463
QCOMPARE(persistedItemsSpy.count(), 0);
2465
evaluate<void>(model, "items.insert([ \"color\": \"blue\" ])");
2466
QCOMPARE(itemsSpy.count(), 0);
2467
QCOMPARE(persistedItemsSpy.count(), 0);
2469
QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: get: index out of range");
2470
QVERIFY(evaluate<bool>(model, "items.get(0) === undefined"));
2472
component.completeCreate();
2475
void tst_qquickvisualdatamodel::insert_data()
2477
QTest::addColumn<QUrl>("source");
2478
QTest::addColumn<QString>("expression");
2479
QTest::addColumn<int>("modelCount");
2480
QTest::addColumn<int>("visualCount");
2481
QTest::addColumn<int>("index");
2482
QTest::addColumn<bool>("inItems");
2483
QTest::addColumn<bool>("persisted");
2484
QTest::addColumn<bool>("visible");
2485
QTest::addColumn<bool>("selected");
2486
QTest::addColumn<bool>("modelData");
2487
QTest::addColumn<QString>("property");
2488
QTest::addColumn<QStringList>("propertyData");
2490
const QUrl listModelSource[] = {
2491
testFileUrl("listmodelproperties.qml"),
2492
testFileUrl("listmodelproperties-package.qml") };
2493
const QUrl singleRoleSource[] = {
2494
testFileUrl("singleroleproperties.qml"),
2495
testFileUrl("singleroleproperties-package.qml") };
2496
const QUrl multipleRoleSource[] = {
2497
testFileUrl("multipleroleproperties.qml"),
2498
testFileUrl("multipleroleproperties-package.qml") };
2499
const QUrl stringListSource[] = {
2500
testFileUrl("stringlistproperties.qml"),
2501
testFileUrl("stringlistproperties-package.qml") };
2502
const QUrl objectListSource[] = {
2503
testFileUrl("objectlistproperties.qml"),
2504
testFileUrl("objectlistproperties-package.qml") };
2506
for (int i = 0; i < 2; ++i) {
2508
QTest::newRow("ListModel.items prepend")
2509
<< listModelSource[i]
2510
<< QString("items.insert(0, {\"number\": \"eight\"})")
2511
<< 4 << 5 << 0 << true << false << false << false << true
2512
<< QString("number")
2513
<< (QStringList() << "eight" << "one" << "two" << "three" << "four");
2515
QTest::newRow("ListModel.items append")
2516
<< listModelSource[i]
2517
<< QString("items.insert({\"number\": \"eight\"})")
2518
<< 4 << 5 << 4 << true << false << false << false << true
2519
<< QString("number")
2520
<< (QStringList() << "one" << "two" << "three" << "four" << "eight");
2522
QTest::newRow("ListModel.items insert at 2")
2523
<< listModelSource[i]
2524
<< QString("items.insert(2, {\"number\": \"eight\"})")
2525
<< 4 << 5 << 2 << true << false << false << false << true
2526
<< QString("number")
2527
<< (QStringList() << "one" << "two" << "eight" << "three" << "four");
2529
QTest::newRow("ListModel.items insert at items.get(2)")
2530
<< listModelSource[i]
2531
<< QString("items.insert(items.get(2), {\"number\": \"eight\"})")
2532
<< 4 << 5 << 2 << true << false << false << false << true
2533
<< QString("number")
2534
<< (QStringList() << "one" << "two" << "eight" << "three" << "four");
2536
QTest::newRow("ListModel.items insert at visibleItems.get(2)")
2537
<< listModelSource[i]
2538
<< QString("items.insert(visibleItems.get(2), {\"number\": \"eight\"})")
2539
<< 4 << 5 << 2 << true << false << false << false << true
2540
<< QString("number")
2541
<< (QStringList() << "one" << "two" << "eight" << "three" << "four");
2543
QTest::newRow("ListModel.selectedItems insert at items.get(2)")
2544
<< listModelSource[i]
2545
<< QString("selectedItems.insert(items.get(2), {\"number\": \"eight\"})")
2546
<< 4 << 5 << 2 << false << false << false << true << true
2547
<< QString("number")
2548
<< (QStringList() << "one" << "two" << "eight" << "three" << "four");
2550
QTest::newRow("ListModel.selectedItems insert at visibleItems.get(2)")
2551
<< listModelSource[i]
2552
<< QString("selectedItems.insert(visibleItems.get(2), {\"number\": \"eight\"})")
2553
<< 4 << 5 << 2 << false << false << false << true << true
2554
<< QString("number")
2555
<< (QStringList() << "one" << "two" << "eight" << "three" << "four");
2557
QTest::newRow("ListModel.items prepend modelData")
2558
<< listModelSource[i]
2559
<< QString("items.insert(0, {\"modelData\": \"eight\"})")
2560
<< 4 << 5 << 0 << true << false << false << false << true
2561
<< QString("number")
2562
<< (QStringList() << "eight" << "one" << "two" << "three" << "four");
2564
QTest::newRow("ListModel.items prepend, edit number")
2565
<< listModelSource[i]
2567
"items.insert(0, {\"number\": \"eight\"}); "
2568
"items.get(0).model.number = \"seven\"; }")
2569
<< 4 << 5 << 0 << true << false << false << false << true
2570
<< QString("number")
2571
<< (QStringList() << "seven" << "one" << "two" << "three" << "four");
2573
QTest::newRow("ListModel.items prepend, edit modelData")
2574
<< listModelSource[i]
2576
"items.insert(0, {\"number\": \"eight\"}); "
2577
"items.get(0).model.modelData = \"seven\"; }")
2578
<< 4 << 5 << 0 << true << false << false << false << true
2579
<< QString("number")
2580
<< (QStringList() << "seven" << "one" << "two" << "three" << "four");
2582
QTest::newRow("ListModel.items prepend, edit resolved")
2583
<< listModelSource[i]
2585
"items.insert(0, {\"number\": \"eight\"}); "
2586
"items.get(2).model.number = \"seven\"; }")
2587
<< 4 << 5 << 0 << true << false << false << false << true
2588
<< QString("number")
2589
<< (QStringList() << "eight" << "one" << "two" << "three" << "four");
2591
QTest::newRow("ListModel.items prepend with groups")
2592
<< listModelSource[i]
2593
<< QString("items.insert(0, {\"number\": \"eight\"}, [\"visible\", \"truncheon\"])")
2594
<< 4 << 5 << 0 << true << false << true << false << true
2595
<< QString("number")
2596
<< (QStringList() << "eight" << "one" << "two" << "three" << "four");
2598
QTest::newRow("ListModel.items append with groups")
2599
<< listModelSource[i]
2600
<< QString("items.insert({\"number\": \"eight\"}, [\"visible\", \"selected\"])")
2601
<< 4 << 5 << 4 << true << false << true << true << true
2602
<< QString("number")
2603
<< (QStringList() << "one" << "two" << "three" << "four" << "eight");
2605
QTest::newRow("ListModel.items insert at 2 with groups")
2606
<< listModelSource[i]
2607
<< QString("items.insert(2, {\"number\": \"eight\"}, \"visible\")")
2608
<< 4 << 5 << 2 << true << false << true << false << true
2609
<< QString("number")
2610
<< (QStringList() << "one" << "two" << "eight" << "three" << "four");
2613
QTest::newRow("ListModel.items prepend")
2614
<< listModelSource[i]
2615
<< QString("items.create(0, {\"number\": \"eight\"})")
2616
<< 4 << 5 << 0 << true << true << false << false << true
2617
<< QString("number")
2618
<< (QStringList() << "eight" << "one" << "two" << "three" << "four");
2620
QTest::newRow("ListModel.items append")
2621
<< listModelSource[i]
2622
<< QString("items.create({\"number\": \"eight\"})")
2623
<< 4 << 5 << 4 << true << true << false << false << true
2624
<< QString("number")
2625
<< (QStringList() << "one" << "two" << "three" << "four" << "eight");
2627
QTest::newRow("ListModel.items create at 2")
2628
<< listModelSource[i]
2629
<< QString("items.create(2, {\"number\": \"eight\"})")
2630
<< 4 << 5 << 2 << true << true << false << false << true
2631
<< QString("number")
2632
<< (QStringList() << "one" << "two" << "eight" << "three" << "four");
2634
QTest::newRow("ListModel.items create at items.get(2)")
2635
<< listModelSource[i]
2636
<< QString("items.create(items.get(2), {\"number\": \"eight\"})")
2637
<< 4 << 5 << 2 << true << true << false << false << true
2638
<< QString("number")
2639
<< (QStringList() << "one" << "two" << "eight" << "three" << "four");
2641
QTest::newRow("ListModel.items create at visibleItems.get(2)")
2642
<< listModelSource[i]
2643
<< QString("items.create(visibleItems.get(2), {\"number\": \"eight\"})")
2644
<< 4 << 5 << 2 << true << true << false << false << true
2645
<< QString("number")
2646
<< (QStringList() << "one" << "two" << "eight" << "three" << "four");
2648
QTest::newRow("ListModel.selectedItems create at items.get(2)")
2649
<< listModelSource[i]
2650
<< QString("selectedItems.create(items.get(2), {\"number\": \"eight\"})")
2651
<< 4 << 5 << 2 << false << true << false << true << true
2652
<< QString("number")
2653
<< (QStringList() << "one" << "two" << "eight" << "three" << "four");
2655
QTest::newRow("ListModel.selectedItems create at visibleItems.get(2)")
2656
<< listModelSource[i]
2657
<< QString("selectedItems.create(visibleItems.get(2), {\"number\": \"eight\"})")
2658
<< 4 << 5 << 2 << false << true << false << true << true
2659
<< QString("number")
2660
<< (QStringList() << "one" << "two" << "eight" << "three" << "four");
2662
QTest::newRow("ListModel.items create prepended")
2663
<< listModelSource[i]
2664
<< QString("items.create(0, {\"number\": \"eight\"})")
2665
<< 4 << 5 << 0 << true << true << false << false << true
2666
<< QString("number")
2667
<< (QStringList() << "eight" << "one" << "two" << "three" << "four");
2669
QTest::newRow("ListModel.items create appended")
2670
<< listModelSource[i]
2671
<< QString("items.create({\"number\": \"eight\"})")
2672
<< 4 << 5 << 4 << true << true << false << false << true
2673
<< QString("number")
2674
<< (QStringList() << "one" << "two" << "three" << "four" << "eight");
2676
QTest::newRow("ListModel.items create at 2")
2677
<< listModelSource[i]
2678
<< QString("items.create(2, {\"number\": \"eight\"})")
2679
<< 4 << 5 << 2 << true << true << false << false << true
2680
<< QString("number")
2681
<< (QStringList() << "one" << "two" << "eight" << "three" << "four");
2683
QTest::newRow("ListModel.items create at items.get(2)")
2684
<< listModelSource[i]
2685
<< QString("items.create(items.get(2), {\"number\": \"eight\"})")
2686
<< 4 << 5 << 2 << true << true << false << false << true
2687
<< QString("number")
2688
<< (QStringList() << "one" << "two" << "eight" << "three" << "four");
2690
QTest::newRow("ListModel.items create at visibleItems.get(2)")
2691
<< listModelSource[i]
2692
<< QString("items.create(visibleItems.get(2), {\"number\": \"eight\"})")
2693
<< 4 << 5 << 2 << true << true << false << false << true
2694
<< QString("number")
2695
<< (QStringList() << "one" << "two" << "eight" << "three" << "four");
2697
QTest::newRow("ListModel.create prepend modelData")
2698
<< listModelSource[i]
2699
<< QString("items.create(0, {\"modelData\": \"eight\"})")
2700
<< 4 << 5 << 0 << true << true << false << false << true
2701
<< QString("number")
2702
<< (QStringList() << "eight" << "one" << "two" << "three" << "four");
2704
QTest::newRow("ListModel.items create prepended, edit number")
2705
<< listModelSource[i]
2707
"var item = items.create(0, {\"number\": \"eight\"}); "
2708
"item.setTest3(\"seven\"); }")
2709
<< 4 << 5 << 0 << true << true << false << false << true
2710
<< QString("number")
2711
<< (QStringList() << "seven" << "one" << "two" << "three" << "four");
2713
QTest::newRow("ListModel.items create prepended, edit model.number")
2714
<< listModelSource[i]
2716
"var item = items.create(0, {\"number\": \"eight\"}); "
2717
"item.setTest4(\"seven\"); }")
2718
<< 4 << 5 << 0 << true << true << false << false << true
2719
<< QString("number")
2720
<< (QStringList() << "seven" << "one" << "two" << "three" << "four");
2722
QTest::newRow("ListModel.items create prepended, edit modelData")
2723
<< listModelSource[i]
2725
"var item = items.create(0, {\"number\": \"eight\"}); "
2726
"item.setTest5(\"seven\"); }")
2727
<< 4 << 5 << 0 << true << true << false << false << true
2728
<< QString("number")
2729
<< (QStringList() << "seven" << "one" << "two" << "three" << "four");
2731
QTest::newRow("ListModel.items create prepended, edit model.modelData")
2732
<< listModelSource[i]
2734
"var item = items.create(0, {\"number\": \"eight\"}); "
2735
"item.setTest6(\"seven\"); }")
2736
<< 4 << 5 << 0 << true << true << false << false << true
2737
<< QString("number")
2738
<< (QStringList() << "seven" << "one" << "two" << "three" << "four");
2740
QTest::newRow("ListModel.items create prepended with groups")
2741
<< listModelSource[i]
2742
<< QString("items.create(0, {\"number\": \"eight\"}, [\"visible\", \"truncheon\"])")
2743
<< 4 << 5 << 0 << true << true << true << false << true
2744
<< QString("number")
2745
<< (QStringList() << "eight" << "one" << "two" << "three" << "four");
2747
QTest::newRow("ListModel.items create appended with groups")
2748
<< listModelSource[i]
2749
<< QString("items.create({\"number\": \"eight\"}, [\"visible\", \"selected\"])")
2750
<< 4 << 5 << 4 << true << true << true << true << true
2751
<< QString("number")
2752
<< (QStringList() << "one" << "two" << "three" << "four" << "eight");
2754
QTest::newRow("ListModel.items create inserted with groups")
2755
<< listModelSource[i]
2756
<< QString("items.create(2, {\"number\": \"eight\"}, \"visible\")")
2757
<< 4 << 5 << 2 << true << true << true << false << true
2758
<< QString("number")
2759
<< (QStringList() << "one" << "two" << "eight" << "three" << "four");
2761
QTest::newRow("ListModel.items create prepended clear persistence")
2762
<< listModelSource[i]
2763
<< QString("{ items.create(0, {\"number\": \"eight\"}); "
2764
"items.get(0).inPersistedItems = false }")
2765
<< 4 << 5 << 0 << true << false << false << false << true
2766
<< QString("number")
2767
<< (QStringList() << "eight" << "one" << "two" << "three" << "four");
2769
QTest::newRow("ListModel.items create appended clear persistence")
2770
<< listModelSource[i]
2771
<< QString("{ items.create({\"number\": \"eight\"}); "
2772
"items.get(4).inPersistedItems = false }")
2773
<< 4 << 5 << 4 << true << false << false << false << true
2774
<< QString("number")
2775
<< (QStringList() << "one" << "two" << "three" << "four" << "eight");
2777
QTest::newRow("ListModel.items create inserted clear persistence")
2778
<< listModelSource[i]
2779
<< QString("{ items.create(2, {\"number\": \"eight\"}); "
2780
"items.get(2).inPersistedItems = false }")
2781
<< 4 << 5 << 2 << true << false << false << false << true
2782
<< QString("number")
2783
<< (QStringList() << "one" << "two" << "eight" << "three" << "four");
2785
// AbstractItemModel (Single Role).
2786
QTest::newRow("AbstractItemModel.items prepend")
2787
<< singleRoleSource[i]
2788
<< QString("items.insert(0, {\"name\": \"eight\"})")
2789
<< 4 << 5 << 0 << true << false << false << false << true
2791
<< (QStringList() << "eight" << "one" << "two" << "three" << "four");
2793
QTest::newRow("AbstractItemModel.items append")
2794
<< singleRoleSource[i]
2795
<< QString("items.insert({\"name\": \"eight\"})")
2796
<< 4 << 5 << 4 << true << false << false << false << true
2798
<< (QStringList() << "one" << "two" << "three" << "four" << "eight");
2800
QTest::newRow("AbstractItemModel.items insert at 2")
2801
<< singleRoleSource[i]
2802
<< QString("items.insert(2, {\"name\": \"eight\"})")
2803
<< 4 << 5 << 2 << true << false << false << false << true
2805
<< (QStringList() << "one" << "two" << "eight" << "three" << "four");
2807
QTest::newRow("AbstractItemModel.items prepend modelData")
2808
<< singleRoleSource[i]
2809
<< QString("items.insert(0, {\"modelData\": \"eight\"})")
2810
<< 4 << 5 << 0 << true << false << false << false << true
2812
<< (QStringList() << "eight" << "one" << "two" << "three" << "four");
2814
QTest::newRow("AbstractItemModel.items prepend, edit name")
2815
<< singleRoleSource[i]
2817
"items.insert(0, {\"name\": \"eight\"}); "
2818
"items.get(0).model.name = \"seven\"; }")
2819
<< 4 << 5 << 0 << true << false << false << false << true
2821
<< (QStringList() << "seven" << "one" << "two" << "three" << "four");
2823
QTest::newRow("AbstractItemModel.items prepend, edit modelData")
2824
<< singleRoleSource[i]
2826
"items.insert(0, {\"name\": \"eight\"}); "
2827
"items.get(0).model.modelData = \"seven\"; }")
2828
<< 4 << 5 << 0 << true << false << false << false << true
2830
<< (QStringList() << "seven" << "one" << "two" << "three" << "four");
2832
QTest::newRow("AbstractItemModel.items prepend, edit resolved")
2833
<< singleRoleSource[i]
2835
"items.insert(0, {\"name\": \"eight\"}); "
2836
"items.get(2).model.name = \"seven\"; }")
2837
<< 4 << 5 << 0 << true << false << false << false << true
2839
<< (QStringList() << "eight" << "one" << "two" << "three" << "four");
2841
QTest::newRow("AbstractItemModel.create prepend modelData")
2842
<< singleRoleSource[i]
2843
<< QString("items.create(0, {\"modelData\": \"eight\"})")
2844
<< 4 << 5 << 0 << true << true << false << false << true
2846
<< (QStringList() << "eight" << "one" << "two" << "three" << "four");
2848
QTest::newRow("AbstractItemModel.items create prepended, edit name")
2849
<< singleRoleSource[i]
2851
"var item = items.create(0, {\"name\": \"eight\"}); "
2852
"item.setTest3(\"seven\"); }")
2853
<< 4 << 5 << 0 << true << true << false << false << true
2855
<< (QStringList() << "seven" << "one" << "two" << "three" << "four");
2857
QTest::newRow("AbstractItemModel.items create prepended, edit model.name")
2858
<< singleRoleSource[i]
2860
"var item = items.create(0, {\"name\": \"eight\"}); "
2861
"item.setTest4(\"seven\"); }")
2862
<< 4 << 5 << 0 << true << true << false << false << true
2864
<< (QStringList() << "seven" << "one" << "two" << "three" << "four");
2866
QTest::newRow("AbstractItemModel.items create prepended, edit modelData")
2867
<< singleRoleSource[i]
2869
"var item = items.create(0, {\"name\": \"eight\"}); "
2870
"item.setTest5(\"seven\"); }")
2871
<< 4 << 5 << 0 << true << true << false << false << true
2873
<< (QStringList() << "seven" << "one" << "two" << "three" << "four");
2875
QTest::newRow("AbstractItemModel.items create prepended, edit model.modelData")
2876
<< singleRoleSource[i]
2878
"var item = items.create(0, {\"name\": \"eight\"}); "
2879
"item.setTest6(\"seven\"); }")
2880
<< 4 << 5 << 0 << true << true << false << false << true
2882
<< (QStringList() << "seven" << "one" << "two" << "three" << "four");
2884
// AbstractItemModel (Multiple Roles).
2885
QTest::newRow("StandardItemModel.items prepend")
2886
<< multipleRoleSource[i]
2887
<< QString("items.insert(0, {\"display\": \"Row 8 Item\"})")
2888
<< 4 << 5 << 0 << true << false << false << false << false
2889
<< QString("display")
2890
<< (QStringList() << "Row 8 Item" << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2892
QTest::newRow("StandardItemModel.items append")
2893
<< multipleRoleSource[i]
2894
<< QString("items.insert({\"display\": \"Row 8 Item\"})")
2895
<< 4 << 5 << 4 << true << false << false << false << false
2896
<< QString("display")
2897
<< (QStringList() << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item" << "Row 8 Item");
2899
QTest::newRow("StandardItemModel.items insert at 2")
2900
<< multipleRoleSource[i]
2901
<< QString("items.insert(2, {\"display\": \"Row 8 Item\"})")
2902
<< 4 << 5 << 2 << true << false << false << false << false
2903
<< QString("display")
2904
<< (QStringList() << "Row 1 Item" << "Row 2 Item" << "Row 8 Item" << "Row 3 Item" << "Row 4 Item");
2906
QTest::newRow("StandardItemModel.items prepend modelData")
2907
<< multipleRoleSource[i]
2908
<< QString("items.insert(0, {\"modelData\": \"Row 8 Item\"})")
2909
<< 4 << 5 << 0 << true << false << false << false << false
2910
<< QString("display")
2911
<< (QStringList() << QString() << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2913
QTest::newRow("StandardItemModel.items prepend, edit display")
2914
<< multipleRoleSource[i]
2916
"items.insert(0, {\"display\": \"Row 8 Item\"}); "
2917
"items.get(0).model.display = \"Row 7 Item\"; }")
2918
<< 4 << 5 << 0 << true << false << false << false << false
2919
<< QString("display")
2920
<< (QStringList() << "Row 7 Item" << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2922
QTest::newRow("StandardItemModel.items prepend, edit modelData")
2923
<< multipleRoleSource[i]
2925
"items.insert(0, {\"display\": \"Row 8 Item\"}); "
2926
"items.get(0).model.modelData = \"Row 7 Item\"; }")
2927
<< 4 << 5 << 0 << true << false << false << false << false
2928
<< QString("display")
2929
<< (QStringList() << "Row 8 Item" << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2931
QTest::newRow("StandardItemModel.items prepend, edit resolved")
2932
<< multipleRoleSource[i]
2934
"items.insert(0, {\"display\": \"Row 8 Item\"}); "
2935
"items.get(2).model.display = \"Row 7 Item\"; }")
2936
<< 4 << 5 << 0 << true << false << false << false << false
2937
<< QString("display")
2938
<< (QStringList() << "Row 8 Item" << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2940
QTest::newRow("StandardItemModel.create prepend modelData")
2941
<< multipleRoleSource[i]
2942
<< QString("items.create(0, {\"modelData\": \"Row 8 Item\"})")
2943
<< 4 << 5 << 0 << true << true << false << false << false
2944
<< QString("display")
2945
<< (QStringList() << QString() << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2947
QTest::newRow("StandardItemModel.items create prepended, edit display")
2948
<< multipleRoleSource[i]
2950
"var item = items.create(0, {\"display\": \"Row 8 Item\"}); "
2951
"item.setTest3(\"Row 7 Item\"); }")
2952
<< 4 << 5 << 0 << true << true << false << false << false
2953
<< QString("display")
2954
<< (QStringList() << "Row 7 Item" << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2956
QTest::newRow("StandardItemModel.items create prepended, edit model.display")
2957
<< multipleRoleSource[i]
2959
"var item = items.create(0, {\"display\": \"Row 8 Item\"}); "
2960
"item.setTest4(\"Row 7 Item\"); }")
2961
<< 4 << 5 << 0 << true << true << false << false << false
2962
<< QString("display")
2963
<< (QStringList() << "Row 7 Item" << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2966
QTest::newRow("StringList.items prepend")
2967
<< stringListSource[i]
2968
<< QString("items.insert(0, {\"modelData\": \"eight\"})")
2969
<< 4 << 5 << 0 << true << false << false << false << false
2970
<< QString("modelData")
2971
<< (QStringList() << "eight" << "one" << "two" << "three" << "four");
2973
QTest::newRow("StringList.items append")
2974
<< stringListSource[i]
2975
<< QString("items.insert({\"modelData\": \"eight\"})")
2976
<< 4 << 5 << 4 << true << false << false << false << false
2977
<< QString("modelData")
2978
<< (QStringList() << "one" << "two" << "three" << "four" << "eight");
2980
QTest::newRow("StringList.items insert at 2")
2981
<< stringListSource[i]
2982
<< QString("items.insert(2, {\"modelData\": \"eight\"})")
2983
<< 4 << 5 << 2 << true << false << false << false << false
2984
<< QString("modelData")
2985
<< (QStringList() << "one" << "two" << "eight" << "three" << "four");
2987
QTest::newRow("StringList.items prepend, edit modelData")
2988
<< stringListSource[i]
2990
"items.insert(0, {\"modelData\": \"eight\"}); "
2991
"items.get(0).model.modelData = \"seven\"; }")
2992
<< 4 << 5 << 0 << true << false << false << false << false
2993
<< QString("modelData")
2994
<< (QStringList() << "seven" << "one" << "two" << "three" << "four");
2996
QTest::newRow("StringList.items prepend, edit resolved")
2997
<< stringListSource[i]
2999
"items.insert(0, {\"modelData\": \"eight\"}); "
3000
"items.get(2).model.modelData = \"seven\"; }")
3001
<< 4 << 5 << 0 << true << false << false << false << false
3002
<< QString("modelData")
3003
<< (QStringList() << "eight" << "one" << "two" << "three" << "four");
3005
QTest::newRow("StringList.create prepend modelData")
3006
<< stringListSource[i]
3007
<< QString("items.create(0, {\"modelData\": \"eight\"})")
3008
<< 4 << 5 << 0 << true << true << false << false << false
3009
<< QString("modelData")
3010
<< (QStringList() << "eight" << "one" << "two" << "three" << "four");
3012
QTest::newRow("StringList.items create prepended, edit modelData")
3013
<< stringListSource[i]
3015
"var item = items.create(0, {\"modelData\": \"eight\"}); "
3016
"item.setTest3(\"seven\"); }")
3017
<< 4 << 5 << 0 << true << true << false << false << false
3018
<< QString("modelData")
3019
<< (QStringList() << "seven" << "one" << "two" << "three" << "four");
3021
QTest::newRow("StringList.items create prepended, edit model.modelData")
3022
<< stringListSource[i]
3024
"var item = items.create(0, {\"modelData\": \"eight\"}); "
3025
"item.setTest4(\"seven\"); }")
3026
<< 4 << 5 << 0 << true << true << false << false << false
3027
<< QString("modelData")
3028
<< (QStringList() << "seven" << "one" << "two" << "three" << "four");
3031
QTest::newRow("ObjectList.items prepend")
3032
<< objectListSource[i]
3033
<< QString("items.insert(0, {\"name\": \"Item 8\"})")
3034
<< 4 << 4 << 4 << false << false << false << false << false
3036
<< (QStringList() << "Item 1" << "Item 2" << "Item 3" << "Item 4");
3038
QTest::newRow("ObjectList.items append")
3039
<< objectListSource[i]
3040
<< QString("items.insert({\"name\": \"Item 8\"})")
3041
<< 4 << 4 << 4 << false << false << false << false << false
3043
<< (QStringList() << "Item 1" << "Item 2" << "Item 3" << "Item 4");
3045
QTest::newRow("ObjectList.items insert at 2")
3046
<< objectListSource[i]
3047
<< QString("items.insert(2, {\"name\": \"Item 8\"})")
3048
<< 4 << 4 << 4 << false << false << false << false << false
3050
<< (QStringList() << "Item 1" << "Item 2" << "Item 3" << "Item 4");
3054
void tst_qquickvisualdatamodel::insert()
3056
QFETCH(QUrl, source);
3057
QFETCH(QString, expression);
3058
QFETCH(int, modelCount);
3059
QFETCH(int, visualCount);
3061
QFETCH(bool, inItems);
3062
QFETCH(bool, persisted);
3063
QFETCH(bool, visible);
3064
QFETCH(bool, selected);
3065
QFETCH(bool, modelData);
3066
QFETCH(QString, property);
3067
QFETCH(QStringList, propertyData);
3069
QQuickWindow window;
3071
QQmlComponent component(&engine);
3072
component.loadUrl(source);
3073
QScopedPointer<QObject> object(component.create());
3074
QQuickListView *listView = qobject_cast<QQuickListView *>(object.data());
3076
listView->setParentItem(window.contentItem());
3078
QQuickItem *contentItem = listView->contentItem();
3079
QVERIFY(contentItem);
3081
QObject *visualModel = listView->findChild<QObject *>("visualModel");
3082
QVERIFY(visualModel);
3084
evaluate<void>(visualModel, expression);
3086
QCOMPARE(evaluate<int>(listView, "count"), inItems ? visualCount : modelCount);
3087
QCOMPARE(evaluate<int>(visualModel, "count"), inItems ? visualCount : modelCount);
3088
QCOMPARE(evaluate<int>(visualModel, "items.count"), inItems ? visualCount : modelCount);
3089
QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), persisted ? 1 : 0);
3090
QCOMPARE(evaluate<int>(visualModel, "visibleItems.count"), visible ? visualCount : modelCount);
3091
QCOMPARE(evaluate<int>(visualModel, "selectedItems.count"), selected ? 1 : 0);
3093
QCOMPARE(propertyData.count(), visualCount);
3094
for (int i = 0; i < visualCount; ++i) {
3096
if (modelIndex > index)
3098
else if (modelIndex == index)
3101
const int itemsIndex = inItems || i <= index ? i : i - 1;
3105
get = QString("items.get(%1)").arg(itemsIndex);
3107
QQuickItem *item = findItem<QQuickItem>(contentItem, "delegate", modelIndex);
3110
QCOMPARE(evaluate<int>(item, "test1"), modelIndex);
3111
QCOMPARE(evaluate<int>(item, "test2"), modelIndex);
3112
QCOMPARE(evaluate<QString>(item, "test3"), propertyData.at(i));
3113
QCOMPARE(evaluate<QString>(item, "test4"), propertyData.at(i));
3116
QCOMPARE(evaluate<QString>(item, "test5"), propertyData.at(i));
3117
QCOMPARE(evaluate<QString>(item, "test6"), propertyData.at(i));
3120
QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inItems"), true);
3121
QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inPersistedItems"), false);
3122
QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inVisible"), true);
3123
QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inSelected"), false);
3124
QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.isUnresolved"), false);
3126
QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.itemsIndex"), itemsIndex);
3127
QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.persistedItemsIndex"), persisted && i > index ? 1 : 0);
3128
QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.visibleIndex"), visible || i <= index ? i : i - 1);
3129
QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.selectedIndex"), selected && i > index ? 1 : 0);
3130
} else if (inItems) {
3131
get = QString("items.get(%1)").arg(index);
3132
} else if (persisted) {
3133
get = "persistedItems.get(0)";
3134
} else if (visible) {
3135
get = QString("visibleItems.get(%1)").arg(index);
3136
} else if (selected) {
3137
get = "selectedItems.get(0)";
3142
QCOMPARE(evaluate<int>(visualModel, get + ".model.index"), modelIndex);
3144
QCOMPARE(evaluate<QString>(visualModel, get + ".model." + property), propertyData.at(i));
3146
QCOMPARE(evaluate<bool>(visualModel, get + ".inItems"), inItems || i != index);
3147
QCOMPARE(evaluate<bool>(visualModel, get + ".inPersistedItems"), persisted && i == index);
3148
QCOMPARE(evaluate<bool>(visualModel, get + ".inVisible"), visible || i != index);
3149
QCOMPARE(evaluate<bool>(visualModel, get + ".inSelected"), selected && i == index);
3150
QCOMPARE(evaluate<bool>(visualModel, get + ".isUnresolved"), i == index);
3152
QCOMPARE(evaluate<int>(visualModel, get + ".itemsIndex"), inItems || i <= index ? i : i - 1);
3153
QCOMPARE(evaluate<int>(visualModel, get + ".persistedItemsIndex"), persisted && i > index ? 1 : 0);
3154
QCOMPARE(evaluate<int>(visualModel, get + ".visibleIndex"), visible || i <= index ? i : i - 1);
3155
QCOMPARE(evaluate<int>(visualModel, get + ".selectedIndex"), selected && i > index ? 1 : 0);
3161
item = evaluate<QObject *>(visualModel, QString("items.create(%1)").arg(index));
3163
item = evaluate<QObject *>(visualModel, QString("persistedItems.create(%1)").arg(0));
3165
item = evaluate<QObject *>(visualModel, QString("visibleItems.create(%1)").arg(index));
3167
item = evaluate<QObject *>(visualModel, QString("selectedItems.create(%1)").arg(0));
3173
QCOMPARE(evaluate<int>(item, "test1"), -1);
3174
QCOMPARE(evaluate<int>(item, "test2"), -1);
3175
QCOMPARE(evaluate<QString>(item, "test3"), propertyData.at(index));
3176
QCOMPARE(evaluate<QString>(item, "test4"), propertyData.at(index));
3179
QCOMPARE(evaluate<QString>(item, "test5"), propertyData.at(index));
3180
QCOMPARE(evaluate<QString>(item, "test6"), propertyData.at(index));
3183
QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inItems"), inItems);
3184
QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inPersistedItems"), true);
3185
QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inVisible"), visible);
3186
QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inSelected"), selected);
3187
QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.isUnresolved"), true);
3189
QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.itemsIndex"), index);
3190
QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.persistedItemsIndex"), 0);
3191
QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.visibleIndex"), index);
3192
QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.selectedIndex"), 0);
3195
void tst_qquickvisualdatamodel::resolve_data()
3197
QTest::addColumn<QUrl>("source");
3198
QTest::addColumn<QString>("setupExpression");
3199
QTest::addColumn<QString>("resolveExpression");
3200
QTest::addColumn<int>("unresolvedCount");
3201
QTest::addColumn<int>("modelCount");
3202
QTest::addColumn<int>("visualCount");
3203
QTest::addColumn<int>("index");
3204
QTest::addColumn<bool>("inItems");
3205
QTest::addColumn<bool>("persisted");
3206
QTest::addColumn<bool>("visible");
3207
QTest::addColumn<bool>("selected");
3208
QTest::addColumn<bool>("modelData");
3209
QTest::addColumn<QString>("property");
3210
QTest::addColumn<QStringList>("propertyData");
3212
const QUrl listModelSource[] = {
3213
testFileUrl("listmodelproperties.qml"),
3214
testFileUrl("listmodelproperties-package.qml") };
3215
const QUrl singleRoleSource[] = {
3216
testFileUrl("singleroleproperties.qml"),
3217
testFileUrl("singleroleproperties-package.qml") };
3218
const QUrl multipleRoleSource[] = {
3219
testFileUrl("multipleroleproperties.qml"),
3220
testFileUrl("multipleroleproperties-package.qml") };
3221
const QUrl stringListSource[] = {
3222
testFileUrl("stringlistproperties.qml"),
3223
testFileUrl("stringlistproperties-package.qml") };
3225
for (int i = 0; i < 2; ++i) {
3227
QTest::newRow("ListModel.items prepend, resolve prepended")
3228
<< listModelSource[i]
3229
<< QString("items.insert(0, {\"number\": \"eight\"})")
3230
<< QString("{ listModel.insert(0, {\"number\": \"seven\"}); items.resolve(0, 1) }")
3231
<< 5 << 5 << 5 << 0 << true << false << true << false << true
3232
<< QString("number")
3233
<< (QStringList() << "seven" << "one" << "two" << "three" << "four");
3235
QTest::newRow("ListModel.items prepend, resolve appended")
3236
<< listModelSource[i]
3237
<< QString("items.insert(0, {\"number\": \"eight\"})")
3238
<< QString("{ listModel.append({\"number\": \"seven\"}); items.resolve(0, 5) }")
3239
<< 5 << 5 << 5 << 4 << true << false << true << false << true
3240
<< QString("number")
3241
<< (QStringList() << "one" << "two" << "three" << "four" << "seven");
3243
QTest::newRow("ListModel.items prepend, resolve inserted")
3244
<< listModelSource[i]
3245
<< QString("items.insert(0, {\"number\": \"eight\"})")
3246
<< QString("{ listModel.insert(2, {\"number\": \"seven\"}); items.resolve(0, 3) }")
3247
<< 5 << 5 << 5 << 2 << true << false << true << false << true
3248
<< QString("number")
3249
<< (QStringList() << "one" << "two" << "seven" << "three" << "four");
3251
QTest::newRow("ListModel.items append, resolve prepended")
3252
<< listModelSource[i]
3253
<< QString("items.insert({\"number\": \"eight\"})")
3254
<< QString("{ listModel.insert(0, {\"number\": \"seven\"}); items.resolve(5, 0) }")
3255
<< 5 << 5 << 5 << 0 << true << false << true << false << true
3256
<< QString("number")
3257
<< (QStringList() << "seven" << "one" << "two" << "three" << "four");
3259
QTest::newRow("ListModel.items append, resolve appended")
3260
<< listModelSource[i]
3261
<< QString("items.insert({\"number\": \"eight\"})")
3262
<< QString("{ listModel.append({\"number\": \"seven\"}); items.resolve(5, 4) }")
3263
<< 5 << 5 << 5 << 4 << true << false << true << false << true
3264
<< QString("number")
3265
<< (QStringList() << "one" << "two" << "three" << "four" << "seven");
3267
QTest::newRow("ListModel.items append, resolve inserted")
3268
<< listModelSource[i]
3269
<< QString("items.insert({\"number\": \"eight\"})")
3270
<< QString("{ listModel.insert(2, {\"number\": \"seven\"}); items.resolve(5, 2) }")
3271
<< 5 << 5 << 5 << 2 << true << false << true << false << true
3272
<< QString("number")
3273
<< (QStringList() << "one" << "two" << "seven" << "three" << "four");
3275
QTest::newRow("ListModel.items insert, resolve prepended")
3276
<< listModelSource[i]
3277
<< QString("items.insert(2, {\"number\": \"eight\"})")
3278
<< QString("{ listModel.insert(0, {\"number\": \"seven\"}); items.resolve(3, 0) }")
3279
<< 5 << 5 << 5 << 0 << true << false << true << false << true
3280
<< QString("number")
3281
<< (QStringList() << "seven" << "one" << "two" << "three" << "four");
3283
QTest::newRow("ListModel.items insert, resolve appended")
3284
<< listModelSource[i]
3285
<< QString("items.insert(2, {\"number\": \"eight\"})")
3286
<< QString("{ listModel.append({\"number\": \"seven\"}); items.resolve(2, 5) }")
3287
<< 5 << 5 << 5 << 4 << true << false << true << false << true
3288
<< QString("number")
3289
<< (QStringList() << "one" << "two" << "three" << "four" << "seven");
3291
QTest::newRow("ListModel.items insert, resolve inserted")
3292
<< listModelSource[i]
3293
<< QString("items.insert(2, {\"number\": \"eight\"})")
3294
<< QString("{ listModel.insert(2, {\"number\": \"seven\"}); items.resolve(2, 3) }")
3295
<< 5 << 5 << 5 << 2 << true << false << true << false << true
3296
<< QString("number")
3297
<< (QStringList() << "one" << "two" << "seven" << "three" << "four");
3299
QTest::newRow("ListModel.items prepend, move resolved")
3300
<< listModelSource[i]
3301
<< QString("items.insert(0, {\"number\": \"eight\"})")
3302
<< QString("{ listModel.insert(0, {\"number\": \"seven\"}); "
3303
"items.resolve(0, 1); "
3304
"listModel.move(0, 2, 1) }")
3305
<< 5 << 5 << 5 << 2 << true << false << true << false << true
3306
<< QString("number")
3307
<< (QStringList() << "one" << "two" << "seven" << "three" << "four");
3309
QTest::newRow("ListModel.items append, move resolved")
3310
<< listModelSource[i]
3311
<< QString("items.insert({\"number\": \"eight\"})")
3312
<< QString("{ listModel.append({\"number\": \"seven\"}); "
3313
"items.resolve(5, 4); "
3314
"listModel.move(4, 2, 1) }")
3315
<< 5 << 5 << 5 << 2 << true << false << true << false << true
3316
<< QString("number")
3317
<< (QStringList() << "one" << "two" << "seven" << "three" << "four");
3319
QTest::newRow("ListModel.items insert, move resolved")
3320
<< listModelSource[i]
3321
<< QString("items.insert(2, {\"number\": \"eight\"})")
3322
<< QString("{ listModel.insert(2, {\"number\": \"seven\"}); "
3323
"items.resolve(2, 3);"
3324
"listModel.move(2, 0, 1) }")
3325
<< 5 << 5 << 5 << 0 << true << false << true << false << true
3326
<< QString("number")
3327
<< (QStringList() << "seven" << "one" << "two" << "three" << "four");
3329
QTest::newRow("ListModel.items prepend, remove resolved")
3330
<< listModelSource[i]
3331
<< QString("items.insert(0, {\"number\": \"eight\"})")
3332
<< QString("{ listModel.insert(0, {\"number\": \"seven\"}); "
3333
"items.resolve(0, 1); "
3334
"listModel.remove(0, 1) }")
3335
<< 5 << 4 << 4 << 4 << false << false << false << false << true
3336
<< QString("number")
3337
<< (QStringList() << "one" << "two" << "three" << "four");
3339
QTest::newRow("ListModel.items append, remove resolved")
3340
<< listModelSource[i]
3341
<< QString("items.insert({\"number\": \"eight\"})")
3342
<< QString("{ listModel.append({\"number\": \"seven\"}); "
3343
"items.resolve(5, 4); "
3344
"listModel.remove(4, 1) }")
3345
<< 5 << 4 << 4 << 4 << false << false << false << false << true
3346
<< QString("number")
3347
<< (QStringList() << "one" << "two" << "three" << "four");
3349
QTest::newRow("ListModel.items insert, remove resolved")
3350
<< listModelSource[i]
3351
<< QString("items.insert(2, {\"number\": \"eight\"})")
3352
<< QString("{ listModel.insert(2, {\"number\": \"seven\"}); "
3353
"items.resolve(2, 3);"
3354
"listModel.remove(2, 1) }")
3355
<< 5 << 4 << 4 << 4 << false << false << false << false << true
3356
<< QString("number")
3357
<< (QStringList() << "one" << "two" << "three" << "four");
3359
QTest::newRow("ListModel.selectedItems prepend, resolve prepended")
3360
<< listModelSource[i]
3361
<< QString("selectedItems.insert(0, {\"number\": \"eight\"})")
3362
<< QString("{ listModel.insert(0, {\"number\": \"seven\"}); "
3363
"selectedItems.resolve(selectedItems.get(0), items.get(0)) }")
3364
<< 4 << 5 << 5 << 0 << true << false << true << true << true
3365
<< QString("number")
3366
<< (QStringList() << "seven" << "one" << "two" << "three" << "four");
3368
QTest::newRow("ListModel.selectedItems prepend, resolve appended")
3369
<< listModelSource[i]
3370
<< QString("selectedItems.insert(0, {\"number\": \"eight\"})")
3371
<< QString("{ listModel.append({\"number\": \"seven\"}); "
3372
"selectedItems.resolve(selectedItems.get(0), items.get(4)) }")
3373
<< 4 << 5 << 5 << 4 << true << false << true << true << true
3374
<< QString("number")
3375
<< (QStringList() << "one" << "two" << "three" << "four" << "seven");
3377
QTest::newRow("ListModel.selectedItems prepend, resolve inserted")
3378
<< listModelSource[i]
3379
<< QString("selectedItems.insert(0, {\"number\": \"eight\"})")
3380
<< QString("{ listModel.insert(2, {\"number\": \"seven\"}); "
3381
"selectedItems.resolve(selectedItems.get(0), items.get(2)) }")
3382
<< 4 << 5 << 5 << 2 << true << false << true << true << true
3383
<< QString("number")
3384
<< (QStringList() << "one" << "two" << "seven" << "three" << "four");
3386
QTest::newRow("ListModel.selectedItems append, resolve prepended")
3387
<< listModelSource[i]
3388
<< QString("selectedItems.insert({\"number\": \"eight\"})")
3389
<< QString("{ listModel.insert(0, {\"number\": \"seven\"}); "
3390
"selectedItems.resolve(selectedItems.get(0), items.get(0)) }")
3391
<< 4 << 5 << 5 << 0 << true << false << true << true << true
3392
<< QString("number")
3393
<< (QStringList() << "seven" << "one" << "two" << "three" << "four");
3395
QTest::newRow("ListModel.selectedItems append, resolve appended")
3396
<< listModelSource[i]
3397
<< QString("selectedItems.insert({\"number\": \"eight\"})")
3398
<< QString("{ listModel.append({\"number\": \"seven\"}); "
3399
"selectedItems.resolve(selectedItems.get(0), items.get(4)) }")
3400
<< 4 << 5 << 5 << 4 << true << false << true << true << true
3401
<< QString("number")
3402
<< (QStringList() << "one" << "two" << "three" << "four" << "seven");
3404
QTest::newRow("ListModel.selectedItems append, resolve inserted")
3405
<< listModelSource[i]
3406
<< QString("selectedItems.insert({\"number\": \"eight\"})")
3407
<< QString("{ listModel.insert(2, {\"number\": \"seven\"}); "
3408
"selectedItems.resolve(selectedItems.get(0), items.get(2)) }")
3409
<< 4 << 5 << 5 << 2 << true << false << true << true << true
3410
<< QString("number")
3411
<< (QStringList() << "one" << "two" << "seven" << "three" << "four");
3413
// AbstractItemModel (Single Role)
3414
QTest::newRow("ListModel.items prepend, resolve prepended")
3415
<< singleRoleSource[i]
3416
<< QString("items.insert(0, {\"name\": \"eight\"})")
3417
<< QString("{ items.resolve(0, 1) }")
3418
<< 5 << 4 << 4 << 0 << true << false << true << false << true
3420
<< (QStringList() << "one" << "two" << "three" << "four");
3423
QTest::newRow("ListModel.items append, resolve appended")
3424
<< singleRoleSource[i]
3425
<< QString("items.insert({\"name\": \"eight\"})")
3426
<< QString("{ items.resolve(4, 3) }")
3427
<< 5 << 4 << 4 << 3 << true << false << true << false << true
3429
<< (QStringList() << "one" << "two" << "three" << "four");
3431
QTest::newRow("ListModel.items insert, resolve inserted")
3432
<< singleRoleSource[i]
3433
<< QString("items.insert(2, {\"name\": \"eight\"})")
3434
<< QString("{ items.resolve(2, 3) }")
3435
<< 5 << 4 << 4 << 2 << true << false << true << false << true
3437
<< (QStringList() << "one" << "two" << "three" << "four");
3439
// AbstractItemModel (Single Role)
3440
QTest::newRow("AbstractItemModel.items prepend, resolve prepended")
3441
<< singleRoleSource[i]
3442
<< QString("items.insert(0, {\"name\": \"eight\"})")
3443
<< QString("{ items.resolve(0, 1) }")
3444
<< 5 << 4 << 4 << 0 << true << false << true << false << true
3446
<< (QStringList() << "one" << "two" << "three" << "four");
3448
QTest::newRow("AbstractItemModel.items append, resolve appended")
3449
<< singleRoleSource[i]
3450
<< QString("items.insert({\"name\": \"eight\"})")
3451
<< QString("{ items.resolve(4, 3) }")
3452
<< 5 << 4 << 4 << 3 << true << false << true << false << true
3454
<< (QStringList() << "one" << "two" << "three" << "four");
3456
QTest::newRow("AbstractItemModel.items insert, resolve inserted")
3457
<< singleRoleSource[i]
3458
<< QString("items.insert(2, {\"name\": \"eight\"})")
3459
<< QString("{ items.resolve(2, 3) }")
3460
<< 5 << 4 << 4 << 2 << true << false << true << false << true
3462
<< (QStringList() << "one" << "two" << "three" << "four");
3464
// AbstractItemModel (Multiple Roles)
3465
QTest::newRow("StandardItemModel.items prepend, resolve prepended")
3466
<< multipleRoleSource[i]
3467
<< QString("items.insert(0, {\"display\": \"Row 8 Item\"})")
3468
<< QString("{ items.resolve(0, 1) }")
3469
<< 5 << 4 << 4 << 0 << true << false << true << false << false
3470
<< QString("display")
3471
<< (QStringList() << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
3473
QTest::newRow("StandardItemModel.items append, resolve appended")
3474
<< multipleRoleSource[i]
3475
<< QString("items.insert({\"display\": \"Row 8 Item\"})")
3476
<< QString("{ items.resolve(4, 3) }")
3477
<< 5 << 4 << 4 << 3 << true << false << true << false << false
3478
<< QString("display")
3479
<< (QStringList() << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
3481
QTest::newRow("StandardItemModel.items insert, resolve inserted")
3482
<< multipleRoleSource[i]
3483
<< QString("items.insert(2, {\"display\": \"Row 8 Item\"})")
3484
<< QString("{ items.resolve(2, 3) }")
3485
<< 5 << 4 << 4 << 2 << true << false << true << false << false
3486
<< QString("display")
3487
<< (QStringList() << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
3490
QTest::newRow("StringList.items prepend, resolve prepended")
3491
<< stringListSource[i]
3492
<< QString("items.insert(0, {\"modelData\": \"eight\"})")
3493
<< QString("{ items.resolve(0, 1) }")
3494
<< 5 << 4 << 4 << 0 << true << false << true << false << false
3495
<< QString("modelData")
3496
<< (QStringList() << "one" << "two" << "three" << "four");
3498
QTest::newRow("StringList.items append, resolve appended")
3499
<< stringListSource[i]
3500
<< QString("items.insert({\"modelData\": \"eight\"})")
3501
<< QString("{ items.resolve(4, 3) }")
3502
<< 5 << 4 << 4 << 3 << true << false << true << false << false
3503
<< QString("modelData")
3504
<< (QStringList() << "one" << "two" << "three" << "four");
3506
QTest::newRow("StringList.items insert, resolve inserted")
3507
<< stringListSource[i]
3508
<< QString("items.insert(2, {\"modelData\": \"eight\"})")
3509
<< QString("{ items.resolve(2, 3) }")
3510
<< 5 << 4 << 4 << 2 << true << false << true << false << false
3511
<< QString("modelData")
3512
<< (QStringList() << "one" << "two" << "three" << "four");
3516
void tst_qquickvisualdatamodel::resolve()
3518
QFETCH(QUrl, source);
3519
QFETCH(QString, setupExpression);
3520
QFETCH(QString, resolveExpression);
3521
QFETCH(int, unresolvedCount);
3522
QFETCH(int, modelCount);
3523
QFETCH(int, visualCount);
3525
QFETCH(bool, inItems);
3526
QFETCH(bool, persisted);
3527
QFETCH(bool, visible);
3528
QFETCH(bool, selected);
3529
QFETCH(bool, modelData);
3530
QFETCH(QString, property);
3531
QFETCH(QStringList, propertyData);
3533
QQuickWindow window;
3535
QQmlComponent component(&engine);
3536
component.loadUrl(source);
3537
QScopedPointer<QObject> object(component.create());
3538
QQuickListView *listView = qobject_cast<QQuickListView *>(object.data());
3540
listView->setParentItem(window.contentItem());
3542
QQuickItem *contentItem = listView->contentItem();
3543
QVERIFY(contentItem);
3545
QObject *visualModel = listView->findChild<QObject *>("visualModel");
3546
QVERIFY(visualModel);
3548
evaluate<void>(visualModel, setupExpression);
3549
QCOMPARE(evaluate<int>(listView, "count"), unresolvedCount);
3551
evaluate<void>(visualModel, resolveExpression);
3553
QCOMPARE(evaluate<int>(listView, "count"), inItems ? visualCount : modelCount);
3554
QCOMPARE(evaluate<int>(visualModel, "count"), inItems ? visualCount : modelCount);
3555
QCOMPARE(evaluate<int>(visualModel, "items.count"), inItems ? visualCount : modelCount);
3556
QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), persisted ? 1 : 0);
3557
QCOMPARE(evaluate<int>(visualModel, "visibleItems.count"), visible ? visualCount : modelCount);
3558
QCOMPARE(evaluate<int>(visualModel, "selectedItems.count"), selected ? 1 : 0);
3560
QCOMPARE(propertyData.count(), visualCount);
3561
for (int i = 0; i < visualCount; ++i) {
3564
const int itemsIndex = inItems || i <= index ? i : i - 1;
3568
get = QString("items.get(%1)").arg(itemsIndex);
3570
QQuickItem *item = findItem<QQuickItem>(contentItem, "delegate", modelIndex);
3573
QCOMPARE(evaluate<int>(item, "test1"), modelIndex);
3574
QCOMPARE(evaluate<int>(item, "test2"), modelIndex);
3575
QCOMPARE(evaluate<QString>(item, "test3"), propertyData.at(i));
3576
QCOMPARE(evaluate<QString>(item, "test4"), propertyData.at(i));
3579
QCOMPARE(evaluate<QString>(item, "test5"), propertyData.at(i));
3580
QCOMPARE(evaluate<QString>(item, "test6"), propertyData.at(i));
3583
QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inItems"), true);
3584
QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inPersistedItems"), false);
3585
QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inVisible"), true);
3586
QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inSelected"), false);
3587
QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.isUnresolved"), false);
3589
QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.itemsIndex"), itemsIndex);
3590
QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.persistedItemsIndex"), persisted && i > index ? 1 : 0);
3591
QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.visibleIndex"), visible || i <= index ? i : i - 1);
3592
QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.selectedIndex"), selected && i > index ? 1 : 0);
3593
} else if (inItems) {
3594
get = QString("items.get(%1)").arg(index);
3595
} else if (persisted) {
3596
get = "persistedItems.get(0)";
3597
} else if (visible) {
3598
get = QString("visibleItems.get(%1)").arg(index);
3599
} else if (selected) {
3600
get = "selectedItems.get(0)";
3605
QCOMPARE(evaluate<int>(visualModel, get + ".model.index"), modelIndex);
3607
QCOMPARE(evaluate<QString>(visualModel, get + ".model." + property), propertyData.at(i));
3609
QCOMPARE(evaluate<bool>(visualModel, get + ".inItems"), inItems || i != index);
3610
QCOMPARE(evaluate<bool>(visualModel, get + ".inPersistedItems"), persisted && i == index);
3611
QCOMPARE(evaluate<bool>(visualModel, get + ".inVisible"), visible || i != index);
3612
QCOMPARE(evaluate<bool>(visualModel, get + ".inSelected"), selected && i == index);
3613
QCOMPARE(evaluate<bool>(visualModel, get + ".isUnresolved"), false);
3615
QCOMPARE(evaluate<int>(visualModel, get + ".itemsIndex"), inItems || i <= index ? i : i - 1);
3616
QCOMPARE(evaluate<int>(visualModel, get + ".persistedItemsIndex"), persisted && i > index ? 1 : 0);
3617
QCOMPARE(evaluate<int>(visualModel, get + ".visibleIndex"), visible || i <= index ? i : i - 1);
3618
QCOMPARE(evaluate<int>(visualModel, get + ".selectedIndex"), selected && i > index ? 1 : 0);
3624
item = evaluate<QObject *>(visualModel, QString("items.create(%1)").arg(index));
3626
item = evaluate<QObject *>(visualModel, QString("persistedItems.create(%1)").arg(0));
3628
item = evaluate<QObject *>(visualModel, QString("visibleItems.create(%1)").arg(index));
3630
item = evaluate<QObject *>(visualModel, QString("selectedItems.create(%1)").arg(0));
3636
QCOMPARE(evaluate<int>(item, "test1"), index);
3637
QCOMPARE(evaluate<int>(item, "test2"), index);
3638
QCOMPARE(evaluate<QString>(item, "test3"), propertyData.at(index));
3639
QCOMPARE(evaluate<QString>(item, "test4"), propertyData.at(index));
3642
QCOMPARE(evaluate<QString>(item, "test5"), propertyData.at(index));
3643
QCOMPARE(evaluate<QString>(item, "test6"), propertyData.at(index));
3646
QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inItems"), inItems);
3647
QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inPersistedItems"), true);
3648
QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inVisible"), visible);
3649
QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inSelected"), selected);
3650
QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.isUnresolved"), false);
3652
QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.itemsIndex"), index);
3653
QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.persistedItemsIndex"), 0);
3654
QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.visibleIndex"), index);
3655
QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.selectedIndex"), 0);
3658
void tst_qquickvisualdatamodel::warnings_data()
3660
QTest::addColumn<QUrl>("source");
3661
QTest::addColumn<QString>("expression");
3662
QTest::addColumn<QString>("warning");
3663
QTest::addColumn<int>("count");
3665
QTest::newRow("insert < 0")
3666
<< testFileUrl("listmodelproperties.qml")
3667
<< QString("items.insert(-2, {\"number\": \"eight\"})")
3668
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("insert: index out of range"))
3671
QTest::newRow("insert > length")
3672
<< testFileUrl("listmodelproperties.qml")
3673
<< QString("items.insert(8, {\"number\": \"eight\"})")
3674
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("insert: index out of range"))
3677
QTest::newRow("create < 0")
3678
<< testFileUrl("listmodelproperties.qml")
3679
<< QString("items.create(-2, {\"number\": \"eight\"})")
3680
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("create: index out of range"))
3683
QTest::newRow("create > length")
3684
<< testFileUrl("listmodelproperties.qml")
3685
<< QString("items.create(8, {\"number\": \"eight\"})")
3686
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("create: index out of range"))
3689
QTest::newRow("resolve from < 0")
3690
<< testFileUrl("listmodelproperties.qml")
3691
<< QString("items.resolve(-2, 3)")
3692
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: from index out of range"))
3695
QTest::newRow("resolve from > length")
3696
<< testFileUrl("listmodelproperties.qml")
3697
<< QString("items.resolve(8, 3)")
3698
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: from index out of range"))
3701
QTest::newRow("resolve to < 0")
3702
<< testFileUrl("listmodelproperties.qml")
3703
<< QString("items.resolve(3, -2)")
3704
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: to index out of range"))
3707
QTest::newRow("resolve to > length")
3708
<< testFileUrl("listmodelproperties.qml")
3709
<< QString("items.resolve(3, 8)")
3710
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: to index out of range"))
3713
QTest::newRow("resolve from invalid index")
3714
<< testFileUrl("listmodelproperties.qml")
3715
<< QString("items.resolve(\"two\", 3)")
3716
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: from index invalid"))
3719
QTest::newRow("resolve to invalid index")
3720
<< testFileUrl("listmodelproperties.qml")
3721
<< QString("items.resolve(3, \"two\")")
3722
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: to index invalid"))
3725
QTest::newRow("resolve already resolved item")
3726
<< testFileUrl("listmodelproperties.qml")
3727
<< QString("items.resolve(3, 2)")
3728
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: from is not an unresolved item"))
3731
QTest::newRow("resolve already resolved item")
3732
<< testFileUrl("listmodelproperties.qml")
3733
<< QString("{ items.insert(0, {\"number\": \"eight\"});"
3734
"items.insert(1, {\"number\": \"seven\"});"
3735
"items.resolve(0, 1)}")
3736
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: to is not a model item"))
3739
QTest::newRow("remove index < 0")
3740
<< testFileUrl("listmodelproperties.qml")
3741
<< QString("items.remove(-2, 1)")
3742
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("remove: index out of range"))
3745
QTest::newRow("remove index == length")
3746
<< testFileUrl("listmodelproperties.qml")
3747
<< QString("items.remove(4, 1)")
3748
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("remove: index out of range"))
3751
QTest::newRow("remove index > length")
3752
<< testFileUrl("listmodelproperties.qml")
3753
<< QString("items.remove(9, 1)")
3754
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("remove: index out of range"))
3757
QTest::newRow("remove invalid index")
3758
<< testFileUrl("listmodelproperties.qml")
3759
<< QString("items.remove(\"nine\", 1)")
3760
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("remove: invalid index"))
3763
QTest::newRow("remove count < 0")
3764
<< testFileUrl("listmodelproperties.qml")
3765
<< QString("items.remove(1, -2)")
3766
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("remove: invalid count"))
3769
QTest::newRow("remove index + count > length")
3770
<< testFileUrl("listmodelproperties.qml")
3771
<< QString("items.remove(2, 4, \"selected\")")
3772
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("remove: invalid count"))
3775
QTest::newRow("addGroups index < 0")
3776
<< testFileUrl("listmodelproperties.qml")
3777
<< QString("items.addGroups(-2, 1, \"selected\")")
3778
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("addGroups: index out of range"))
3781
QTest::newRow("addGroups index == length")
3782
<< testFileUrl("listmodelproperties.qml")
3783
<< QString("items.addGroups(4, 1, \"selected\")")
3784
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("addGroups: index out of range"))
3787
QTest::newRow("addGroups index > length")
3788
<< testFileUrl("listmodelproperties.qml")
3789
<< QString("items.addGroups(9, 1, \"selected\")")
3790
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("addGroups: index out of range"))
3793
QTest::newRow("addGroups count < 0")
3794
<< testFileUrl("listmodelproperties.qml")
3795
<< QString("items.addGroups(1, -2, \"selected\")")
3796
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("addGroups: invalid count"))
3799
QTest::newRow("addGroups index + count > length")
3800
<< testFileUrl("listmodelproperties.qml")
3801
<< QString("items.addGroups(2, 4, \"selected\")")
3802
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("addGroups: invalid count"))
3805
QTest::newRow("removeGroups index < 0")
3806
<< testFileUrl("listmodelproperties.qml")
3807
<< QString("items.removeGroups(-2, 1, \"selected\")")
3808
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("removeGroups: index out of range"))
3811
QTest::newRow("removeGroups index == length")
3812
<< testFileUrl("listmodelproperties.qml")
3813
<< QString("items.removeGroups(4, 1, \"selected\")")
3814
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("removeGroups: index out of range"))
3817
QTest::newRow("removeGroups index > length")
3818
<< testFileUrl("listmodelproperties.qml")
3819
<< QString("items.removeGroups(9, 1, \"selected\")")
3820
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("removeGroups: index out of range"))
3823
QTest::newRow("removeGroups count < 0")
3824
<< testFileUrl("listmodelproperties.qml")
3825
<< QString("items.removeGroups(1, -2, \"selected\")")
3826
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("removeGroups: invalid count"))
3829
QTest::newRow("removeGroups index + count > length")
3830
<< testFileUrl("listmodelproperties.qml")
3831
<< QString("items.removeGroups(2, 4, \"selected\")")
3832
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("removeGroups: invalid count"))
3835
QTest::newRow("setGroups index < 0")
3836
<< testFileUrl("listmodelproperties.qml")
3837
<< QString("items.setGroups(-2, 1, \"selected\")")
3838
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("setGroups: index out of range"))
3841
QTest::newRow("setGroups index == length")
3842
<< testFileUrl("listmodelproperties.qml")
3843
<< QString("items.setGroups(4, 1, \"selected\")")
3844
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("setGroups: index out of range"))
3847
QTest::newRow("setGroups index > length")
3848
<< testFileUrl("listmodelproperties.qml")
3849
<< QString("items.setGroups(9, 1, \"selected\")")
3850
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("setGroups: index out of range"))
3853
QTest::newRow("setGroups count < 0")
3854
<< testFileUrl("listmodelproperties.qml")
3855
<< QString("items.setGroups(1, -2, \"selected\")")
3856
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("setGroups: invalid count"))
3859
QTest::newRow("setGroups index + count > length")
3860
<< testFileUrl("listmodelproperties.qml")
3861
<< QString("items.setGroups(2, 4, \"selected\")")
3862
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("setGroups: invalid count"))
3865
QTest::newRow("move from < 0")
3866
<< testFileUrl("listmodelproperties.qml")
3867
<< QString("items.move(-2, 1, 1)")
3868
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: from index out of range"))
3871
QTest::newRow("move from == length")
3872
<< testFileUrl("listmodelproperties.qml")
3873
<< QString("items.move(4, 1, 1)")
3874
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: from index out of range"))
3877
QTest::newRow("move from > length")
3878
<< testFileUrl("listmodelproperties.qml")
3879
<< QString("items.move(9, 1, 1)")
3880
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: from index out of range"))
3883
QTest::newRow("move invalid from")
3884
<< testFileUrl("listmodelproperties.qml")
3885
<< QString("items.move(\"nine\", 1, 1)")
3886
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: invalid from index"))
3889
QTest::newRow("move to < 0")
3890
<< testFileUrl("listmodelproperties.qml")
3891
<< QString("items.move(1, -2, 1)")
3892
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: to index out of range"))
3895
QTest::newRow("move to == length")
3896
<< testFileUrl("listmodelproperties.qml")
3897
<< QString("items.move(1, 4, 1)")
3898
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: to index out of range"))
3901
QTest::newRow("move to > length")
3902
<< testFileUrl("listmodelproperties.qml")
3903
<< QString("items.move(1, 9, 1)")
3904
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: to index out of range"))
3907
QTest::newRow("move invalid to")
3908
<< testFileUrl("listmodelproperties.qml")
3909
<< QString("items.move(1, \"nine\", 1)")
3910
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: invalid to index"))
3913
QTest::newRow("move count < 0")
3914
<< testFileUrl("listmodelproperties.qml")
3915
<< QString("items.move(1, 1, -2)")
3916
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: invalid count"))
3919
QTest::newRow("move from + count > length")
3920
<< testFileUrl("listmodelproperties.qml")
3921
<< QString("items.move(2, 1, 4)")
3922
<< ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: from index out of range"))
3926
void tst_qquickvisualdatamodel::warnings()
3928
QFETCH(QUrl, source);
3929
QFETCH(QString, expression);
3930
QFETCH(QString, warning);
3933
QQuickWindow window;
3935
QQmlComponent component(&engine);
3936
component.loadUrl(source);
3937
QScopedPointer<QObject> object(component.create());
3938
QQuickListView *listView = qobject_cast<QQuickListView *>(object.data());
3940
listView->setParentItem(window.contentItem());
3942
QQuickItem *contentItem = listView->contentItem();
3943
QVERIFY(contentItem);
3945
QObject *visualModel = evaluate<QObject *>(listView, "model");
3946
QVERIFY(visualModel);
3948
QTest::ignoreMessage(QtWarningMsg, warning.toUtf8());
3950
evaluate<void>(visualModel, expression);
3951
QCOMPARE(evaluate<int>(listView, "count"), count);
3954
void tst_qquickvisualdatamodel::invalidAttachment()
3956
QQmlComponent component(&engine);
3957
component.loadUrl(testFileUrl("invalidAttachment.qml"));
3959
QScopedPointer<QObject> object(component.create());
3961
QCOMPARE(component.errors().count(), 0);
3963
QVariant property = object->property("invalidVdm");
3964
QCOMPARE(property.userType(), qMetaTypeId<QQuickVisualDataModel *>());
3965
QVERIFY(!property.value<QQuickVisualDataModel *>());
3967
QQuickItem *item = findItem<QQuickItem>(static_cast<QQuickItem *>(object.data()), "delegate");
3970
property = item->property("validVdm");
3971
QCOMPARE(property.userType(), qMetaTypeId<QQuickVisualDataModel *>());
3972
QVERIFY(property.value<QQuickVisualDataModel *>());
3974
property = item->property("invalidVdm");
3975
QCOMPARE(property.userType(), qMetaTypeId<QQuickVisualDataModel *>());
3976
QVERIFY(!property.value<QQuickVisualDataModel *>());
3979
void tst_qquickvisualdatamodel::asynchronousInsert_data()
3981
QTest::addColumn<int>("requestIndex");
3982
QTest::addColumn<int>("insertIndex");
3983
QTest::addColumn<int>("insertCount");
3984
QTest::addColumn<int>("completeIndex");
3986
QTest::newRow("insert before") << 4 << 1 << 3 << 7;
3987
QTest::newRow("insert after") << 4 << 6 << 3 << 4;
3988
QTest::newRow("insert at") << 4 << 4 << 3 << 7;
3991
void tst_qquickvisualdatamodel::asynchronousInsert()
3993
QFETCH(int, requestIndex);
3994
QFETCH(int, insertIndex);
3995
QFETCH(int, insertCount);
3996
QFETCH(int, completeIndex);
3998
QCOMPARE(controller.incubatingObjectCount(), 0);
4000
QQmlComponent c(&engine, testFileUrl("visualdatamodel.qml"));
4003
for (int i = 0; i < 8; i++)
4004
model.addItem("Original item" + QString::number(i), "");
4006
engine.rootContext()->setContextProperty("myModel", &model);
4008
QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel*>(c.create());
4009
QVERIFY(visualModel);
4011
ItemRequester requester;
4012
connect(visualModel, SIGNAL(initItem(int,QQuickItem*)), &requester, SLOT(initItem(int,QQuickItem*)));
4013
connect(visualModel, SIGNAL(createdItem(int,QQuickItem*)), &requester, SLOT(createdItem(int,QQuickItem*)));
4014
connect(visualModel, SIGNAL(destroyingItem(QQuickItem*)), &requester, SLOT(destroyingItem(QQuickItem*)));
4016
QQuickItem *item = visualModel->item(requestIndex, true);
4019
QVERIFY(!requester.itemInitialized);
4020
QVERIFY(!requester.itemCreated);
4021
QVERIFY(!requester.itemDestroyed);
4023
QList<QPair<QString, QString> > newItems;
4024
for (int i = 0; i < insertCount; i++)
4025
newItems.append(qMakePair(QLatin1String("New item") + QString::number(i), QString(QLatin1String(""))));
4026
model.insertItems(insertIndex, newItems);
4028
item = visualModel->item(completeIndex, false);
4031
QCOMPARE(requester.itemInitialized, item);
4032
QCOMPARE(requester.indexInitialized, completeIndex);
4033
QCOMPARE(requester.itemCreated, item);
4034
QCOMPARE(requester.indexCreated, completeIndex);
4035
QVERIFY(!requester.itemDestroyed);
4037
QCOMPARE(controller.incubatingObjectCount(), 0);
4039
visualModel->release(item);
4041
QCOMPARE(requester.itemDestroyed, item);
4044
void tst_qquickvisualdatamodel::asynchronousRemove_data()
4046
QTest::addColumn<int>("requestIndex");
4047
QTest::addColumn<int>("removeIndex");
4048
QTest::addColumn<int>("removeCount");
4049
QTest::addColumn<int>("completeIndex");
4051
QTest::newRow("remove before") << 4 << 1 << 3 << 1;
4052
QTest::newRow("remove after") << 4 << 6 << 2 << 4;
4053
QTest::newRow("remove requested") << 4 << 4 << 3 << -1;
4056
void tst_qquickvisualdatamodel::asynchronousRemove()
4058
QFETCH(int, requestIndex);
4059
QFETCH(int, removeIndex);
4060
QFETCH(int, removeCount);
4061
QFETCH(int, completeIndex);
4063
QCOMPARE(controller.incubatingObjectCount(), 0);
4065
QQmlComponent c(&engine, testFileUrl("visualdatamodel.qml"));
4068
for (int i = 0; i < 8; i++)
4069
model.addItem("Original item" + QString::number(i), "");
4071
engine.rootContext()->setContextProperty("myModel", &model);
4073
QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel*>(c.create());
4074
QVERIFY(visualModel);
4076
ItemRequester requester;
4077
connect(visualModel, SIGNAL(initItem(int,QQuickItem*)), &requester, SLOT(initItem(int,QQuickItem*)));
4078
connect(visualModel, SIGNAL(createdItem(int,QQuickItem*)), &requester, SLOT(createdItem(int,QQuickItem*)));
4079
connect(visualModel, SIGNAL(destroyingItem(QQuickItem*)), &requester, SLOT(destroyingItem(QQuickItem*)));
4081
QQuickItem *item = visualModel->item(requestIndex, true);
4084
QVERIFY(!requester.itemInitialized);
4085
QVERIFY(!requester.itemCreated);
4086
QVERIFY(!requester.itemDestroyed);
4088
model.removeItems(removeIndex, removeCount);
4090
if (completeIndex == -1) {
4091
QElapsedTimer timer;
4094
controller.incubateFor(50);
4095
} while (timer.elapsed() < 1000 && controller.incubatingObjectCount() > 0);
4097
QVERIFY(requester.itemInitialized);
4098
QCOMPARE(requester.itemCreated, requester.itemInitialized);
4099
QCOMPARE(requester.itemDestroyed, requester.itemInitialized);
4101
item = visualModel->item(completeIndex, false);
4104
QCOMPARE(requester.itemInitialized, item);
4105
QCOMPARE(requester.indexInitialized, completeIndex);
4106
QCOMPARE(requester.itemCreated, item);
4107
QCOMPARE(requester.indexCreated, completeIndex);
4108
QVERIFY(!requester.itemDestroyed);
4110
QCOMPARE(controller.incubatingObjectCount(), 0);
4112
visualModel->release(item);
4114
QCOMPARE(requester.itemDestroyed, item);
4118
void tst_qquickvisualdatamodel::asynchronousMove_data()
4120
QTest::addColumn<int>("requestIndex");
4121
QTest::addColumn<int>("from");
4122
QTest::addColumn<int>("to");
4123
QTest::addColumn<int>("count");
4124
QTest::addColumn<int>("completeIndex");
4126
QTest::newRow("move before") << 4 << 1 << 0 << 3 << 4;
4127
QTest::newRow("move after") << 4 << 6 << 5 << 2 << 4;
4128
QTest::newRow("move requested") << 4 << 4 << 3 << 2 << 3;
4129
QTest::newRow("move before to after") << 4 << 1 << 4 << 3 << 1;
4130
QTest::newRow("move after to before") << 4 << 6 << 2 << 2 << 6;
4133
void tst_qquickvisualdatamodel::asynchronousMove()
4135
QFETCH(int, requestIndex);
4139
QFETCH(int, completeIndex);
4141
QCOMPARE(controller.incubatingObjectCount(), 0);
4143
QQmlComponent c(&engine, testFileUrl("visualdatamodel.qml"));
4146
for (int i = 0; i < 8; i++)
4147
model.addItem("Original item" + QString::number(i), "");
4149
engine.rootContext()->setContextProperty("myModel", &model);
4151
QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel*>(c.create());
4152
QVERIFY(visualModel);
4154
ItemRequester requester;
4155
connect(visualModel, SIGNAL(initItem(int,QQuickItem*)), &requester, SLOT(initItem(int,QQuickItem*)));
4156
connect(visualModel, SIGNAL(createdItem(int,QQuickItem*)), &requester, SLOT(createdItem(int,QQuickItem*)));
4157
connect(visualModel, SIGNAL(destroyingItem(QQuickItem*)), &requester, SLOT(destroyingItem(QQuickItem*)));
4159
QQuickItem *item = visualModel->item(requestIndex, true);
4162
QVERIFY(!requester.itemInitialized);
4163
QVERIFY(!requester.itemCreated);
4164
QVERIFY(!requester.itemDestroyed);
4166
model.moveItems(from, to, count);
4168
item = visualModel->item(completeIndex, false);
4172
QCOMPARE(requester.itemInitialized, item);
4173
QCOMPARE(requester.indexInitialized, completeIndex);
4174
QCOMPARE(requester.itemCreated, item);
4175
QCOMPARE(requester.indexCreated, completeIndex);
4176
QVERIFY(!requester.itemDestroyed);
4178
QCOMPARE(controller.incubatingObjectCount(), 0);
4180
visualModel->release(item);
4182
QCOMPARE(requester.itemDestroyed, item);
4185
void tst_qquickvisualdatamodel::asynchronousCancel()
4187
const int requestIndex = 4;
4189
QCOMPARE(controller.incubatingObjectCount(), 0);
4191
QQmlComponent c(&engine, testFileUrl("visualdatamodel.qml"));
4194
for (int i = 0; i < 8; i++)
4195
model.addItem("Original item" + QString::number(i), "");
4197
engine.rootContext()->setContextProperty("myModel", &model);
4199
QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel*>(c.create());
4200
QVERIFY(visualModel);
4202
QQuickItem *item = visualModel->item(requestIndex, true);
4204
QCOMPARE(controller.incubatingObjectCount(), 1);
4206
visualModel->cancel(requestIndex);
4207
QCOMPARE(controller.incubatingObjectCount(), 0);
4210
void tst_qquickvisualdatamodel::invalidContext()
4214
for (int i = 0; i < 8; i++)
4215
model.addItem("Original item" + QString::number(i), "");
4217
engine.rootContext()->setContextProperty("myModel", &model);
4219
QScopedPointer<QQmlContext> context(new QQmlContext(engine.rootContext()));
4221
QQmlComponent c(&engine, testFileUrl("visualdatamodel.qml"));
4224
QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel*>(c.create(context.data()));
4225
QVERIFY(visualModel);
4227
QQuickItem *item = visualModel->item(4, false);
4229
visualModel->release(item);
4231
delete context.take();
4233
model.insertItem(4, "new item", "");
4235
item = visualModel->item(4, false);
4239
QTEST_MAIN(tst_qquickvisualdatamodel)
4241
#include "tst_qquickvisualdatamodel.moc"