1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the test suite of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
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 QAbstractListModel
88 Q_PROPERTY(QStringList values READ getList WRITE setList)
90 SingleRoleModel(const QByteArray &role = "name", QObject *parent = 0)
91 : QAbstractListModel(parent)
93 QHash<int, QByteArray> roles;
94 roles.insert(Qt::DisplayRole , role);
96 list << "one" << "two" << "three" << "four";
99 void emitMove(int sourceFirst, int sourceLast, int destinationChild) {
100 emit beginMoveRows(QModelIndex(), sourceFirst, sourceLast, QModelIndex(), destinationChild);
106 QStringList getList() const { return list; }
107 void setList(const QStringList &l) { list = l; }
110 void set(int idx, QString string) {
112 emit dataChanged(index(idx,0), index(idx,0));
116 int rowCount(const QModelIndex & /* parent */ = QModelIndex()) const {
119 QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const {
120 if (role == Qt::DisplayRole)
121 return list.at(index.row());
126 class StandardItem : public QObject, public QStandardItem
129 Q_PROPERTY(QString text READ readText WRITE setText)
132 QString readText() const { return text(); }
133 void writeText(const QString &text) { setText(text); }
136 class StandardItemModel : public QStandardItemModel
139 Q_PROPERTY(QQmlListProperty<StandardItem> items READ items CONSTANT)
140 Q_CLASSINFO("DefaultProperty", "items")
142 QQmlListProperty<StandardItem> items() { return QQmlListProperty<StandardItem>(this, 0, append); }
144 static void append(QQmlListProperty<StandardItem> *property, StandardItem *item)
146 static_cast<QStandardItemModel *>(property->object)->appendRow(item);
150 class DataSubObject : public QObject
154 Q_PROPERTY(QString subName READ subName WRITE setSubName NOTIFY subNameChanged)
157 DataSubObject(QObject *parent=0) : QObject(parent) {}
159 QString subName() const { return m_subName; }
160 void setSubName(const QString &name) {
161 if (name != m_subName) {
163 emit subNameChanged();
168 void subNameChanged();
174 class DataObject : public QObject
178 Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
179 Q_PROPERTY(QString color READ color WRITE setColor NOTIFY colorChanged)
180 Q_PROPERTY(QObject *object READ object)
183 DataObject(QObject *parent=0) : QObject(parent) {}
184 DataObject(const QString &name, const QString &color, QObject *parent=0)
185 : QObject(parent), m_name(name), m_color(color), m_object(new DataSubObject(this)) { }
188 QString name() const { return m_name; }
189 void setName(const QString &name) {
190 if (name != m_name) {
196 QString color() const { return m_color; }
197 void setColor(const QString &color) {
198 if (color != m_color) {
204 QObject *object() const { return m_object; }
205 void setSubName(const QString &sn) {
206 m_object->setSubName(sn);
216 DataSubObject *m_object;
219 class ItemRequester : public QObject
223 ItemRequester(QObject *parent = 0)
228 , indexInitialized(-1)
233 QQuickItem *itemInitialized;
234 QQuickItem *itemCreated;
235 QQuickItem *itemDestroyed;
236 int indexInitialized;
240 void initItem(int index, QQuickItem *item)
242 itemInitialized = item;
243 indexInitialized = index;
246 void createdItem(int index, QQuickItem *item)
249 indexCreated = index;
252 void destroyingItem(QQuickItem *item)
254 itemDestroyed = item;
258 QML_DECLARE_TYPE(SingleRoleModel)
259 QML_DECLARE_TYPE(DataObject)
260 QML_DECLARE_TYPE(StandardItem)
261 QML_DECLARE_TYPE(StandardItemModel)
263 class tst_qquickvisualdatamodel : public QQmlDataTest
267 tst_qquickvisualdatamodel();
271 void cleanupTestCase();
273 void updateLayout_data();
275 void childChanged_data();
277 void noDelegate_data();
279 void itemsDestroyed_data();
280 void itemsDestroyed();
281 void objectListModel();
283 void modelProperties();
284 void packagesDestroyed();
285 void qaimRowsMoved();
286 void qaimRowsMoved_data();
293 void invalidGroups();
295 void onChanged_data();
298 void incompleteModel();
303 void warnings_data();
305 void invalidAttachment();
306 void asynchronousInsert_data();
307 void asynchronousInsert();
308 void asynchronousRemove_data();
309 void asynchronousRemove();
310 void asynchronousMove();
311 void asynchronousMove_data();
312 void asynchronousCancel();
315 template <int N> void groups_verify(
316 const SingleRoleModel &model,
317 QQuickItem *contentItem,
318 const int (&mIndex)[N],
319 const int (&iIndex)[N],
320 const int (&vIndex)[N],
321 const int (&sIndex)[N],
322 const bool (&vMember)[N],
323 const bool (&sMember)[N]);
325 template <int N> void get_verify(
326 const SingleRoleModel &model,
327 QQuickVisualDataModel *visualModel,
328 QQuickVisualDataGroup *visibleItems,
329 QQuickVisualDataGroup *selectedItems,
330 const int (&mIndex)[N],
331 const int (&iIndex)[N],
332 const int (&vIndex)[N],
333 const int (&sIndex)[N],
334 const bool (&vMember)[N],
335 const bool (&sMember)[N]);
338 QQmlIncubationController controller;
342 Q_DECLARE_METATYPE(QQuickChangeSet)
344 template <typename T> static T evaluate(QObject *scope, const QString &expression)
346 QQmlExpression expr(qmlContext(scope), scope, expression);
347 T result = expr.evaluate().value<T>();
349 qWarning() << expr.error().toString();
353 template <> void evaluate<void>(QObject *scope, const QString &expression)
355 QQmlExpression expr(qmlContext(scope), scope, expression);
358 qWarning() << expr.error().toString();
361 void tst_qquickvisualdatamodel::initTestCase()
363 QQmlDataTest::initTestCase();
364 qRegisterMetaType<QQuickChangeSet>();
366 qmlRegisterType<SingleRoleModel>("tst_qquickvisualdatamodel", 1, 0, "SingleRoleModel");
367 qmlRegisterType<DataObject>("tst_qquickvisualdatamodel", 1, 0, "DataObject");
368 qmlRegisterType<StandardItem>("tst_qquickvisualdatamodel", 1, 0, "StandardItem");
369 qmlRegisterType<StandardItemModel>("tst_qquickvisualdatamodel", 1, 0, "StandardItemModel");
371 engine.setIncubationController(&controller);
374 void tst_qquickvisualdatamodel::cleanupTestCase()
378 tst_qquickvisualdatamodel::tst_qquickvisualdatamodel()
382 void tst_qquickvisualdatamodel::rootIndex()
385 QQmlComponent c(&engine, testFileUrl("visualdatamodel.qml"));
387 QStandardItemModel model;
388 initStandardTreeModel(&model);
390 engine.rootContext()->setContextProperty("myModel", &model);
392 QQuickVisualDataModel *obj = qobject_cast<QQuickVisualDataModel*>(c.create());
395 QMetaObject::invokeMethod(obj, "setRoot");
396 QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == model.index(0,0));
398 QMetaObject::invokeMethod(obj, "setRootToParent");
399 QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == QModelIndex());
401 QMetaObject::invokeMethod(obj, "setRoot");
402 QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == model.index(0,0));
403 model.clear(); // will emit modelReset()
404 QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == QModelIndex());
409 void tst_qquickvisualdatamodel::updateLayout_data()
411 QTest::addColumn<QUrl>("source");
413 QTest::newRow("item delegate") << testFileUrl("datalist.qml");
414 QTest::newRow("package delegate") << testFileUrl("datalist-package.qml");
417 void tst_qquickvisualdatamodel::updateLayout()
419 QFETCH(QUrl, source);
423 QStandardItemModel model;
424 initStandardTreeModel(&model);
426 view.rootContext()->setContextProperty("myModel", &model);
428 view.setSource(source);
430 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
431 QVERIFY(listview != 0);
433 QQuickItem *contentItem = listview->contentItem();
434 QVERIFY(contentItem != 0);
436 QQuickText *name = findItem<QQuickText>(contentItem, "display", 0);
438 QCOMPARE(name->text(), QString("Row 1 Item"));
439 name = findItem<QQuickText>(contentItem, "display", 1);
441 QCOMPARE(name->text(), QString("Row 2 Item"));
442 name = findItem<QQuickText>(contentItem, "display", 2);
444 QCOMPARE(name->text(), QString("Row 3 Item"));
446 model.invisibleRootItem()->sortChildren(0, Qt::DescendingOrder);
448 name = findItem<QQuickText>(contentItem, "display", 0);
450 QCOMPARE(name->text(), QString("Row 3 Item"));
451 name = findItem<QQuickText>(contentItem, "display", 1);
453 QCOMPARE(name->text(), QString("Row 2 Item"));
454 name = findItem<QQuickText>(contentItem, "display", 2);
456 QCOMPARE(name->text(), QString("Row 1 Item"));
459 void tst_qquickvisualdatamodel::childChanged_data()
461 QTest::addColumn<QUrl>("source");
463 QTest::newRow("item delegate") << testFileUrl("datalist.qml");
464 QTest::newRow("package delegate") << testFileUrl("datalist-package.qml");
467 void tst_qquickvisualdatamodel::childChanged()
469 QFETCH(QUrl, source);
473 QStandardItemModel model;
474 initStandardTreeModel(&model);
476 view.rootContext()->setContextProperty("myModel", &model);
478 view.setSource(source);
480 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
481 QVERIFY(listview != 0);
483 QQuickItem *contentItem = listview->contentItem();
484 QVERIFY(contentItem != 0);
486 QQuickVisualDataModel *vdm = listview->findChild<QQuickVisualDataModel*>("visualModel");
487 vdm->setRootIndex(QVariant::fromValue(model.indexFromItem(model.item(1,0))));
488 QCOMPARE(listview->count(), 1);
490 QQuickText *name = findItem<QQuickText>(contentItem, "display", 0);
492 QCOMPARE(name->text(), QString("Row 2 Child Item"));
494 model.item(1,0)->child(0,0)->setText("Row 2 updated child");
496 name = findItem<QQuickText>(contentItem, "display", 0);
498 QCOMPARE(name->text(), QString("Row 2 updated child"));
500 model.item(1,0)->appendRow(new QStandardItem(QLatin1String("Row 2 Child Item 2")));
501 QCOMPARE(listview->count(), 2);
503 name = findItem<QQuickText>(contentItem, "display", 1);
505 QCOMPARE(name->text(), QString("Row 2 Child Item 2"));
507 model.item(1,0)->takeRow(1);
508 name = findItem<QQuickText>(contentItem, "display", 1);
511 vdm->setRootIndex(QVariant::fromValue(QModelIndex()));
512 QCOMPARE(listview->count(), 3);
513 name = findItem<QQuickText>(contentItem, "display", 0);
515 QCOMPARE(name->text(), QString("Row 1 Item"));
516 name = findItem<QQuickText>(contentItem, "display", 1);
518 QCOMPARE(name->text(), QString("Row 2 Item"));
519 name = findItem<QQuickText>(contentItem, "display", 2);
521 QCOMPARE(name->text(), QString("Row 3 Item"));
524 void tst_qquickvisualdatamodel::objectListModel()
528 QList<QObject*> dataList;
529 dataList.append(new DataObject("Item 1", "red"));
530 dataList.append(new DataObject("Item 2", "green"));
531 dataList.append(new DataObject("Item 3", "blue"));
532 dataList.append(new DataObject("Item 4", "yellow"));
534 QQmlContext *ctxt = view.rootContext();
535 ctxt->setContextProperty("myModel", QVariant::fromValue(dataList));
537 view.setSource(testFileUrl("objectlist.qml"));
539 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
540 QVERIFY(listview != 0);
542 QQuickItem *contentItem = listview->contentItem();
543 QVERIFY(contentItem != 0);
545 QQuickText *name = findItem<QQuickText>(contentItem, "name", 0);
546 QCOMPARE(name->text(), QString("Item 1"));
547 QCOMPARE(name->property("modelName").toString(), QString("Item 1"));
549 QQuickText *section = findItem<QQuickText>(contentItem, "section", 0);
550 QCOMPARE(section->text(), QString("Item 1"));
552 dataList[0]->setProperty("name", QLatin1String("Changed"));
553 QCOMPARE(name->text(), QString("Changed"));
554 QCOMPARE(name->property("modelName").toString(), QString("Changed"));
556 // Test resolving nested section property
557 DataObject *obj = static_cast<DataObject*>(dataList[0]);
558 obj->setSubName("SubItem 1");
560 QMetaObject::invokeMethod(listview, "changeSectionProperty");
561 section = findItem<QQuickText>(contentItem, "section", 0);
562 QCOMPARE(section->text(), QString("SubItem 1"));
565 void tst_qquickvisualdatamodel::singleRole()
570 SingleRoleModel model;
572 QQmlContext *ctxt = view.rootContext();
573 ctxt->setContextProperty("myModel", &model);
575 view.setSource(testFileUrl("singlerole1.qml"));
577 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
578 QVERIFY(listview != 0);
580 QQuickItem *contentItem = listview->contentItem();
581 QVERIFY(contentItem != 0);
583 QQuickText *name = findItem<QQuickText>(contentItem, "name", 1);
584 QCOMPARE(name->text(), QString("two"));
586 model.set(1, "Changed");
587 QCOMPARE(name->text(), QString("Changed"));
592 SingleRoleModel model;
594 QQmlContext *ctxt = view.rootContext();
595 ctxt->setContextProperty("myModel", &model);
597 view.setSource(testFileUrl("singlerole2.qml"));
599 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
600 QVERIFY(listview != 0);
602 QQuickItem *contentItem = listview->contentItem();
603 QVERIFY(contentItem != 0);
605 QQuickText *name = findItem<QQuickText>(contentItem, "name", 1);
606 QCOMPARE(name->text(), QString("two"));
608 model.set(1, "Changed");
609 QCOMPARE(name->text(), QString("Changed"));
614 SingleRoleModel model("modelData");
616 QQmlContext *ctxt = view.rootContext();
617 ctxt->setContextProperty("myModel", &model);
619 view.setSource(testFileUrl("singlerole2.qml"));
621 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
622 QVERIFY(listview != 0);
624 QQuickItem *contentItem = listview->contentItem();
625 QVERIFY(contentItem != 0);
627 QQuickText *name = findItem<QQuickText>(contentItem, "name", 1);
628 QCOMPARE(name->text(), QString("two"));
630 model.set(1, "Changed");
631 QCOMPARE(name->text(), QString("Changed"));
635 void tst_qquickvisualdatamodel::modelProperties()
640 SingleRoleModel model;
642 QQmlContext *ctxt = view.rootContext();
643 ctxt->setContextProperty("myModel", &model);
645 view.setSource(testFileUrl("modelproperties.qml"));
647 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
648 QVERIFY(listview != 0);
650 QQuickItem *contentItem = listview->contentItem();
651 QVERIFY(contentItem != 0);
653 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", 1);
655 QCOMPARE(delegate->property("test1").toString(),QString("two"));
656 QCOMPARE(delegate->property("test2").toString(),QString("two"));
657 QCOMPARE(delegate->property("test3").toString(),QString("two"));
658 QCOMPARE(delegate->property("test4").toString(),QString("two"));
659 QVERIFY(!delegate->property("test9").isValid());
660 QCOMPARE(delegate->property("test5").toString(),QString(""));
661 QVERIFY(delegate->property("test6").value<QObject*>() != 0);
662 QCOMPARE(delegate->property("test7").toInt(),1);
663 QCOMPARE(delegate->property("test8").toInt(),1);
669 QList<QObject*> dataList;
670 dataList.append(new DataObject("Item 1", "red"));
671 dataList.append(new DataObject("Item 2", "green"));
672 dataList.append(new DataObject("Item 3", "blue"));
673 dataList.append(new DataObject("Item 4", "yellow"));
675 QQmlContext *ctxt = view.rootContext();
676 ctxt->setContextProperty("myModel", QVariant::fromValue(dataList));
678 view.setSource(testFileUrl("modelproperties.qml"));
680 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
681 QVERIFY(listview != 0);
683 QQuickItem *contentItem = listview->contentItem();
684 QVERIFY(contentItem != 0);
686 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", 1);
688 QCOMPARE(delegate->property("test1").toString(),QString("Item 2"));
689 QCOMPARE(delegate->property("test2").toString(),QString("Item 2"));
690 QVERIFY(qobject_cast<DataObject*>(delegate->property("test3").value<QObject*>()) != 0);
691 QVERIFY(qobject_cast<DataObject*>(delegate->property("test4").value<QObject*>()) != 0);
692 QCOMPARE(delegate->property("test5").toString(),QString("Item 2"));
693 QCOMPARE(delegate->property("test9").toString(),QString("Item 2"));
694 QVERIFY(delegate->property("test6").value<QObject*>() != 0);
695 QCOMPARE(delegate->property("test7").toInt(),1);
696 QCOMPARE(delegate->property("test8").toInt(),1);
702 QStandardItemModel model;
703 initStandardTreeModel(&model);
705 view.rootContext()->setContextProperty("myModel", &model);
707 QUrl source(testFileUrl("modelproperties2.qml"));
710 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":13: ReferenceError: modelData is not defined");
711 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":13: ReferenceError: modelData is not defined");
712 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":13: ReferenceError: modelData is not defined");
713 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":11: ReferenceError: modelData is not defined");
714 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":11: ReferenceError: modelData is not defined");
715 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":11: ReferenceError: modelData is not defined");
716 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":17: TypeError: Cannot read property 'display' of undefined");
717 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":17: TypeError: Cannot read property 'display' of undefined");
718 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":17: TypeError: Cannot read property 'display' of undefined");
720 view.setSource(source);
722 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
723 QVERIFY(listview != 0);
725 QQuickItem *contentItem = listview->contentItem();
726 QVERIFY(contentItem != 0);
728 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", 1);
730 QCOMPARE(delegate->property("test1").toString(),QString("Row 2 Item"));
731 QCOMPARE(delegate->property("test2").toString(),QString("Row 2 Item"));
732 QVERIFY(!delegate->property("test3").isValid());
733 QVERIFY(!delegate->property("test4").isValid());
734 QVERIFY(!delegate->property("test5").isValid());
735 QVERIFY(!delegate->property("test9").isValid());
736 QVERIFY(delegate->property("test6").value<QObject*>() != 0);
737 QCOMPARE(delegate->property("test7").toInt(),1);
738 QCOMPARE(delegate->property("test8").toInt(),1);
740 //### should also test QStringList and QVariantList
743 void tst_qquickvisualdatamodel::noDelegate_data()
745 QTest::addColumn<QUrl>("source");
747 QTest::newRow("item delegate") << testFileUrl("datalist.qml");
748 QTest::newRow("package delegate") << testFileUrl("datalist-package.qml");
751 void tst_qquickvisualdatamodel::noDelegate()
753 QFETCH(QUrl, source);
757 QStandardItemModel model;
758 initStandardTreeModel(&model);
760 view.rootContext()->setContextProperty("myModel", &model);
762 view.setSource(source);
764 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
765 QVERIFY(listview != 0);
767 QQuickVisualDataModel *vdm = listview->findChild<QQuickVisualDataModel*>("visualModel");
769 QCOMPARE(vdm->count(), 3);
772 QCOMPARE(vdm->count(), 0);
775 void tst_qquickvisualdatamodel::itemsDestroyed_data()
777 QTest::addColumn<QUrl>("source");
779 QTest::newRow("listView") << testFileUrl("itemsDestroyed_listView.qml");
780 QTest::newRow("package") << testFileUrl("itemsDestroyed_package.qml");
781 QTest::newRow("pathView") << testFileUrl("itemsDestroyed_pathView.qml");
782 QTest::newRow("repeater") << testFileUrl("itemsDestroyed_repeater.qml");
785 void tst_qquickvisualdatamodel::itemsDestroyed()
787 QFETCH(QUrl, source);
789 QQmlGuard<QQuickItem> delegate;
793 QStandardItemModel model;
794 initStandardTreeModel(&model);
795 view.rootContext()->setContextProperty("myModel", &model);
796 view.setSource(source);
799 QTest::qWaitForWindowShown(&view);
801 QVERIFY(delegate = findItem<QQuickItem>(view.rootItem(), "delegate", 1));
803 QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
807 void tst_qquickvisualdatamodel::packagesDestroyed()
809 SingleRoleModel model;
811 for (int i=0; i<30; i++)
812 model.list << (QLatin1String("item ") + i);
815 view.rootContext()->setContextProperty("testModel", &model);
817 QString filename(testFile("packageView.qml"));
818 view.setSource(QUrl::fromLocalFile(filename));
820 qApp->processEvents();
822 QQuickListView *leftview = findItem<QQuickListView>(view.rootObject(), "leftList");
823 QTRY_VERIFY(leftview != 0);
825 QQuickListView *rightview = findItem<QQuickListView>(view.rootObject(), "rightList");
826 QTRY_VERIFY(rightview != 0);
828 QQuickItem *leftContent = leftview->contentItem();
829 QTRY_VERIFY(leftContent != 0);
831 QQuickItem *rightContent = rightview->contentItem();
832 QTRY_VERIFY(rightContent != 0);
834 QCOMPARE(leftview->currentIndex(), 0);
835 QCOMPARE(rightview->currentIndex(), 0);
837 rightview->setCurrentIndex(20);
838 QTRY_COMPARE(rightview->contentY(), 100.0);
840 QQmlGuard<QQuickItem> left;
841 QQmlGuard<QQuickItem> right;
843 QVERIFY(findItem<QQuickItem>(leftContent, "wrapper", 1));
844 QVERIFY(findItem<QQuickItem>(rightContent, "wrapper", 1));
846 QVERIFY(left = findItem<QQuickItem>(leftContent, "wrapper", 19));
847 QVERIFY(right = findItem<QQuickItem>(rightContent, "wrapper", 19));
849 rightview->setCurrentIndex(0);
850 QCOMPARE(rightview->currentIndex(), 0);
852 QTRY_COMPARE(rightview->contentY(), 0.0);
853 QCoreApplication::sendPostedEvents();
858 QVERIFY(left = findItem<QQuickItem>(leftContent, "wrapper", 1));
859 QVERIFY(right = findItem<QQuickItem>(rightContent, "wrapper", 1));
861 rightview->setCurrentIndex(20);
862 QTRY_COMPARE(rightview->contentY(), 100.0);
867 QVERIFY(findItem<QQuickItem>(leftContent, "wrapper", 19));
868 QVERIFY(findItem<QQuickItem>(rightContent, "wrapper", 19));
870 leftview->setCurrentIndex(20);
871 QTRY_COMPARE(leftview->contentY(), 100.0);
877 void tst_qquickvisualdatamodel::qaimRowsMoved()
879 // Test parameters passed in QAIM::rowsMoved() signal are converted correctly
880 // when translated and emitted as the QListModelInterface::itemsMoved() signal
881 QFETCH(int, sourceFirst);
882 QFETCH(int, sourceLast);
883 QFETCH(int, destinationChild);
884 QFETCH(int, expectFrom);
885 QFETCH(int, expectTo);
886 QFETCH(int, expectCount);
889 QQmlComponent c(&engine, testFileUrl("visualdatamodel.qml"));
891 SingleRoleModel model;
893 for (int i=0; i<30; i++)
894 model.list << (QLatin1String("item ") + i);
895 engine.rootContext()->setContextProperty("myModel", &model);
897 QQuickVisualDataModel *obj = qobject_cast<QQuickVisualDataModel*>(c.create());
900 QSignalSpy spy(obj, SIGNAL(modelUpdated(QQuickChangeSet,bool)));
901 model.emitMove(sourceFirst, sourceLast, destinationChild);
902 QCOMPARE(spy.count(), 1);
904 QCOMPARE(spy[0].count(), 2);
905 QQuickChangeSet changeSet = spy[0][0].value<QQuickChangeSet>();
906 QCOMPARE(changeSet.removes().count(), 1);
907 QCOMPARE(changeSet.removes().at(0).index, expectFrom);
908 QCOMPARE(changeSet.removes().at(0).count, expectCount);
909 QCOMPARE(changeSet.inserts().count(), 1);
910 QCOMPARE(changeSet.inserts().at(0).index, expectTo);
911 QCOMPARE(changeSet.inserts().at(0).count, expectCount);
912 QCOMPARE(changeSet.removes().at(0).moveId, changeSet.inserts().at(0).moveId);
913 QCOMPARE(spy[0][1].toBool(), false);
918 void tst_qquickvisualdatamodel::qaimRowsMoved_data()
920 QTest::addColumn<int>("sourceFirst");
921 QTest::addColumn<int>("sourceLast");
922 QTest::addColumn<int>("destinationChild");
923 QTest::addColumn<int>("expectFrom");
924 QTest::addColumn<int>("expectTo");
925 QTest::addColumn<int>("expectCount");
927 QTest::newRow("move 1 forward")
931 QTest::newRow("move 1 backwards")
935 QTest::newRow("move multiple forwards")
939 QTest::newRow("move multiple forwards, with same to")
943 QTest::newRow("move multiple backwards")
948 void tst_qquickvisualdatamodel::remove_data()
950 QTest::addColumn<QUrl>("source");
951 QTest::addColumn<QString>("package delegate");
953 QTest::newRow("item delegate")
954 << testFileUrl("groups.qml")
956 QTest::newRow("package")
957 << testFileUrl("groups-package.qml")
958 << QString("package.");
961 void tst_qquickvisualdatamodel::remove()
965 SingleRoleModel model;
966 model.list = QStringList()
980 QQmlContext *ctxt = view.rootContext();
981 ctxt->setContextProperty("myModel", &model);
983 view.setSource(testFileUrl("groups.qml"));
985 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
986 QVERIFY(listview != 0);
988 QQuickItem *contentItem = listview->contentItem();
989 QVERIFY(contentItem != 0);
991 QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel *>(qvariant_cast<QObject *>(listview->model()));
992 QVERIFY(visualModel);
995 QCOMPARE(listview->count(), 12);
996 QCOMPARE(visualModel->items()->count(), 12);
997 static const int mIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
998 static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1000 for (int i = 0; i < lengthOf(mIndex); ++i) {
1001 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1003 QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
1004 QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
1005 QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
1008 evaluate<void>(visualModel, "items.remove(2)");
1009 QCOMPARE(listview->count(), 11);
1010 QCOMPARE(visualModel->items()->count(), 11);
1011 static const int mIndex[] = { 0, 1, 3, 4, 5, 6, 7, 8, 9,10,11 };
1012 static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10 };
1014 for (int i = 0; i < lengthOf(mIndex); ++i) {
1015 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1017 QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
1018 QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
1019 QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
1022 evaluate<void>(visualModel, "items.remove(1, 4)");
1023 QCOMPARE(listview->count(), 7);
1024 QCOMPARE(visualModel->items()->count(), 7);
1025 static const int mIndex[] = { 0, 6, 7, 8, 9,10,11 };
1026 static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6 };
1028 for (int i = 0; i < lengthOf(mIndex); ++i) {
1029 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1031 QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
1032 QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
1033 QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
1036 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: remove: index out of range");
1037 evaluate<void>(visualModel, "items.remove(-8, 4)");
1038 QCOMPARE(listview->count(), 7);
1039 QCOMPARE(visualModel->items()->count(), 7);
1041 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: remove: index out of range");
1042 evaluate<void>(visualModel, "items.remove(12, 2)");
1043 QCOMPARE(listview->count(), 7);
1044 QCOMPARE(visualModel->items()->count(), 7);
1046 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: remove: invalid count");
1047 evaluate<void>(visualModel, "items.remove(5, 3)");
1048 QCOMPARE(listview->count(), 7);
1049 QCOMPARE(visualModel->items()->count(), 7);
1051 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: remove: invalid count");
1052 evaluate<void>(visualModel, "items.remove(5, -2)");
1053 QCOMPARE(listview->count(), 7);
1054 QCOMPARE(visualModel->items()->count(), 7);
1058 void tst_qquickvisualdatamodel::move_data()
1060 QTest::addColumn<QUrl>("source");
1061 QTest::addColumn<QString>("package delegate");
1063 QTest::newRow("item delegate")
1064 << testFileUrl("groups.qml")
1066 QTest::newRow("package")
1067 << testFileUrl("groups-package.qml")
1068 << QString("package.");
1071 void tst_qquickvisualdatamodel::move()
1075 SingleRoleModel model;
1076 model.list = QStringList()
1090 QQmlContext *ctxt = view.rootContext();
1091 ctxt->setContextProperty("myModel", &model);
1093 view.setSource(testFileUrl("groups.qml"));
1095 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
1096 QVERIFY(listview != 0);
1098 QQuickItem *contentItem = listview->contentItem();
1099 QVERIFY(contentItem != 0);
1101 QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel *>(qvariant_cast<QObject *>(listview->model()));
1102 QVERIFY(visualModel);
1105 QCOMPARE(listview->count(), 12);
1106 QCOMPARE(visualModel->items()->count(), 12);
1107 static const int mIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1108 static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1110 for (int i = 0; i < lengthOf(mIndex); ++i) {
1111 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1113 QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
1114 QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
1115 QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
1118 evaluate<void>(visualModel, "items.move(2, 4)");
1119 QCOMPARE(listview->count(), 12);
1120 QCOMPARE(visualModel->items()->count(), 12);
1121 static const int mIndex[] = { 0, 1, 3, 4, 2, 5, 6, 7, 8, 9,10,11 };
1122 static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1124 for (int i = 0; i < lengthOf(mIndex); ++i) {
1125 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1127 QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
1128 QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
1129 QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
1132 evaluate<void>(visualModel, "items.move(4, 2)");
1133 QCOMPARE(listview->count(), 12);
1134 QCOMPARE(visualModel->items()->count(), 12);
1135 static const int mIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1136 static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1138 for (int i = 0; i < lengthOf(mIndex); ++i) {
1139 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1141 QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
1142 QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
1143 QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
1146 evaluate<void>(visualModel, "items.move(8, 0, 4)");
1147 QCOMPARE(listview->count(), 12);
1148 QCOMPARE(visualModel->items()->count(), 12);
1149 static const int mIndex[] = { 8, 9,10,11, 0, 1, 2, 3, 4, 5, 6, 7 };
1150 static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1152 for (int i = 0; i < lengthOf(mIndex); ++i) {
1153 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1155 QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
1156 QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
1157 QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
1160 evaluate<void>(visualModel, "items.move(3, 4, 5)");
1161 QCOMPARE(listview->count(), 12);
1162 QCOMPARE(visualModel->items()->count(), 12);
1163 static const int mIndex[] = { 8, 9,10,4, 11, 0, 1, 2, 3, 5, 6, 7 };
1164 static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1166 for (int i = 0; i < lengthOf(mIndex); ++i) {
1167 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1169 QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
1170 QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
1171 QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
1174 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: invalid count");
1175 evaluate<void>(visualModel, "items.move(5, 2, -2)");
1176 QCOMPARE(listview->count(), 12);
1177 QCOMPARE(visualModel->items()->count(), 12);
1179 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: from index out of range");
1180 evaluate<void>(visualModel, "items.move(-6, 2, 1)");
1181 QCOMPARE(listview->count(), 12);
1182 QCOMPARE(visualModel->items()->count(), 12);
1184 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: from index out of range");
1185 evaluate<void>(visualModel, "items.move(15, 2, 1)");
1186 QCOMPARE(listview->count(), 12);
1187 QCOMPARE(visualModel->items()->count(), 12);
1189 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: from index out of range");
1190 evaluate<void>(visualModel, "items.move(11, 1, 3)");
1191 QCOMPARE(listview->count(), 12);
1192 QCOMPARE(visualModel->items()->count(), 12);
1194 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: to index out of range");
1195 evaluate<void>(visualModel, "items.move(2, -5, 1)");
1196 QCOMPARE(listview->count(), 12);
1197 QCOMPARE(visualModel->items()->count(), 12);
1199 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: to index out of range");
1200 evaluate<void>(visualModel, "items.move(2, 14, 1)");
1201 QCOMPARE(listview->count(), 12);
1202 QCOMPARE(visualModel->items()->count(), 12);
1204 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: to index out of range");
1205 evaluate<void>(visualModel, "items.move(2, 11, 4)");
1206 QCOMPARE(listview->count(), 12);
1207 QCOMPARE(visualModel->items()->count(), 12);
1211 void tst_qquickvisualdatamodel::groups_data()
1213 QTest::addColumn<QUrl>("source");
1214 QTest::addColumn<QString>("part");
1216 QTest::newRow("item delegate")
1217 << testFileUrl("groups.qml")
1219 QTest::newRow("package")
1220 << testFileUrl("groups-package.qml")
1221 << QString("visualModel.parts.package.");
1224 template <int N> void tst_qquickvisualdatamodel::groups_verify(
1225 const SingleRoleModel &model,
1226 QQuickItem *contentItem,
1227 const int (&mIndex)[N],
1228 const int (&iIndex)[N],
1229 const int (&vIndex)[N],
1230 const int (&sIndex)[N],
1231 const bool (&vMember)[N],
1232 const bool (&sMember)[N])
1235 for (int i = 0; i < N; ++i) {
1236 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1238 QCOMPARE(evaluate<QString>(delegate, "test1"), model.list.at(mIndex[i]));
1239 QCOMPARE(evaluate<int>(delegate, "test2") , mIndex[i]);
1240 QCOMPARE(evaluate<int>(delegate, "test3") , iIndex[i]);
1241 QCOMPARE(evaluate<bool>(delegate, "test4"), true);
1242 QCOMPARE(evaluate<int>(delegate, "test5") , vIndex[i]);
1243 QCOMPARE(evaluate<bool>(delegate, "test6"), vMember[i]);
1244 QCOMPARE(evaluate<int>(delegate, "test7") , sIndex[i]);
1245 QCOMPARE(evaluate<bool>(delegate, "test8"), sMember[i]);
1246 QCOMPARE(evaluate<QStringList>(delegate, "test9").contains("items") , bool(true));
1247 QCOMPARE(evaluate<QStringList>(delegate, "test9").contains("visible") , bool(vMember[i]));
1248 QCOMPARE(evaluate<QStringList>(delegate, "test9").contains("selected"), bool(sMember[i]));
1253 #define VERIFY_GROUPS \
1254 groups_verify(model, contentItem, mIndex, iIndex, vIndex, sIndex, vMember, sMember); \
1258 void tst_qquickvisualdatamodel::groups()
1260 QFETCH(QUrl, source);
1261 QFETCH(QString, part);
1265 SingleRoleModel model;
1266 model.list = QStringList()
1280 QQmlContext *ctxt = view.rootContext();
1281 ctxt->setContextProperty("myModel", &model);
1283 view.setSource(source);
1285 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
1286 QVERIFY(listview != 0);
1288 QQuickItem *contentItem = listview->contentItem();
1289 QVERIFY(contentItem != 0);
1291 QQuickVisualDataModel *visualModel = listview->findChild<QQuickVisualDataModel *>("visualModel");
1292 QVERIFY(visualModel);
1294 QQuickVisualDataGroup *visibleItems = listview->findChild<QQuickVisualDataGroup *>("visibleItems");
1295 QVERIFY(visibleItems);
1297 QQuickVisualDataGroup *selectedItems = listview->findChild<QQuickVisualDataGroup *>("selectedItems");
1298 QVERIFY(selectedItems);
1300 const bool f = false;
1301 const bool t = true;
1304 QCOMPARE(listview->count(), 12);
1305 QCOMPARE(visualModel->items()->count(), 12);
1306 QCOMPARE(visibleItems->count(), 12);
1307 QCOMPARE(selectedItems->count(), 0);
1308 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1309 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1310 static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1311 static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
1312 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1313 static const bool sMember[] = { f, f, f, f, f, f, f, f, f, f, f, f };
1316 evaluate<void>(visualModel, "items.addGroups(8, \"selected\")");
1317 QCOMPARE(listview->count(), 12);
1318 QCOMPARE(visualModel->items()->count(), 12);
1319 QCOMPARE(visibleItems->count(), 12);
1320 QCOMPARE(selectedItems->count(), 1);
1321 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1322 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1323 static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1324 static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
1325 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 };
1326 static const bool sMember[] = { f, f, f, f, f, f, f, f, t, f, f, f };
1329 evaluate<void>(visualModel, "items.addGroups(6, 4, [\"visible\", \"selected\"])");
1330 QCOMPARE(listview->count(), 12);
1331 QCOMPARE(visualModel->items()->count(), 12);
1332 QCOMPARE(visibleItems->count(), 12);
1333 QCOMPARE(selectedItems->count(), 4);
1334 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1335 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1336 static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1337 static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
1338 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 4 };
1339 static const bool sMember[] = { f, f, f, f, f, f, t, t, t, t, f, f };
1342 evaluate<void>(visualModel, "items.setGroups(2, [\"items\", \"selected\"])");
1343 QCOMPARE(listview->count(), 12);
1344 QCOMPARE(visualModel->items()->count(), 12);
1345 QCOMPARE(visibleItems->count(), 11);
1346 QCOMPARE(selectedItems->count(), 5);
1347 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1348 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1349 static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9,10 };
1350 static const bool vMember[] = { t, t, f, t, t, t, t, t, t, t, t, t };
1351 static const int sIndex [] = { 0, 0, 0, 1, 1, 1, 1, 2, 3, 4, 5, 5 };
1352 static const bool sMember[] = { f, f, t, f, f, f, t, t, t, t, f, f };
1355 evaluate<void>(selectedItems, "setGroups(0, 3, \"items\")");
1356 QCOMPARE(listview->count(), 12);
1357 QCOMPARE(visualModel->items()->count(), 12);
1358 QCOMPARE(visibleItems->count(), 9);
1359 QCOMPARE(selectedItems->count(), 2);
1360 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1361 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1362 static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 5, 5, 6, 7, 8 };
1363 static const bool vMember[] = { t, t, f, t, t, t, f, f, t, t, t, t };
1364 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 };
1365 static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f };
1368 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: addGroups: invalid count");
1369 evaluate<void>(visualModel, "items.addGroups(11, -4, \"items\")");
1370 QCOMPARE(listview->count(), 12);
1371 QCOMPARE(visualModel->items()->count(), 12);
1372 QCOMPARE(visibleItems->count(), 9);
1373 QCOMPARE(selectedItems->count(), 2);
1375 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: addGroups: index out of range");
1376 evaluate<void>(visualModel, "items.addGroups(-1, 3, \"items\")");
1377 QCOMPARE(listview->count(), 12);
1378 QCOMPARE(visualModel->items()->count(), 12);
1379 QCOMPARE(visibleItems->count(), 9);
1380 QCOMPARE(selectedItems->count(), 2);
1382 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: addGroups: index out of range");
1383 evaluate<void>(visualModel, "items.addGroups(14, 3, \"items\")");
1384 QCOMPARE(listview->count(), 12);
1385 QCOMPARE(visualModel->items()->count(), 12);
1386 QCOMPARE(visibleItems->count(), 9);
1387 QCOMPARE(selectedItems->count(), 2);
1389 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: addGroups: invalid count");
1390 evaluate<void>(visualModel, "items.addGroups(11, 5, \"items\")");
1391 QCOMPARE(listview->count(), 12);
1392 QCOMPARE(visualModel->items()->count(), 12);
1393 QCOMPARE(visibleItems->count(), 9);
1394 QCOMPARE(selectedItems->count(), 2);
1396 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: setGroups: invalid count");
1397 evaluate<void>(visualModel, "items.setGroups(11, -4, \"items\")");
1398 QCOMPARE(listview->count(), 12);
1399 QCOMPARE(visualModel->items()->count(), 12);
1400 QCOMPARE(visibleItems->count(), 9);
1401 QCOMPARE(selectedItems->count(), 2);
1403 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: setGroups: index out of range");
1404 evaluate<void>(visualModel, "items.setGroups(-1, 3, \"items\")");
1405 QCOMPARE(listview->count(), 12);
1406 QCOMPARE(visualModel->items()->count(), 12);
1407 QCOMPARE(visibleItems->count(), 9);
1408 QCOMPARE(selectedItems->count(), 2);
1410 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: setGroups: index out of range");
1411 evaluate<void>(visualModel, "items.setGroups(14, 3, \"items\")");
1412 QCOMPARE(listview->count(), 12);
1413 QCOMPARE(visualModel->items()->count(), 12);
1414 QCOMPARE(visibleItems->count(), 9);
1415 QCOMPARE(selectedItems->count(), 2);
1417 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: setGroups: invalid count");
1418 evaluate<void>(visualModel, "items.setGroups(11, 5, \"items\")");
1419 QCOMPARE(listview->count(), 12);
1420 QCOMPARE(visualModel->items()->count(), 12);
1421 QCOMPARE(visibleItems->count(), 9);
1422 QCOMPARE(selectedItems->count(), 2);
1424 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: removeGroups: invalid count");
1425 evaluate<void>(visualModel, "items.removeGroups(11, -4, \"items\")");
1426 QCOMPARE(listview->count(), 12);
1427 QCOMPARE(visualModel->items()->count(), 12);
1429 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: removeGroups: index out of range");
1430 evaluate<void>(visualModel, "items.removeGroups(-1, 3, \"items\")");
1431 QCOMPARE(listview->count(), 12);
1432 QCOMPARE(visualModel->items()->count(), 12);
1433 QCOMPARE(visibleItems->count(), 9);
1434 QCOMPARE(selectedItems->count(), 2);
1436 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: removeGroups: index out of range");
1437 evaluate<void>(visualModel, "items.removeGroups(14, 3, \"items\")");
1438 QCOMPARE(listview->count(), 12);
1439 QCOMPARE(visualModel->items()->count(), 12);
1440 QCOMPARE(visibleItems->count(), 9);
1441 QCOMPARE(selectedItems->count(), 2);
1443 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: removeGroups: invalid count");
1444 evaluate<void>(visualModel, "items.removeGroups(11, 5, \"items\")");
1445 QCOMPARE(listview->count(), 12);
1446 QCOMPARE(visualModel->items()->count(), 12);
1447 QCOMPARE(visibleItems->count(), 9);
1448 QCOMPARE(selectedItems->count(), 2);
1450 evaluate<void>(visualModel, part + "filterOnGroup = \"visible\"");
1451 QCOMPARE(listview->count(), 9);
1452 QCOMPARE(visualModel->items()->count(), 12);
1453 QCOMPARE(visibleItems->count(), 9);
1454 QCOMPARE(selectedItems->count(), 2);
1455 QCOMPARE(evaluate<QString>(visualModel, part + "filterOnGroup"), QString("visible"));
1457 evaluate<void>(visualModel, part + "filterOnGroup = \"selected\"");
1458 QCOMPARE(listview->count(), 2);
1459 QCOMPARE(visualModel->items()->count(), 12);
1460 QCOMPARE(visibleItems->count(), 9);
1461 QCOMPARE(selectedItems->count(), 2);
1462 QCOMPARE(evaluate<QString>(visualModel, part + "filterOnGroup"), QString("selected"));
1464 evaluate<void>(visualModel, part + "filterOnGroup = undefined");
1465 QCOMPARE(listview->count(), 12);
1466 QCOMPARE(visualModel->items()->count(), 12);
1467 QCOMPARE(visibleItems->count(), 9);
1468 QCOMPARE(selectedItems->count(), 2);
1469 QCOMPARE(evaluate<QString>(visualModel, part + "filterOnGroup"), QString("items"));
1471 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", 5);
1474 evaluate<void>(delegate, "hide()");
1475 QCOMPARE(listview->count(), 12);
1476 QCOMPARE(visualModel->items()->count(), 12);
1477 QCOMPARE(visibleItems->count(), 8);
1478 QCOMPARE(selectedItems->count(), 2);
1479 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1480 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1481 static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 6, 7 };
1482 static const bool vMember[] = { t, t, f, t, t, f, f, f, t, t, t, t };
1483 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 };
1484 static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f };
1487 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", 5);
1490 evaluate<void>(delegate, "select()");
1491 QCOMPARE(listview->count(), 12);
1492 QCOMPARE(visualModel->items()->count(), 12);
1493 QCOMPARE(visibleItems->count(), 8);
1494 QCOMPARE(selectedItems->count(), 3);
1495 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1496 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1497 static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 6, 7 };
1498 static const bool vMember[] = { t, t, f, t, t, f, f, f, t, t, t, t };
1499 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 3, 3 };
1500 static const bool sMember[] = { f, f, f, f, f, t, f, f, t, t, f, f };
1503 evaluate<void>(visualModel, "items.move(2, 6, 3)");
1504 QCOMPARE(listview->count(), 12);
1505 QCOMPARE(visualModel->items()->count(), 12);
1506 QCOMPARE(visibleItems->count(), 8);
1507 QCOMPARE(selectedItems->count(), 3);
1508 static const int mIndex [] = { 0, 1, 5, 6, 7, 8, 2, 3, 4, 9,10,11 };
1509 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1510 static const int vIndex [] = { 0, 1, 2, 2, 2, 2, 3, 3, 4, 5, 6, 7 };
1511 static const bool vMember[] = { t, t, f, f, f, t, f, t, t, t, t, t };
1512 static const int sIndex [] = { 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3 };
1513 static const bool sMember[] = { f, f, t, f, f, t, f, f, f, t, f, f };
1518 template <int N> void tst_qquickvisualdatamodel::get_verify(
1519 const SingleRoleModel &model,
1520 QQuickVisualDataModel *visualModel,
1521 QQuickVisualDataGroup *visibleItems,
1522 QQuickVisualDataGroup *selectedItems,
1523 const int (&mIndex)[N],
1524 const int (&iIndex)[N],
1525 const int (&vIndex)[N],
1526 const int (&sIndex)[N],
1527 const bool (&vMember)[N],
1528 const bool (&sMember)[N])
1531 for (int i = 0; i < N; ++i) {
1532 QCOMPARE(evaluate<QString>(visualModel, QString("items.get(%1).model.name").arg(i)), model.list.at(mIndex[i]));
1533 QCOMPARE(evaluate<QString>(visualModel, QString("items.get(%1).model.modelData").arg(i)), model.list.at(mIndex[i]));
1534 QCOMPARE(evaluate<int>(visualModel, QString("items.get(%1).model.index").arg(i)), mIndex[i]);
1535 QCOMPARE(evaluate<int>(visualModel, QString("items.get(%1).itemsIndex").arg(i)), iIndex[i]);
1536 QCOMPARE(evaluate<bool>(visualModel, QString("items.get(%1).inItems").arg(i)), true);
1537 QCOMPARE(evaluate<int>(visualModel, QString("items.get(%1).visibleIndex").arg(i)), vIndex[i]);
1538 QCOMPARE(evaluate<bool>(visualModel, QString("items.get(%1).inVisible").arg(i)), vMember[i]);
1539 QCOMPARE(evaluate<int>(visualModel, QString("items.get(%1).selectedIndex").arg(i)), sIndex[i]);
1540 QCOMPARE(evaluate<bool>(visualModel, QString("items.get(%1).inSelected").arg(i)), sMember[i]);
1541 QCOMPARE(evaluate<bool>(visualModel, QString("contains(items.get(%1).groups, \"items\")").arg(i)), true);
1542 QCOMPARE(evaluate<bool>(visualModel, QString("contains(items.get(%1).groups, \"visible\")").arg(i)), vMember[i]);
1543 QCOMPARE(evaluate<bool>(visualModel, QString("contains(items.get(%1).groups, \"selected\")").arg(i)), sMember[i]);
1546 QCOMPARE(evaluate<QString>(visibleItems, QString("get(%1).model.name").arg(vIndex[i])), model.list.at(mIndex[i]));
1547 QCOMPARE(evaluate<QString>(visibleItems, QString("get(%1).model.modelData").arg(vIndex[i])), model.list.at(mIndex[i]));
1548 QCOMPARE(evaluate<int>(visibleItems, QString("get(%1).model.index").arg(vIndex[i])), mIndex[i]);
1549 QCOMPARE(evaluate<int>(visibleItems, QString("get(%1).itemsIndex").arg(vIndex[i])), iIndex[i]);
1550 QCOMPARE(evaluate<bool>(visibleItems, QString("get(%1).inItems").arg(vIndex[i])), true);
1551 QCOMPARE(evaluate<int>(visibleItems, QString("get(%1).visibleIndex").arg(vIndex[i])), vIndex[i]);
1552 QCOMPARE(evaluate<bool>(visibleItems, QString("get(%1).inVisible").arg(vIndex[i])), vMember[i]);
1553 QCOMPARE(evaluate<int>(visibleItems, QString("get(%1).selectedIndex").arg(vIndex[i])), sIndex[i]);
1554 QCOMPARE(evaluate<bool>(visibleItems, QString("get(%1).inSelected").arg(vIndex[i])), sMember[i]);
1556 QCOMPARE(evaluate<bool>(visibleItems, QString("contains(get(%1).groups, \"items\")").arg(vIndex[i])), true);
1557 QCOMPARE(evaluate<bool>(visibleItems, QString("contains(get(%1).groups, \"visible\")").arg(vIndex[i])), vMember[i]);
1558 QCOMPARE(evaluate<bool>(visibleItems, QString("contains(get(%1).groups, \"selected\")").arg(vIndex[i])), sMember[i]);
1561 QCOMPARE(evaluate<QString>(selectedItems, QString("get(%1).model.name").arg(sIndex[i])), model.list.at(mIndex[i]));
1562 QCOMPARE(evaluate<QString>(selectedItems, QString("get(%1).model.modelData").arg(sIndex[i])), model.list.at(mIndex[i]));
1563 QCOMPARE(evaluate<int>(selectedItems, QString("get(%1).model.index").arg(sIndex[i])), mIndex[i]);
1564 QCOMPARE(evaluate<int>(selectedItems, QString("get(%1).itemsIndex").arg(sIndex[i])), iIndex[i]);
1565 QCOMPARE(evaluate<bool>(selectedItems, QString("get(%1).inItems").arg(sIndex[i])), true);
1566 QCOMPARE(evaluate<int>(selectedItems, QString("get(%1).visibleIndex").arg(sIndex[i])), vIndex[i]);
1567 QCOMPARE(evaluate<bool>(selectedItems, QString("get(%1).inVisible").arg(sIndex[i])), vMember[i]);
1568 QCOMPARE(evaluate<int>(selectedItems, QString("get(%1).selectedIndex").arg(sIndex[i])), sIndex[i]);
1569 QCOMPARE(evaluate<bool>(selectedItems, QString("get(%1).inSelected").arg(sIndex[i])), sMember[i]);
1570 QCOMPARE(evaluate<bool>(selectedItems, QString("contains(get(%1).groups, \"items\")").arg(sIndex[i])), true);
1571 QCOMPARE(evaluate<bool>(selectedItems, QString("contains(get(%1).groups, \"visible\")").arg(sIndex[i])), vMember[i]);
1572 QCOMPARE(evaluate<bool>(selectedItems, QString("contains(get(%1).groups, \"selected\")").arg(sIndex[i])), sMember[i]);
1578 #define VERIFY_GET \
1579 get_verify(model, visualModel, visibleItems, selectedItems, mIndex, iIndex, vIndex, sIndex, vMember, sMember); \
1582 void tst_qquickvisualdatamodel::get()
1586 SingleRoleModel model;
1587 model.list = QStringList()
1601 QQmlContext *ctxt = view.rootContext();
1602 ctxt->setContextProperty("myModel", &model);
1604 view.setSource(testFileUrl("groups.qml"));
1606 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
1607 QVERIFY(listview != 0);
1609 QQuickItem *contentItem = listview->contentItem();
1610 QVERIFY(contentItem != 0);
1612 QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel *>(qvariant_cast<QObject *>(listview->model()));
1613 QVERIFY(visualModel);
1615 QQuickVisualDataGroup *visibleItems = visualModel->findChild<QQuickVisualDataGroup *>("visibleItems");
1616 QVERIFY(visibleItems);
1618 QQuickVisualDataGroup *selectedItems = visualModel->findChild<QQuickVisualDataGroup *>("selectedItems");
1619 QVERIFY(selectedItems);
1621 QV8Engine *v8Engine = QQmlEnginePrivate::getV8Engine(ctxt->engine());
1624 const bool f = false;
1625 const bool t = true;
1628 QCOMPARE(listview->count(), 12);
1629 QCOMPARE(visualModel->items()->count(), 12);
1630 QCOMPARE(visibleItems->count(), 12);
1631 QCOMPARE(selectedItems->count(), 0);
1632 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1633 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1634 static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1635 static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
1636 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1637 static const bool sMember[] = { f, f, f, f, f, f, f, f, f, f, f, f };
1640 evaluate<void>(visualModel, "items.addGroups(8, \"selected\")");
1641 QCOMPARE(listview->count(), 12);
1642 QCOMPARE(visualModel->items()->count(), 12);
1643 QCOMPARE(visibleItems->count(), 12);
1644 QCOMPARE(selectedItems->count(), 1);
1645 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1646 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1647 static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1648 static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
1649 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 };
1650 static const bool sMember[] = { f, f, f, f, f, f, f, f, t, f, f, f };
1653 evaluate<void>(visualModel, "items.addGroups(6, 4, [\"visible\", \"selected\"])");
1654 QCOMPARE(listview->count(), 12);
1655 QCOMPARE(visualModel->items()->count(), 12);
1656 QCOMPARE(visibleItems->count(), 12);
1657 QCOMPARE(selectedItems->count(), 4);
1658 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1659 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1660 static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1661 static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
1662 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 4 };
1663 static const bool sMember[] = { f, f, f, f, f, f, t, t, t, t, f, f };
1666 evaluate<void>(visualModel, "items.setGroups(2, [\"items\", \"selected\"])");
1667 QCOMPARE(listview->count(), 12);
1668 QCOMPARE(visualModel->items()->count(), 12);
1669 QCOMPARE(visibleItems->count(), 11);
1670 QCOMPARE(selectedItems->count(), 5);
1671 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1672 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1673 static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9,10 };
1674 static const bool vMember[] = { t, t, f, t, t, t, t, t, t, t, t, t };
1675 static const int sIndex [] = { 0, 0, 0, 1, 1, 1, 1, 2, 3, 4, 5, 5 };
1676 static const bool sMember[] = { f, f, t, f, f, f, t, t, t, t, f, f };
1679 evaluate<void>(selectedItems, "setGroups(0, 3, \"items\")");
1680 QCOMPARE(listview->count(), 12);
1681 QCOMPARE(visualModel->items()->count(), 12);
1682 QCOMPARE(visibleItems->count(), 9);
1683 QCOMPARE(selectedItems->count(), 2);
1684 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1685 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1686 static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 5, 5, 6, 7, 8 };
1687 static const bool vMember[] = { t, t, f, t, t, t, f, f, t, t, t, t };
1688 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 };
1689 static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f };
1692 evaluate<void>(visualModel, "items.get(5).inVisible = false");
1693 QCOMPARE(listview->count(), 12);
1694 QCOMPARE(visualModel->items()->count(), 12);
1695 QCOMPARE(visibleItems->count(), 8);
1696 QCOMPARE(selectedItems->count(), 2);
1697 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1698 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1699 static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 6, 7 };
1700 static const bool vMember[] = { t, t, f, t, t, f, f, f, t, t, t, t };
1701 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 };
1702 static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f };
1705 evaluate<void>(visualModel, "items.get(5).inSelected = true");
1706 QCOMPARE(listview->count(), 12);
1707 QCOMPARE(visualModel->items()->count(), 12);
1708 QCOMPARE(visibleItems->count(), 8);
1709 QCOMPARE(selectedItems->count(), 3);
1710 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1711 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1712 static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 6, 7 };
1713 static const bool vMember[] = { t, t, f, t, t, f, f, f, t, t, t, t };
1714 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 3, 3 };
1715 static const bool sMember[] = { f, f, f, f, f, t, f, f, t, t, f, f };
1718 evaluate<void>(visualModel, "items.get(5).groups = [\"visible\", \"items\"]");
1719 QCOMPARE(listview->count(), 12);
1720 QCOMPARE(visualModel->items()->count(), 12);
1721 QCOMPARE(visibleItems->count(), 9);
1722 QCOMPARE(selectedItems->count(), 2);
1723 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1724 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1725 static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 5, 5, 6, 7, 8 };
1726 static const bool vMember[] = { t, t, f, t, t, t, f, f, t, t, t, t };
1727 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 };
1728 static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f };
1733 void tst_qquickvisualdatamodel::invalidGroups()
1735 QUrl source = testFileUrl("groups-invalid.qml");
1736 QTest::ignoreMessage(QtWarningMsg, (source.toString() + ":12:9: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("Group names must start with a lower case letter")).toUtf8());
1738 QQmlComponent component(&engine, source);
1739 QScopedPointer<QObject> object(component.create());
1742 QCOMPARE(evaluate<int>(object.data(), "groups.length"), 4);
1743 QCOMPARE(evaluate<QString>(object.data(), "groups[0].name"), QString("items"));
1744 QCOMPARE(evaluate<QString>(object.data(), "groups[1].name"), QString("persistedItems"));
1745 QCOMPARE(evaluate<QString>(object.data(), "groups[2].name"), QString("visible"));
1746 QCOMPARE(evaluate<QString>(object.data(), "groups[3].name"), QString("selected"));
1749 void tst_qquickvisualdatamodel::onChanged_data()
1751 QTest::addColumn<QString>("expression");
1752 QTest::addColumn<QStringList>("tests");
1754 QTest::newRow("item appended")
1755 << QString("listModel.append({\"number\": \"five\"})")
1757 << "verify(vm.removed, [], [], [])"
1758 << "verify(vm.inserted, [4], [1], [undefined])"
1759 << "verify(vi.removed, [], [], [])"
1760 << "verify(vi.inserted, [4], [1], [undefined])"
1761 << "verify(si.removed, [], [], [])"
1762 << "verify(si.inserted, [], [], [])");
1763 QTest::newRow("item prepended")
1764 << QString("listModel.insert(0, {\"number\": \"five\"})")
1766 << "verify(vm.removed, [], [], [])"
1767 << "verify(vm.inserted, [0], [1], [undefined])"
1768 << "verify(vi.removed, [], [], [])"
1769 << "verify(vi.inserted, [0], [1], [undefined])"
1770 << "verify(si.removed, [], [], [])"
1771 << "verify(si.inserted, [], [], [])");
1772 QTest::newRow("item inserted")
1773 << QString("listModel.insert(2, {\"number\": \"five\"})")
1775 << "verify(vm.removed, [], [], [])"
1776 << "verify(vm.inserted, [2], [1], [undefined])"
1777 << "verify(vi.removed, [], [], [])"
1778 << "verify(vi.inserted, [2], [1], [undefined])"
1779 << "verify(si.removed, [], [], [])"
1780 << "verify(si.inserted, [], [], [])");
1782 QTest::newRow("item removed tail")
1783 << QString("listModel.remove(3)")
1785 << "verify(vm.removed, [3], [1], [undefined])"
1786 << "verify(vm.inserted, [], [], [])"
1787 << "verify(vi.removed, [3], [1], [undefined])"
1788 << "verify(vi.inserted, [], [], [])"
1789 << "verify(si.removed, [], [], [])"
1790 << "verify(si.inserted, [], [], [])");
1791 QTest::newRow("item removed head")
1792 << QString("listModel.remove(0)")
1794 << "verify(vm.removed, [0], [1], [undefined])"
1795 << "verify(vm.inserted, [], [], [])"
1796 << "verify(vi.removed, [0], [1], [undefined])"
1797 << "verify(vi.inserted, [], [], [])"
1798 << "verify(si.removed, [], [], [])"
1799 << "verify(si.inserted, [], [], [])");
1800 QTest::newRow("item removed middle")
1801 << QString("listModel.remove(1)")
1803 << "verify(vm.removed, [1], [1], [undefined])"
1804 << "verify(vm.inserted, [], [], [])"
1805 << "verify(vi.removed, [1], [1], [undefined])"
1806 << "verify(vi.inserted, [], [], [])"
1807 << "verify(si.removed, [], [], [])"
1808 << "verify(si.inserted, [], [], [])");
1811 QTest::newRow("item moved from tail")
1812 << QString("listModel.move(3, 0, 1)")
1814 << "verify(vm.removed, [3], [1], [vm.inserted[0].moveId])"
1815 << "verify(vm.inserted, [0], [1], [vm.removed[0].moveId])"
1816 << "verify(vi.removed, [3], [1], [vi.inserted[0].moveId])"
1817 << "verify(vi.inserted, [0], [1], [vi.removed[0].moveId])"
1818 << "verify(si.removed, [], [], [])"
1819 << "verify(si.inserted, [], [], [])");
1820 QTest::newRow("item moved from head")
1821 << QString("listModel.move(0, 2, 2)")
1823 << "verify(vm.removed, [0], [2], [vm.inserted[0].moveId])"
1824 << "verify(vm.inserted, [2], [2], [vm.removed[0].moveId])"
1825 << "verify(vi.removed, [0], [2], [vi.inserted[0].moveId])"
1826 << "verify(vi.inserted, [2], [2], [vi.removed[0].moveId])"
1827 << "verify(si.removed, [], [], [])"
1828 << "verify(si.inserted, [], [], [])");
1830 QTest::newRow("groups changed")
1831 << QString("items.setGroups(1, 2, [\"items\", \"selected\"])")
1833 << "verify(vm.inserted, [], [], [])"
1834 << "verify(vm.removed, [], [], [])"
1835 << "verify(vi.removed, [1], [2], [undefined])"
1836 << "verify(vi.inserted, [], [], [])"
1837 << "verify(si.removed, [], [], [])"
1838 << "verify(si.inserted, [0], [2], [undefined])");
1840 QTest::newRow("multiple removes")
1841 << QString("{ vi.remove(1, 1); "
1842 "vi.removeGroups(0, 2, \"items\") }")
1844 << "verify(vm.removed, [0, 1], [1, 1], [undefined, undefined])"
1845 << "verify(vm.inserted, [], [], [])"
1846 << "verify(vi.removed, [1], [1], [undefined])"
1847 << "verify(vi.inserted, [], [], [])"
1848 << "verify(si.removed, [], [], [])"
1849 << "verify(si.inserted, [], [], [])");
1852 void tst_qquickvisualdatamodel::onChanged()
1854 QFETCH(QString, expression);
1855 QFETCH(QStringList, tests);
1857 QQmlComponent component(&engine, testFileUrl("onChanged.qml"));
1858 QScopedPointer<QObject> object(component.create());
1861 evaluate<void>(object.data(), expression);
1863 foreach (const QString &test, tests) {
1864 bool passed = evaluate<bool>(object.data(), test);
1871 void tst_qquickvisualdatamodel::create()
1875 SingleRoleModel model;
1876 model.list = QStringList()
1898 QQmlContext *ctxt = view.rootContext();
1899 ctxt->setContextProperty("myModel", &model);
1901 view.setSource(testFileUrl("create.qml"));
1903 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
1904 QVERIFY(listview != 0);
1906 QQuickItem *contentItem = listview->contentItem();
1907 QVERIFY(contentItem != 0);
1909 QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel *>(qvariant_cast<QObject *>(listview->model()));
1910 QVERIFY(visualModel);
1912 QCOMPARE(listview->count(), 20);
1914 QQmlGuard<QQuickItem> delegate;
1916 // persistedItems.includeByDefault is true, so all items belong to persistedItems initially.
1917 QVERIFY(delegate = findItem<QQuickItem>(contentItem, "delegate", 1));
1918 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
1920 // changing include by default doesn't remove persistance.
1921 evaluate<void>(visualModel, "persistedItems.includeByDefault = false");
1922 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
1924 // removing from persistedItems does.
1925 evaluate<void>(visualModel, "persistedItems.remove(0, 20)");
1926 QCOMPARE(listview->count(), 20);
1927 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), false);
1929 // Request an item instantiated by the view.
1930 QVERIFY(delegate = qobject_cast<QQuickItem *>(evaluate<QObject *>(visualModel, "items.create(1)")));
1931 QCOMPARE(delegate.data(), findItem<QQuickItem>(contentItem, "delegate", 1));
1932 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
1933 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 1);
1935 evaluate<void>(delegate, "VisualDataModel.inPersistedItems = false");
1936 QCOMPARE(listview->count(), 20);
1937 QCoreApplication::sendPostedEvents(delegate, QEvent::DeferredDelete);
1939 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), false);
1940 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 0);
1942 // Request an item not instantiated by the view.
1943 QVERIFY(!findItem<QQuickItem>(contentItem, "delegate", 15));
1944 QVERIFY(delegate = qobject_cast<QQuickItem *>(evaluate<QObject *>(visualModel, "items.create(15)")));
1945 QCOMPARE(delegate.data(), findItem<QQuickItem>(contentItem, "delegate", 15));
1946 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
1947 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 1);
1949 evaluate<void>(visualModel, "persistedItems.remove(0)");
1950 QCoreApplication::sendPostedEvents(delegate, QEvent::DeferredDelete);
1952 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 0);
1954 // Request an item not instantiated by the view, then scroll the view so it will request it.
1955 QVERIFY(!findItem<QQuickItem>(contentItem, "delegate", 16));
1956 QVERIFY(delegate = qobject_cast<QQuickItem *>(evaluate<QObject *>(visualModel, "items.create(16)")));
1957 QCOMPARE(delegate.data(), findItem<QQuickItem>(contentItem, "delegate", 16));
1958 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
1959 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 1);
1961 evaluate<void>(listview, "positionViewAtIndex(19, ListView.End)");
1962 QCOMPARE(listview->count(), 20);
1963 evaluate<void>(delegate, "VisualDataModel.groups = [\"items\"]");
1964 QCoreApplication::sendPostedEvents(delegate, QEvent::DeferredDelete);
1966 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), false);
1967 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 0);
1969 // Request and release an item instantiated by the view, then scroll the view so it releases it.
1970 QVERIFY(findItem<QQuickItem>(contentItem, "delegate", 17));
1971 QVERIFY(delegate = qobject_cast<QQuickItem *>(evaluate<QObject *>(visualModel, "items.create(17)")));
1972 QCOMPARE(delegate.data(), findItem<QQuickItem>(contentItem, "delegate", 17));
1973 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
1974 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 1);
1976 evaluate<void>(visualModel, "items.removeGroups(17, \"persistedItems\")");
1977 QCoreApplication::sendPostedEvents(delegate, QEvent::DeferredDelete);
1979 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), false);
1980 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 0);
1981 evaluate<void>(listview, "positionViewAtIndex(1, ListView.Beginning)");
1982 QCOMPARE(listview->count(), 20);
1983 QCoreApplication::sendPostedEvents(delegate, QEvent::DeferredDelete);
1986 // Adding an item to the persistedItems group won't instantiate it, but if later requested by
1987 // the view it will be persisted.
1988 evaluate<void>(visualModel, "items.addGroups(18, \"persistedItems\")");
1989 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 1);
1990 QVERIFY(!findItem<QQuickItem>(contentItem, "delegate", 18));
1991 evaluate<void>(listview, "positionViewAtIndex(19, ListView.End)");
1992 QCOMPARE(listview->count(), 20);
1993 QVERIFY(delegate = findItem<QQuickItem>(contentItem, "delegate", 18));
1994 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
1995 QCoreApplication::sendPostedEvents(delegate, QEvent::DeferredDelete);
1997 evaluate<void>(listview, "positionViewAtIndex(1, ListView.Beginning)");
1998 QCOMPARE(listview->count(), 20);
1999 QCoreApplication::sendPostedEvents(delegate, QEvent::DeferredDelete);
2002 // Remove an uninstantiated but cached item from the persistedItems group.
2003 evaluate<void>(visualModel, "items.addGroups(19, \"persistedItems\")");
2004 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 2);
2005 QVERIFY(!findItem<QQuickItem>(contentItem, "delegate", 19));
2006 // Store a reference to the item so it is retained in the cache.
2007 evaluate<void>(visualModel, "persistentHandle = items.get(19)");
2008 QCOMPARE(evaluate<bool>(visualModel, "persistentHandle.inPersistedItems"), true);
2009 evaluate<void>(visualModel, "items.removeGroups(19, \"persistedItems\")");
2010 QCOMPARE(evaluate<bool>(visualModel, "persistentHandle.inPersistedItems"), false);
2013 void tst_qquickvisualdatamodel::incompleteModel()
2015 // VisualDataModel is first populated in componentComplete. Verify various functions are
2016 // harmlessly ignored until then.
2018 QQmlComponent component(&engine);
2019 component.setData("import QtQuick 2.0\n VisualDataModel {}", testFileUrl(""));
2021 QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
2023 QQuickVisualDataModel *model = qobject_cast<QQuickVisualDataModel *>(object.data());
2026 QSignalSpy itemsSpy(model->items(), SIGNAL(countChanged()));
2027 QSignalSpy persistedItemsSpy(model->items(), SIGNAL(countChanged()));
2029 evaluate<void>(model, "items.removeGroups(0, items.count, \"items\")");
2030 QCOMPARE(itemsSpy.count(), 0);
2031 QCOMPARE(persistedItemsSpy.count(), 0);
2033 evaluate<void>(model, "items.setGroups(0, items.count, \"persistedItems\")");
2034 QCOMPARE(itemsSpy.count(), 0);
2035 QCOMPARE(persistedItemsSpy.count(), 0);
2037 evaluate<void>(model, "items.addGroups(0, items.count, \"persistedItems\")");
2038 QCOMPARE(itemsSpy.count(), 0);
2039 QCOMPARE(persistedItemsSpy.count(), 0);
2041 evaluate<void>(model, "items.remove(0, items.count)");
2042 QCOMPARE(itemsSpy.count(), 0);
2043 QCOMPARE(persistedItemsSpy.count(), 0);
2045 evaluate<void>(model, "items.insert([ \"color\": \"blue\" ])");
2046 QCOMPARE(itemsSpy.count(), 0);
2047 QCOMPARE(persistedItemsSpy.count(), 0);
2049 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: get: index out of range");
2050 QVERIFY(evaluate<bool>(model, "items.get(0) === undefined"));
2052 component.completeCreate();
2055 void tst_qquickvisualdatamodel::insert_data()
2057 QTest::addColumn<QUrl>("source");
2058 QTest::addColumn<QString>("expression");
2059 QTest::addColumn<int>("modelCount");
2060 QTest::addColumn<int>("visualCount");
2061 QTest::addColumn<int>("index");
2062 QTest::addColumn<bool>("inItems");
2063 QTest::addColumn<bool>("persisted");
2064 QTest::addColumn<bool>("visible");
2065 QTest::addColumn<bool>("selected");
2066 QTest::addColumn<bool>("modelData");
2067 QTest::addColumn<QString>("property");
2068 QTest::addColumn<QStringList>("propertyData");
2070 const QUrl listModelSource[] = {
2071 testFileUrl("listmodelproperties.qml"),
2072 testFileUrl("listmodelproperties-package.qml") };
2073 const QUrl singleRoleSource[] = {
2074 testFileUrl("singleroleproperties.qml"),
2075 testFileUrl("singleroleproperties-package.qml") };
2076 const QUrl multipleRoleSource[] = {
2077 testFileUrl("multipleroleproperties.qml"),
2078 testFileUrl("multipleroleproperties-package.qml") };
2079 const QUrl stringListSource[] = {
2080 testFileUrl("stringlistproperties.qml"),
2081 testFileUrl("stringlistproperties-package.qml") };
2082 const QUrl objectListSource[] = {
2083 testFileUrl("objectlistproperties.qml"),
2084 testFileUrl("objectlistproperties-package.qml") };
2086 for (int i = 0; i < 2; ++i) {
2088 QTest::newRow("ListModel.items prepend")
2089 << listModelSource[i]
2090 << QString("items.insert(0, {\"number\": \"eight\"})")
2091 << 4 << 5 << 0 << true << false << false << false << true
2092 << QString("number")
2093 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2095 QTest::newRow("ListModel.items append")
2096 << listModelSource[i]
2097 << QString("items.insert({\"number\": \"eight\"})")
2098 << 4 << 5 << 4 << true << false << false << false << true
2099 << QString("number")
2100 << (QStringList() << "one" << "two" << "three" << "four" << "eight");
2102 QTest::newRow("ListModel.items insert at 2")
2103 << listModelSource[i]
2104 << QString("items.insert(2, {\"number\": \"eight\"})")
2105 << 4 << 5 << 2 << true << false << false << false << true
2106 << QString("number")
2107 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2109 QTest::newRow("ListModel.items insert at items.get(2)")
2110 << listModelSource[i]
2111 << QString("items.insert(items.get(2), {\"number\": \"eight\"})")
2112 << 4 << 5 << 2 << true << false << false << false << true
2113 << QString("number")
2114 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2116 QTest::newRow("ListModel.items insert at visibleItems.get(2)")
2117 << listModelSource[i]
2118 << QString("items.insert(visibleItems.get(2), {\"number\": \"eight\"})")
2119 << 4 << 5 << 2 << true << false << false << false << true
2120 << QString("number")
2121 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2123 QTest::newRow("ListModel.selectedItems insert at items.get(2)")
2124 << listModelSource[i]
2125 << QString("selectedItems.insert(items.get(2), {\"number\": \"eight\"})")
2126 << 4 << 5 << 2 << false << false << false << true << true
2127 << QString("number")
2128 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2130 QTest::newRow("ListModel.selectedItems insert at visibleItems.get(2)")
2131 << listModelSource[i]
2132 << QString("selectedItems.insert(visibleItems.get(2), {\"number\": \"eight\"})")
2133 << 4 << 5 << 2 << false << false << false << true << true
2134 << QString("number")
2135 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2137 QTest::newRow("ListModel.items prepend modelData")
2138 << listModelSource[i]
2139 << QString("items.insert(0, {\"modelData\": \"eight\"})")
2140 << 4 << 5 << 0 << true << false << false << false << true
2141 << QString("number")
2142 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2144 QTest::newRow("ListModel.items prepend, edit number")
2145 << listModelSource[i]
2147 "items.insert(0, {\"number\": \"eight\"}); "
2148 "items.get(0).model.number = \"seven\"; }")
2149 << 4 << 5 << 0 << true << false << false << false << true
2150 << QString("number")
2151 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2153 QTest::newRow("ListModel.items prepend, edit modelData")
2154 << listModelSource[i]
2156 "items.insert(0, {\"number\": \"eight\"}); "
2157 "items.get(0).model.modelData = \"seven\"; }")
2158 << 4 << 5 << 0 << true << false << false << false << true
2159 << QString("number")
2160 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2162 QTest::newRow("ListModel.items prepend, edit resolved")
2163 << listModelSource[i]
2165 "items.insert(0, {\"number\": \"eight\"}); "
2166 "items.get(2).model.number = \"seven\"; }")
2167 << 4 << 5 << 0 << true << false << false << false << true
2168 << QString("number")
2169 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2171 QTest::newRow("ListModel.items prepend with groups")
2172 << listModelSource[i]
2173 << QString("items.insert(0, {\"number\": \"eight\"}, [\"visible\", \"truncheon\"])")
2174 << 4 << 5 << 0 << true << false << true << false << true
2175 << QString("number")
2176 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2178 QTest::newRow("ListModel.items append with groups")
2179 << listModelSource[i]
2180 << QString("items.insert({\"number\": \"eight\"}, [\"visible\", \"selected\"])")
2181 << 4 << 5 << 4 << true << false << true << true << true
2182 << QString("number")
2183 << (QStringList() << "one" << "two" << "three" << "four" << "eight");
2185 QTest::newRow("ListModel.items insert at 2 with groups")
2186 << listModelSource[i]
2187 << QString("items.insert(2, {\"number\": \"eight\"}, \"visible\")")
2188 << 4 << 5 << 2 << true << false << true << false << true
2189 << QString("number")
2190 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2193 QTest::newRow("ListModel.items prepend")
2194 << listModelSource[i]
2195 << QString("items.create(0, {\"number\": \"eight\"})")
2196 << 4 << 5 << 0 << true << true << false << false << true
2197 << QString("number")
2198 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2200 QTest::newRow("ListModel.items append")
2201 << listModelSource[i]
2202 << QString("items.create({\"number\": \"eight\"})")
2203 << 4 << 5 << 4 << true << true << false << false << true
2204 << QString("number")
2205 << (QStringList() << "one" << "two" << "three" << "four" << "eight");
2207 QTest::newRow("ListModel.items create at 2")
2208 << listModelSource[i]
2209 << QString("items.create(2, {\"number\": \"eight\"})")
2210 << 4 << 5 << 2 << true << true << false << false << true
2211 << QString("number")
2212 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2214 QTest::newRow("ListModel.items create at items.get(2)")
2215 << listModelSource[i]
2216 << QString("items.create(items.get(2), {\"number\": \"eight\"})")
2217 << 4 << 5 << 2 << true << true << false << false << true
2218 << QString("number")
2219 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2221 QTest::newRow("ListModel.items create at visibleItems.get(2)")
2222 << listModelSource[i]
2223 << QString("items.create(visibleItems.get(2), {\"number\": \"eight\"})")
2224 << 4 << 5 << 2 << true << true << false << false << true
2225 << QString("number")
2226 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2228 QTest::newRow("ListModel.selectedItems create at items.get(2)")
2229 << listModelSource[i]
2230 << QString("selectedItems.create(items.get(2), {\"number\": \"eight\"})")
2231 << 4 << 5 << 2 << false << true << false << true << true
2232 << QString("number")
2233 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2235 QTest::newRow("ListModel.selectedItems create at visibleItems.get(2)")
2236 << listModelSource[i]
2237 << QString("selectedItems.create(visibleItems.get(2), {\"number\": \"eight\"})")
2238 << 4 << 5 << 2 << false << true << false << true << true
2239 << QString("number")
2240 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2242 QTest::newRow("ListModel.items create prepended")
2243 << listModelSource[i]
2244 << QString("items.create(0, {\"number\": \"eight\"})")
2245 << 4 << 5 << 0 << true << true << false << false << true
2246 << QString("number")
2247 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2249 QTest::newRow("ListModel.items create appended")
2250 << listModelSource[i]
2251 << QString("items.create({\"number\": \"eight\"})")
2252 << 4 << 5 << 4 << true << true << false << false << true
2253 << QString("number")
2254 << (QStringList() << "one" << "two" << "three" << "four" << "eight");
2256 QTest::newRow("ListModel.items create at 2")
2257 << listModelSource[i]
2258 << QString("items.create(2, {\"number\": \"eight\"})")
2259 << 4 << 5 << 2 << true << true << false << false << true
2260 << QString("number")
2261 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2263 QTest::newRow("ListModel.items create at items.get(2)")
2264 << listModelSource[i]
2265 << QString("items.create(items.get(2), {\"number\": \"eight\"})")
2266 << 4 << 5 << 2 << true << true << false << false << true
2267 << QString("number")
2268 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2270 QTest::newRow("ListModel.items create at visibleItems.get(2)")
2271 << listModelSource[i]
2272 << QString("items.create(visibleItems.get(2), {\"number\": \"eight\"})")
2273 << 4 << 5 << 2 << true << true << false << false << true
2274 << QString("number")
2275 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2277 QTest::newRow("ListModel.create prepend modelData")
2278 << listModelSource[i]
2279 << QString("items.create(0, {\"modelData\": \"eight\"})")
2280 << 4 << 5 << 0 << true << true << false << false << true
2281 << QString("number")
2282 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2284 QTest::newRow("ListModel.items create prepended, edit number")
2285 << listModelSource[i]
2287 "var item = items.create(0, {\"number\": \"eight\"}); "
2288 "item.setTest3(\"seven\"); }")
2289 << 4 << 5 << 0 << true << true << false << false << true
2290 << QString("number")
2291 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2293 QTest::newRow("ListModel.items create prepended, edit model.number")
2294 << listModelSource[i]
2296 "var item = items.create(0, {\"number\": \"eight\"}); "
2297 "item.setTest4(\"seven\"); }")
2298 << 4 << 5 << 0 << true << true << false << false << true
2299 << QString("number")
2300 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2302 QTest::newRow("ListModel.items create prepended, edit modelData")
2303 << listModelSource[i]
2305 "var item = items.create(0, {\"number\": \"eight\"}); "
2306 "item.setTest5(\"seven\"); }")
2307 << 4 << 5 << 0 << true << true << false << false << true
2308 << QString("number")
2309 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2311 QTest::newRow("ListModel.items create prepended, edit model.modelData")
2312 << listModelSource[i]
2314 "var item = items.create(0, {\"number\": \"eight\"}); "
2315 "item.setTest6(\"seven\"); }")
2316 << 4 << 5 << 0 << true << true << false << false << true
2317 << QString("number")
2318 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2320 QTest::newRow("ListModel.items create prepended with groups")
2321 << listModelSource[i]
2322 << QString("items.create(0, {\"number\": \"eight\"}, [\"visible\", \"truncheon\"])")
2323 << 4 << 5 << 0 << true << true << true << false << true
2324 << QString("number")
2325 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2327 QTest::newRow("ListModel.items create appended with groups")
2328 << listModelSource[i]
2329 << QString("items.create({\"number\": \"eight\"}, [\"visible\", \"selected\"])")
2330 << 4 << 5 << 4 << true << true << true << true << true
2331 << QString("number")
2332 << (QStringList() << "one" << "two" << "three" << "four" << "eight");
2334 QTest::newRow("ListModel.items create inserted with groups")
2335 << listModelSource[i]
2336 << QString("items.create(2, {\"number\": \"eight\"}, \"visible\")")
2337 << 4 << 5 << 2 << true << true << true << false << true
2338 << QString("number")
2339 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2341 QTest::newRow("ListModel.items create prepended clear persistence")
2342 << listModelSource[i]
2343 << QString("{ items.create(0, {\"number\": \"eight\"}); "
2344 "items.get(0).inPersistedItems = false }")
2345 << 4 << 5 << 0 << true << false << false << false << true
2346 << QString("number")
2347 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2349 QTest::newRow("ListModel.items create appended clear persistence")
2350 << listModelSource[i]
2351 << QString("{ items.create({\"number\": \"eight\"}); "
2352 "items.get(4).inPersistedItems = false }")
2353 << 4 << 5 << 4 << true << false << false << false << true
2354 << QString("number")
2355 << (QStringList() << "one" << "two" << "three" << "four" << "eight");
2357 QTest::newRow("ListModel.items create inserted clear persistence")
2358 << listModelSource[i]
2359 << QString("{ items.create(2, {\"number\": \"eight\"}); "
2360 "items.get(2).inPersistedItems = false }")
2361 << 4 << 5 << 2 << true << false << false << false << true
2362 << QString("number")
2363 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2365 // AbstractItemModel (Single Role).
2366 QTest::newRow("AbstractItemModel.items prepend")
2367 << singleRoleSource[i]
2368 << QString("items.insert(0, {\"name\": \"eight\"})")
2369 << 4 << 5 << 0 << true << false << false << false << true
2371 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2373 QTest::newRow("AbstractItemModel.items append")
2374 << singleRoleSource[i]
2375 << QString("items.insert({\"name\": \"eight\"})")
2376 << 4 << 5 << 4 << true << false << false << false << true
2378 << (QStringList() << "one" << "two" << "three" << "four" << "eight");
2380 QTest::newRow("AbstractItemModel.items insert at 2")
2381 << singleRoleSource[i]
2382 << QString("items.insert(2, {\"name\": \"eight\"})")
2383 << 4 << 5 << 2 << true << false << false << false << true
2385 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2387 QTest::newRow("AbstractItemModel.items prepend modelData")
2388 << singleRoleSource[i]
2389 << QString("items.insert(0, {\"modelData\": \"eight\"})")
2390 << 4 << 5 << 0 << true << false << false << false << true
2392 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2394 QTest::newRow("AbstractItemModel.items prepend, edit name")
2395 << singleRoleSource[i]
2397 "items.insert(0, {\"name\": \"eight\"}); "
2398 "items.get(0).model.name = \"seven\"; }")
2399 << 4 << 5 << 0 << true << false << false << false << true
2401 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2403 QTest::newRow("AbstractItemModel.items prepend, edit modelData")
2404 << singleRoleSource[i]
2406 "items.insert(0, {\"name\": \"eight\"}); "
2407 "items.get(0).model.modelData = \"seven\"; }")
2408 << 4 << 5 << 0 << true << false << false << false << true
2410 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2412 QTest::newRow("AbstractItemModel.items prepend, edit resolved")
2413 << singleRoleSource[i]
2415 "items.insert(0, {\"name\": \"eight\"}); "
2416 "items.get(2).model.name = \"seven\"; }")
2417 << 4 << 5 << 0 << true << false << false << false << true
2419 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2421 QTest::newRow("AbstractItemModel.create prepend modelData")
2422 << singleRoleSource[i]
2423 << QString("items.create(0, {\"modelData\": \"eight\"})")
2424 << 4 << 5 << 0 << true << true << false << false << true
2426 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2428 QTest::newRow("AbstractItemModel.items create prepended, edit name")
2429 << singleRoleSource[i]
2431 "var item = items.create(0, {\"name\": \"eight\"}); "
2432 "item.setTest3(\"seven\"); }")
2433 << 4 << 5 << 0 << true << true << false << false << true
2435 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2437 QTest::newRow("AbstractItemModel.items create prepended, edit model.name")
2438 << singleRoleSource[i]
2440 "var item = items.create(0, {\"name\": \"eight\"}); "
2441 "item.setTest4(\"seven\"); }")
2442 << 4 << 5 << 0 << true << true << false << false << true
2444 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2446 QTest::newRow("AbstractItemModel.items create prepended, edit modelData")
2447 << singleRoleSource[i]
2449 "var item = items.create(0, {\"name\": \"eight\"}); "
2450 "item.setTest5(\"seven\"); }")
2451 << 4 << 5 << 0 << true << true << false << false << true
2453 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2455 QTest::newRow("AbstractItemModel.items create prepended, edit model.modelData")
2456 << singleRoleSource[i]
2458 "var item = items.create(0, {\"name\": \"eight\"}); "
2459 "item.setTest6(\"seven\"); }")
2460 << 4 << 5 << 0 << true << true << false << false << true
2462 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2464 // AbstractItemModel (Multiple Roles).
2465 QTest::newRow("StandardItemModel.items prepend")
2466 << multipleRoleSource[i]
2467 << QString("items.insert(0, {\"display\": \"Row 8 Item\"})")
2468 << 4 << 5 << 0 << true << false << false << false << false
2469 << QString("display")
2470 << (QStringList() << "Row 8 Item" << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2472 QTest::newRow("StandardItemModel.items append")
2473 << multipleRoleSource[i]
2474 << QString("items.insert({\"display\": \"Row 8 Item\"})")
2475 << 4 << 5 << 4 << true << false << false << false << false
2476 << QString("display")
2477 << (QStringList() << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item" << "Row 8 Item");
2479 QTest::newRow("StandardItemModel.items insert at 2")
2480 << multipleRoleSource[i]
2481 << QString("items.insert(2, {\"display\": \"Row 8 Item\"})")
2482 << 4 << 5 << 2 << true << false << false << false << false
2483 << QString("display")
2484 << (QStringList() << "Row 1 Item" << "Row 2 Item" << "Row 8 Item" << "Row 3 Item" << "Row 4 Item");
2486 QTest::newRow("StandardItemModel.items prepend modelData")
2487 << multipleRoleSource[i]
2488 << QString("items.insert(0, {\"modelData\": \"Row 8 Item\"})")
2489 << 4 << 5 << 0 << true << false << false << false << false
2490 << QString("display")
2491 << (QStringList() << QString() << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2493 QTest::newRow("StandardItemModel.items prepend, edit display")
2494 << multipleRoleSource[i]
2496 "items.insert(0, {\"display\": \"Row 8 Item\"}); "
2497 "items.get(0).model.display = \"Row 7 Item\"; }")
2498 << 4 << 5 << 0 << true << false << false << false << false
2499 << QString("display")
2500 << (QStringList() << "Row 7 Item" << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2502 QTest::newRow("StandardItemModel.items prepend, edit modelData")
2503 << multipleRoleSource[i]
2505 "items.insert(0, {\"display\": \"Row 8 Item\"}); "
2506 "items.get(0).model.modelData = \"Row 7 Item\"; }")
2507 << 4 << 5 << 0 << true << false << false << false << false
2508 << QString("display")
2509 << (QStringList() << "Row 8 Item" << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2511 QTest::newRow("StandardItemModel.items prepend, edit resolved")
2512 << multipleRoleSource[i]
2514 "items.insert(0, {\"display\": \"Row 8 Item\"}); "
2515 "items.get(2).model.display = \"Row 7 Item\"; }")
2516 << 4 << 5 << 0 << true << false << false << false << false
2517 << QString("display")
2518 << (QStringList() << "Row 8 Item" << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2520 QTest::newRow("StandardItemModel.create prepend modelData")
2521 << multipleRoleSource[i]
2522 << QString("items.create(0, {\"modelData\": \"Row 8 Item\"})")
2523 << 4 << 5 << 0 << true << true << false << false << false
2524 << QString("display")
2525 << (QStringList() << QString() << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2527 QTest::newRow("StandardItemModel.items create prepended, edit display")
2528 << multipleRoleSource[i]
2530 "var item = items.create(0, {\"display\": \"Row 8 Item\"}); "
2531 "item.setTest3(\"Row 7 Item\"); }")
2532 << 4 << 5 << 0 << true << true << false << false << false
2533 << QString("display")
2534 << (QStringList() << "Row 7 Item" << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2536 QTest::newRow("StandardItemModel.items create prepended, edit model.display")
2537 << multipleRoleSource[i]
2539 "var item = items.create(0, {\"display\": \"Row 8 Item\"}); "
2540 "item.setTest4(\"Row 7 Item\"); }")
2541 << 4 << 5 << 0 << true << true << false << false << false
2542 << QString("display")
2543 << (QStringList() << "Row 7 Item" << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2546 QTest::newRow("StringList.items prepend")
2547 << stringListSource[i]
2548 << QString("items.insert(0, {\"modelData\": \"eight\"})")
2549 << 4 << 5 << 0 << true << false << false << false << false
2550 << QString("modelData")
2551 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2553 QTest::newRow("StringList.items append")
2554 << stringListSource[i]
2555 << QString("items.insert({\"modelData\": \"eight\"})")
2556 << 4 << 5 << 4 << true << false << false << false << false
2557 << QString("modelData")
2558 << (QStringList() << "one" << "two" << "three" << "four" << "eight");
2560 QTest::newRow("StringList.items insert at 2")
2561 << stringListSource[i]
2562 << QString("items.insert(2, {\"modelData\": \"eight\"})")
2563 << 4 << 5 << 2 << true << false << false << false << false
2564 << QString("modelData")
2565 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2567 QTest::newRow("StringList.items prepend, edit modelData")
2568 << stringListSource[i]
2570 "items.insert(0, {\"modelData\": \"eight\"}); "
2571 "items.get(0).model.modelData = \"seven\"; }")
2572 << 4 << 5 << 0 << true << false << false << false << false
2573 << QString("modelData")
2574 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2576 QTest::newRow("StringList.items prepend, edit resolved")
2577 << stringListSource[i]
2579 "items.insert(0, {\"modelData\": \"eight\"}); "
2580 "items.get(2).model.modelData = \"seven\"; }")
2581 << 4 << 5 << 0 << true << false << false << false << false
2582 << QString("modelData")
2583 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2585 QTest::newRow("StringList.create prepend modelData")
2586 << stringListSource[i]
2587 << QString("items.create(0, {\"modelData\": \"eight\"})")
2588 << 4 << 5 << 0 << true << true << false << false << false
2589 << QString("modelData")
2590 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2592 QTest::newRow("StringList.items create prepended, edit modelData")
2593 << stringListSource[i]
2595 "var item = items.create(0, {\"modelData\": \"eight\"}); "
2596 "item.setTest3(\"seven\"); }")
2597 << 4 << 5 << 0 << true << true << false << false << false
2598 << QString("modelData")
2599 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2601 QTest::newRow("StringList.items create prepended, edit model.modelData")
2602 << stringListSource[i]
2604 "var item = items.create(0, {\"modelData\": \"eight\"}); "
2605 "item.setTest4(\"seven\"); }")
2606 << 4 << 5 << 0 << true << true << false << false << false
2607 << QString("modelData")
2608 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2611 QTest::newRow("ObjectList.items prepend")
2612 << objectListSource[i]
2613 << QString("items.insert(0, {\"name\": \"Item 8\"})")
2614 << 4 << 4 << 4 << false << false << false << false << false
2616 << (QStringList() << "Item 1" << "Item 2" << "Item 3" << "Item 4");
2618 QTest::newRow("ObjectList.items append")
2619 << objectListSource[i]
2620 << QString("items.insert({\"name\": \"Item 8\"})")
2621 << 4 << 4 << 4 << false << false << false << false << false
2623 << (QStringList() << "Item 1" << "Item 2" << "Item 3" << "Item 4");
2625 QTest::newRow("ObjectList.items insert at 2")
2626 << objectListSource[i]
2627 << QString("items.insert(2, {\"name\": \"Item 8\"})")
2628 << 4 << 4 << 4 << false << false << false << false << false
2630 << (QStringList() << "Item 1" << "Item 2" << "Item 3" << "Item 4");
2634 void tst_qquickvisualdatamodel::insert()
2636 QFETCH(QUrl, source);
2637 QFETCH(QString, expression);
2638 QFETCH(int, modelCount);
2639 QFETCH(int, visualCount);
2641 QFETCH(bool, inItems);
2642 QFETCH(bool, persisted);
2643 QFETCH(bool, visible);
2644 QFETCH(bool, selected);
2645 QFETCH(bool, modelData);
2646 QFETCH(QString, property);
2647 QFETCH(QStringList, propertyData);
2649 QQuickWindow window;
2651 QQmlComponent component(&engine);
2652 component.loadUrl(source);
2653 QScopedPointer<QObject> object(component.create());
2654 QQuickListView *listView = qobject_cast<QQuickListView *>(object.data());
2656 listView->setParentItem(window.rootItem());
2658 QQuickItem *contentItem = listView->contentItem();
2659 QVERIFY(contentItem);
2661 QObject *visualModel = listView->findChild<QObject *>("visualModel");
2662 QVERIFY(visualModel);
2664 evaluate<void>(visualModel, expression);
2666 QCOMPARE(evaluate<int>(listView, "count"), inItems ? visualCount : modelCount);
2667 QCOMPARE(evaluate<int>(visualModel, "count"), inItems ? visualCount : modelCount);
2668 QCOMPARE(evaluate<int>(visualModel, "items.count"), inItems ? visualCount : modelCount);
2669 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), persisted ? 1 : 0);
2670 QCOMPARE(evaluate<int>(visualModel, "visibleItems.count"), visible ? visualCount : modelCount);
2671 QCOMPARE(evaluate<int>(visualModel, "selectedItems.count"), selected ? 1 : 0);
2673 QCOMPARE(propertyData.count(), visualCount);
2674 for (int i = 0; i < visualCount; ++i) {
2676 if (modelIndex > index)
2678 else if (modelIndex == index)
2681 const int itemsIndex = inItems || i <= index ? i : i - 1;
2685 get = QString("items.get(%1)").arg(itemsIndex);
2687 QQuickItem *item = findItem<QQuickItem>(contentItem, "delegate", modelIndex);
2690 QCOMPARE(evaluate<int>(item, "test1"), modelIndex);
2691 QCOMPARE(evaluate<int>(item, "test2"), modelIndex);
2692 QCOMPARE(evaluate<QString>(item, "test3"), propertyData.at(i));
2693 QCOMPARE(evaluate<QString>(item, "test4"), propertyData.at(i));
2696 QCOMPARE(evaluate<QString>(item, "test5"), propertyData.at(i));
2697 QCOMPARE(evaluate<QString>(item, "test6"), propertyData.at(i));
2700 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inItems"), true);
2701 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inPersistedItems"), false);
2702 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inVisible"), true);
2703 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inSelected"), false);
2704 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.isUnresolved"), false);
2706 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.itemsIndex"), itemsIndex);
2707 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.persistedItemsIndex"), persisted && i > index ? 1 : 0);
2708 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.visibleIndex"), visible || i <= index ? i : i - 1);
2709 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.selectedIndex"), selected && i > index ? 1 : 0);
2710 } else if (inItems) {
2711 get = QString("items.get(%1)").arg(index);
2712 } else if (persisted) {
2713 get = "persistedItems.get(0)";
2714 } else if (visible) {
2715 get = QString("visibleItems.get(%1)").arg(index);
2716 } else if (selected) {
2717 get = "selectedItems.get(0)";
2722 QCOMPARE(evaluate<int>(visualModel, get + ".model.index"), modelIndex);
2724 QCOMPARE(evaluate<QString>(visualModel, get + ".model." + property), propertyData.at(i));
2726 QCOMPARE(evaluate<bool>(visualModel, get + ".inItems"), inItems || i != index);
2727 QCOMPARE(evaluate<bool>(visualModel, get + ".inPersistedItems"), persisted && i == index);
2728 QCOMPARE(evaluate<bool>(visualModel, get + ".inVisible"), visible || i != index);
2729 QCOMPARE(evaluate<bool>(visualModel, get + ".inSelected"), selected && i == index);
2730 QCOMPARE(evaluate<bool>(visualModel, get + ".isUnresolved"), i == index);
2732 QCOMPARE(evaluate<int>(visualModel, get + ".itemsIndex"), inItems || i <= index ? i : i - 1);
2733 QCOMPARE(evaluate<int>(visualModel, get + ".persistedItemsIndex"), persisted && i > index ? 1 : 0);
2734 QCOMPARE(evaluate<int>(visualModel, get + ".visibleIndex"), visible || i <= index ? i : i - 1);
2735 QCOMPARE(evaluate<int>(visualModel, get + ".selectedIndex"), selected && i > index ? 1 : 0);
2741 item = evaluate<QObject *>(visualModel, QString("items.create(%1)").arg(index));
2743 item = evaluate<QObject *>(visualModel, QString("persistedItems.create(%1)").arg(0));
2745 item = evaluate<QObject *>(visualModel, QString("visibleItems.create(%1)").arg(index));
2747 item = evaluate<QObject *>(visualModel, QString("selectedItems.create(%1)").arg(0));
2753 QCOMPARE(evaluate<int>(item, "test1"), -1);
2754 QCOMPARE(evaluate<int>(item, "test2"), -1);
2755 QCOMPARE(evaluate<QString>(item, "test3"), propertyData.at(index));
2756 QCOMPARE(evaluate<QString>(item, "test4"), propertyData.at(index));
2759 QCOMPARE(evaluate<QString>(item, "test5"), propertyData.at(index));
2760 QCOMPARE(evaluate<QString>(item, "test6"), propertyData.at(index));
2763 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inItems"), inItems);
2764 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inPersistedItems"), true);
2765 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inVisible"), visible);
2766 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inSelected"), selected);
2767 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.isUnresolved"), true);
2769 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.itemsIndex"), index);
2770 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.persistedItemsIndex"), 0);
2771 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.visibleIndex"), index);
2772 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.selectedIndex"), 0);
2775 void tst_qquickvisualdatamodel::resolve_data()
2777 QTest::addColumn<QUrl>("source");
2778 QTest::addColumn<QString>("setupExpression");
2779 QTest::addColumn<QString>("resolveExpression");
2780 QTest::addColumn<int>("unresolvedCount");
2781 QTest::addColumn<int>("modelCount");
2782 QTest::addColumn<int>("visualCount");
2783 QTest::addColumn<int>("index");
2784 QTest::addColumn<bool>("inItems");
2785 QTest::addColumn<bool>("persisted");
2786 QTest::addColumn<bool>("visible");
2787 QTest::addColumn<bool>("selected");
2788 QTest::addColumn<bool>("modelData");
2789 QTest::addColumn<QString>("property");
2790 QTest::addColumn<QStringList>("propertyData");
2792 const QUrl listModelSource[] = {
2793 testFileUrl("listmodelproperties.qml"),
2794 testFileUrl("listmodelproperties-package.qml") };
2795 const QUrl singleRoleSource[] = {
2796 testFileUrl("singleroleproperties.qml"),
2797 testFileUrl("singleroleproperties-package.qml") };
2798 const QUrl multipleRoleSource[] = {
2799 testFileUrl("multipleroleproperties.qml"),
2800 testFileUrl("multipleroleproperties-package.qml") };
2801 const QUrl stringListSource[] = {
2802 testFileUrl("stringlistproperties.qml"),
2803 testFileUrl("stringlistproperties-package.qml") };
2805 for (int i = 0; i < 2; ++i) {
2807 QTest::newRow("ListModel.items prepend, resolve prepended")
2808 << listModelSource[i]
2809 << QString("items.insert(0, {\"number\": \"eight\"})")
2810 << QString("{ listModel.insert(0, {\"number\": \"seven\"}); items.resolve(0, 1) }")
2811 << 5 << 5 << 5 << 0 << true << false << true << false << true
2812 << QString("number")
2813 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2815 QTest::newRow("ListModel.items prepend, resolve appended")
2816 << listModelSource[i]
2817 << QString("items.insert(0, {\"number\": \"eight\"})")
2818 << QString("{ listModel.append({\"number\": \"seven\"}); items.resolve(0, 5) }")
2819 << 5 << 5 << 5 << 4 << true << false << true << false << true
2820 << QString("number")
2821 << (QStringList() << "one" << "two" << "three" << "four" << "seven");
2823 QTest::newRow("ListModel.items prepend, resolve inserted")
2824 << listModelSource[i]
2825 << QString("items.insert(0, {\"number\": \"eight\"})")
2826 << QString("{ listModel.insert(2, {\"number\": \"seven\"}); items.resolve(0, 3) }")
2827 << 5 << 5 << 5 << 2 << true << false << true << false << true
2828 << QString("number")
2829 << (QStringList() << "one" << "two" << "seven" << "three" << "four");
2831 QTest::newRow("ListModel.items append, resolve prepended")
2832 << listModelSource[i]
2833 << QString("items.insert({\"number\": \"eight\"})")
2834 << QString("{ listModel.insert(0, {\"number\": \"seven\"}); items.resolve(5, 0) }")
2835 << 5 << 5 << 5 << 0 << true << false << true << false << true
2836 << QString("number")
2837 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2839 QTest::newRow("ListModel.items append, resolve appended")
2840 << listModelSource[i]
2841 << QString("items.insert({\"number\": \"eight\"})")
2842 << QString("{ listModel.append({\"number\": \"seven\"}); items.resolve(5, 4) }")
2843 << 5 << 5 << 5 << 4 << true << false << true << false << true
2844 << QString("number")
2845 << (QStringList() << "one" << "two" << "three" << "four" << "seven");
2847 QTest::newRow("ListModel.items append, resolve inserted")
2848 << listModelSource[i]
2849 << QString("items.insert({\"number\": \"eight\"})")
2850 << QString("{ listModel.insert(2, {\"number\": \"seven\"}); items.resolve(5, 2) }")
2851 << 5 << 5 << 5 << 2 << true << false << true << false << true
2852 << QString("number")
2853 << (QStringList() << "one" << "two" << "seven" << "three" << "four");
2855 QTest::newRow("ListModel.items insert, resolve prepended")
2856 << listModelSource[i]
2857 << QString("items.insert(2, {\"number\": \"eight\"})")
2858 << QString("{ listModel.insert(0, {\"number\": \"seven\"}); items.resolve(3, 0) }")
2859 << 5 << 5 << 5 << 0 << true << false << true << false << true
2860 << QString("number")
2861 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2863 QTest::newRow("ListModel.items insert, resolve appended")
2864 << listModelSource[i]
2865 << QString("items.insert(2, {\"number\": \"eight\"})")
2866 << QString("{ listModel.append({\"number\": \"seven\"}); items.resolve(2, 5) }")
2867 << 5 << 5 << 5 << 4 << true << false << true << false << true
2868 << QString("number")
2869 << (QStringList() << "one" << "two" << "three" << "four" << "seven");
2871 QTest::newRow("ListModel.items insert, resolve inserted")
2872 << listModelSource[i]
2873 << QString("items.insert(2, {\"number\": \"eight\"})")
2874 << QString("{ listModel.insert(2, {\"number\": \"seven\"}); items.resolve(2, 3) }")
2875 << 5 << 5 << 5 << 2 << true << false << true << false << true
2876 << QString("number")
2877 << (QStringList() << "one" << "two" << "seven" << "three" << "four");
2879 QTest::newRow("ListModel.items prepend, move resolved")
2880 << listModelSource[i]
2881 << QString("items.insert(0, {\"number\": \"eight\"})")
2882 << QString("{ listModel.insert(0, {\"number\": \"seven\"}); "
2883 "items.resolve(0, 1); "
2884 "listModel.move(0, 2, 1) }")
2885 << 5 << 5 << 5 << 2 << true << false << true << false << true
2886 << QString("number")
2887 << (QStringList() << "one" << "two" << "seven" << "three" << "four");
2889 QTest::newRow("ListModel.items append, move resolved")
2890 << listModelSource[i]
2891 << QString("items.insert({\"number\": \"eight\"})")
2892 << QString("{ listModel.append({\"number\": \"seven\"}); "
2893 "items.resolve(5, 4); "
2894 "listModel.move(4, 2, 1) }")
2895 << 5 << 5 << 5 << 2 << true << false << true << false << true
2896 << QString("number")
2897 << (QStringList() << "one" << "two" << "seven" << "three" << "four");
2899 QTest::newRow("ListModel.items insert, move resolved")
2900 << listModelSource[i]
2901 << QString("items.insert(2, {\"number\": \"eight\"})")
2902 << QString("{ listModel.insert(2, {\"number\": \"seven\"}); "
2903 "items.resolve(2, 3);"
2904 "listModel.move(2, 0, 1) }")
2905 << 5 << 5 << 5 << 0 << true << false << true << false << true
2906 << QString("number")
2907 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2909 QTest::newRow("ListModel.items prepend, remove resolved")
2910 << listModelSource[i]
2911 << QString("items.insert(0, {\"number\": \"eight\"})")
2912 << QString("{ listModel.insert(0, {\"number\": \"seven\"}); "
2913 "items.resolve(0, 1); "
2914 "listModel.remove(0, 1) }")
2915 << 5 << 4 << 4 << 4 << false << false << false << false << true
2916 << QString("number")
2917 << (QStringList() << "one" << "two" << "three" << "four");
2919 QTest::newRow("ListModel.items append, remove resolved")
2920 << listModelSource[i]
2921 << QString("items.insert({\"number\": \"eight\"})")
2922 << QString("{ listModel.append({\"number\": \"seven\"}); "
2923 "items.resolve(5, 4); "
2924 "listModel.remove(4, 1) }")
2925 << 5 << 4 << 4 << 4 << false << false << false << false << true
2926 << QString("number")
2927 << (QStringList() << "one" << "two" << "three" << "four");
2929 QTest::newRow("ListModel.items insert, remove resolved")
2930 << listModelSource[i]
2931 << QString("items.insert(2, {\"number\": \"eight\"})")
2932 << QString("{ listModel.insert(2, {\"number\": \"seven\"}); "
2933 "items.resolve(2, 3);"
2934 "listModel.remove(2, 1) }")
2935 << 5 << 4 << 4 << 4 << false << false << false << false << true
2936 << QString("number")
2937 << (QStringList() << "one" << "two" << "three" << "four");
2939 QTest::newRow("ListModel.selectedItems prepend, resolve prepended")
2940 << listModelSource[i]
2941 << QString("selectedItems.insert(0, {\"number\": \"eight\"})")
2942 << QString("{ listModel.insert(0, {\"number\": \"seven\"}); "
2943 "selectedItems.resolve(selectedItems.get(0), items.get(0)) }")
2944 << 4 << 5 << 5 << 0 << true << false << true << true << true
2945 << QString("number")
2946 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2948 QTest::newRow("ListModel.selectedItems prepend, resolve appended")
2949 << listModelSource[i]
2950 << QString("selectedItems.insert(0, {\"number\": \"eight\"})")
2951 << QString("{ listModel.append({\"number\": \"seven\"}); "
2952 "selectedItems.resolve(selectedItems.get(0), items.get(4)) }")
2953 << 4 << 5 << 5 << 4 << true << false << true << true << true
2954 << QString("number")
2955 << (QStringList() << "one" << "two" << "three" << "four" << "seven");
2957 QTest::newRow("ListModel.selectedItems prepend, resolve inserted")
2958 << listModelSource[i]
2959 << QString("selectedItems.insert(0, {\"number\": \"eight\"})")
2960 << QString("{ listModel.insert(2, {\"number\": \"seven\"}); "
2961 "selectedItems.resolve(selectedItems.get(0), items.get(2)) }")
2962 << 4 << 5 << 5 << 2 << true << false << true << true << true
2963 << QString("number")
2964 << (QStringList() << "one" << "two" << "seven" << "three" << "four");
2966 QTest::newRow("ListModel.selectedItems append, resolve prepended")
2967 << listModelSource[i]
2968 << QString("selectedItems.insert({\"number\": \"eight\"})")
2969 << QString("{ listModel.insert(0, {\"number\": \"seven\"}); "
2970 "selectedItems.resolve(selectedItems.get(0), items.get(0)) }")
2971 << 4 << 5 << 5 << 0 << true << false << true << true << true
2972 << QString("number")
2973 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2975 QTest::newRow("ListModel.selectedItems append, resolve appended")
2976 << listModelSource[i]
2977 << QString("selectedItems.insert({\"number\": \"eight\"})")
2978 << QString("{ listModel.append({\"number\": \"seven\"}); "
2979 "selectedItems.resolve(selectedItems.get(0), items.get(4)) }")
2980 << 4 << 5 << 5 << 4 << true << false << true << true << true
2981 << QString("number")
2982 << (QStringList() << "one" << "two" << "three" << "four" << "seven");
2984 QTest::newRow("ListModel.selectedItems append, resolve inserted")
2985 << listModelSource[i]
2986 << QString("selectedItems.insert({\"number\": \"eight\"})")
2987 << QString("{ listModel.insert(2, {\"number\": \"seven\"}); "
2988 "selectedItems.resolve(selectedItems.get(0), items.get(2)) }")
2989 << 4 << 5 << 5 << 2 << true << false << true << true << true
2990 << QString("number")
2991 << (QStringList() << "one" << "two" << "seven" << "three" << "four");
2993 // AbstractItemModel (Single Role)
2994 QTest::newRow("ListModel.items prepend, resolve prepended")
2995 << singleRoleSource[i]
2996 << QString("items.insert(0, {\"name\": \"eight\"})")
2997 << QString("{ items.resolve(0, 1) }")
2998 << 5 << 4 << 4 << 0 << true << false << true << false << true
3000 << (QStringList() << "one" << "two" << "three" << "four");
3003 QTest::newRow("ListModel.items append, resolve appended")
3004 << singleRoleSource[i]
3005 << QString("items.insert({\"name\": \"eight\"})")
3006 << QString("{ items.resolve(4, 3) }")
3007 << 5 << 4 << 4 << 3 << true << false << true << false << true
3009 << (QStringList() << "one" << "two" << "three" << "four");
3011 QTest::newRow("ListModel.items insert, resolve inserted")
3012 << singleRoleSource[i]
3013 << QString("items.insert(2, {\"name\": \"eight\"})")
3014 << QString("{ items.resolve(2, 3) }")
3015 << 5 << 4 << 4 << 2 << true << false << true << false << true
3017 << (QStringList() << "one" << "two" << "three" << "four");
3019 // AbstractItemModel (Single Role)
3020 QTest::newRow("AbstractItemModel.items prepend, resolve prepended")
3021 << singleRoleSource[i]
3022 << QString("items.insert(0, {\"name\": \"eight\"})")
3023 << QString("{ items.resolve(0, 1) }")
3024 << 5 << 4 << 4 << 0 << true << false << true << false << true
3026 << (QStringList() << "one" << "two" << "three" << "four");
3028 QTest::newRow("AbstractItemModel.items append, resolve appended")
3029 << singleRoleSource[i]
3030 << QString("items.insert({\"name\": \"eight\"})")
3031 << QString("{ items.resolve(4, 3) }")
3032 << 5 << 4 << 4 << 3 << true << false << true << false << true
3034 << (QStringList() << "one" << "two" << "three" << "four");
3036 QTest::newRow("AbstractItemModel.items insert, resolve inserted")
3037 << singleRoleSource[i]
3038 << QString("items.insert(2, {\"name\": \"eight\"})")
3039 << QString("{ items.resolve(2, 3) }")
3040 << 5 << 4 << 4 << 2 << true << false << true << false << true
3042 << (QStringList() << "one" << "two" << "three" << "four");
3044 // AbstractItemModel (Multiple Roles)
3045 QTest::newRow("StandardItemModel.items prepend, resolve prepended")
3046 << multipleRoleSource[i]
3047 << QString("items.insert(0, {\"display\": \"Row 8 Item\"})")
3048 << QString("{ items.resolve(0, 1) }")
3049 << 5 << 4 << 4 << 0 << true << false << true << false << false
3050 << QString("display")
3051 << (QStringList() << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
3053 QTest::newRow("StandardItemModel.items append, resolve appended")
3054 << multipleRoleSource[i]
3055 << QString("items.insert({\"display\": \"Row 8 Item\"})")
3056 << QString("{ items.resolve(4, 3) }")
3057 << 5 << 4 << 4 << 3 << true << false << true << false << false
3058 << QString("display")
3059 << (QStringList() << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
3061 QTest::newRow("StandardItemModel.items insert, resolve inserted")
3062 << multipleRoleSource[i]
3063 << QString("items.insert(2, {\"display\": \"Row 8 Item\"})")
3064 << QString("{ items.resolve(2, 3) }")
3065 << 5 << 4 << 4 << 2 << true << false << true << false << false
3066 << QString("display")
3067 << (QStringList() << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
3070 QTest::newRow("StringList.items prepend, resolve prepended")
3071 << stringListSource[i]
3072 << QString("items.insert(0, {\"modelData\": \"eight\"})")
3073 << QString("{ items.resolve(0, 1) }")
3074 << 5 << 4 << 4 << 0 << true << false << true << false << false
3075 << QString("modelData")
3076 << (QStringList() << "one" << "two" << "three" << "four");
3078 QTest::newRow("StringList.items append, resolve appended")
3079 << stringListSource[i]
3080 << QString("items.insert({\"modelData\": \"eight\"})")
3081 << QString("{ items.resolve(4, 3) }")
3082 << 5 << 4 << 4 << 3 << true << false << true << false << false
3083 << QString("modelData")
3084 << (QStringList() << "one" << "two" << "three" << "four");
3086 QTest::newRow("StringList.items insert, resolve inserted")
3087 << stringListSource[i]
3088 << QString("items.insert(2, {\"modelData\": \"eight\"})")
3089 << QString("{ items.resolve(2, 3) }")
3090 << 5 << 4 << 4 << 2 << true << false << true << false << false
3091 << QString("modelData")
3092 << (QStringList() << "one" << "two" << "three" << "four");
3096 void tst_qquickvisualdatamodel::resolve()
3098 QFETCH(QUrl, source);
3099 QFETCH(QString, setupExpression);
3100 QFETCH(QString, resolveExpression);
3101 QFETCH(int, unresolvedCount);
3102 QFETCH(int, modelCount);
3103 QFETCH(int, visualCount);
3105 QFETCH(bool, inItems);
3106 QFETCH(bool, persisted);
3107 QFETCH(bool, visible);
3108 QFETCH(bool, selected);
3109 QFETCH(bool, modelData);
3110 QFETCH(QString, property);
3111 QFETCH(QStringList, propertyData);
3113 QQuickWindow window;
3115 QQmlComponent component(&engine);
3116 component.loadUrl(source);
3117 QScopedPointer<QObject> object(component.create());
3118 QQuickListView *listView = qobject_cast<QQuickListView *>(object.data());
3120 listView->setParentItem(window.rootItem());
3122 QQuickItem *contentItem = listView->contentItem();
3123 QVERIFY(contentItem);
3125 QObject *visualModel = listView->findChild<QObject *>("visualModel");
3126 QVERIFY(visualModel);
3128 evaluate<void>(visualModel, setupExpression);
3129 QCOMPARE(evaluate<int>(listView, "count"), unresolvedCount);
3131 evaluate<void>(visualModel, resolveExpression);
3133 QCOMPARE(evaluate<int>(listView, "count"), inItems ? visualCount : modelCount);
3134 QCOMPARE(evaluate<int>(visualModel, "count"), inItems ? visualCount : modelCount);
3135 QCOMPARE(evaluate<int>(visualModel, "items.count"), inItems ? visualCount : modelCount);
3136 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), persisted ? 1 : 0);
3137 QCOMPARE(evaluate<int>(visualModel, "visibleItems.count"), visible ? visualCount : modelCount);
3138 QCOMPARE(evaluate<int>(visualModel, "selectedItems.count"), selected ? 1 : 0);
3140 QCOMPARE(propertyData.count(), visualCount);
3141 for (int i = 0; i < visualCount; ++i) {
3144 const int itemsIndex = inItems || i <= index ? i : i - 1;
3148 get = QString("items.get(%1)").arg(itemsIndex);
3150 QQuickItem *item = findItem<QQuickItem>(contentItem, "delegate", modelIndex);
3153 QCOMPARE(evaluate<int>(item, "test1"), modelIndex);
3154 QCOMPARE(evaluate<int>(item, "test2"), modelIndex);
3155 QCOMPARE(evaluate<QString>(item, "test3"), propertyData.at(i));
3156 QCOMPARE(evaluate<QString>(item, "test4"), propertyData.at(i));
3159 QCOMPARE(evaluate<QString>(item, "test5"), propertyData.at(i));
3160 QCOMPARE(evaluate<QString>(item, "test6"), propertyData.at(i));
3163 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inItems"), true);
3164 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inPersistedItems"), false);
3165 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inVisible"), true);
3166 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inSelected"), false);
3167 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.isUnresolved"), false);
3169 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.itemsIndex"), itemsIndex);
3170 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.persistedItemsIndex"), persisted && i > index ? 1 : 0);
3171 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.visibleIndex"), visible || i <= index ? i : i - 1);
3172 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.selectedIndex"), selected && i > index ? 1 : 0);
3173 } else if (inItems) {
3174 get = QString("items.get(%1)").arg(index);
3175 } else if (persisted) {
3176 get = "persistedItems.get(0)";
3177 } else if (visible) {
3178 get = QString("visibleItems.get(%1)").arg(index);
3179 } else if (selected) {
3180 get = "selectedItems.get(0)";
3185 QCOMPARE(evaluate<int>(visualModel, get + ".model.index"), modelIndex);
3187 QCOMPARE(evaluate<QString>(visualModel, get + ".model." + property), propertyData.at(i));
3189 QCOMPARE(evaluate<bool>(visualModel, get + ".inItems"), inItems || i != index);
3190 QCOMPARE(evaluate<bool>(visualModel, get + ".inPersistedItems"), persisted && i == index);
3191 QCOMPARE(evaluate<bool>(visualModel, get + ".inVisible"), visible || i != index);
3192 QCOMPARE(evaluate<bool>(visualModel, get + ".inSelected"), selected && i == index);
3193 QCOMPARE(evaluate<bool>(visualModel, get + ".isUnresolved"), false);
3195 QCOMPARE(evaluate<int>(visualModel, get + ".itemsIndex"), inItems || i <= index ? i : i - 1);
3196 QCOMPARE(evaluate<int>(visualModel, get + ".persistedItemsIndex"), persisted && i > index ? 1 : 0);
3197 QCOMPARE(evaluate<int>(visualModel, get + ".visibleIndex"), visible || i <= index ? i : i - 1);
3198 QCOMPARE(evaluate<int>(visualModel, get + ".selectedIndex"), selected && i > index ? 1 : 0);
3204 item = evaluate<QObject *>(visualModel, QString("items.create(%1)").arg(index));
3206 item = evaluate<QObject *>(visualModel, QString("persistedItems.create(%1)").arg(0));
3208 item = evaluate<QObject *>(visualModel, QString("visibleItems.create(%1)").arg(index));
3210 item = evaluate<QObject *>(visualModel, QString("selectedItems.create(%1)").arg(0));
3216 QCOMPARE(evaluate<int>(item, "test1"), index);
3217 QCOMPARE(evaluate<int>(item, "test2"), index);
3218 QCOMPARE(evaluate<QString>(item, "test3"), propertyData.at(index));
3219 QCOMPARE(evaluate<QString>(item, "test4"), propertyData.at(index));
3222 QCOMPARE(evaluate<QString>(item, "test5"), propertyData.at(index));
3223 QCOMPARE(evaluate<QString>(item, "test6"), propertyData.at(index));
3226 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inItems"), inItems);
3227 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inPersistedItems"), true);
3228 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inVisible"), visible);
3229 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inSelected"), selected);
3230 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.isUnresolved"), false);
3232 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.itemsIndex"), index);
3233 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.persistedItemsIndex"), 0);
3234 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.visibleIndex"), index);
3235 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.selectedIndex"), 0);
3238 void tst_qquickvisualdatamodel::warnings_data()
3240 QTest::addColumn<QUrl>("source");
3241 QTest::addColumn<QString>("expression");
3242 QTest::addColumn<QString>("warning");
3243 QTest::addColumn<int>("count");
3245 QTest::newRow("insert < 0")
3246 << testFileUrl("listmodelproperties.qml")
3247 << QString("items.insert(-2, {\"number\": \"eight\"})")
3248 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("insert: index out of range"))
3251 QTest::newRow("insert > length")
3252 << testFileUrl("listmodelproperties.qml")
3253 << QString("items.insert(8, {\"number\": \"eight\"})")
3254 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("insert: index out of range"))
3257 QTest::newRow("create < 0")
3258 << testFileUrl("listmodelproperties.qml")
3259 << QString("items.create(-2, {\"number\": \"eight\"})")
3260 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("create: index out of range"))
3263 QTest::newRow("create > length")
3264 << testFileUrl("listmodelproperties.qml")
3265 << QString("items.create(8, {\"number\": \"eight\"})")
3266 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("create: index out of range"))
3269 QTest::newRow("resolve from < 0")
3270 << testFileUrl("listmodelproperties.qml")
3271 << QString("items.resolve(-2, 3)")
3272 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: from index out of range"))
3275 QTest::newRow("resolve from > length")
3276 << testFileUrl("listmodelproperties.qml")
3277 << QString("items.resolve(8, 3)")
3278 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: from index out of range"))
3281 QTest::newRow("resolve to < 0")
3282 << testFileUrl("listmodelproperties.qml")
3283 << QString("items.resolve(3, -2)")
3284 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: to index out of range"))
3287 QTest::newRow("resolve to > length")
3288 << testFileUrl("listmodelproperties.qml")
3289 << QString("items.resolve(3, 8)")
3290 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: to index out of range"))
3293 QTest::newRow("resolve from invalid index")
3294 << testFileUrl("listmodelproperties.qml")
3295 << QString("items.resolve(\"two\", 3)")
3296 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: from index invalid"))
3299 QTest::newRow("resolve to invalid index")
3300 << testFileUrl("listmodelproperties.qml")
3301 << QString("items.resolve(3, \"two\")")
3302 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: to index invalid"))
3305 QTest::newRow("resolve already resolved item")
3306 << testFileUrl("listmodelproperties.qml")
3307 << QString("items.resolve(3, 2)")
3308 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: from is not an unresolved item"))
3311 QTest::newRow("resolve already resolved item")
3312 << testFileUrl("listmodelproperties.qml")
3313 << QString("{ items.insert(0, {\"number\": \"eight\"});"
3314 "items.insert(1, {\"number\": \"seven\"});"
3315 "items.resolve(0, 1)}")
3316 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: to is not a model item"))
3319 QTest::newRow("remove index < 0")
3320 << testFileUrl("listmodelproperties.qml")
3321 << QString("items.remove(-2, 1)")
3322 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("remove: index out of range"))
3325 QTest::newRow("remove index == length")
3326 << testFileUrl("listmodelproperties.qml")
3327 << QString("items.remove(4, 1)")
3328 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("remove: index out of range"))
3331 QTest::newRow("remove index > length")
3332 << testFileUrl("listmodelproperties.qml")
3333 << QString("items.remove(9, 1)")
3334 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("remove: index out of range"))
3337 QTest::newRow("remove invalid index")
3338 << testFileUrl("listmodelproperties.qml")
3339 << QString("items.remove(\"nine\", 1)")
3340 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("remove: invalid index"))
3343 QTest::newRow("remove count < 0")
3344 << testFileUrl("listmodelproperties.qml")
3345 << QString("items.remove(1, -2)")
3346 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("remove: invalid count"))
3349 QTest::newRow("remove index + count > length")
3350 << testFileUrl("listmodelproperties.qml")
3351 << QString("items.remove(2, 4, \"selected\")")
3352 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("remove: invalid count"))
3355 QTest::newRow("addGroups index < 0")
3356 << testFileUrl("listmodelproperties.qml")
3357 << QString("items.addGroups(-2, 1, \"selected\")")
3358 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("addGroups: index out of range"))
3361 QTest::newRow("addGroups index == length")
3362 << testFileUrl("listmodelproperties.qml")
3363 << QString("items.addGroups(4, 1, \"selected\")")
3364 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("addGroups: index out of range"))
3367 QTest::newRow("addGroups index > length")
3368 << testFileUrl("listmodelproperties.qml")
3369 << QString("items.addGroups(9, 1, \"selected\")")
3370 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("addGroups: index out of range"))
3373 QTest::newRow("addGroups count < 0")
3374 << testFileUrl("listmodelproperties.qml")
3375 << QString("items.addGroups(1, -2, \"selected\")")
3376 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("addGroups: invalid count"))
3379 QTest::newRow("addGroups index + count > length")
3380 << testFileUrl("listmodelproperties.qml")
3381 << QString("items.addGroups(2, 4, \"selected\")")
3382 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("addGroups: invalid count"))
3385 QTest::newRow("removeGroups index < 0")
3386 << testFileUrl("listmodelproperties.qml")
3387 << QString("items.removeGroups(-2, 1, \"selected\")")
3388 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("removeGroups: index out of range"))
3391 QTest::newRow("removeGroups index == length")
3392 << testFileUrl("listmodelproperties.qml")
3393 << QString("items.removeGroups(4, 1, \"selected\")")
3394 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("removeGroups: index out of range"))
3397 QTest::newRow("removeGroups index > length")
3398 << testFileUrl("listmodelproperties.qml")
3399 << QString("items.removeGroups(9, 1, \"selected\")")
3400 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("removeGroups: index out of range"))
3403 QTest::newRow("removeGroups count < 0")
3404 << testFileUrl("listmodelproperties.qml")
3405 << QString("items.removeGroups(1, -2, \"selected\")")
3406 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("removeGroups: invalid count"))
3409 QTest::newRow("removeGroups index + count > length")
3410 << testFileUrl("listmodelproperties.qml")
3411 << QString("items.removeGroups(2, 4, \"selected\")")
3412 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("removeGroups: invalid count"))
3415 QTest::newRow("setGroups index < 0")
3416 << testFileUrl("listmodelproperties.qml")
3417 << QString("items.setGroups(-2, 1, \"selected\")")
3418 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("setGroups: index out of range"))
3421 QTest::newRow("setGroups index == length")
3422 << testFileUrl("listmodelproperties.qml")
3423 << QString("items.setGroups(4, 1, \"selected\")")
3424 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("setGroups: index out of range"))
3427 QTest::newRow("setGroups index > length")
3428 << testFileUrl("listmodelproperties.qml")
3429 << QString("items.setGroups(9, 1, \"selected\")")
3430 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("setGroups: index out of range"))
3433 QTest::newRow("setGroups count < 0")
3434 << testFileUrl("listmodelproperties.qml")
3435 << QString("items.setGroups(1, -2, \"selected\")")
3436 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("setGroups: invalid count"))
3439 QTest::newRow("setGroups index + count > length")
3440 << testFileUrl("listmodelproperties.qml")
3441 << QString("items.setGroups(2, 4, \"selected\")")
3442 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("setGroups: invalid count"))
3445 QTest::newRow("move from < 0")
3446 << testFileUrl("listmodelproperties.qml")
3447 << QString("items.move(-2, 1, 1)")
3448 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: from index out of range"))
3451 QTest::newRow("move from == length")
3452 << testFileUrl("listmodelproperties.qml")
3453 << QString("items.move(4, 1, 1)")
3454 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: from index out of range"))
3457 QTest::newRow("move from > length")
3458 << testFileUrl("listmodelproperties.qml")
3459 << QString("items.move(9, 1, 1)")
3460 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: from index out of range"))
3463 QTest::newRow("move invalid from")
3464 << testFileUrl("listmodelproperties.qml")
3465 << QString("items.move(\"nine\", 1, 1)")
3466 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: invalid from index"))
3469 QTest::newRow("move to < 0")
3470 << testFileUrl("listmodelproperties.qml")
3471 << QString("items.move(1, -2, 1)")
3472 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: to index out of range"))
3475 QTest::newRow("move to == length")
3476 << testFileUrl("listmodelproperties.qml")
3477 << QString("items.move(1, 4, 1)")
3478 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: to index out of range"))
3481 QTest::newRow("move to > length")
3482 << testFileUrl("listmodelproperties.qml")
3483 << QString("items.move(1, 9, 1)")
3484 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: to index out of range"))
3487 QTest::newRow("move invalid to")
3488 << testFileUrl("listmodelproperties.qml")
3489 << QString("items.move(1, \"nine\", 1)")
3490 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: invalid to index"))
3493 QTest::newRow("move count < 0")
3494 << testFileUrl("listmodelproperties.qml")
3495 << QString("items.move(1, 1, -2)")
3496 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: invalid count"))
3499 QTest::newRow("move from + count > length")
3500 << testFileUrl("listmodelproperties.qml")
3501 << QString("items.move(2, 1, 4)")
3502 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: from index out of range"))
3506 void tst_qquickvisualdatamodel::warnings()
3508 QFETCH(QUrl, source);
3509 QFETCH(QString, expression);
3510 QFETCH(QString, warning);
3513 QQuickWindow window;
3515 QQmlComponent component(&engine);
3516 component.loadUrl(source);
3517 QScopedPointer<QObject> object(component.create());
3518 QQuickListView *listView = qobject_cast<QQuickListView *>(object.data());
3520 listView->setParentItem(window.rootItem());
3522 QQuickItem *contentItem = listView->contentItem();
3523 QVERIFY(contentItem);
3525 QObject *visualModel = evaluate<QObject *>(listView, "model");
3526 QVERIFY(visualModel);
3528 QTest::ignoreMessage(QtWarningMsg, warning.toUtf8());
3530 evaluate<void>(visualModel, expression);
3531 QCOMPARE(evaluate<int>(listView, "count"), count);
3534 void tst_qquickvisualdatamodel::invalidAttachment()
3536 QQmlComponent component(&engine);
3537 component.loadUrl(testFileUrl("invalidAttachment.qml"));
3539 QScopedPointer<QObject> object(component.create());
3541 QCOMPARE(component.errors().count(), 0);
3543 QVariant property = object->property("invalidVdm");
3544 QCOMPARE(property.userType(), qMetaTypeId<QQuickVisualDataModel *>());
3545 QVERIFY(!property.value<QQuickVisualDataModel *>());
3547 QQuickItem *item = findItem<QQuickItem>(static_cast<QQuickItem *>(object.data()), "delegate");
3550 property = item->property("validVdm");
3551 QCOMPARE(property.userType(), qMetaTypeId<QQuickVisualDataModel *>());
3552 QVERIFY(property.value<QQuickVisualDataModel *>());
3554 property = item->property("invalidVdm");
3555 QCOMPARE(property.userType(), qMetaTypeId<QQuickVisualDataModel *>());
3556 QVERIFY(!property.value<QQuickVisualDataModel *>());
3559 void tst_qquickvisualdatamodel::asynchronousInsert_data()
3561 QTest::addColumn<int>("requestIndex");
3562 QTest::addColumn<int>("insertIndex");
3563 QTest::addColumn<int>("insertCount");
3564 QTest::addColumn<int>("completeIndex");
3566 QTest::newRow("insert before") << 4 << 1 << 3 << 7;
3567 QTest::newRow("insert after") << 4 << 6 << 3 << 4;
3568 QTest::newRow("insert at") << 4 << 4 << 3 << 7;
3571 void tst_qquickvisualdatamodel::asynchronousInsert()
3573 QFETCH(int, requestIndex);
3574 QFETCH(int, insertIndex);
3575 QFETCH(int, insertCount);
3576 QFETCH(int, completeIndex);
3578 QCOMPARE(controller.incubatingObjectCount(), 0);
3580 QQmlComponent c(&engine, testFileUrl("visualdatamodel.qml"));
3583 for (int i = 0; i < 8; i++)
3584 model.addItem("Original item" + QString::number(i), "");
3586 engine.rootContext()->setContextProperty("myModel", &model);
3588 QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel*>(c.create());
3589 QVERIFY(visualModel);
3591 ItemRequester requester;
3592 connect(visualModel, SIGNAL(initItem(int,QQuickItem*)), &requester, SLOT(initItem(int,QQuickItem*)));
3593 connect(visualModel, SIGNAL(createdItem(int,QQuickItem*)), &requester, SLOT(createdItem(int,QQuickItem*)));
3594 connect(visualModel, SIGNAL(destroyingItem(QQuickItem*)), &requester, SLOT(destroyingItem(QQuickItem*)));
3596 QQuickItem *item = visualModel->item(requestIndex, true);
3599 QVERIFY(!requester.itemInitialized);
3600 QVERIFY(!requester.itemCreated);
3601 QVERIFY(!requester.itemDestroyed);
3603 QList<QPair<QString, QString> > newItems;
3604 for (int i = 0; i < insertCount; i++)
3605 newItems.append(qMakePair(QLatin1String("New item") + QString::number(i), QString(QLatin1String(""))));
3606 model.insertItems(insertIndex, newItems);
3608 item = visualModel->item(completeIndex, false);
3611 QCOMPARE(requester.itemInitialized, item);
3612 QCOMPARE(requester.indexInitialized, completeIndex);
3613 QCOMPARE(requester.itemCreated, item);
3614 QCOMPARE(requester.indexCreated, completeIndex);
3615 QVERIFY(!requester.itemDestroyed);
3617 QCOMPARE(controller.incubatingObjectCount(), 0);
3619 visualModel->release(item);
3621 QCOMPARE(requester.itemDestroyed, item);
3624 void tst_qquickvisualdatamodel::asynchronousRemove_data()
3626 QTest::addColumn<int>("requestIndex");
3627 QTest::addColumn<int>("removeIndex");
3628 QTest::addColumn<int>("removeCount");
3629 QTest::addColumn<int>("completeIndex");
3631 QTest::newRow("remove before") << 4 << 1 << 3 << 1;
3632 QTest::newRow("remove after") << 4 << 6 << 2 << 4;
3633 QTest::newRow("remove requested") << 4 << 4 << 3 << -1;
3636 void tst_qquickvisualdatamodel::asynchronousRemove()
3638 QFETCH(int, requestIndex);
3639 QFETCH(int, removeIndex);
3640 QFETCH(int, removeCount);
3641 QFETCH(int, completeIndex);
3643 QCOMPARE(controller.incubatingObjectCount(), 0);
3645 QQmlComponent c(&engine, testFileUrl("visualdatamodel.qml"));
3648 for (int i = 0; i < 8; i++)
3649 model.addItem("Original item" + QString::number(i), "");
3651 engine.rootContext()->setContextProperty("myModel", &model);
3653 QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel*>(c.create());
3654 QVERIFY(visualModel);
3656 ItemRequester requester;
3657 connect(visualModel, SIGNAL(initItem(int,QQuickItem*)), &requester, SLOT(initItem(int,QQuickItem*)));
3658 connect(visualModel, SIGNAL(createdItem(int,QQuickItem*)), &requester, SLOT(createdItem(int,QQuickItem*)));
3659 connect(visualModel, SIGNAL(destroyingItem(QQuickItem*)), &requester, SLOT(destroyingItem(QQuickItem*)));
3661 QQuickItem *item = visualModel->item(requestIndex, true);
3664 QVERIFY(!requester.itemInitialized);
3665 QVERIFY(!requester.itemCreated);
3666 QVERIFY(!requester.itemDestroyed);
3668 model.removeItems(removeIndex, removeCount);
3670 if (completeIndex == -1) {
3671 QElapsedTimer timer;
3674 controller.incubateFor(50);
3675 } while (timer.elapsed() < 1000 && controller.incubatingObjectCount() > 0);
3677 QVERIFY(requester.itemInitialized);
3678 QCOMPARE(requester.itemCreated, requester.itemInitialized);
3679 QCOMPARE(requester.itemDestroyed, requester.itemInitialized);
3681 item = visualModel->item(completeIndex, false);
3684 QCOMPARE(requester.itemInitialized, item);
3685 QCOMPARE(requester.indexInitialized, completeIndex);
3686 QCOMPARE(requester.itemCreated, item);
3687 QCOMPARE(requester.indexCreated, completeIndex);
3688 QVERIFY(!requester.itemDestroyed);
3690 QCOMPARE(controller.incubatingObjectCount(), 0);
3692 visualModel->release(item);
3694 QCOMPARE(requester.itemDestroyed, item);
3698 void tst_qquickvisualdatamodel::asynchronousMove_data()
3700 QTest::addColumn<int>("requestIndex");
3701 QTest::addColumn<int>("from");
3702 QTest::addColumn<int>("to");
3703 QTest::addColumn<int>("count");
3704 QTest::addColumn<int>("completeIndex");
3706 QTest::newRow("move before") << 4 << 1 << 0 << 3 << 4;
3707 QTest::newRow("move after") << 4 << 6 << 5 << 2 << 4;
3708 QTest::newRow("move requested") << 4 << 4 << 3 << 2 << 3;
3709 QTest::newRow("move before to after") << 4 << 1 << 4 << 3 << 1;
3710 QTest::newRow("move after to before") << 4 << 6 << 2 << 2 << 6;
3713 void tst_qquickvisualdatamodel::asynchronousMove()
3715 QFETCH(int, requestIndex);
3719 QFETCH(int, completeIndex);
3721 QCOMPARE(controller.incubatingObjectCount(), 0);
3723 QQmlComponent c(&engine, testFileUrl("visualdatamodel.qml"));
3726 for (int i = 0; i < 8; i++)
3727 model.addItem("Original item" + QString::number(i), "");
3729 engine.rootContext()->setContextProperty("myModel", &model);
3731 QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel*>(c.create());
3732 QVERIFY(visualModel);
3734 ItemRequester requester;
3735 connect(visualModel, SIGNAL(initItem(int,QQuickItem*)), &requester, SLOT(initItem(int,QQuickItem*)));
3736 connect(visualModel, SIGNAL(createdItem(int,QQuickItem*)), &requester, SLOT(createdItem(int,QQuickItem*)));
3737 connect(visualModel, SIGNAL(destroyingItem(QQuickItem*)), &requester, SLOT(destroyingItem(QQuickItem*)));
3739 QQuickItem *item = visualModel->item(requestIndex, true);
3742 QVERIFY(!requester.itemInitialized);
3743 QVERIFY(!requester.itemCreated);
3744 QVERIFY(!requester.itemDestroyed);
3746 model.moveItems(from, to, count);
3748 item = visualModel->item(completeIndex, false);
3752 QCOMPARE(requester.itemInitialized, item);
3753 QCOMPARE(requester.indexInitialized, completeIndex);
3754 QCOMPARE(requester.itemCreated, item);
3755 QCOMPARE(requester.indexCreated, completeIndex);
3756 QVERIFY(!requester.itemDestroyed);
3758 QCOMPARE(controller.incubatingObjectCount(), 0);
3760 visualModel->release(item);
3762 QCOMPARE(requester.itemDestroyed, item);
3765 void tst_qquickvisualdatamodel::asynchronousCancel()
3767 const int requestIndex = 4;
3769 QCOMPARE(controller.incubatingObjectCount(), 0);
3771 QQmlComponent c(&engine, testFileUrl("visualdatamodel.qml"));
3774 for (int i = 0; i < 8; i++)
3775 model.addItem("Original item" + QString::number(i), "");
3777 engine.rootContext()->setContextProperty("myModel", &model);
3779 QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel*>(c.create());
3780 QVERIFY(visualModel);
3782 QQuickItem *item = visualModel->item(requestIndex, true);
3784 QCOMPARE(controller.incubatingObjectCount(), 1);
3786 visualModel->cancel(requestIndex);
3787 QCOMPARE(controller.incubatingObjectCount(), 0);
3790 QTEST_MAIN(tst_qquickvisualdatamodel)
3792 #include "tst_qquickvisualdatamodel.moc"