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>
61 using namespace QQuickVisualTestUtil;
62 using namespace QQuickViewTestUtil;
64 template <typename T, int N> int lengthOf(const T (&)[N]) { return N; }
67 #include <QStandardItemModel>
68 static void initStandardTreeModel(QStandardItemModel *model)
71 item = new QStandardItem(QLatin1String("Row 1 Item"));
72 model->insertRow(0, item);
74 item = new QStandardItem(QLatin1String("Row 2 Item"));
75 item->setCheckable(true);
76 model->insertRow(1, item);
78 QStandardItem *childItem = new QStandardItem(QLatin1String("Row 2 Child Item"));
79 item->setChild(0, childItem);
81 item = new QStandardItem(QLatin1String("Row 3 Item"));
82 item->setIcon(QIcon());
83 model->insertRow(2, item);
87 class SingleRoleModel : public QAbstractListModel
90 Q_PROPERTY(QStringList values READ getList WRITE setList)
92 SingleRoleModel(const QByteArray &role = "name", QObject *parent = 0)
93 : QAbstractListModel(parent)
95 QHash<int, QByteArray> roles;
96 roles.insert(Qt::DisplayRole , role);
98 list << "one" << "two" << "three" << "four";
101 void emitMove(int sourceFirst, int sourceLast, int destinationChild) {
102 emit beginMoveRows(QModelIndex(), sourceFirst, sourceLast, QModelIndex(), destinationChild);
108 QStringList getList() const { return list; }
109 void setList(const QStringList &l) { list = l; }
112 void set(int idx, QString string) {
114 emit dataChanged(index(idx,0), index(idx,0));
118 int rowCount(const QModelIndex & /* parent */ = QModelIndex()) const {
121 QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const {
122 if (role == Qt::DisplayRole)
123 return list.at(index.row());
128 #ifndef QT_NO_WIDGETS
129 class StandardItem : public QObject, public QStandardItem
132 Q_PROPERTY(QString text READ readText WRITE setText)
135 QString readText() const { return text(); }
136 void writeText(const QString &text) { setText(text); }
139 class StandardItemModel : public QStandardItemModel
142 Q_PROPERTY(QQmlListProperty<StandardItem> items READ items CONSTANT)
143 Q_CLASSINFO("DefaultProperty", "items")
145 QQmlListProperty<StandardItem> items() { return QQmlListProperty<StandardItem>(this, 0, append); }
147 static void append(QQmlListProperty<StandardItem> *property, StandardItem *item)
149 static_cast<QStandardItemModel *>(property->object)->appendRow(item);
154 class DataSubObject : public QObject
158 Q_PROPERTY(QString subName READ subName WRITE setSubName NOTIFY subNameChanged)
161 DataSubObject(QObject *parent=0) : QObject(parent) {}
163 QString subName() const { return m_subName; }
164 void setSubName(const QString &name) {
165 if (name != m_subName) {
167 emit subNameChanged();
172 void subNameChanged();
178 class DataObject : public QObject
182 Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
183 Q_PROPERTY(QString color READ color WRITE setColor NOTIFY colorChanged)
184 Q_PROPERTY(QObject *object READ object)
187 DataObject(QObject *parent=0) : QObject(parent) {}
188 DataObject(const QString &name, const QString &color, QObject *parent=0)
189 : QObject(parent), m_name(name), m_color(color), m_object(new DataSubObject(this)) { }
192 QString name() const { return m_name; }
193 void setName(const QString &name) {
194 if (name != m_name) {
200 QString color() const { return m_color; }
201 void setColor(const QString &color) {
202 if (color != m_color) {
208 QObject *object() const { return m_object; }
209 void setSubName(const QString &sn) {
210 m_object->setSubName(sn);
220 DataSubObject *m_object;
223 class ItemRequester : public QObject
227 ItemRequester(QObject *parent = 0)
232 , indexInitialized(-1)
237 QQuickItem *itemInitialized;
238 QQuickItem *itemCreated;
239 QQuickItem *itemDestroyed;
240 int indexInitialized;
244 void initItem(int index, QQuickItem *item)
246 itemInitialized = item;
247 indexInitialized = index;
250 void createdItem(int index, QQuickItem *item)
253 indexCreated = index;
256 void destroyingItem(QQuickItem *item)
258 itemDestroyed = item;
262 QML_DECLARE_TYPE(SingleRoleModel)
263 QML_DECLARE_TYPE(DataObject)
264 #ifndef QT_NO_WIDGETS
265 QML_DECLARE_TYPE(StandardItem)
266 QML_DECLARE_TYPE(StandardItemModel)
269 class tst_qquickvisualdatamodel : public QQmlDataTest
273 tst_qquickvisualdatamodel();
277 void cleanupTestCase();
278 #ifndef QT_NO_WIDGETS
280 void updateLayout_data();
282 void childChanged_data();
284 void noDelegate_data();
286 void itemsDestroyed_data();
287 void itemsDestroyed();
289 void objectListModel();
291 void modelProperties();
292 void packagesDestroyed();
293 void qaimRowsMoved();
294 void qaimRowsMoved_data();
301 void invalidGroups();
303 void onChanged_data();
306 void incompleteModel();
311 void warnings_data();
313 void invalidAttachment();
314 void asynchronousInsert_data();
315 void asynchronousInsert();
316 void asynchronousRemove_data();
317 void asynchronousRemove();
318 void asynchronousMove();
319 void asynchronousMove_data();
320 void asynchronousCancel();
323 template <int N> void groups_verify(
324 const SingleRoleModel &model,
325 QQuickItem *contentItem,
326 const int (&mIndex)[N],
327 const int (&iIndex)[N],
328 const int (&vIndex)[N],
329 const int (&sIndex)[N],
330 const bool (&vMember)[N],
331 const bool (&sMember)[N]);
333 template <int N> void get_verify(
334 const SingleRoleModel &model,
335 QQuickVisualDataModel *visualModel,
336 QQuickVisualDataGroup *visibleItems,
337 QQuickVisualDataGroup *selectedItems,
338 const int (&mIndex)[N],
339 const int (&iIndex)[N],
340 const int (&vIndex)[N],
341 const int (&sIndex)[N],
342 const bool (&vMember)[N],
343 const bool (&sMember)[N]);
346 QQmlIncubationController controller;
350 Q_DECLARE_METATYPE(QQuickChangeSet)
352 template <typename T> static T evaluate(QObject *scope, const QString &expression)
354 QQmlExpression expr(qmlContext(scope), scope, expression);
355 T result = expr.evaluate().value<T>();
357 qWarning() << expr.error().toString();
361 template <> void evaluate<void>(QObject *scope, const QString &expression)
363 QQmlExpression expr(qmlContext(scope), scope, expression);
366 qWarning() << expr.error().toString();
369 void tst_qquickvisualdatamodel::initTestCase()
371 QQmlDataTest::initTestCase();
372 qRegisterMetaType<QQuickChangeSet>();
374 qmlRegisterType<SingleRoleModel>("tst_qquickvisualdatamodel", 1, 0, "SingleRoleModel");
375 qmlRegisterType<DataObject>("tst_qquickvisualdatamodel", 1, 0, "DataObject");
376 #ifndef QT_NO_WIDGETS
377 qmlRegisterType<StandardItem>("tst_qquickvisualdatamodel", 1, 0, "StandardItem");
378 qmlRegisterType<StandardItemModel>("tst_qquickvisualdatamodel", 1, 0, "StandardItemModel");
381 engine.setIncubationController(&controller);
384 void tst_qquickvisualdatamodel::cleanupTestCase()
388 tst_qquickvisualdatamodel::tst_qquickvisualdatamodel()
392 #ifndef QT_NO_WIDGETS
393 void tst_qquickvisualdatamodel::rootIndex()
396 QQmlComponent c(&engine, testFileUrl("visualdatamodel.qml"));
398 QStandardItemModel model;
399 initStandardTreeModel(&model);
401 engine.rootContext()->setContextProperty("myModel", &model);
403 QQuickVisualDataModel *obj = qobject_cast<QQuickVisualDataModel*>(c.create());
406 QMetaObject::invokeMethod(obj, "setRoot");
407 QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == model.index(0,0));
409 QMetaObject::invokeMethod(obj, "setRootToParent");
410 QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == QModelIndex());
412 QMetaObject::invokeMethod(obj, "setRoot");
413 QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == model.index(0,0));
414 model.clear(); // will emit modelReset()
415 QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == QModelIndex());
420 void tst_qquickvisualdatamodel::updateLayout_data()
422 QTest::addColumn<QUrl>("source");
424 QTest::newRow("item delegate") << testFileUrl("datalist.qml");
425 QTest::newRow("package delegate") << testFileUrl("datalist-package.qml");
428 void tst_qquickvisualdatamodel::updateLayout()
430 QFETCH(QUrl, source);
434 QStandardItemModel model;
435 initStandardTreeModel(&model);
437 view.rootContext()->setContextProperty("myModel", &model);
439 view.setSource(source);
441 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
442 QVERIFY(listview != 0);
444 QQuickItem *contentItem = listview->contentItem();
445 QVERIFY(contentItem != 0);
447 QQuickText *name = findItem<QQuickText>(contentItem, "display", 0);
449 QCOMPARE(name->text(), QString("Row 1 Item"));
450 name = findItem<QQuickText>(contentItem, "display", 1);
452 QCOMPARE(name->text(), QString("Row 2 Item"));
453 name = findItem<QQuickText>(contentItem, "display", 2);
455 QCOMPARE(name->text(), QString("Row 3 Item"));
457 model.invisibleRootItem()->sortChildren(0, Qt::DescendingOrder);
459 name = findItem<QQuickText>(contentItem, "display", 0);
461 QCOMPARE(name->text(), QString("Row 3 Item"));
462 name = findItem<QQuickText>(contentItem, "display", 1);
464 QCOMPARE(name->text(), QString("Row 2 Item"));
465 name = findItem<QQuickText>(contentItem, "display", 2);
467 QCOMPARE(name->text(), QString("Row 1 Item"));
470 void tst_qquickvisualdatamodel::childChanged_data()
472 QTest::addColumn<QUrl>("source");
474 QTest::newRow("item delegate") << testFileUrl("datalist.qml");
475 QTest::newRow("package delegate") << testFileUrl("datalist-package.qml");
478 void tst_qquickvisualdatamodel::childChanged()
480 QFETCH(QUrl, source);
484 QStandardItemModel model;
485 initStandardTreeModel(&model);
487 view.rootContext()->setContextProperty("myModel", &model);
489 view.setSource(source);
491 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
492 QVERIFY(listview != 0);
494 QQuickItem *contentItem = listview->contentItem();
495 QVERIFY(contentItem != 0);
497 QQuickVisualDataModel *vdm = listview->findChild<QQuickVisualDataModel*>("visualModel");
498 vdm->setRootIndex(QVariant::fromValue(model.indexFromItem(model.item(1,0))));
499 QCOMPARE(listview->count(), 1);
501 QQuickText *name = findItem<QQuickText>(contentItem, "display", 0);
503 QCOMPARE(name->text(), QString("Row 2 Child Item"));
505 model.item(1,0)->child(0,0)->setText("Row 2 updated child");
507 name = findItem<QQuickText>(contentItem, "display", 0);
509 QCOMPARE(name->text(), QString("Row 2 updated child"));
511 model.item(1,0)->appendRow(new QStandardItem(QLatin1String("Row 2 Child Item 2")));
512 QCOMPARE(listview->count(), 2);
514 name = findItem<QQuickText>(contentItem, "display", 1);
516 QCOMPARE(name->text(), QString("Row 2 Child Item 2"));
518 model.item(1,0)->takeRow(1);
519 name = findItem<QQuickText>(contentItem, "display", 1);
522 vdm->setRootIndex(QVariant::fromValue(QModelIndex()));
523 QCOMPARE(listview->count(), 3);
524 name = findItem<QQuickText>(contentItem, "display", 0);
526 QCOMPARE(name->text(), QString("Row 1 Item"));
527 name = findItem<QQuickText>(contentItem, "display", 1);
529 QCOMPARE(name->text(), QString("Row 2 Item"));
530 name = findItem<QQuickText>(contentItem, "display", 2);
532 QCOMPARE(name->text(), QString("Row 3 Item"));
536 void tst_qquickvisualdatamodel::objectListModel()
540 QList<QObject*> dataList;
541 dataList.append(new DataObject("Item 1", "red"));
542 dataList.append(new DataObject("Item 2", "green"));
543 dataList.append(new DataObject("Item 3", "blue"));
544 dataList.append(new DataObject("Item 4", "yellow"));
546 QQmlContext *ctxt = view.rootContext();
547 ctxt->setContextProperty("myModel", QVariant::fromValue(dataList));
549 view.setSource(testFileUrl("objectlist.qml"));
551 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
552 QVERIFY(listview != 0);
554 QQuickItem *contentItem = listview->contentItem();
555 QVERIFY(contentItem != 0);
557 QQuickText *name = findItem<QQuickText>(contentItem, "name", 0);
558 QCOMPARE(name->text(), QString("Item 1"));
559 QCOMPARE(name->property("modelName").toString(), QString("Item 1"));
561 QQuickText *section = findItem<QQuickText>(contentItem, "section", 0);
562 QCOMPARE(section->text(), QString("Item 1"));
564 dataList[0]->setProperty("name", QLatin1String("Changed"));
565 QCOMPARE(name->text(), QString("Changed"));
566 QCOMPARE(name->property("modelName").toString(), QString("Changed"));
568 // Test resolving nested section property
569 DataObject *obj = static_cast<DataObject*>(dataList[0]);
570 obj->setSubName("SubItem 1");
572 QMetaObject::invokeMethod(listview, "changeSectionProperty");
573 section = findItem<QQuickText>(contentItem, "section", 0);
574 QCOMPARE(section->text(), QString("SubItem 1"));
577 void tst_qquickvisualdatamodel::singleRole()
582 SingleRoleModel model;
584 QQmlContext *ctxt = view.rootContext();
585 ctxt->setContextProperty("myModel", &model);
587 view.setSource(testFileUrl("singlerole1.qml"));
589 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
590 QVERIFY(listview != 0);
592 QQuickItem *contentItem = listview->contentItem();
593 QVERIFY(contentItem != 0);
595 QQuickText *name = findItem<QQuickText>(contentItem, "name", 1);
596 QCOMPARE(name->text(), QString("two"));
598 model.set(1, "Changed");
599 QCOMPARE(name->text(), QString("Changed"));
604 SingleRoleModel model;
606 QQmlContext *ctxt = view.rootContext();
607 ctxt->setContextProperty("myModel", &model);
609 view.setSource(testFileUrl("singlerole2.qml"));
611 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
612 QVERIFY(listview != 0);
614 QQuickItem *contentItem = listview->contentItem();
615 QVERIFY(contentItem != 0);
617 QQuickText *name = findItem<QQuickText>(contentItem, "name", 1);
618 QCOMPARE(name->text(), QString("two"));
620 model.set(1, "Changed");
621 QCOMPARE(name->text(), QString("Changed"));
626 SingleRoleModel model("modelData");
628 QQmlContext *ctxt = view.rootContext();
629 ctxt->setContextProperty("myModel", &model);
631 view.setSource(testFileUrl("singlerole2.qml"));
633 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
634 QVERIFY(listview != 0);
636 QQuickItem *contentItem = listview->contentItem();
637 QVERIFY(contentItem != 0);
639 QQuickText *name = findItem<QQuickText>(contentItem, "name", 1);
640 QCOMPARE(name->text(), QString("two"));
642 model.set(1, "Changed");
643 QCOMPARE(name->text(), QString("Changed"));
647 void tst_qquickvisualdatamodel::modelProperties()
652 SingleRoleModel model;
654 QQmlContext *ctxt = view.rootContext();
655 ctxt->setContextProperty("myModel", &model);
657 view.setSource(testFileUrl("modelproperties.qml"));
659 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
660 QVERIFY(listview != 0);
662 QQuickItem *contentItem = listview->contentItem();
663 QVERIFY(contentItem != 0);
665 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", 1);
667 QCOMPARE(delegate->property("test1").toString(),QString("two"));
668 QCOMPARE(delegate->property("test2").toString(),QString("two"));
669 QCOMPARE(delegate->property("test3").toString(),QString("two"));
670 QCOMPARE(delegate->property("test4").toString(),QString("two"));
671 QVERIFY(!delegate->property("test9").isValid());
672 QCOMPARE(delegate->property("test5").toString(),QString(""));
673 QVERIFY(delegate->property("test6").value<QObject*>() != 0);
674 QCOMPARE(delegate->property("test7").toInt(),1);
675 QCOMPARE(delegate->property("test8").toInt(),1);
681 QList<QObject*> dataList;
682 dataList.append(new DataObject("Item 1", "red"));
683 dataList.append(new DataObject("Item 2", "green"));
684 dataList.append(new DataObject("Item 3", "blue"));
685 dataList.append(new DataObject("Item 4", "yellow"));
687 QQmlContext *ctxt = view.rootContext();
688 ctxt->setContextProperty("myModel", QVariant::fromValue(dataList));
690 view.setSource(testFileUrl("modelproperties.qml"));
692 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
693 QVERIFY(listview != 0);
695 QQuickItem *contentItem = listview->contentItem();
696 QVERIFY(contentItem != 0);
698 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", 1);
700 QCOMPARE(delegate->property("test1").toString(),QString("Item 2"));
701 QCOMPARE(delegate->property("test2").toString(),QString("Item 2"));
702 QVERIFY(qobject_cast<DataObject*>(delegate->property("test3").value<QObject*>()) != 0);
703 QVERIFY(qobject_cast<DataObject*>(delegate->property("test4").value<QObject*>()) != 0);
704 QCOMPARE(delegate->property("test5").toString(),QString("Item 2"));
705 QCOMPARE(delegate->property("test9").toString(),QString("Item 2"));
706 QVERIFY(delegate->property("test6").value<QObject*>() != 0);
707 QCOMPARE(delegate->property("test7").toInt(),1);
708 QCOMPARE(delegate->property("test8").toInt(),1);
711 #ifndef QT_NO_WIDGETS
715 QStandardItemModel model;
716 initStandardTreeModel(&model);
718 view.rootContext()->setContextProperty("myModel", &model);
720 QUrl source(testFileUrl("modelproperties2.qml"));
723 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":13: ReferenceError: modelData is not defined");
724 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":13: ReferenceError: modelData is not defined");
725 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":13: ReferenceError: modelData is not defined");
726 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":11: ReferenceError: modelData is not defined");
727 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":11: ReferenceError: modelData is not defined");
728 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":11: ReferenceError: modelData is not defined");
729 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":17: TypeError: Cannot read property 'display' of undefined");
730 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":17: TypeError: Cannot read property 'display' of undefined");
731 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":17: TypeError: Cannot read property 'display' of undefined");
733 view.setSource(source);
735 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
736 QVERIFY(listview != 0);
738 QQuickItem *contentItem = listview->contentItem();
739 QVERIFY(contentItem != 0);
741 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", 1);
743 QCOMPARE(delegate->property("test1").toString(),QString("Row 2 Item"));
744 QCOMPARE(delegate->property("test2").toString(),QString("Row 2 Item"));
745 QVERIFY(!delegate->property("test3").isValid());
746 QVERIFY(!delegate->property("test4").isValid());
747 QVERIFY(!delegate->property("test5").isValid());
748 QVERIFY(!delegate->property("test9").isValid());
749 QVERIFY(delegate->property("test6").value<QObject*>() != 0);
750 QCOMPARE(delegate->property("test7").toInt(),1);
751 QCOMPARE(delegate->property("test8").toInt(),1);
754 //### should also test QStringList and QVariantList
757 #ifndef QT_NO_WIDGETS
758 void tst_qquickvisualdatamodel::noDelegate_data()
760 QTest::addColumn<QUrl>("source");
762 QTest::newRow("item delegate") << testFileUrl("datalist.qml");
763 QTest::newRow("package delegate") << testFileUrl("datalist-package.qml");
766 void tst_qquickvisualdatamodel::noDelegate()
768 QFETCH(QUrl, source);
772 QStandardItemModel model;
773 initStandardTreeModel(&model);
775 view.rootContext()->setContextProperty("myModel", &model);
777 view.setSource(source);
779 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
780 QVERIFY(listview != 0);
782 QQuickVisualDataModel *vdm = listview->findChild<QQuickVisualDataModel*>("visualModel");
784 QCOMPARE(vdm->count(), 3);
787 QCOMPARE(vdm->count(), 0);
790 void tst_qquickvisualdatamodel::itemsDestroyed_data()
792 QTest::addColumn<QUrl>("source");
794 QTest::newRow("listView") << testFileUrl("itemsDestroyed_listView.qml");
795 QTest::newRow("package") << testFileUrl("itemsDestroyed_package.qml");
796 QTest::newRow("pathView") << testFileUrl("itemsDestroyed_pathView.qml");
797 QTest::newRow("repeater") << testFileUrl("itemsDestroyed_repeater.qml");
800 void tst_qquickvisualdatamodel::itemsDestroyed()
802 QFETCH(QUrl, source);
804 QQmlGuard<QQuickItem> delegate;
808 QStandardItemModel model;
809 initStandardTreeModel(&model);
810 view.rootContext()->setContextProperty("myModel", &model);
811 view.setSource(source);
814 QTest::qWaitForWindowShown(&view);
816 QVERIFY(delegate = findItem<QQuickItem>(view.rootItem(), "delegate", 1));
818 QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
823 void tst_qquickvisualdatamodel::packagesDestroyed()
825 SingleRoleModel model;
827 for (int i=0; i<30; i++)
828 model.list << (QLatin1String("item ") + i);
831 view.rootContext()->setContextProperty("testModel", &model);
833 QString filename(testFile("packageView.qml"));
834 view.setSource(QUrl::fromLocalFile(filename));
836 qApp->processEvents();
838 QQuickListView *leftview = findItem<QQuickListView>(view.rootObject(), "leftList");
839 QTRY_VERIFY(leftview != 0);
841 QQuickListView *rightview = findItem<QQuickListView>(view.rootObject(), "rightList");
842 QTRY_VERIFY(rightview != 0);
844 QQuickItem *leftContent = leftview->contentItem();
845 QTRY_VERIFY(leftContent != 0);
847 QQuickItem *rightContent = rightview->contentItem();
848 QTRY_VERIFY(rightContent != 0);
850 QCOMPARE(leftview->currentIndex(), 0);
851 QCOMPARE(rightview->currentIndex(), 0);
853 rightview->setCurrentIndex(20);
854 QTRY_COMPARE(rightview->contentY(), 100.0);
856 QQmlGuard<QQuickItem> left;
857 QQmlGuard<QQuickItem> right;
859 QVERIFY(findItem<QQuickItem>(leftContent, "wrapper", 1));
860 QVERIFY(findItem<QQuickItem>(rightContent, "wrapper", 1));
862 QVERIFY(left = findItem<QQuickItem>(leftContent, "wrapper", 19));
863 QVERIFY(right = findItem<QQuickItem>(rightContent, "wrapper", 19));
865 rightview->setCurrentIndex(0);
866 QCOMPARE(rightview->currentIndex(), 0);
868 QTRY_COMPARE(rightview->contentY(), 0.0);
869 QCoreApplication::sendPostedEvents();
874 QVERIFY(left = findItem<QQuickItem>(leftContent, "wrapper", 1));
875 QVERIFY(right = findItem<QQuickItem>(rightContent, "wrapper", 1));
877 rightview->setCurrentIndex(20);
878 QTRY_COMPARE(rightview->contentY(), 100.0);
883 QVERIFY(findItem<QQuickItem>(leftContent, "wrapper", 19));
884 QVERIFY(findItem<QQuickItem>(rightContent, "wrapper", 19));
886 leftview->setCurrentIndex(20);
887 QTRY_COMPARE(leftview->contentY(), 100.0);
893 void tst_qquickvisualdatamodel::qaimRowsMoved()
895 // Test parameters passed in QAIM::rowsMoved() signal are converted correctly
896 // when translated and emitted as the QListModelInterface::itemsMoved() signal
897 QFETCH(int, sourceFirst);
898 QFETCH(int, sourceLast);
899 QFETCH(int, destinationChild);
900 QFETCH(int, expectFrom);
901 QFETCH(int, expectTo);
902 QFETCH(int, expectCount);
905 QQmlComponent c(&engine, testFileUrl("visualdatamodel.qml"));
907 SingleRoleModel model;
909 for (int i=0; i<30; i++)
910 model.list << (QLatin1String("item ") + i);
911 engine.rootContext()->setContextProperty("myModel", &model);
913 QQuickVisualDataModel *obj = qobject_cast<QQuickVisualDataModel*>(c.create());
916 QSignalSpy spy(obj, SIGNAL(modelUpdated(QQuickChangeSet,bool)));
917 model.emitMove(sourceFirst, sourceLast, destinationChild);
918 QCOMPARE(spy.count(), 1);
920 QCOMPARE(spy[0].count(), 2);
921 QQuickChangeSet changeSet = spy[0][0].value<QQuickChangeSet>();
922 QCOMPARE(changeSet.removes().count(), 1);
923 QCOMPARE(changeSet.removes().at(0).index, expectFrom);
924 QCOMPARE(changeSet.removes().at(0).count, expectCount);
925 QCOMPARE(changeSet.inserts().count(), 1);
926 QCOMPARE(changeSet.inserts().at(0).index, expectTo);
927 QCOMPARE(changeSet.inserts().at(0).count, expectCount);
928 QCOMPARE(changeSet.removes().at(0).moveId, changeSet.inserts().at(0).moveId);
929 QCOMPARE(spy[0][1].toBool(), false);
934 void tst_qquickvisualdatamodel::qaimRowsMoved_data()
936 QTest::addColumn<int>("sourceFirst");
937 QTest::addColumn<int>("sourceLast");
938 QTest::addColumn<int>("destinationChild");
939 QTest::addColumn<int>("expectFrom");
940 QTest::addColumn<int>("expectTo");
941 QTest::addColumn<int>("expectCount");
943 QTest::newRow("move 1 forward")
947 QTest::newRow("move 1 backwards")
951 QTest::newRow("move multiple forwards")
955 QTest::newRow("move multiple forwards, with same to")
959 QTest::newRow("move multiple backwards")
964 void tst_qquickvisualdatamodel::remove_data()
966 QTest::addColumn<QUrl>("source");
967 QTest::addColumn<QString>("package delegate");
969 QTest::newRow("item delegate")
970 << testFileUrl("groups.qml")
972 QTest::newRow("package")
973 << testFileUrl("groups-package.qml")
974 << QString("package.");
977 void tst_qquickvisualdatamodel::remove()
981 SingleRoleModel model;
982 model.list = QStringList()
996 QQmlContext *ctxt = view.rootContext();
997 ctxt->setContextProperty("myModel", &model);
999 view.setSource(testFileUrl("groups.qml"));
1001 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
1002 QVERIFY(listview != 0);
1004 QQuickItem *contentItem = listview->contentItem();
1005 QVERIFY(contentItem != 0);
1007 QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel *>(qvariant_cast<QObject *>(listview->model()));
1008 QVERIFY(visualModel);
1011 QCOMPARE(listview->count(), 12);
1012 QCOMPARE(visualModel->items()->count(), 12);
1013 static const int mIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1014 static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1016 for (int i = 0; i < lengthOf(mIndex); ++i) {
1017 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1019 QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
1020 QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
1021 QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
1024 evaluate<void>(visualModel, "items.remove(2)");
1025 QCOMPARE(listview->count(), 11);
1026 QCOMPARE(visualModel->items()->count(), 11);
1027 static const int mIndex[] = { 0, 1, 3, 4, 5, 6, 7, 8, 9,10,11 };
1028 static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10 };
1030 for (int i = 0; i < lengthOf(mIndex); ++i) {
1031 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1033 QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
1034 QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
1035 QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
1038 evaluate<void>(visualModel, "items.remove(1, 4)");
1039 QCOMPARE(listview->count(), 7);
1040 QCOMPARE(visualModel->items()->count(), 7);
1041 static const int mIndex[] = { 0, 6, 7, 8, 9,10,11 };
1042 static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6 };
1044 for (int i = 0; i < lengthOf(mIndex); ++i) {
1045 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1047 QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
1048 QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
1049 QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
1052 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: remove: index out of range");
1053 evaluate<void>(visualModel, "items.remove(-8, 4)");
1054 QCOMPARE(listview->count(), 7);
1055 QCOMPARE(visualModel->items()->count(), 7);
1057 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: remove: index out of range");
1058 evaluate<void>(visualModel, "items.remove(12, 2)");
1059 QCOMPARE(listview->count(), 7);
1060 QCOMPARE(visualModel->items()->count(), 7);
1062 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: remove: invalid count");
1063 evaluate<void>(visualModel, "items.remove(5, 3)");
1064 QCOMPARE(listview->count(), 7);
1065 QCOMPARE(visualModel->items()->count(), 7);
1067 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: remove: invalid count");
1068 evaluate<void>(visualModel, "items.remove(5, -2)");
1069 QCOMPARE(listview->count(), 7);
1070 QCOMPARE(visualModel->items()->count(), 7);
1074 void tst_qquickvisualdatamodel::move_data()
1076 QTest::addColumn<QUrl>("source");
1077 QTest::addColumn<QString>("package delegate");
1079 QTest::newRow("item delegate")
1080 << testFileUrl("groups.qml")
1082 QTest::newRow("package")
1083 << testFileUrl("groups-package.qml")
1084 << QString("package.");
1087 void tst_qquickvisualdatamodel::move()
1091 SingleRoleModel model;
1092 model.list = QStringList()
1106 QQmlContext *ctxt = view.rootContext();
1107 ctxt->setContextProperty("myModel", &model);
1109 view.setSource(testFileUrl("groups.qml"));
1111 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
1112 QVERIFY(listview != 0);
1114 QQuickItem *contentItem = listview->contentItem();
1115 QVERIFY(contentItem != 0);
1117 QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel *>(qvariant_cast<QObject *>(listview->model()));
1118 QVERIFY(visualModel);
1121 QCOMPARE(listview->count(), 12);
1122 QCOMPARE(visualModel->items()->count(), 12);
1123 static const int mIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1124 static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1126 for (int i = 0; i < lengthOf(mIndex); ++i) {
1127 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1129 QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
1130 QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
1131 QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
1134 evaluate<void>(visualModel, "items.move(2, 4)");
1135 QCOMPARE(listview->count(), 12);
1136 QCOMPARE(visualModel->items()->count(), 12);
1137 static const int mIndex[] = { 0, 1, 3, 4, 2, 5, 6, 7, 8, 9,10,11 };
1138 static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1140 for (int i = 0; i < lengthOf(mIndex); ++i) {
1141 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1143 QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
1144 QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
1145 QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
1148 evaluate<void>(visualModel, "items.move(4, 2)");
1149 QCOMPARE(listview->count(), 12);
1150 QCOMPARE(visualModel->items()->count(), 12);
1151 static const int mIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1152 static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1154 for (int i = 0; i < lengthOf(mIndex); ++i) {
1155 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1157 QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
1158 QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
1159 QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
1162 evaluate<void>(visualModel, "items.move(8, 0, 4)");
1163 QCOMPARE(listview->count(), 12);
1164 QCOMPARE(visualModel->items()->count(), 12);
1165 static const int mIndex[] = { 8, 9,10,11, 0, 1, 2, 3, 4, 5, 6, 7 };
1166 static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1168 for (int i = 0; i < lengthOf(mIndex); ++i) {
1169 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1171 QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
1172 QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
1173 QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
1176 evaluate<void>(visualModel, "items.move(3, 4, 5)");
1177 QCOMPARE(listview->count(), 12);
1178 QCOMPARE(visualModel->items()->count(), 12);
1179 static const int mIndex[] = { 8, 9,10,4, 11, 0, 1, 2, 3, 5, 6, 7 };
1180 static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1182 for (int i = 0; i < lengthOf(mIndex); ++i) {
1183 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1185 QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
1186 QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
1187 QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
1190 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: invalid count");
1191 evaluate<void>(visualModel, "items.move(5, 2, -2)");
1192 QCOMPARE(listview->count(), 12);
1193 QCOMPARE(visualModel->items()->count(), 12);
1195 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: from index out of range");
1196 evaluate<void>(visualModel, "items.move(-6, 2, 1)");
1197 QCOMPARE(listview->count(), 12);
1198 QCOMPARE(visualModel->items()->count(), 12);
1200 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: from index out of range");
1201 evaluate<void>(visualModel, "items.move(15, 2, 1)");
1202 QCOMPARE(listview->count(), 12);
1203 QCOMPARE(visualModel->items()->count(), 12);
1205 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: from index out of range");
1206 evaluate<void>(visualModel, "items.move(11, 1, 3)");
1207 QCOMPARE(listview->count(), 12);
1208 QCOMPARE(visualModel->items()->count(), 12);
1210 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: to index out of range");
1211 evaluate<void>(visualModel, "items.move(2, -5, 1)");
1212 QCOMPARE(listview->count(), 12);
1213 QCOMPARE(visualModel->items()->count(), 12);
1215 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: to index out of range");
1216 evaluate<void>(visualModel, "items.move(2, 14, 1)");
1217 QCOMPARE(listview->count(), 12);
1218 QCOMPARE(visualModel->items()->count(), 12);
1220 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: to index out of range");
1221 evaluate<void>(visualModel, "items.move(2, 11, 4)");
1222 QCOMPARE(listview->count(), 12);
1223 QCOMPARE(visualModel->items()->count(), 12);
1227 void tst_qquickvisualdatamodel::groups_data()
1229 QTest::addColumn<QUrl>("source");
1230 QTest::addColumn<QString>("part");
1232 QTest::newRow("item delegate")
1233 << testFileUrl("groups.qml")
1235 QTest::newRow("package")
1236 << testFileUrl("groups-package.qml")
1237 << QString("visualModel.parts.package.");
1240 template <int N> void tst_qquickvisualdatamodel::groups_verify(
1241 const SingleRoleModel &model,
1242 QQuickItem *contentItem,
1243 const int (&mIndex)[N],
1244 const int (&iIndex)[N],
1245 const int (&vIndex)[N],
1246 const int (&sIndex)[N],
1247 const bool (&vMember)[N],
1248 const bool (&sMember)[N])
1251 for (int i = 0; i < N; ++i) {
1252 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1254 QCOMPARE(evaluate<QString>(delegate, "test1"), model.list.at(mIndex[i]));
1255 QCOMPARE(evaluate<int>(delegate, "test2") , mIndex[i]);
1256 QCOMPARE(evaluate<int>(delegate, "test3") , iIndex[i]);
1257 QCOMPARE(evaluate<bool>(delegate, "test4"), true);
1258 QCOMPARE(evaluate<int>(delegate, "test5") , vIndex[i]);
1259 QCOMPARE(evaluate<bool>(delegate, "test6"), vMember[i]);
1260 QCOMPARE(evaluate<int>(delegate, "test7") , sIndex[i]);
1261 QCOMPARE(evaluate<bool>(delegate, "test8"), sMember[i]);
1262 QCOMPARE(evaluate<QStringList>(delegate, "test9").contains("items") , bool(true));
1263 QCOMPARE(evaluate<QStringList>(delegate, "test9").contains("visible") , bool(vMember[i]));
1264 QCOMPARE(evaluate<QStringList>(delegate, "test9").contains("selected"), bool(sMember[i]));
1269 #define VERIFY_GROUPS \
1270 groups_verify(model, contentItem, mIndex, iIndex, vIndex, sIndex, vMember, sMember); \
1274 void tst_qquickvisualdatamodel::groups()
1276 QFETCH(QUrl, source);
1277 QFETCH(QString, part);
1281 SingleRoleModel model;
1282 model.list = QStringList()
1296 QQmlContext *ctxt = view.rootContext();
1297 ctxt->setContextProperty("myModel", &model);
1299 view.setSource(source);
1301 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
1302 QVERIFY(listview != 0);
1304 QQuickItem *contentItem = listview->contentItem();
1305 QVERIFY(contentItem != 0);
1307 QQuickVisualDataModel *visualModel = listview->findChild<QQuickVisualDataModel *>("visualModel");
1308 QVERIFY(visualModel);
1310 QQuickVisualDataGroup *visibleItems = listview->findChild<QQuickVisualDataGroup *>("visibleItems");
1311 QVERIFY(visibleItems);
1313 QQuickVisualDataGroup *selectedItems = listview->findChild<QQuickVisualDataGroup *>("selectedItems");
1314 QVERIFY(selectedItems);
1316 const bool f = false;
1317 const bool t = true;
1320 QCOMPARE(listview->count(), 12);
1321 QCOMPARE(visualModel->items()->count(), 12);
1322 QCOMPARE(visibleItems->count(), 12);
1323 QCOMPARE(selectedItems->count(), 0);
1324 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1325 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1326 static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1327 static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
1328 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1329 static const bool sMember[] = { f, f, f, f, f, f, f, f, f, f, f, f };
1332 evaluate<void>(visualModel, "items.addGroups(8, \"selected\")");
1333 QCOMPARE(listview->count(), 12);
1334 QCOMPARE(visualModel->items()->count(), 12);
1335 QCOMPARE(visibleItems->count(), 12);
1336 QCOMPARE(selectedItems->count(), 1);
1337 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1338 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1339 static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1340 static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
1341 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 };
1342 static const bool sMember[] = { f, f, f, f, f, f, f, f, t, f, f, f };
1345 evaluate<void>(visualModel, "items.addGroups(6, 4, [\"visible\", \"selected\"])");
1346 QCOMPARE(listview->count(), 12);
1347 QCOMPARE(visualModel->items()->count(), 12);
1348 QCOMPARE(visibleItems->count(), 12);
1349 QCOMPARE(selectedItems->count(), 4);
1350 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1351 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1352 static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1353 static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
1354 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 4 };
1355 static const bool sMember[] = { f, f, f, f, f, f, t, t, t, t, f, f };
1358 evaluate<void>(visualModel, "items.setGroups(2, [\"items\", \"selected\"])");
1359 QCOMPARE(listview->count(), 12);
1360 QCOMPARE(visualModel->items()->count(), 12);
1361 QCOMPARE(visibleItems->count(), 11);
1362 QCOMPARE(selectedItems->count(), 5);
1363 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1364 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1365 static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9,10 };
1366 static const bool vMember[] = { t, t, f, t, t, t, t, t, t, t, t, t };
1367 static const int sIndex [] = { 0, 0, 0, 1, 1, 1, 1, 2, 3, 4, 5, 5 };
1368 static const bool sMember[] = { f, f, t, f, f, f, t, t, t, t, f, f };
1371 evaluate<void>(selectedItems, "setGroups(0, 3, \"items\")");
1372 QCOMPARE(listview->count(), 12);
1373 QCOMPARE(visualModel->items()->count(), 12);
1374 QCOMPARE(visibleItems->count(), 9);
1375 QCOMPARE(selectedItems->count(), 2);
1376 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1377 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1378 static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 5, 5, 6, 7, 8 };
1379 static const bool vMember[] = { t, t, f, t, t, t, f, f, t, t, t, t };
1380 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 };
1381 static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f };
1384 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: addGroups: invalid count");
1385 evaluate<void>(visualModel, "items.addGroups(11, -4, \"items\")");
1386 QCOMPARE(listview->count(), 12);
1387 QCOMPARE(visualModel->items()->count(), 12);
1388 QCOMPARE(visibleItems->count(), 9);
1389 QCOMPARE(selectedItems->count(), 2);
1391 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: addGroups: index out of range");
1392 evaluate<void>(visualModel, "items.addGroups(-1, 3, \"items\")");
1393 QCOMPARE(listview->count(), 12);
1394 QCOMPARE(visualModel->items()->count(), 12);
1395 QCOMPARE(visibleItems->count(), 9);
1396 QCOMPARE(selectedItems->count(), 2);
1398 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: addGroups: index out of range");
1399 evaluate<void>(visualModel, "items.addGroups(14, 3, \"items\")");
1400 QCOMPARE(listview->count(), 12);
1401 QCOMPARE(visualModel->items()->count(), 12);
1402 QCOMPARE(visibleItems->count(), 9);
1403 QCOMPARE(selectedItems->count(), 2);
1405 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: addGroups: invalid count");
1406 evaluate<void>(visualModel, "items.addGroups(11, 5, \"items\")");
1407 QCOMPARE(listview->count(), 12);
1408 QCOMPARE(visualModel->items()->count(), 12);
1409 QCOMPARE(visibleItems->count(), 9);
1410 QCOMPARE(selectedItems->count(), 2);
1412 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: setGroups: invalid count");
1413 evaluate<void>(visualModel, "items.setGroups(11, -4, \"items\")");
1414 QCOMPARE(listview->count(), 12);
1415 QCOMPARE(visualModel->items()->count(), 12);
1416 QCOMPARE(visibleItems->count(), 9);
1417 QCOMPARE(selectedItems->count(), 2);
1419 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: setGroups: index out of range");
1420 evaluate<void>(visualModel, "items.setGroups(-1, 3, \"items\")");
1421 QCOMPARE(listview->count(), 12);
1422 QCOMPARE(visualModel->items()->count(), 12);
1423 QCOMPARE(visibleItems->count(), 9);
1424 QCOMPARE(selectedItems->count(), 2);
1426 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: setGroups: index out of range");
1427 evaluate<void>(visualModel, "items.setGroups(14, 3, \"items\")");
1428 QCOMPARE(listview->count(), 12);
1429 QCOMPARE(visualModel->items()->count(), 12);
1430 QCOMPARE(visibleItems->count(), 9);
1431 QCOMPARE(selectedItems->count(), 2);
1433 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: setGroups: invalid count");
1434 evaluate<void>(visualModel, "items.setGroups(11, 5, \"items\")");
1435 QCOMPARE(listview->count(), 12);
1436 QCOMPARE(visualModel->items()->count(), 12);
1437 QCOMPARE(visibleItems->count(), 9);
1438 QCOMPARE(selectedItems->count(), 2);
1440 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: removeGroups: invalid count");
1441 evaluate<void>(visualModel, "items.removeGroups(11, -4, \"items\")");
1442 QCOMPARE(listview->count(), 12);
1443 QCOMPARE(visualModel->items()->count(), 12);
1445 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: removeGroups: index out of range");
1446 evaluate<void>(visualModel, "items.removeGroups(-1, 3, \"items\")");
1447 QCOMPARE(listview->count(), 12);
1448 QCOMPARE(visualModel->items()->count(), 12);
1449 QCOMPARE(visibleItems->count(), 9);
1450 QCOMPARE(selectedItems->count(), 2);
1452 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: removeGroups: index out of range");
1453 evaluate<void>(visualModel, "items.removeGroups(14, 3, \"items\")");
1454 QCOMPARE(listview->count(), 12);
1455 QCOMPARE(visualModel->items()->count(), 12);
1456 QCOMPARE(visibleItems->count(), 9);
1457 QCOMPARE(selectedItems->count(), 2);
1459 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: removeGroups: invalid count");
1460 evaluate<void>(visualModel, "items.removeGroups(11, 5, \"items\")");
1461 QCOMPARE(listview->count(), 12);
1462 QCOMPARE(visualModel->items()->count(), 12);
1463 QCOMPARE(visibleItems->count(), 9);
1464 QCOMPARE(selectedItems->count(), 2);
1466 evaluate<void>(visualModel, part + "filterOnGroup = \"visible\"");
1467 QCOMPARE(listview->count(), 9);
1468 QCOMPARE(visualModel->items()->count(), 12);
1469 QCOMPARE(visibleItems->count(), 9);
1470 QCOMPARE(selectedItems->count(), 2);
1471 QCOMPARE(evaluate<QString>(visualModel, part + "filterOnGroup"), QString("visible"));
1473 evaluate<void>(visualModel, part + "filterOnGroup = \"selected\"");
1474 QCOMPARE(listview->count(), 2);
1475 QCOMPARE(visualModel->items()->count(), 12);
1476 QCOMPARE(visibleItems->count(), 9);
1477 QCOMPARE(selectedItems->count(), 2);
1478 QCOMPARE(evaluate<QString>(visualModel, part + "filterOnGroup"), QString("selected"));
1480 evaluate<void>(visualModel, part + "filterOnGroup = undefined");
1481 QCOMPARE(listview->count(), 12);
1482 QCOMPARE(visualModel->items()->count(), 12);
1483 QCOMPARE(visibleItems->count(), 9);
1484 QCOMPARE(selectedItems->count(), 2);
1485 QCOMPARE(evaluate<QString>(visualModel, part + "filterOnGroup"), QString("items"));
1487 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", 5);
1490 evaluate<void>(delegate, "hide()");
1491 QCOMPARE(listview->count(), 12);
1492 QCOMPARE(visualModel->items()->count(), 12);
1493 QCOMPARE(visibleItems->count(), 8);
1494 QCOMPARE(selectedItems->count(), 2);
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, 0, 0, 0, 1, 2, 2 };
1500 static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f };
1503 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", 5);
1506 evaluate<void>(delegate, "select()");
1507 QCOMPARE(listview->count(), 12);
1508 QCOMPARE(visualModel->items()->count(), 12);
1509 QCOMPARE(visibleItems->count(), 8);
1510 QCOMPARE(selectedItems->count(), 3);
1511 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1512 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1513 static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 6, 7 };
1514 static const bool vMember[] = { t, t, f, t, t, f, f, f, t, t, t, t };
1515 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 3, 3 };
1516 static const bool sMember[] = { f, f, f, f, f, t, f, f, t, t, f, f };
1519 evaluate<void>(visualModel, "items.move(2, 6, 3)");
1520 QCOMPARE(listview->count(), 12);
1521 QCOMPARE(visualModel->items()->count(), 12);
1522 QCOMPARE(visibleItems->count(), 8);
1523 QCOMPARE(selectedItems->count(), 3);
1524 static const int mIndex [] = { 0, 1, 5, 6, 7, 8, 2, 3, 4, 9,10,11 };
1525 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1526 static const int vIndex [] = { 0, 1, 2, 2, 2, 2, 3, 3, 4, 5, 6, 7 };
1527 static const bool vMember[] = { t, t, f, f, f, t, f, t, t, t, t, t };
1528 static const int sIndex [] = { 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3 };
1529 static const bool sMember[] = { f, f, t, f, f, t, f, f, f, t, f, f };
1534 template <int N> void tst_qquickvisualdatamodel::get_verify(
1535 const SingleRoleModel &model,
1536 QQuickVisualDataModel *visualModel,
1537 QQuickVisualDataGroup *visibleItems,
1538 QQuickVisualDataGroup *selectedItems,
1539 const int (&mIndex)[N],
1540 const int (&iIndex)[N],
1541 const int (&vIndex)[N],
1542 const int (&sIndex)[N],
1543 const bool (&vMember)[N],
1544 const bool (&sMember)[N])
1547 for (int i = 0; i < N; ++i) {
1548 QCOMPARE(evaluate<QString>(visualModel, QString("items.get(%1).model.name").arg(i)), model.list.at(mIndex[i]));
1549 QCOMPARE(evaluate<QString>(visualModel, QString("items.get(%1).model.modelData").arg(i)), model.list.at(mIndex[i]));
1550 QCOMPARE(evaluate<int>(visualModel, QString("items.get(%1).model.index").arg(i)), mIndex[i]);
1551 QCOMPARE(evaluate<int>(visualModel, QString("items.get(%1).itemsIndex").arg(i)), iIndex[i]);
1552 QCOMPARE(evaluate<bool>(visualModel, QString("items.get(%1).inItems").arg(i)), true);
1553 QCOMPARE(evaluate<int>(visualModel, QString("items.get(%1).visibleIndex").arg(i)), vIndex[i]);
1554 QCOMPARE(evaluate<bool>(visualModel, QString("items.get(%1).inVisible").arg(i)), vMember[i]);
1555 QCOMPARE(evaluate<int>(visualModel, QString("items.get(%1).selectedIndex").arg(i)), sIndex[i]);
1556 QCOMPARE(evaluate<bool>(visualModel, QString("items.get(%1).inSelected").arg(i)), sMember[i]);
1557 QCOMPARE(evaluate<bool>(visualModel, QString("contains(items.get(%1).groups, \"items\")").arg(i)), true);
1558 QCOMPARE(evaluate<bool>(visualModel, QString("contains(items.get(%1).groups, \"visible\")").arg(i)), vMember[i]);
1559 QCOMPARE(evaluate<bool>(visualModel, QString("contains(items.get(%1).groups, \"selected\")").arg(i)), sMember[i]);
1562 QCOMPARE(evaluate<QString>(visibleItems, QString("get(%1).model.name").arg(vIndex[i])), model.list.at(mIndex[i]));
1563 QCOMPARE(evaluate<QString>(visibleItems, QString("get(%1).model.modelData").arg(vIndex[i])), model.list.at(mIndex[i]));
1564 QCOMPARE(evaluate<int>(visibleItems, QString("get(%1).model.index").arg(vIndex[i])), mIndex[i]);
1565 QCOMPARE(evaluate<int>(visibleItems, QString("get(%1).itemsIndex").arg(vIndex[i])), iIndex[i]);
1566 QCOMPARE(evaluate<bool>(visibleItems, QString("get(%1).inItems").arg(vIndex[i])), true);
1567 QCOMPARE(evaluate<int>(visibleItems, QString("get(%1).visibleIndex").arg(vIndex[i])), vIndex[i]);
1568 QCOMPARE(evaluate<bool>(visibleItems, QString("get(%1).inVisible").arg(vIndex[i])), vMember[i]);
1569 QCOMPARE(evaluate<int>(visibleItems, QString("get(%1).selectedIndex").arg(vIndex[i])), sIndex[i]);
1570 QCOMPARE(evaluate<bool>(visibleItems, QString("get(%1).inSelected").arg(vIndex[i])), sMember[i]);
1572 QCOMPARE(evaluate<bool>(visibleItems, QString("contains(get(%1).groups, \"items\")").arg(vIndex[i])), true);
1573 QCOMPARE(evaluate<bool>(visibleItems, QString("contains(get(%1).groups, \"visible\")").arg(vIndex[i])), vMember[i]);
1574 QCOMPARE(evaluate<bool>(visibleItems, QString("contains(get(%1).groups, \"selected\")").arg(vIndex[i])), sMember[i]);
1577 QCOMPARE(evaluate<QString>(selectedItems, QString("get(%1).model.name").arg(sIndex[i])), model.list.at(mIndex[i]));
1578 QCOMPARE(evaluate<QString>(selectedItems, QString("get(%1).model.modelData").arg(sIndex[i])), model.list.at(mIndex[i]));
1579 QCOMPARE(evaluate<int>(selectedItems, QString("get(%1).model.index").arg(sIndex[i])), mIndex[i]);
1580 QCOMPARE(evaluate<int>(selectedItems, QString("get(%1).itemsIndex").arg(sIndex[i])), iIndex[i]);
1581 QCOMPARE(evaluate<bool>(selectedItems, QString("get(%1).inItems").arg(sIndex[i])), true);
1582 QCOMPARE(evaluate<int>(selectedItems, QString("get(%1).visibleIndex").arg(sIndex[i])), vIndex[i]);
1583 QCOMPARE(evaluate<bool>(selectedItems, QString("get(%1).inVisible").arg(sIndex[i])), vMember[i]);
1584 QCOMPARE(evaluate<int>(selectedItems, QString("get(%1).selectedIndex").arg(sIndex[i])), sIndex[i]);
1585 QCOMPARE(evaluate<bool>(selectedItems, QString("get(%1).inSelected").arg(sIndex[i])), sMember[i]);
1586 QCOMPARE(evaluate<bool>(selectedItems, QString("contains(get(%1).groups, \"items\")").arg(sIndex[i])), true);
1587 QCOMPARE(evaluate<bool>(selectedItems, QString("contains(get(%1).groups, \"visible\")").arg(sIndex[i])), vMember[i]);
1588 QCOMPARE(evaluate<bool>(selectedItems, QString("contains(get(%1).groups, \"selected\")").arg(sIndex[i])), sMember[i]);
1594 #define VERIFY_GET \
1595 get_verify(model, visualModel, visibleItems, selectedItems, mIndex, iIndex, vIndex, sIndex, vMember, sMember); \
1598 void tst_qquickvisualdatamodel::get()
1602 SingleRoleModel model;
1603 model.list = QStringList()
1617 QQmlContext *ctxt = view.rootContext();
1618 ctxt->setContextProperty("myModel", &model);
1620 view.setSource(testFileUrl("groups.qml"));
1622 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
1623 QVERIFY(listview != 0);
1625 QQuickItem *contentItem = listview->contentItem();
1626 QVERIFY(contentItem != 0);
1628 QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel *>(qvariant_cast<QObject *>(listview->model()));
1629 QVERIFY(visualModel);
1631 QQuickVisualDataGroup *visibleItems = visualModel->findChild<QQuickVisualDataGroup *>("visibleItems");
1632 QVERIFY(visibleItems);
1634 QQuickVisualDataGroup *selectedItems = visualModel->findChild<QQuickVisualDataGroup *>("selectedItems");
1635 QVERIFY(selectedItems);
1637 QV8Engine *v8Engine = QQmlEnginePrivate::getV8Engine(ctxt->engine());
1640 const bool f = false;
1641 const bool t = true;
1644 QCOMPARE(listview->count(), 12);
1645 QCOMPARE(visualModel->items()->count(), 12);
1646 QCOMPARE(visibleItems->count(), 12);
1647 QCOMPARE(selectedItems->count(), 0);
1648 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1649 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1650 static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1651 static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
1652 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1653 static const bool sMember[] = { f, f, f, f, f, f, f, f, f, f, f, f };
1656 evaluate<void>(visualModel, "items.addGroups(8, \"selected\")");
1657 QCOMPARE(listview->count(), 12);
1658 QCOMPARE(visualModel->items()->count(), 12);
1659 QCOMPARE(visibleItems->count(), 12);
1660 QCOMPARE(selectedItems->count(), 1);
1661 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1662 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1663 static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1664 static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
1665 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 };
1666 static const bool sMember[] = { f, f, f, f, f, f, f, f, t, f, f, f };
1669 evaluate<void>(visualModel, "items.addGroups(6, 4, [\"visible\", \"selected\"])");
1670 QCOMPARE(listview->count(), 12);
1671 QCOMPARE(visualModel->items()->count(), 12);
1672 QCOMPARE(visibleItems->count(), 12);
1673 QCOMPARE(selectedItems->count(), 4);
1674 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1675 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1676 static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1677 static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
1678 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 4 };
1679 static const bool sMember[] = { f, f, f, f, f, f, t, t, t, t, f, f };
1682 evaluate<void>(visualModel, "items.setGroups(2, [\"items\", \"selected\"])");
1683 QCOMPARE(listview->count(), 12);
1684 QCOMPARE(visualModel->items()->count(), 12);
1685 QCOMPARE(visibleItems->count(), 11);
1686 QCOMPARE(selectedItems->count(), 5);
1687 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1688 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1689 static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9,10 };
1690 static const bool vMember[] = { t, t, f, t, t, t, t, t, t, t, t, t };
1691 static const int sIndex [] = { 0, 0, 0, 1, 1, 1, 1, 2, 3, 4, 5, 5 };
1692 static const bool sMember[] = { f, f, t, f, f, f, t, t, t, t, f, f };
1695 evaluate<void>(selectedItems, "setGroups(0, 3, \"items\")");
1696 QCOMPARE(listview->count(), 12);
1697 QCOMPARE(visualModel->items()->count(), 12);
1698 QCOMPARE(visibleItems->count(), 9);
1699 QCOMPARE(selectedItems->count(), 2);
1700 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1701 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1702 static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 5, 5, 6, 7, 8 };
1703 static const bool vMember[] = { t, t, f, t, t, t, f, f, t, t, t, t };
1704 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 };
1705 static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f };
1708 evaluate<void>(visualModel, "items.get(5).inVisible = false");
1709 QCOMPARE(listview->count(), 12);
1710 QCOMPARE(visualModel->items()->count(), 12);
1711 QCOMPARE(visibleItems->count(), 8);
1712 QCOMPARE(selectedItems->count(), 2);
1713 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1714 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1715 static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 6, 7 };
1716 static const bool vMember[] = { t, t, f, t, t, f, f, f, t, t, t, t };
1717 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 };
1718 static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f };
1721 evaluate<void>(visualModel, "items.get(5).inSelected = true");
1722 QCOMPARE(listview->count(), 12);
1723 QCOMPARE(visualModel->items()->count(), 12);
1724 QCOMPARE(visibleItems->count(), 8);
1725 QCOMPARE(selectedItems->count(), 3);
1726 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1727 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1728 static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 6, 7 };
1729 static const bool vMember[] = { t, t, f, t, t, f, f, f, t, t, t, t };
1730 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 3, 3 };
1731 static const bool sMember[] = { f, f, f, f, f, t, f, f, t, t, f, f };
1734 evaluate<void>(visualModel, "items.get(5).groups = [\"visible\", \"items\"]");
1735 QCOMPARE(listview->count(), 12);
1736 QCOMPARE(visualModel->items()->count(), 12);
1737 QCOMPARE(visibleItems->count(), 9);
1738 QCOMPARE(selectedItems->count(), 2);
1739 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1740 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1741 static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 5, 5, 6, 7, 8 };
1742 static const bool vMember[] = { t, t, f, t, t, t, f, f, t, t, t, t };
1743 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 };
1744 static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f };
1749 void tst_qquickvisualdatamodel::invalidGroups()
1751 QUrl source = testFileUrl("groups-invalid.qml");
1752 QTest::ignoreMessage(QtWarningMsg, (source.toString() + ":12:9: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("Group names must start with a lower case letter")).toUtf8());
1754 QQmlComponent component(&engine, source);
1755 QScopedPointer<QObject> object(component.create());
1758 QCOMPARE(evaluate<int>(object.data(), "groups.length"), 4);
1759 QCOMPARE(evaluate<QString>(object.data(), "groups[0].name"), QString("items"));
1760 QCOMPARE(evaluate<QString>(object.data(), "groups[1].name"), QString("persistedItems"));
1761 QCOMPARE(evaluate<QString>(object.data(), "groups[2].name"), QString("visible"));
1762 QCOMPARE(evaluate<QString>(object.data(), "groups[3].name"), QString("selected"));
1765 void tst_qquickvisualdatamodel::onChanged_data()
1767 QTest::addColumn<QString>("expression");
1768 QTest::addColumn<QStringList>("tests");
1770 QTest::newRow("item appended")
1771 << QString("listModel.append({\"number\": \"five\"})")
1773 << "verify(vm.removed, [], [], [])"
1774 << "verify(vm.inserted, [4], [1], [undefined])"
1775 << "verify(vi.removed, [], [], [])"
1776 << "verify(vi.inserted, [4], [1], [undefined])"
1777 << "verify(si.removed, [], [], [])"
1778 << "verify(si.inserted, [], [], [])");
1779 QTest::newRow("item prepended")
1780 << QString("listModel.insert(0, {\"number\": \"five\"})")
1782 << "verify(vm.removed, [], [], [])"
1783 << "verify(vm.inserted, [0], [1], [undefined])"
1784 << "verify(vi.removed, [], [], [])"
1785 << "verify(vi.inserted, [0], [1], [undefined])"
1786 << "verify(si.removed, [], [], [])"
1787 << "verify(si.inserted, [], [], [])");
1788 QTest::newRow("item inserted")
1789 << QString("listModel.insert(2, {\"number\": \"five\"})")
1791 << "verify(vm.removed, [], [], [])"
1792 << "verify(vm.inserted, [2], [1], [undefined])"
1793 << "verify(vi.removed, [], [], [])"
1794 << "verify(vi.inserted, [2], [1], [undefined])"
1795 << "verify(si.removed, [], [], [])"
1796 << "verify(si.inserted, [], [], [])");
1798 QTest::newRow("item removed tail")
1799 << QString("listModel.remove(3)")
1801 << "verify(vm.removed, [3], [1], [undefined])"
1802 << "verify(vm.inserted, [], [], [])"
1803 << "verify(vi.removed, [3], [1], [undefined])"
1804 << "verify(vi.inserted, [], [], [])"
1805 << "verify(si.removed, [], [], [])"
1806 << "verify(si.inserted, [], [], [])");
1807 QTest::newRow("item removed head")
1808 << QString("listModel.remove(0)")
1810 << "verify(vm.removed, [0], [1], [undefined])"
1811 << "verify(vm.inserted, [], [], [])"
1812 << "verify(vi.removed, [0], [1], [undefined])"
1813 << "verify(vi.inserted, [], [], [])"
1814 << "verify(si.removed, [], [], [])"
1815 << "verify(si.inserted, [], [], [])");
1816 QTest::newRow("item removed middle")
1817 << QString("listModel.remove(1)")
1819 << "verify(vm.removed, [1], [1], [undefined])"
1820 << "verify(vm.inserted, [], [], [])"
1821 << "verify(vi.removed, [1], [1], [undefined])"
1822 << "verify(vi.inserted, [], [], [])"
1823 << "verify(si.removed, [], [], [])"
1824 << "verify(si.inserted, [], [], [])");
1827 QTest::newRow("item moved from tail")
1828 << QString("listModel.move(3, 0, 1)")
1830 << "verify(vm.removed, [3], [1], [vm.inserted[0].moveId])"
1831 << "verify(vm.inserted, [0], [1], [vm.removed[0].moveId])"
1832 << "verify(vi.removed, [3], [1], [vi.inserted[0].moveId])"
1833 << "verify(vi.inserted, [0], [1], [vi.removed[0].moveId])"
1834 << "verify(si.removed, [], [], [])"
1835 << "verify(si.inserted, [], [], [])");
1836 QTest::newRow("item moved from head")
1837 << QString("listModel.move(0, 2, 2)")
1839 << "verify(vm.removed, [0], [2], [vm.inserted[0].moveId])"
1840 << "verify(vm.inserted, [2], [2], [vm.removed[0].moveId])"
1841 << "verify(vi.removed, [0], [2], [vi.inserted[0].moveId])"
1842 << "verify(vi.inserted, [2], [2], [vi.removed[0].moveId])"
1843 << "verify(si.removed, [], [], [])"
1844 << "verify(si.inserted, [], [], [])");
1846 QTest::newRow("groups changed")
1847 << QString("items.setGroups(1, 2, [\"items\", \"selected\"])")
1849 << "verify(vm.inserted, [], [], [])"
1850 << "verify(vm.removed, [], [], [])"
1851 << "verify(vi.removed, [1], [2], [undefined])"
1852 << "verify(vi.inserted, [], [], [])"
1853 << "verify(si.removed, [], [], [])"
1854 << "verify(si.inserted, [0], [2], [undefined])");
1856 QTest::newRow("multiple removes")
1857 << QString("{ vi.remove(1, 1); "
1858 "vi.removeGroups(0, 2, \"items\") }")
1860 << "verify(vm.removed, [0, 1], [1, 1], [undefined, undefined])"
1861 << "verify(vm.inserted, [], [], [])"
1862 << "verify(vi.removed, [1], [1], [undefined])"
1863 << "verify(vi.inserted, [], [], [])"
1864 << "verify(si.removed, [], [], [])"
1865 << "verify(si.inserted, [], [], [])");
1868 void tst_qquickvisualdatamodel::onChanged()
1870 QFETCH(QString, expression);
1871 QFETCH(QStringList, tests);
1873 QQmlComponent component(&engine, testFileUrl("onChanged.qml"));
1874 QScopedPointer<QObject> object(component.create());
1877 evaluate<void>(object.data(), expression);
1879 foreach (const QString &test, tests) {
1880 bool passed = evaluate<bool>(object.data(), test);
1887 void tst_qquickvisualdatamodel::create()
1891 SingleRoleModel model;
1892 model.list = QStringList()
1914 QQmlContext *ctxt = view.rootContext();
1915 ctxt->setContextProperty("myModel", &model);
1917 view.setSource(testFileUrl("create.qml"));
1919 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
1920 QVERIFY(listview != 0);
1922 QQuickItem *contentItem = listview->contentItem();
1923 QVERIFY(contentItem != 0);
1925 QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel *>(qvariant_cast<QObject *>(listview->model()));
1926 QVERIFY(visualModel);
1928 QCOMPARE(listview->count(), 20);
1930 QQmlGuard<QQuickItem> delegate;
1932 // persistedItems.includeByDefault is true, so all items belong to persistedItems initially.
1933 QVERIFY(delegate = findItem<QQuickItem>(contentItem, "delegate", 1));
1934 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
1936 // changing include by default doesn't remove persistance.
1937 evaluate<void>(visualModel, "persistedItems.includeByDefault = false");
1938 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
1940 // removing from persistedItems does.
1941 evaluate<void>(visualModel, "persistedItems.remove(0, 20)");
1942 QCOMPARE(listview->count(), 20);
1943 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), false);
1945 // Request an item instantiated by the view.
1946 QVERIFY(delegate = qobject_cast<QQuickItem *>(evaluate<QObject *>(visualModel, "items.create(1)")));
1947 QCOMPARE(delegate.data(), findItem<QQuickItem>(contentItem, "delegate", 1));
1948 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
1949 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 1);
1951 evaluate<void>(delegate, "VisualDataModel.inPersistedItems = false");
1952 QCOMPARE(listview->count(), 20);
1953 QCoreApplication::sendPostedEvents(delegate, QEvent::DeferredDelete);
1955 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), false);
1956 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 0);
1958 // Request an item not instantiated by the view.
1959 QVERIFY(!findItem<QQuickItem>(contentItem, "delegate", 15));
1960 QVERIFY(delegate = qobject_cast<QQuickItem *>(evaluate<QObject *>(visualModel, "items.create(15)")));
1961 QCOMPARE(delegate.data(), findItem<QQuickItem>(contentItem, "delegate", 15));
1962 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
1963 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 1);
1965 evaluate<void>(visualModel, "persistedItems.remove(0)");
1966 QCoreApplication::sendPostedEvents(delegate, QEvent::DeferredDelete);
1968 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 0);
1970 // Request an item not instantiated by the view, then scroll the view so it will request it.
1971 QVERIFY(!findItem<QQuickItem>(contentItem, "delegate", 16));
1972 QVERIFY(delegate = qobject_cast<QQuickItem *>(evaluate<QObject *>(visualModel, "items.create(16)")));
1973 QCOMPARE(delegate.data(), findItem<QQuickItem>(contentItem, "delegate", 16));
1974 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
1975 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 1);
1977 evaluate<void>(listview, "positionViewAtIndex(19, ListView.End)");
1978 QCOMPARE(listview->count(), 20);
1979 evaluate<void>(delegate, "VisualDataModel.groups = [\"items\"]");
1980 QCoreApplication::sendPostedEvents(delegate, QEvent::DeferredDelete);
1982 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), false);
1983 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 0);
1985 // Request and release an item instantiated by the view, then scroll the view so it releases it.
1986 QVERIFY(findItem<QQuickItem>(contentItem, "delegate", 17));
1987 QVERIFY(delegate = qobject_cast<QQuickItem *>(evaluate<QObject *>(visualModel, "items.create(17)")));
1988 QCOMPARE(delegate.data(), findItem<QQuickItem>(contentItem, "delegate", 17));
1989 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
1990 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 1);
1992 evaluate<void>(visualModel, "items.removeGroups(17, \"persistedItems\")");
1993 QCoreApplication::sendPostedEvents(delegate, QEvent::DeferredDelete);
1995 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), false);
1996 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 0);
1997 evaluate<void>(listview, "positionViewAtIndex(1, ListView.Beginning)");
1998 QCOMPARE(listview->count(), 20);
1999 QCoreApplication::sendPostedEvents(delegate, QEvent::DeferredDelete);
2002 // Adding an item to the persistedItems group won't instantiate it, but if later requested by
2003 // the view it will be persisted.
2004 evaluate<void>(visualModel, "items.addGroups(18, \"persistedItems\")");
2005 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 1);
2006 QVERIFY(!findItem<QQuickItem>(contentItem, "delegate", 18));
2007 evaluate<void>(listview, "positionViewAtIndex(19, ListView.End)");
2008 QCOMPARE(listview->count(), 20);
2009 QVERIFY(delegate = findItem<QQuickItem>(contentItem, "delegate", 18));
2010 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
2011 QCoreApplication::sendPostedEvents(delegate, QEvent::DeferredDelete);
2013 evaluate<void>(listview, "positionViewAtIndex(1, ListView.Beginning)");
2014 QCOMPARE(listview->count(), 20);
2015 QCoreApplication::sendPostedEvents(delegate, QEvent::DeferredDelete);
2018 // Remove an uninstantiated but cached item from the persistedItems group.
2019 evaluate<void>(visualModel, "items.addGroups(19, \"persistedItems\")");
2020 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 2);
2021 QVERIFY(!findItem<QQuickItem>(contentItem, "delegate", 19));
2022 // Store a reference to the item so it is retained in the cache.
2023 evaluate<void>(visualModel, "persistentHandle = items.get(19)");
2024 QCOMPARE(evaluate<bool>(visualModel, "persistentHandle.inPersistedItems"), true);
2025 evaluate<void>(visualModel, "items.removeGroups(19, \"persistedItems\")");
2026 QCOMPARE(evaluate<bool>(visualModel, "persistentHandle.inPersistedItems"), false);
2029 void tst_qquickvisualdatamodel::incompleteModel()
2031 // VisualDataModel is first populated in componentComplete. Verify various functions are
2032 // harmlessly ignored until then.
2034 QQmlComponent component(&engine);
2035 component.setData("import QtQuick 2.0\n VisualDataModel {}", testFileUrl(""));
2037 QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
2039 QQuickVisualDataModel *model = qobject_cast<QQuickVisualDataModel *>(object.data());
2042 QSignalSpy itemsSpy(model->items(), SIGNAL(countChanged()));
2043 QSignalSpy persistedItemsSpy(model->items(), SIGNAL(countChanged()));
2045 evaluate<void>(model, "items.removeGroups(0, items.count, \"items\")");
2046 QCOMPARE(itemsSpy.count(), 0);
2047 QCOMPARE(persistedItemsSpy.count(), 0);
2049 evaluate<void>(model, "items.setGroups(0, items.count, \"persistedItems\")");
2050 QCOMPARE(itemsSpy.count(), 0);
2051 QCOMPARE(persistedItemsSpy.count(), 0);
2053 evaluate<void>(model, "items.addGroups(0, items.count, \"persistedItems\")");
2054 QCOMPARE(itemsSpy.count(), 0);
2055 QCOMPARE(persistedItemsSpy.count(), 0);
2057 evaluate<void>(model, "items.remove(0, items.count)");
2058 QCOMPARE(itemsSpy.count(), 0);
2059 QCOMPARE(persistedItemsSpy.count(), 0);
2061 evaluate<void>(model, "items.insert([ \"color\": \"blue\" ])");
2062 QCOMPARE(itemsSpy.count(), 0);
2063 QCOMPARE(persistedItemsSpy.count(), 0);
2065 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: get: index out of range");
2066 QVERIFY(evaluate<bool>(model, "items.get(0) === undefined"));
2068 component.completeCreate();
2071 void tst_qquickvisualdatamodel::insert_data()
2073 QTest::addColumn<QUrl>("source");
2074 QTest::addColumn<QString>("expression");
2075 QTest::addColumn<int>("modelCount");
2076 QTest::addColumn<int>("visualCount");
2077 QTest::addColumn<int>("index");
2078 QTest::addColumn<bool>("inItems");
2079 QTest::addColumn<bool>("persisted");
2080 QTest::addColumn<bool>("visible");
2081 QTest::addColumn<bool>("selected");
2082 QTest::addColumn<bool>("modelData");
2083 QTest::addColumn<QString>("property");
2084 QTest::addColumn<QStringList>("propertyData");
2086 const QUrl listModelSource[] = {
2087 testFileUrl("listmodelproperties.qml"),
2088 testFileUrl("listmodelproperties-package.qml") };
2089 const QUrl singleRoleSource[] = {
2090 testFileUrl("singleroleproperties.qml"),
2091 testFileUrl("singleroleproperties-package.qml") };
2092 const QUrl multipleRoleSource[] = {
2093 testFileUrl("multipleroleproperties.qml"),
2094 testFileUrl("multipleroleproperties-package.qml") };
2095 const QUrl stringListSource[] = {
2096 testFileUrl("stringlistproperties.qml"),
2097 testFileUrl("stringlistproperties-package.qml") };
2098 const QUrl objectListSource[] = {
2099 testFileUrl("objectlistproperties.qml"),
2100 testFileUrl("objectlistproperties-package.qml") };
2102 for (int i = 0; i < 2; ++i) {
2104 QTest::newRow("ListModel.items prepend")
2105 << listModelSource[i]
2106 << QString("items.insert(0, {\"number\": \"eight\"})")
2107 << 4 << 5 << 0 << true << false << false << false << true
2108 << QString("number")
2109 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2111 QTest::newRow("ListModel.items append")
2112 << listModelSource[i]
2113 << QString("items.insert({\"number\": \"eight\"})")
2114 << 4 << 5 << 4 << true << false << false << false << true
2115 << QString("number")
2116 << (QStringList() << "one" << "two" << "three" << "four" << "eight");
2118 QTest::newRow("ListModel.items insert at 2")
2119 << listModelSource[i]
2120 << QString("items.insert(2, {\"number\": \"eight\"})")
2121 << 4 << 5 << 2 << true << false << false << false << true
2122 << QString("number")
2123 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2125 QTest::newRow("ListModel.items insert at items.get(2)")
2126 << listModelSource[i]
2127 << QString("items.insert(items.get(2), {\"number\": \"eight\"})")
2128 << 4 << 5 << 2 << true << false << false << false << true
2129 << QString("number")
2130 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2132 QTest::newRow("ListModel.items insert at visibleItems.get(2)")
2133 << listModelSource[i]
2134 << QString("items.insert(visibleItems.get(2), {\"number\": \"eight\"})")
2135 << 4 << 5 << 2 << true << false << false << false << true
2136 << QString("number")
2137 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2139 QTest::newRow("ListModel.selectedItems insert at items.get(2)")
2140 << listModelSource[i]
2141 << QString("selectedItems.insert(items.get(2), {\"number\": \"eight\"})")
2142 << 4 << 5 << 2 << false << false << false << true << true
2143 << QString("number")
2144 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2146 QTest::newRow("ListModel.selectedItems insert at visibleItems.get(2)")
2147 << listModelSource[i]
2148 << QString("selectedItems.insert(visibleItems.get(2), {\"number\": \"eight\"})")
2149 << 4 << 5 << 2 << false << false << false << true << true
2150 << QString("number")
2151 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2153 QTest::newRow("ListModel.items prepend modelData")
2154 << listModelSource[i]
2155 << QString("items.insert(0, {\"modelData\": \"eight\"})")
2156 << 4 << 5 << 0 << true << false << false << false << true
2157 << QString("number")
2158 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2160 QTest::newRow("ListModel.items prepend, edit number")
2161 << listModelSource[i]
2163 "items.insert(0, {\"number\": \"eight\"}); "
2164 "items.get(0).model.number = \"seven\"; }")
2165 << 4 << 5 << 0 << true << false << false << false << true
2166 << QString("number")
2167 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2169 QTest::newRow("ListModel.items prepend, edit modelData")
2170 << listModelSource[i]
2172 "items.insert(0, {\"number\": \"eight\"}); "
2173 "items.get(0).model.modelData = \"seven\"; }")
2174 << 4 << 5 << 0 << true << false << false << false << true
2175 << QString("number")
2176 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2178 QTest::newRow("ListModel.items prepend, edit resolved")
2179 << listModelSource[i]
2181 "items.insert(0, {\"number\": \"eight\"}); "
2182 "items.get(2).model.number = \"seven\"; }")
2183 << 4 << 5 << 0 << true << false << false << false << true
2184 << QString("number")
2185 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2187 QTest::newRow("ListModel.items prepend with groups")
2188 << listModelSource[i]
2189 << QString("items.insert(0, {\"number\": \"eight\"}, [\"visible\", \"truncheon\"])")
2190 << 4 << 5 << 0 << true << false << true << false << true
2191 << QString("number")
2192 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2194 QTest::newRow("ListModel.items append with groups")
2195 << listModelSource[i]
2196 << QString("items.insert({\"number\": \"eight\"}, [\"visible\", \"selected\"])")
2197 << 4 << 5 << 4 << true << false << true << true << true
2198 << QString("number")
2199 << (QStringList() << "one" << "two" << "three" << "four" << "eight");
2201 QTest::newRow("ListModel.items insert at 2 with groups")
2202 << listModelSource[i]
2203 << QString("items.insert(2, {\"number\": \"eight\"}, \"visible\")")
2204 << 4 << 5 << 2 << true << false << true << false << true
2205 << QString("number")
2206 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2209 QTest::newRow("ListModel.items prepend")
2210 << listModelSource[i]
2211 << QString("items.create(0, {\"number\": \"eight\"})")
2212 << 4 << 5 << 0 << true << true << false << false << true
2213 << QString("number")
2214 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2216 QTest::newRow("ListModel.items append")
2217 << listModelSource[i]
2218 << QString("items.create({\"number\": \"eight\"})")
2219 << 4 << 5 << 4 << true << true << false << false << true
2220 << QString("number")
2221 << (QStringList() << "one" << "two" << "three" << "four" << "eight");
2223 QTest::newRow("ListModel.items create at 2")
2224 << listModelSource[i]
2225 << QString("items.create(2, {\"number\": \"eight\"})")
2226 << 4 << 5 << 2 << true << true << false << false << true
2227 << QString("number")
2228 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2230 QTest::newRow("ListModel.items create at items.get(2)")
2231 << listModelSource[i]
2232 << QString("items.create(items.get(2), {\"number\": \"eight\"})")
2233 << 4 << 5 << 2 << true << true << false << false << true
2234 << QString("number")
2235 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2237 QTest::newRow("ListModel.items create at visibleItems.get(2)")
2238 << listModelSource[i]
2239 << QString("items.create(visibleItems.get(2), {\"number\": \"eight\"})")
2240 << 4 << 5 << 2 << true << true << false << false << true
2241 << QString("number")
2242 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2244 QTest::newRow("ListModel.selectedItems create at items.get(2)")
2245 << listModelSource[i]
2246 << QString("selectedItems.create(items.get(2), {\"number\": \"eight\"})")
2247 << 4 << 5 << 2 << false << true << false << true << true
2248 << QString("number")
2249 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2251 QTest::newRow("ListModel.selectedItems create at visibleItems.get(2)")
2252 << listModelSource[i]
2253 << QString("selectedItems.create(visibleItems.get(2), {\"number\": \"eight\"})")
2254 << 4 << 5 << 2 << false << true << false << true << true
2255 << QString("number")
2256 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2258 QTest::newRow("ListModel.items create prepended")
2259 << listModelSource[i]
2260 << QString("items.create(0, {\"number\": \"eight\"})")
2261 << 4 << 5 << 0 << true << true << false << false << true
2262 << QString("number")
2263 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2265 QTest::newRow("ListModel.items create appended")
2266 << listModelSource[i]
2267 << QString("items.create({\"number\": \"eight\"})")
2268 << 4 << 5 << 4 << true << true << false << false << true
2269 << QString("number")
2270 << (QStringList() << "one" << "two" << "three" << "four" << "eight");
2272 QTest::newRow("ListModel.items create at 2")
2273 << listModelSource[i]
2274 << QString("items.create(2, {\"number\": \"eight\"})")
2275 << 4 << 5 << 2 << true << true << false << false << true
2276 << QString("number")
2277 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2279 QTest::newRow("ListModel.items create at items.get(2)")
2280 << listModelSource[i]
2281 << QString("items.create(items.get(2), {\"number\": \"eight\"})")
2282 << 4 << 5 << 2 << true << true << false << false << true
2283 << QString("number")
2284 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2286 QTest::newRow("ListModel.items create at visibleItems.get(2)")
2287 << listModelSource[i]
2288 << QString("items.create(visibleItems.get(2), {\"number\": \"eight\"})")
2289 << 4 << 5 << 2 << true << true << false << false << true
2290 << QString("number")
2291 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2293 QTest::newRow("ListModel.create prepend modelData")
2294 << listModelSource[i]
2295 << QString("items.create(0, {\"modelData\": \"eight\"})")
2296 << 4 << 5 << 0 << true << true << false << false << true
2297 << QString("number")
2298 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2300 QTest::newRow("ListModel.items create prepended, edit number")
2301 << listModelSource[i]
2303 "var item = items.create(0, {\"number\": \"eight\"}); "
2304 "item.setTest3(\"seven\"); }")
2305 << 4 << 5 << 0 << true << true << false << false << true
2306 << QString("number")
2307 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2309 QTest::newRow("ListModel.items create prepended, edit model.number")
2310 << listModelSource[i]
2312 "var item = items.create(0, {\"number\": \"eight\"}); "
2313 "item.setTest4(\"seven\"); }")
2314 << 4 << 5 << 0 << true << true << false << false << true
2315 << QString("number")
2316 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2318 QTest::newRow("ListModel.items create prepended, edit modelData")
2319 << listModelSource[i]
2321 "var item = items.create(0, {\"number\": \"eight\"}); "
2322 "item.setTest5(\"seven\"); }")
2323 << 4 << 5 << 0 << true << true << false << false << true
2324 << QString("number")
2325 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2327 QTest::newRow("ListModel.items create prepended, edit model.modelData")
2328 << listModelSource[i]
2330 "var item = items.create(0, {\"number\": \"eight\"}); "
2331 "item.setTest6(\"seven\"); }")
2332 << 4 << 5 << 0 << true << true << false << false << true
2333 << QString("number")
2334 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2336 QTest::newRow("ListModel.items create prepended with groups")
2337 << listModelSource[i]
2338 << QString("items.create(0, {\"number\": \"eight\"}, [\"visible\", \"truncheon\"])")
2339 << 4 << 5 << 0 << true << true << true << false << true
2340 << QString("number")
2341 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2343 QTest::newRow("ListModel.items create appended with groups")
2344 << listModelSource[i]
2345 << QString("items.create({\"number\": \"eight\"}, [\"visible\", \"selected\"])")
2346 << 4 << 5 << 4 << true << true << true << true << true
2347 << QString("number")
2348 << (QStringList() << "one" << "two" << "three" << "four" << "eight");
2350 QTest::newRow("ListModel.items create inserted with groups")
2351 << listModelSource[i]
2352 << QString("items.create(2, {\"number\": \"eight\"}, \"visible\")")
2353 << 4 << 5 << 2 << true << true << true << false << true
2354 << QString("number")
2355 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2357 QTest::newRow("ListModel.items create prepended clear persistence")
2358 << listModelSource[i]
2359 << QString("{ items.create(0, {\"number\": \"eight\"}); "
2360 "items.get(0).inPersistedItems = false }")
2361 << 4 << 5 << 0 << true << false << false << false << true
2362 << QString("number")
2363 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2365 QTest::newRow("ListModel.items create appended clear persistence")
2366 << listModelSource[i]
2367 << QString("{ items.create({\"number\": \"eight\"}); "
2368 "items.get(4).inPersistedItems = false }")
2369 << 4 << 5 << 4 << true << false << false << false << true
2370 << QString("number")
2371 << (QStringList() << "one" << "two" << "three" << "four" << "eight");
2373 QTest::newRow("ListModel.items create inserted clear persistence")
2374 << listModelSource[i]
2375 << QString("{ items.create(2, {\"number\": \"eight\"}); "
2376 "items.get(2).inPersistedItems = false }")
2377 << 4 << 5 << 2 << true << false << false << false << true
2378 << QString("number")
2379 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2381 // AbstractItemModel (Single Role).
2382 QTest::newRow("AbstractItemModel.items prepend")
2383 << singleRoleSource[i]
2384 << QString("items.insert(0, {\"name\": \"eight\"})")
2385 << 4 << 5 << 0 << true << false << false << false << true
2387 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2389 QTest::newRow("AbstractItemModel.items append")
2390 << singleRoleSource[i]
2391 << QString("items.insert({\"name\": \"eight\"})")
2392 << 4 << 5 << 4 << true << false << false << false << true
2394 << (QStringList() << "one" << "two" << "three" << "four" << "eight");
2396 QTest::newRow("AbstractItemModel.items insert at 2")
2397 << singleRoleSource[i]
2398 << QString("items.insert(2, {\"name\": \"eight\"})")
2399 << 4 << 5 << 2 << true << false << false << false << true
2401 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2403 QTest::newRow("AbstractItemModel.items prepend modelData")
2404 << singleRoleSource[i]
2405 << QString("items.insert(0, {\"modelData\": \"eight\"})")
2406 << 4 << 5 << 0 << true << false << false << false << true
2408 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2410 QTest::newRow("AbstractItemModel.items prepend, edit name")
2411 << singleRoleSource[i]
2413 "items.insert(0, {\"name\": \"eight\"}); "
2414 "items.get(0).model.name = \"seven\"; }")
2415 << 4 << 5 << 0 << true << false << false << false << true
2417 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2419 QTest::newRow("AbstractItemModel.items prepend, edit modelData")
2420 << singleRoleSource[i]
2422 "items.insert(0, {\"name\": \"eight\"}); "
2423 "items.get(0).model.modelData = \"seven\"; }")
2424 << 4 << 5 << 0 << true << false << false << false << true
2426 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2428 QTest::newRow("AbstractItemModel.items prepend, edit resolved")
2429 << singleRoleSource[i]
2431 "items.insert(0, {\"name\": \"eight\"}); "
2432 "items.get(2).model.name = \"seven\"; }")
2433 << 4 << 5 << 0 << true << false << false << false << true
2435 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2437 QTest::newRow("AbstractItemModel.create prepend modelData")
2438 << singleRoleSource[i]
2439 << QString("items.create(0, {\"modelData\": \"eight\"})")
2440 << 4 << 5 << 0 << true << true << false << false << true
2442 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2444 QTest::newRow("AbstractItemModel.items create prepended, edit name")
2445 << singleRoleSource[i]
2447 "var item = items.create(0, {\"name\": \"eight\"}); "
2448 "item.setTest3(\"seven\"); }")
2449 << 4 << 5 << 0 << true << true << false << false << true
2451 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2453 QTest::newRow("AbstractItemModel.items create prepended, edit model.name")
2454 << singleRoleSource[i]
2456 "var item = items.create(0, {\"name\": \"eight\"}); "
2457 "item.setTest4(\"seven\"); }")
2458 << 4 << 5 << 0 << true << true << false << false << true
2460 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2462 QTest::newRow("AbstractItemModel.items create prepended, edit modelData")
2463 << singleRoleSource[i]
2465 "var item = items.create(0, {\"name\": \"eight\"}); "
2466 "item.setTest5(\"seven\"); }")
2467 << 4 << 5 << 0 << true << true << false << false << true
2469 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2471 QTest::newRow("AbstractItemModel.items create prepended, edit model.modelData")
2472 << singleRoleSource[i]
2474 "var item = items.create(0, {\"name\": \"eight\"}); "
2475 "item.setTest6(\"seven\"); }")
2476 << 4 << 5 << 0 << true << true << false << false << true
2478 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2479 #ifndef QT_NO_WIDGETS
2480 // AbstractItemModel (Multiple Roles).
2481 QTest::newRow("StandardItemModel.items prepend")
2482 << multipleRoleSource[i]
2483 << QString("items.insert(0, {\"display\": \"Row 8 Item\"})")
2484 << 4 << 5 << 0 << true << false << false << false << false
2485 << QString("display")
2486 << (QStringList() << "Row 8 Item" << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2488 QTest::newRow("StandardItemModel.items append")
2489 << multipleRoleSource[i]
2490 << QString("items.insert({\"display\": \"Row 8 Item\"})")
2491 << 4 << 5 << 4 << true << false << false << false << false
2492 << QString("display")
2493 << (QStringList() << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item" << "Row 8 Item");
2495 QTest::newRow("StandardItemModel.items insert at 2")
2496 << multipleRoleSource[i]
2497 << QString("items.insert(2, {\"display\": \"Row 8 Item\"})")
2498 << 4 << 5 << 2 << true << false << false << false << false
2499 << QString("display")
2500 << (QStringList() << "Row 1 Item" << "Row 2 Item" << "Row 8 Item" << "Row 3 Item" << "Row 4 Item");
2502 QTest::newRow("StandardItemModel.items prepend modelData")
2503 << multipleRoleSource[i]
2504 << QString("items.insert(0, {\"modelData\": \"Row 8 Item\"})")
2505 << 4 << 5 << 0 << true << false << false << false << false
2506 << QString("display")
2507 << (QStringList() << QString() << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2509 QTest::newRow("StandardItemModel.items prepend, edit display")
2510 << multipleRoleSource[i]
2512 "items.insert(0, {\"display\": \"Row 8 Item\"}); "
2513 "items.get(0).model.display = \"Row 7 Item\"; }")
2514 << 4 << 5 << 0 << true << false << false << false << false
2515 << QString("display")
2516 << (QStringList() << "Row 7 Item" << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2518 QTest::newRow("StandardItemModel.items prepend, edit modelData")
2519 << multipleRoleSource[i]
2521 "items.insert(0, {\"display\": \"Row 8 Item\"}); "
2522 "items.get(0).model.modelData = \"Row 7 Item\"; }")
2523 << 4 << 5 << 0 << true << false << false << false << false
2524 << QString("display")
2525 << (QStringList() << "Row 8 Item" << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2527 QTest::newRow("StandardItemModel.items prepend, edit resolved")
2528 << multipleRoleSource[i]
2530 "items.insert(0, {\"display\": \"Row 8 Item\"}); "
2531 "items.get(2).model.display = \"Row 7 Item\"; }")
2532 << 4 << 5 << 0 << true << false << false << false << false
2533 << QString("display")
2534 << (QStringList() << "Row 8 Item" << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2536 QTest::newRow("StandardItemModel.create prepend modelData")
2537 << multipleRoleSource[i]
2538 << QString("items.create(0, {\"modelData\": \"Row 8 Item\"})")
2539 << 4 << 5 << 0 << true << true << false << false << false
2540 << QString("display")
2541 << (QStringList() << QString() << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2543 QTest::newRow("StandardItemModel.items create prepended, edit display")
2544 << multipleRoleSource[i]
2546 "var item = items.create(0, {\"display\": \"Row 8 Item\"}); "
2547 "item.setTest3(\"Row 7 Item\"); }")
2548 << 4 << 5 << 0 << true << true << false << false << false
2549 << QString("display")
2550 << (QStringList() << "Row 7 Item" << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2552 QTest::newRow("StandardItemModel.items create prepended, edit model.display")
2553 << multipleRoleSource[i]
2555 "var item = items.create(0, {\"display\": \"Row 8 Item\"}); "
2556 "item.setTest4(\"Row 7 Item\"); }")
2557 << 4 << 5 << 0 << true << true << false << false << false
2558 << QString("display")
2559 << (QStringList() << "Row 7 Item" << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2562 QTest::newRow("StringList.items prepend")
2563 << stringListSource[i]
2564 << QString("items.insert(0, {\"modelData\": \"eight\"})")
2565 << 4 << 5 << 0 << true << false << false << false << false
2566 << QString("modelData")
2567 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2569 QTest::newRow("StringList.items append")
2570 << stringListSource[i]
2571 << QString("items.insert({\"modelData\": \"eight\"})")
2572 << 4 << 5 << 4 << true << false << false << false << false
2573 << QString("modelData")
2574 << (QStringList() << "one" << "two" << "three" << "four" << "eight");
2576 QTest::newRow("StringList.items insert at 2")
2577 << stringListSource[i]
2578 << QString("items.insert(2, {\"modelData\": \"eight\"})")
2579 << 4 << 5 << 2 << true << false << false << false << false
2580 << QString("modelData")
2581 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2583 QTest::newRow("StringList.items prepend, edit modelData")
2584 << stringListSource[i]
2586 "items.insert(0, {\"modelData\": \"eight\"}); "
2587 "items.get(0).model.modelData = \"seven\"; }")
2588 << 4 << 5 << 0 << true << false << false << false << false
2589 << QString("modelData")
2590 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2592 QTest::newRow("StringList.items prepend, edit resolved")
2593 << stringListSource[i]
2595 "items.insert(0, {\"modelData\": \"eight\"}); "
2596 "items.get(2).model.modelData = \"seven\"; }")
2597 << 4 << 5 << 0 << true << false << false << false << false
2598 << QString("modelData")
2599 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2601 QTest::newRow("StringList.create prepend modelData")
2602 << stringListSource[i]
2603 << QString("items.create(0, {\"modelData\": \"eight\"})")
2604 << 4 << 5 << 0 << true << true << false << false << false
2605 << QString("modelData")
2606 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2608 QTest::newRow("StringList.items create prepended, edit modelData")
2609 << stringListSource[i]
2611 "var item = items.create(0, {\"modelData\": \"eight\"}); "
2612 "item.setTest3(\"seven\"); }")
2613 << 4 << 5 << 0 << true << true << false << false << false
2614 << QString("modelData")
2615 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2617 QTest::newRow("StringList.items create prepended, edit model.modelData")
2618 << stringListSource[i]
2620 "var item = items.create(0, {\"modelData\": \"eight\"}); "
2621 "item.setTest4(\"seven\"); }")
2622 << 4 << 5 << 0 << true << true << false << false << false
2623 << QString("modelData")
2624 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2627 QTest::newRow("ObjectList.items prepend")
2628 << objectListSource[i]
2629 << QString("items.insert(0, {\"name\": \"Item 8\"})")
2630 << 4 << 4 << 4 << false << false << false << false << false
2632 << (QStringList() << "Item 1" << "Item 2" << "Item 3" << "Item 4");
2634 QTest::newRow("ObjectList.items append")
2635 << objectListSource[i]
2636 << QString("items.insert({\"name\": \"Item 8\"})")
2637 << 4 << 4 << 4 << false << false << false << false << false
2639 << (QStringList() << "Item 1" << "Item 2" << "Item 3" << "Item 4");
2641 QTest::newRow("ObjectList.items insert at 2")
2642 << objectListSource[i]
2643 << QString("items.insert(2, {\"name\": \"Item 8\"})")
2644 << 4 << 4 << 4 << false << false << false << false << false
2646 << (QStringList() << "Item 1" << "Item 2" << "Item 3" << "Item 4");
2650 void tst_qquickvisualdatamodel::insert()
2652 QFETCH(QUrl, source);
2653 QFETCH(QString, expression);
2654 QFETCH(int, modelCount);
2655 QFETCH(int, visualCount);
2657 QFETCH(bool, inItems);
2658 QFETCH(bool, persisted);
2659 QFETCH(bool, visible);
2660 QFETCH(bool, selected);
2661 QFETCH(bool, modelData);
2662 QFETCH(QString, property);
2663 QFETCH(QStringList, propertyData);
2665 QQuickCanvas canvas;
2667 QQmlComponent component(&engine);
2668 component.loadUrl(source);
2669 QScopedPointer<QObject> object(component.create());
2670 QQuickListView *listView = qobject_cast<QQuickListView *>(object.data());
2672 listView->setParentItem(canvas.rootItem());
2674 QQuickItem *contentItem = listView->contentItem();
2675 QVERIFY(contentItem);
2677 QObject *visualModel = listView->findChild<QObject *>("visualModel");
2678 QVERIFY(visualModel);
2680 evaluate<void>(visualModel, expression);
2682 QCOMPARE(evaluate<int>(listView, "count"), inItems ? visualCount : modelCount);
2683 QCOMPARE(evaluate<int>(visualModel, "count"), inItems ? visualCount : modelCount);
2684 QCOMPARE(evaluate<int>(visualModel, "items.count"), inItems ? visualCount : modelCount);
2685 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), persisted ? 1 : 0);
2686 QCOMPARE(evaluate<int>(visualModel, "visibleItems.count"), visible ? visualCount : modelCount);
2687 QCOMPARE(evaluate<int>(visualModel, "selectedItems.count"), selected ? 1 : 0);
2689 QCOMPARE(propertyData.count(), visualCount);
2690 for (int i = 0; i < visualCount; ++i) {
2692 if (modelIndex > index)
2694 else if (modelIndex == index)
2697 const int itemsIndex = inItems || i <= index ? i : i - 1;
2701 get = QString("items.get(%1)").arg(itemsIndex);
2703 QQuickItem *item = findItem<QQuickItem>(contentItem, "delegate", modelIndex);
2706 QCOMPARE(evaluate<int>(item, "test1"), modelIndex);
2707 QCOMPARE(evaluate<int>(item, "test2"), modelIndex);
2708 QCOMPARE(evaluate<QString>(item, "test3"), propertyData.at(i));
2709 QCOMPARE(evaluate<QString>(item, "test4"), propertyData.at(i));
2712 QCOMPARE(evaluate<QString>(item, "test5"), propertyData.at(i));
2713 QCOMPARE(evaluate<QString>(item, "test6"), propertyData.at(i));
2716 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inItems"), true);
2717 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inPersistedItems"), false);
2718 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inVisible"), true);
2719 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inSelected"), false);
2720 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.isUnresolved"), false);
2722 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.itemsIndex"), itemsIndex);
2723 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.persistedItemsIndex"), persisted && i > index ? 1 : 0);
2724 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.visibleIndex"), visible || i <= index ? i : i - 1);
2725 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.selectedIndex"), selected && i > index ? 1 : 0);
2726 } else if (inItems) {
2727 get = QString("items.get(%1)").arg(index);
2728 } else if (persisted) {
2729 get = "persistedItems.get(0)";
2730 } else if (visible) {
2731 get = QString("visibleItems.get(%1)").arg(index);
2732 } else if (selected) {
2733 get = "selectedItems.get(0)";
2738 QCOMPARE(evaluate<int>(visualModel, get + ".model.index"), modelIndex);
2740 QCOMPARE(evaluate<QString>(visualModel, get + ".model." + property), propertyData.at(i));
2742 QCOMPARE(evaluate<bool>(visualModel, get + ".inItems"), inItems || i != index);
2743 QCOMPARE(evaluate<bool>(visualModel, get + ".inPersistedItems"), persisted && i == index);
2744 QCOMPARE(evaluate<bool>(visualModel, get + ".inVisible"), visible || i != index);
2745 QCOMPARE(evaluate<bool>(visualModel, get + ".inSelected"), selected && i == index);
2746 QCOMPARE(evaluate<bool>(visualModel, get + ".isUnresolved"), i == index);
2748 QCOMPARE(evaluate<int>(visualModel, get + ".itemsIndex"), inItems || i <= index ? i : i - 1);
2749 QCOMPARE(evaluate<int>(visualModel, get + ".persistedItemsIndex"), persisted && i > index ? 1 : 0);
2750 QCOMPARE(evaluate<int>(visualModel, get + ".visibleIndex"), visible || i <= index ? i : i - 1);
2751 QCOMPARE(evaluate<int>(visualModel, get + ".selectedIndex"), selected && i > index ? 1 : 0);
2757 item = evaluate<QObject *>(visualModel, QString("items.create(%1)").arg(index));
2759 item = evaluate<QObject *>(visualModel, QString("persistedItems.create(%1)").arg(0));
2761 item = evaluate<QObject *>(visualModel, QString("visibleItems.create(%1)").arg(index));
2763 item = evaluate<QObject *>(visualModel, QString("selectedItems.create(%1)").arg(0));
2769 QCOMPARE(evaluate<int>(item, "test1"), -1);
2770 QCOMPARE(evaluate<int>(item, "test2"), -1);
2771 QCOMPARE(evaluate<QString>(item, "test3"), propertyData.at(index));
2772 QCOMPARE(evaluate<QString>(item, "test4"), propertyData.at(index));
2775 QCOMPARE(evaluate<QString>(item, "test5"), propertyData.at(index));
2776 QCOMPARE(evaluate<QString>(item, "test6"), propertyData.at(index));
2779 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inItems"), inItems);
2780 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inPersistedItems"), true);
2781 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inVisible"), visible);
2782 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inSelected"), selected);
2783 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.isUnresolved"), true);
2785 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.itemsIndex"), index);
2786 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.persistedItemsIndex"), 0);
2787 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.visibleIndex"), index);
2788 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.selectedIndex"), 0);
2791 void tst_qquickvisualdatamodel::resolve_data()
2793 QTest::addColumn<QUrl>("source");
2794 QTest::addColumn<QString>("setupExpression");
2795 QTest::addColumn<QString>("resolveExpression");
2796 QTest::addColumn<int>("unresolvedCount");
2797 QTest::addColumn<int>("modelCount");
2798 QTest::addColumn<int>("visualCount");
2799 QTest::addColumn<int>("index");
2800 QTest::addColumn<bool>("inItems");
2801 QTest::addColumn<bool>("persisted");
2802 QTest::addColumn<bool>("visible");
2803 QTest::addColumn<bool>("selected");
2804 QTest::addColumn<bool>("modelData");
2805 QTest::addColumn<QString>("property");
2806 QTest::addColumn<QStringList>("propertyData");
2808 const QUrl listModelSource[] = {
2809 testFileUrl("listmodelproperties.qml"),
2810 testFileUrl("listmodelproperties-package.qml") };
2811 const QUrl singleRoleSource[] = {
2812 testFileUrl("singleroleproperties.qml"),
2813 testFileUrl("singleroleproperties-package.qml") };
2814 const QUrl multipleRoleSource[] = {
2815 testFileUrl("multipleroleproperties.qml"),
2816 testFileUrl("multipleroleproperties-package.qml") };
2817 const QUrl stringListSource[] = {
2818 testFileUrl("stringlistproperties.qml"),
2819 testFileUrl("stringlistproperties-package.qml") };
2821 for (int i = 0; i < 2; ++i) {
2823 QTest::newRow("ListModel.items prepend, resolve prepended")
2824 << listModelSource[i]
2825 << QString("items.insert(0, {\"number\": \"eight\"})")
2826 << QString("{ listModel.insert(0, {\"number\": \"seven\"}); items.resolve(0, 1) }")
2827 << 5 << 5 << 5 << 0 << true << false << true << false << true
2828 << QString("number")
2829 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2831 QTest::newRow("ListModel.items prepend, resolve appended")
2832 << listModelSource[i]
2833 << QString("items.insert(0, {\"number\": \"eight\"})")
2834 << QString("{ listModel.append({\"number\": \"seven\"}); items.resolve(0, 5) }")
2835 << 5 << 5 << 5 << 4 << true << false << true << false << true
2836 << QString("number")
2837 << (QStringList() << "one" << "two" << "three" << "four" << "seven");
2839 QTest::newRow("ListModel.items prepend, resolve inserted")
2840 << listModelSource[i]
2841 << QString("items.insert(0, {\"number\": \"eight\"})")
2842 << QString("{ listModel.insert(2, {\"number\": \"seven\"}); items.resolve(0, 3) }")
2843 << 5 << 5 << 5 << 2 << true << false << true << false << true
2844 << QString("number")
2845 << (QStringList() << "one" << "two" << "seven" << "three" << "four");
2847 QTest::newRow("ListModel.items append, resolve prepended")
2848 << listModelSource[i]
2849 << QString("items.insert({\"number\": \"eight\"})")
2850 << QString("{ listModel.insert(0, {\"number\": \"seven\"}); items.resolve(5, 0) }")
2851 << 5 << 5 << 5 << 0 << true << false << true << false << true
2852 << QString("number")
2853 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2855 QTest::newRow("ListModel.items append, resolve appended")
2856 << listModelSource[i]
2857 << QString("items.insert({\"number\": \"eight\"})")
2858 << QString("{ listModel.append({\"number\": \"seven\"}); items.resolve(5, 4) }")
2859 << 5 << 5 << 5 << 4 << true << false << true << false << true
2860 << QString("number")
2861 << (QStringList() << "one" << "two" << "three" << "four" << "seven");
2863 QTest::newRow("ListModel.items append, resolve inserted")
2864 << listModelSource[i]
2865 << QString("items.insert({\"number\": \"eight\"})")
2866 << QString("{ listModel.insert(2, {\"number\": \"seven\"}); items.resolve(5, 2) }")
2867 << 5 << 5 << 5 << 2 << true << false << true << false << true
2868 << QString("number")
2869 << (QStringList() << "one" << "two" << "seven" << "three" << "four");
2871 QTest::newRow("ListModel.items insert, resolve prepended")
2872 << listModelSource[i]
2873 << QString("items.insert(2, {\"number\": \"eight\"})")
2874 << QString("{ listModel.insert(0, {\"number\": \"seven\"}); items.resolve(3, 0) }")
2875 << 5 << 5 << 5 << 0 << true << false << true << false << true
2876 << QString("number")
2877 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2879 QTest::newRow("ListModel.items insert, resolve appended")
2880 << listModelSource[i]
2881 << QString("items.insert(2, {\"number\": \"eight\"})")
2882 << QString("{ listModel.append({\"number\": \"seven\"}); items.resolve(2, 5) }")
2883 << 5 << 5 << 5 << 4 << true << false << true << false << true
2884 << QString("number")
2885 << (QStringList() << "one" << "two" << "three" << "four" << "seven");
2887 QTest::newRow("ListModel.items insert, resolve inserted")
2888 << listModelSource[i]
2889 << QString("items.insert(2, {\"number\": \"eight\"})")
2890 << QString("{ listModel.insert(2, {\"number\": \"seven\"}); items.resolve(2, 3) }")
2891 << 5 << 5 << 5 << 2 << true << false << true << false << true
2892 << QString("number")
2893 << (QStringList() << "one" << "two" << "seven" << "three" << "four");
2895 QTest::newRow("ListModel.items prepend, move resolved")
2896 << listModelSource[i]
2897 << QString("items.insert(0, {\"number\": \"eight\"})")
2898 << QString("{ listModel.insert(0, {\"number\": \"seven\"}); "
2899 "items.resolve(0, 1); "
2900 "listModel.move(0, 2, 1) }")
2901 << 5 << 5 << 5 << 2 << true << false << true << false << true
2902 << QString("number")
2903 << (QStringList() << "one" << "two" << "seven" << "three" << "four");
2905 QTest::newRow("ListModel.items append, move resolved")
2906 << listModelSource[i]
2907 << QString("items.insert({\"number\": \"eight\"})")
2908 << QString("{ listModel.append({\"number\": \"seven\"}); "
2909 "items.resolve(5, 4); "
2910 "listModel.move(4, 2, 1) }")
2911 << 5 << 5 << 5 << 2 << true << false << true << false << true
2912 << QString("number")
2913 << (QStringList() << "one" << "two" << "seven" << "three" << "four");
2915 QTest::newRow("ListModel.items insert, move resolved")
2916 << listModelSource[i]
2917 << QString("items.insert(2, {\"number\": \"eight\"})")
2918 << QString("{ listModel.insert(2, {\"number\": \"seven\"}); "
2919 "items.resolve(2, 3);"
2920 "listModel.move(2, 0, 1) }")
2921 << 5 << 5 << 5 << 0 << true << false << true << false << true
2922 << QString("number")
2923 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2925 QTest::newRow("ListModel.items prepend, remove resolved")
2926 << listModelSource[i]
2927 << QString("items.insert(0, {\"number\": \"eight\"})")
2928 << QString("{ listModel.insert(0, {\"number\": \"seven\"}); "
2929 "items.resolve(0, 1); "
2930 "listModel.remove(0, 1) }")
2931 << 5 << 4 << 4 << 4 << false << false << false << false << true
2932 << QString("number")
2933 << (QStringList() << "one" << "two" << "three" << "four");
2935 QTest::newRow("ListModel.items append, remove resolved")
2936 << listModelSource[i]
2937 << QString("items.insert({\"number\": \"eight\"})")
2938 << QString("{ listModel.append({\"number\": \"seven\"}); "
2939 "items.resolve(5, 4); "
2940 "listModel.remove(4, 1) }")
2941 << 5 << 4 << 4 << 4 << false << false << false << false << true
2942 << QString("number")
2943 << (QStringList() << "one" << "two" << "three" << "four");
2945 QTest::newRow("ListModel.items insert, remove resolved")
2946 << listModelSource[i]
2947 << QString("items.insert(2, {\"number\": \"eight\"})")
2948 << QString("{ listModel.insert(2, {\"number\": \"seven\"}); "
2949 "items.resolve(2, 3);"
2950 "listModel.remove(2, 1) }")
2951 << 5 << 4 << 4 << 4 << false << false << false << false << true
2952 << QString("number")
2953 << (QStringList() << "one" << "two" << "three" << "four");
2955 QTest::newRow("ListModel.selectedItems prepend, resolve prepended")
2956 << listModelSource[i]
2957 << QString("selectedItems.insert(0, {\"number\": \"eight\"})")
2958 << QString("{ listModel.insert(0, {\"number\": \"seven\"}); "
2959 "selectedItems.resolve(selectedItems.get(0), items.get(0)) }")
2960 << 4 << 5 << 5 << 0 << true << false << true << true << true
2961 << QString("number")
2962 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2964 QTest::newRow("ListModel.selectedItems prepend, resolve appended")
2965 << listModelSource[i]
2966 << QString("selectedItems.insert(0, {\"number\": \"eight\"})")
2967 << QString("{ listModel.append({\"number\": \"seven\"}); "
2968 "selectedItems.resolve(selectedItems.get(0), items.get(4)) }")
2969 << 4 << 5 << 5 << 4 << true << false << true << true << true
2970 << QString("number")
2971 << (QStringList() << "one" << "two" << "three" << "four" << "seven");
2973 QTest::newRow("ListModel.selectedItems prepend, resolve inserted")
2974 << listModelSource[i]
2975 << QString("selectedItems.insert(0, {\"number\": \"eight\"})")
2976 << QString("{ listModel.insert(2, {\"number\": \"seven\"}); "
2977 "selectedItems.resolve(selectedItems.get(0), items.get(2)) }")
2978 << 4 << 5 << 5 << 2 << true << false << true << true << true
2979 << QString("number")
2980 << (QStringList() << "one" << "two" << "seven" << "three" << "four");
2982 QTest::newRow("ListModel.selectedItems append, resolve prepended")
2983 << listModelSource[i]
2984 << QString("selectedItems.insert({\"number\": \"eight\"})")
2985 << QString("{ listModel.insert(0, {\"number\": \"seven\"}); "
2986 "selectedItems.resolve(selectedItems.get(0), items.get(0)) }")
2987 << 4 << 5 << 5 << 0 << true << false << true << true << true
2988 << QString("number")
2989 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2991 QTest::newRow("ListModel.selectedItems append, resolve appended")
2992 << listModelSource[i]
2993 << QString("selectedItems.insert({\"number\": \"eight\"})")
2994 << QString("{ listModel.append({\"number\": \"seven\"}); "
2995 "selectedItems.resolve(selectedItems.get(0), items.get(4)) }")
2996 << 4 << 5 << 5 << 4 << true << false << true << true << true
2997 << QString("number")
2998 << (QStringList() << "one" << "two" << "three" << "four" << "seven");
3000 QTest::newRow("ListModel.selectedItems append, resolve inserted")
3001 << listModelSource[i]
3002 << QString("selectedItems.insert({\"number\": \"eight\"})")
3003 << QString("{ listModel.insert(2, {\"number\": \"seven\"}); "
3004 "selectedItems.resolve(selectedItems.get(0), items.get(2)) }")
3005 << 4 << 5 << 5 << 2 << true << false << true << true << true
3006 << QString("number")
3007 << (QStringList() << "one" << "two" << "seven" << "three" << "four");
3009 // AbstractItemModel (Single Role)
3010 QTest::newRow("ListModel.items prepend, resolve prepended")
3011 << singleRoleSource[i]
3012 << QString("items.insert(0, {\"name\": \"eight\"})")
3013 << QString("{ items.resolve(0, 1) }")
3014 << 5 << 4 << 4 << 0 << true << false << true << false << true
3016 << (QStringList() << "one" << "two" << "three" << "four");
3019 QTest::newRow("ListModel.items append, resolve appended")
3020 << singleRoleSource[i]
3021 << QString("items.insert({\"name\": \"eight\"})")
3022 << QString("{ items.resolve(4, 3) }")
3023 << 5 << 4 << 4 << 3 << true << false << true << false << true
3025 << (QStringList() << "one" << "two" << "three" << "four");
3027 QTest::newRow("ListModel.items insert, resolve inserted")
3028 << singleRoleSource[i]
3029 << QString("items.insert(2, {\"name\": \"eight\"})")
3030 << QString("{ items.resolve(2, 3) }")
3031 << 5 << 4 << 4 << 2 << true << false << true << false << true
3033 << (QStringList() << "one" << "two" << "three" << "four");
3035 // AbstractItemModel (Single Role)
3036 QTest::newRow("AbstractItemModel.items prepend, resolve prepended")
3037 << singleRoleSource[i]
3038 << QString("items.insert(0, {\"name\": \"eight\"})")
3039 << QString("{ items.resolve(0, 1) }")
3040 << 5 << 4 << 4 << 0 << true << false << true << false << true
3042 << (QStringList() << "one" << "two" << "three" << "four");
3044 QTest::newRow("AbstractItemModel.items append, resolve appended")
3045 << singleRoleSource[i]
3046 << QString("items.insert({\"name\": \"eight\"})")
3047 << QString("{ items.resolve(4, 3) }")
3048 << 5 << 4 << 4 << 3 << true << false << true << false << true
3050 << (QStringList() << "one" << "two" << "three" << "four");
3052 QTest::newRow("AbstractItemModel.items insert, resolve inserted")
3053 << singleRoleSource[i]
3054 << QString("items.insert(2, {\"name\": \"eight\"})")
3055 << QString("{ items.resolve(2, 3) }")
3056 << 5 << 4 << 4 << 2 << true << false << true << false << true
3058 << (QStringList() << "one" << "two" << "three" << "four");
3060 #ifndef QT_NO_WIDGETS
3061 // AbstractItemModel (Multiple Roles)
3062 QTest::newRow("StandardItemModel.items prepend, resolve prepended")
3063 << multipleRoleSource[i]
3064 << QString("items.insert(0, {\"display\": \"Row 8 Item\"})")
3065 << QString("{ items.resolve(0, 1) }")
3066 << 5 << 4 << 4 << 0 << true << false << true << false << false
3067 << QString("display")
3068 << (QStringList() << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
3070 QTest::newRow("StandardItemModel.items append, resolve appended")
3071 << multipleRoleSource[i]
3072 << QString("items.insert({\"display\": \"Row 8 Item\"})")
3073 << QString("{ items.resolve(4, 3) }")
3074 << 5 << 4 << 4 << 3 << true << false << true << false << false
3075 << QString("display")
3076 << (QStringList() << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
3078 QTest::newRow("StandardItemModel.items insert, resolve inserted")
3079 << multipleRoleSource[i]
3080 << QString("items.insert(2, {\"display\": \"Row 8 Item\"})")
3081 << QString("{ items.resolve(2, 3) }")
3082 << 5 << 4 << 4 << 2 << true << false << true << false << false
3083 << QString("display")
3084 << (QStringList() << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
3087 QTest::newRow("StringList.items prepend, resolve prepended")
3088 << stringListSource[i]
3089 << QString("items.insert(0, {\"modelData\": \"eight\"})")
3090 << QString("{ items.resolve(0, 1) }")
3091 << 5 << 4 << 4 << 0 << true << false << true << false << false
3092 << QString("modelData")
3093 << (QStringList() << "one" << "two" << "three" << "four");
3095 QTest::newRow("StringList.items append, resolve appended")
3096 << stringListSource[i]
3097 << QString("items.insert({\"modelData\": \"eight\"})")
3098 << QString("{ items.resolve(4, 3) }")
3099 << 5 << 4 << 4 << 3 << true << false << true << false << false
3100 << QString("modelData")
3101 << (QStringList() << "one" << "two" << "three" << "four");
3103 QTest::newRow("StringList.items insert, resolve inserted")
3104 << stringListSource[i]
3105 << QString("items.insert(2, {\"modelData\": \"eight\"})")
3106 << QString("{ items.resolve(2, 3) }")
3107 << 5 << 4 << 4 << 2 << true << false << true << false << false
3108 << QString("modelData")
3109 << (QStringList() << "one" << "two" << "three" << "four");
3113 void tst_qquickvisualdatamodel::resolve()
3115 QFETCH(QUrl, source);
3116 QFETCH(QString, setupExpression);
3117 QFETCH(QString, resolveExpression);
3118 QFETCH(int, unresolvedCount);
3119 QFETCH(int, modelCount);
3120 QFETCH(int, visualCount);
3122 QFETCH(bool, inItems);
3123 QFETCH(bool, persisted);
3124 QFETCH(bool, visible);
3125 QFETCH(bool, selected);
3126 QFETCH(bool, modelData);
3127 QFETCH(QString, property);
3128 QFETCH(QStringList, propertyData);
3130 QQuickCanvas canvas;
3132 QQmlComponent component(&engine);
3133 component.loadUrl(source);
3134 QScopedPointer<QObject> object(component.create());
3135 QQuickListView *listView = qobject_cast<QQuickListView *>(object.data());
3137 listView->setParentItem(canvas.rootItem());
3139 QQuickItem *contentItem = listView->contentItem();
3140 QVERIFY(contentItem);
3142 QObject *visualModel = listView->findChild<QObject *>("visualModel");
3143 QVERIFY(visualModel);
3145 evaluate<void>(visualModel, setupExpression);
3146 QCOMPARE(evaluate<int>(listView, "count"), unresolvedCount);
3148 evaluate<void>(visualModel, resolveExpression);
3150 QCOMPARE(evaluate<int>(listView, "count"), inItems ? visualCount : modelCount);
3151 QCOMPARE(evaluate<int>(visualModel, "count"), inItems ? visualCount : modelCount);
3152 QCOMPARE(evaluate<int>(visualModel, "items.count"), inItems ? visualCount : modelCount);
3153 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), persisted ? 1 : 0);
3154 QCOMPARE(evaluate<int>(visualModel, "visibleItems.count"), visible ? visualCount : modelCount);
3155 QCOMPARE(evaluate<int>(visualModel, "selectedItems.count"), selected ? 1 : 0);
3157 QCOMPARE(propertyData.count(), visualCount);
3158 for (int i = 0; i < visualCount; ++i) {
3161 const int itemsIndex = inItems || i <= index ? i : i - 1;
3165 get = QString("items.get(%1)").arg(itemsIndex);
3167 QQuickItem *item = findItem<QQuickItem>(contentItem, "delegate", modelIndex);
3170 QCOMPARE(evaluate<int>(item, "test1"), modelIndex);
3171 QCOMPARE(evaluate<int>(item, "test2"), modelIndex);
3172 QCOMPARE(evaluate<QString>(item, "test3"), propertyData.at(i));
3173 QCOMPARE(evaluate<QString>(item, "test4"), propertyData.at(i));
3176 QCOMPARE(evaluate<QString>(item, "test5"), propertyData.at(i));
3177 QCOMPARE(evaluate<QString>(item, "test6"), propertyData.at(i));
3180 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inItems"), true);
3181 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inPersistedItems"), false);
3182 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inVisible"), true);
3183 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inSelected"), false);
3184 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.isUnresolved"), false);
3186 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.itemsIndex"), itemsIndex);
3187 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.persistedItemsIndex"), persisted && i > index ? 1 : 0);
3188 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.visibleIndex"), visible || i <= index ? i : i - 1);
3189 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.selectedIndex"), selected && i > index ? 1 : 0);
3190 } else if (inItems) {
3191 get = QString("items.get(%1)").arg(index);
3192 } else if (persisted) {
3193 get = "persistedItems.get(0)";
3194 } else if (visible) {
3195 get = QString("visibleItems.get(%1)").arg(index);
3196 } else if (selected) {
3197 get = "selectedItems.get(0)";
3202 QCOMPARE(evaluate<int>(visualModel, get + ".model.index"), modelIndex);
3204 QCOMPARE(evaluate<QString>(visualModel, get + ".model." + property), propertyData.at(i));
3206 QCOMPARE(evaluate<bool>(visualModel, get + ".inItems"), inItems || i != index);
3207 QCOMPARE(evaluate<bool>(visualModel, get + ".inPersistedItems"), persisted && i == index);
3208 QCOMPARE(evaluate<bool>(visualModel, get + ".inVisible"), visible || i != index);
3209 QCOMPARE(evaluate<bool>(visualModel, get + ".inSelected"), selected && i == index);
3210 QCOMPARE(evaluate<bool>(visualModel, get + ".isUnresolved"), false);
3212 QCOMPARE(evaluate<int>(visualModel, get + ".itemsIndex"), inItems || i <= index ? i : i - 1);
3213 QCOMPARE(evaluate<int>(visualModel, get + ".persistedItemsIndex"), persisted && i > index ? 1 : 0);
3214 QCOMPARE(evaluate<int>(visualModel, get + ".visibleIndex"), visible || i <= index ? i : i - 1);
3215 QCOMPARE(evaluate<int>(visualModel, get + ".selectedIndex"), selected && i > index ? 1 : 0);
3221 item = evaluate<QObject *>(visualModel, QString("items.create(%1)").arg(index));
3223 item = evaluate<QObject *>(visualModel, QString("persistedItems.create(%1)").arg(0));
3225 item = evaluate<QObject *>(visualModel, QString("visibleItems.create(%1)").arg(index));
3227 item = evaluate<QObject *>(visualModel, QString("selectedItems.create(%1)").arg(0));
3233 QCOMPARE(evaluate<int>(item, "test1"), index);
3234 QCOMPARE(evaluate<int>(item, "test2"), index);
3235 QCOMPARE(evaluate<QString>(item, "test3"), propertyData.at(index));
3236 QCOMPARE(evaluate<QString>(item, "test4"), propertyData.at(index));
3239 QCOMPARE(evaluate<QString>(item, "test5"), propertyData.at(index));
3240 QCOMPARE(evaluate<QString>(item, "test6"), propertyData.at(index));
3243 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inItems"), inItems);
3244 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inPersistedItems"), true);
3245 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inVisible"), visible);
3246 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inSelected"), selected);
3247 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.isUnresolved"), false);
3249 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.itemsIndex"), index);
3250 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.persistedItemsIndex"), 0);
3251 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.visibleIndex"), index);
3252 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.selectedIndex"), 0);
3255 void tst_qquickvisualdatamodel::warnings_data()
3257 QTest::addColumn<QUrl>("source");
3258 QTest::addColumn<QString>("expression");
3259 QTest::addColumn<QString>("warning");
3260 QTest::addColumn<int>("count");
3262 QTest::newRow("insert < 0")
3263 << testFileUrl("listmodelproperties.qml")
3264 << QString("items.insert(-2, {\"number\": \"eight\"})")
3265 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("insert: index out of range"))
3268 QTest::newRow("insert > length")
3269 << testFileUrl("listmodelproperties.qml")
3270 << QString("items.insert(8, {\"number\": \"eight\"})")
3271 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("insert: index out of range"))
3274 QTest::newRow("create < 0")
3275 << testFileUrl("listmodelproperties.qml")
3276 << QString("items.create(-2, {\"number\": \"eight\"})")
3277 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("create: index out of range"))
3280 QTest::newRow("create > length")
3281 << testFileUrl("listmodelproperties.qml")
3282 << QString("items.create(8, {\"number\": \"eight\"})")
3283 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("create: index out of range"))
3286 QTest::newRow("resolve from < 0")
3287 << testFileUrl("listmodelproperties.qml")
3288 << QString("items.resolve(-2, 3)")
3289 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: from index out of range"))
3292 QTest::newRow("resolve from > length")
3293 << testFileUrl("listmodelproperties.qml")
3294 << QString("items.resolve(8, 3)")
3295 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: from index out of range"))
3298 QTest::newRow("resolve to < 0")
3299 << testFileUrl("listmodelproperties.qml")
3300 << QString("items.resolve(3, -2)")
3301 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: to index out of range"))
3304 QTest::newRow("resolve to > length")
3305 << testFileUrl("listmodelproperties.qml")
3306 << QString("items.resolve(3, 8)")
3307 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: to index out of range"))
3310 QTest::newRow("resolve from invalid index")
3311 << testFileUrl("listmodelproperties.qml")
3312 << QString("items.resolve(\"two\", 3)")
3313 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: from index invalid"))
3316 QTest::newRow("resolve to invalid index")
3317 << testFileUrl("listmodelproperties.qml")
3318 << QString("items.resolve(3, \"two\")")
3319 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: to index invalid"))
3322 QTest::newRow("resolve already resolved item")
3323 << testFileUrl("listmodelproperties.qml")
3324 << QString("items.resolve(3, 2)")
3325 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: from is not an unresolved item"))
3328 QTest::newRow("resolve already resolved item")
3329 << testFileUrl("listmodelproperties.qml")
3330 << QString("{ items.insert(0, {\"number\": \"eight\"});"
3331 "items.insert(1, {\"number\": \"seven\"});"
3332 "items.resolve(0, 1)}")
3333 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: to is not a model item"))
3336 QTest::newRow("remove index < 0")
3337 << testFileUrl("listmodelproperties.qml")
3338 << QString("items.remove(-2, 1)")
3339 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("remove: index out of range"))
3342 QTest::newRow("remove index == length")
3343 << testFileUrl("listmodelproperties.qml")
3344 << QString("items.remove(4, 1)")
3345 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("remove: index out of range"))
3348 QTest::newRow("remove index > length")
3349 << testFileUrl("listmodelproperties.qml")
3350 << QString("items.remove(9, 1)")
3351 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("remove: index out of range"))
3354 QTest::newRow("remove invalid index")
3355 << testFileUrl("listmodelproperties.qml")
3356 << QString("items.remove(\"nine\", 1)")
3357 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("remove: invalid index"))
3360 QTest::newRow("remove count < 0")
3361 << testFileUrl("listmodelproperties.qml")
3362 << QString("items.remove(1, -2)")
3363 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("remove: invalid count"))
3366 QTest::newRow("remove index + count > length")
3367 << testFileUrl("listmodelproperties.qml")
3368 << QString("items.remove(2, 4, \"selected\")")
3369 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("remove: invalid count"))
3372 QTest::newRow("addGroups index < 0")
3373 << testFileUrl("listmodelproperties.qml")
3374 << QString("items.addGroups(-2, 1, \"selected\")")
3375 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("addGroups: index out of range"))
3378 QTest::newRow("addGroups index == length")
3379 << testFileUrl("listmodelproperties.qml")
3380 << QString("items.addGroups(4, 1, \"selected\")")
3381 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("addGroups: index out of range"))
3384 QTest::newRow("addGroups index > length")
3385 << testFileUrl("listmodelproperties.qml")
3386 << QString("items.addGroups(9, 1, \"selected\")")
3387 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("addGroups: index out of range"))
3390 QTest::newRow("addGroups count < 0")
3391 << testFileUrl("listmodelproperties.qml")
3392 << QString("items.addGroups(1, -2, \"selected\")")
3393 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("addGroups: invalid count"))
3396 QTest::newRow("addGroups index + count > length")
3397 << testFileUrl("listmodelproperties.qml")
3398 << QString("items.addGroups(2, 4, \"selected\")")
3399 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("addGroups: invalid count"))
3402 QTest::newRow("removeGroups index < 0")
3403 << testFileUrl("listmodelproperties.qml")
3404 << QString("items.removeGroups(-2, 1, \"selected\")")
3405 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("removeGroups: index out of range"))
3408 QTest::newRow("removeGroups index == length")
3409 << testFileUrl("listmodelproperties.qml")
3410 << QString("items.removeGroups(4, 1, \"selected\")")
3411 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("removeGroups: index out of range"))
3414 QTest::newRow("removeGroups index > length")
3415 << testFileUrl("listmodelproperties.qml")
3416 << QString("items.removeGroups(9, 1, \"selected\")")
3417 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("removeGroups: index out of range"))
3420 QTest::newRow("removeGroups count < 0")
3421 << testFileUrl("listmodelproperties.qml")
3422 << QString("items.removeGroups(1, -2, \"selected\")")
3423 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("removeGroups: invalid count"))
3426 QTest::newRow("removeGroups index + count > length")
3427 << testFileUrl("listmodelproperties.qml")
3428 << QString("items.removeGroups(2, 4, \"selected\")")
3429 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("removeGroups: invalid count"))
3432 QTest::newRow("setGroups index < 0")
3433 << testFileUrl("listmodelproperties.qml")
3434 << QString("items.setGroups(-2, 1, \"selected\")")
3435 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("setGroups: index out of range"))
3438 QTest::newRow("setGroups index == length")
3439 << testFileUrl("listmodelproperties.qml")
3440 << QString("items.setGroups(4, 1, \"selected\")")
3441 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("setGroups: index out of range"))
3444 QTest::newRow("setGroups index > length")
3445 << testFileUrl("listmodelproperties.qml")
3446 << QString("items.setGroups(9, 1, \"selected\")")
3447 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("setGroups: index out of range"))
3450 QTest::newRow("setGroups count < 0")
3451 << testFileUrl("listmodelproperties.qml")
3452 << QString("items.setGroups(1, -2, \"selected\")")
3453 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("setGroups: invalid count"))
3456 QTest::newRow("setGroups index + count > length")
3457 << testFileUrl("listmodelproperties.qml")
3458 << QString("items.setGroups(2, 4, \"selected\")")
3459 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("setGroups: invalid count"))
3462 QTest::newRow("move from < 0")
3463 << testFileUrl("listmodelproperties.qml")
3464 << QString("items.move(-2, 1, 1)")
3465 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: from index out of range"))
3468 QTest::newRow("move from == length")
3469 << testFileUrl("listmodelproperties.qml")
3470 << QString("items.move(4, 1, 1)")
3471 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: from index out of range"))
3474 QTest::newRow("move from > length")
3475 << testFileUrl("listmodelproperties.qml")
3476 << QString("items.move(9, 1, 1)")
3477 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: from index out of range"))
3480 QTest::newRow("move invalid from")
3481 << testFileUrl("listmodelproperties.qml")
3482 << QString("items.move(\"nine\", 1, 1)")
3483 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: invalid from index"))
3486 QTest::newRow("move to < 0")
3487 << testFileUrl("listmodelproperties.qml")
3488 << QString("items.move(1, -2, 1)")
3489 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: to index out of range"))
3492 QTest::newRow("move to == length")
3493 << testFileUrl("listmodelproperties.qml")
3494 << QString("items.move(1, 4, 1)")
3495 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: to index out of range"))
3498 QTest::newRow("move to > length")
3499 << testFileUrl("listmodelproperties.qml")
3500 << QString("items.move(1, 9, 1)")
3501 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: to index out of range"))
3504 QTest::newRow("move invalid to")
3505 << testFileUrl("listmodelproperties.qml")
3506 << QString("items.move(1, \"nine\", 1)")
3507 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: invalid to index"))
3510 QTest::newRow("move count < 0")
3511 << testFileUrl("listmodelproperties.qml")
3512 << QString("items.move(1, 1, -2)")
3513 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: invalid count"))
3516 QTest::newRow("move from + count > length")
3517 << testFileUrl("listmodelproperties.qml")
3518 << QString("items.move(2, 1, 4)")
3519 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: from index out of range"))
3523 void tst_qquickvisualdatamodel::warnings()
3525 QFETCH(QUrl, source);
3526 QFETCH(QString, expression);
3527 QFETCH(QString, warning);
3530 QQuickCanvas canvas;
3532 QQmlComponent component(&engine);
3533 component.loadUrl(source);
3534 QScopedPointer<QObject> object(component.create());
3535 QQuickListView *listView = qobject_cast<QQuickListView *>(object.data());
3537 listView->setParentItem(canvas.rootItem());
3539 QQuickItem *contentItem = listView->contentItem();
3540 QVERIFY(contentItem);
3542 QObject *visualModel = evaluate<QObject *>(listView, "model");
3543 QVERIFY(visualModel);
3545 QTest::ignoreMessage(QtWarningMsg, warning.toUtf8());
3547 evaluate<void>(visualModel, expression);
3548 QCOMPARE(evaluate<int>(listView, "count"), count);
3551 void tst_qquickvisualdatamodel::invalidAttachment()
3553 QQmlComponent component(&engine);
3554 component.loadUrl(testFileUrl("invalidAttachment.qml"));
3556 QScopedPointer<QObject> object(component.create());
3558 QCOMPARE(component.errors().count(), 0);
3560 QVariant property = object->property("invalidVdm");
3561 QCOMPARE(property.userType(), qMetaTypeId<QQuickVisualDataModel *>());
3562 QVERIFY(!property.value<QQuickVisualDataModel *>());
3564 QQuickItem *item = findItem<QQuickItem>(static_cast<QQuickItem *>(object.data()), "delegate");
3567 property = item->property("validVdm");
3568 QCOMPARE(property.userType(), qMetaTypeId<QQuickVisualDataModel *>());
3569 QVERIFY(property.value<QQuickVisualDataModel *>());
3571 property = item->property("invalidVdm");
3572 QCOMPARE(property.userType(), qMetaTypeId<QQuickVisualDataModel *>());
3573 QVERIFY(!property.value<QQuickVisualDataModel *>());
3576 void tst_qquickvisualdatamodel::asynchronousInsert_data()
3578 QTest::addColumn<int>("requestIndex");
3579 QTest::addColumn<int>("insertIndex");
3580 QTest::addColumn<int>("insertCount");
3581 QTest::addColumn<int>("completeIndex");
3583 QTest::newRow("insert before") << 4 << 1 << 3 << 7;
3584 QTest::newRow("insert after") << 4 << 6 << 3 << 4;
3585 QTest::newRow("insert at") << 4 << 4 << 3 << 7;
3588 void tst_qquickvisualdatamodel::asynchronousInsert()
3590 QFETCH(int, requestIndex);
3591 QFETCH(int, insertIndex);
3592 QFETCH(int, insertCount);
3593 QFETCH(int, completeIndex);
3595 QCOMPARE(controller.incubatingObjectCount(), 0);
3597 QQmlComponent c(&engine, testFileUrl("visualdatamodel.qml"));
3600 for (int i = 0; i < 8; i++)
3601 model.addItem("Original item" + QString::number(i), "");
3603 engine.rootContext()->setContextProperty("myModel", &model);
3605 QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel*>(c.create());
3606 QVERIFY(visualModel);
3608 ItemRequester requester;
3609 connect(visualModel, SIGNAL(initItem(int,QQuickItem*)), &requester, SLOT(initItem(int,QQuickItem*)));
3610 connect(visualModel, SIGNAL(createdItem(int,QQuickItem*)), &requester, SLOT(createdItem(int,QQuickItem*)));
3611 connect(visualModel, SIGNAL(destroyingItem(QQuickItem*)), &requester, SLOT(destroyingItem(QQuickItem*)));
3613 QQuickItem *item = visualModel->item(requestIndex, true);
3616 QVERIFY(!requester.itemInitialized);
3617 QVERIFY(!requester.itemCreated);
3618 QVERIFY(!requester.itemDestroyed);
3620 QList<QPair<QString, QString> > newItems;
3621 for (int i = 0; i < insertCount; i++)
3622 newItems.append(qMakePair(QLatin1String("New item") + QString::number(i), QString(QLatin1String(""))));
3623 model.insertItems(insertIndex, newItems);
3625 item = visualModel->item(completeIndex, false);
3628 QCOMPARE(requester.itemInitialized, item);
3629 QCOMPARE(requester.indexInitialized, completeIndex);
3630 QCOMPARE(requester.itemCreated, item);
3631 QCOMPARE(requester.indexCreated, completeIndex);
3632 QVERIFY(!requester.itemDestroyed);
3634 QCOMPARE(controller.incubatingObjectCount(), 0);
3636 visualModel->release(item);
3638 QCOMPARE(requester.itemDestroyed, item);
3641 void tst_qquickvisualdatamodel::asynchronousRemove_data()
3643 QTest::addColumn<int>("requestIndex");
3644 QTest::addColumn<int>("removeIndex");
3645 QTest::addColumn<int>("removeCount");
3646 QTest::addColumn<int>("completeIndex");
3648 QTest::newRow("remove before") << 4 << 1 << 3 << 1;
3649 QTest::newRow("remove after") << 4 << 6 << 2 << 4;
3650 QTest::newRow("remove requested") << 4 << 4 << 3 << -1;
3653 void tst_qquickvisualdatamodel::asynchronousRemove()
3655 QFETCH(int, requestIndex);
3656 QFETCH(int, removeIndex);
3657 QFETCH(int, removeCount);
3658 QFETCH(int, completeIndex);
3660 QCOMPARE(controller.incubatingObjectCount(), 0);
3662 QQmlComponent c(&engine, testFileUrl("visualdatamodel.qml"));
3665 for (int i = 0; i < 8; i++)
3666 model.addItem("Original item" + QString::number(i), "");
3668 engine.rootContext()->setContextProperty("myModel", &model);
3670 QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel*>(c.create());
3671 QVERIFY(visualModel);
3673 ItemRequester requester;
3674 connect(visualModel, SIGNAL(initItem(int,QQuickItem*)), &requester, SLOT(initItem(int,QQuickItem*)));
3675 connect(visualModel, SIGNAL(createdItem(int,QQuickItem*)), &requester, SLOT(createdItem(int,QQuickItem*)));
3676 connect(visualModel, SIGNAL(destroyingItem(QQuickItem*)), &requester, SLOT(destroyingItem(QQuickItem*)));
3678 QQuickItem *item = visualModel->item(requestIndex, true);
3681 QVERIFY(!requester.itemInitialized);
3682 QVERIFY(!requester.itemCreated);
3683 QVERIFY(!requester.itemDestroyed);
3685 model.removeItems(removeIndex, removeCount);
3687 if (completeIndex == -1) {
3688 QElapsedTimer timer;
3691 controller.incubateFor(50);
3692 } while (timer.elapsed() < 1000 && controller.incubatingObjectCount() > 0);
3694 QVERIFY(requester.itemInitialized);
3695 QCOMPARE(requester.itemCreated, requester.itemInitialized);
3696 QCOMPARE(requester.itemDestroyed, requester.itemInitialized);
3698 item = visualModel->item(completeIndex, false);
3701 QCOMPARE(requester.itemInitialized, item);
3702 QCOMPARE(requester.indexInitialized, completeIndex);
3703 QCOMPARE(requester.itemCreated, item);
3704 QCOMPARE(requester.indexCreated, completeIndex);
3705 QVERIFY(!requester.itemDestroyed);
3707 QCOMPARE(controller.incubatingObjectCount(), 0);
3709 visualModel->release(item);
3711 QCOMPARE(requester.itemDestroyed, item);
3715 void tst_qquickvisualdatamodel::asynchronousMove_data()
3717 QTest::addColumn<int>("requestIndex");
3718 QTest::addColumn<int>("from");
3719 QTest::addColumn<int>("to");
3720 QTest::addColumn<int>("count");
3721 QTest::addColumn<int>("completeIndex");
3723 QTest::newRow("move before") << 4 << 1 << 0 << 3 << 4;
3724 QTest::newRow("move after") << 4 << 6 << 5 << 2 << 4;
3725 QTest::newRow("move requested") << 4 << 4 << 3 << 2 << 3;
3726 QTest::newRow("move before to after") << 4 << 1 << 4 << 3 << 1;
3727 QTest::newRow("move after to before") << 4 << 6 << 2 << 2 << 6;
3730 void tst_qquickvisualdatamodel::asynchronousMove()
3732 QFETCH(int, requestIndex);
3736 QFETCH(int, completeIndex);
3738 QCOMPARE(controller.incubatingObjectCount(), 0);
3740 QQmlComponent c(&engine, testFileUrl("visualdatamodel.qml"));
3743 for (int i = 0; i < 8; i++)
3744 model.addItem("Original item" + QString::number(i), "");
3746 engine.rootContext()->setContextProperty("myModel", &model);
3748 QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel*>(c.create());
3749 QVERIFY(visualModel);
3751 ItemRequester requester;
3752 connect(visualModel, SIGNAL(initItem(int,QQuickItem*)), &requester, SLOT(initItem(int,QQuickItem*)));
3753 connect(visualModel, SIGNAL(createdItem(int,QQuickItem*)), &requester, SLOT(createdItem(int,QQuickItem*)));
3754 connect(visualModel, SIGNAL(destroyingItem(QQuickItem*)), &requester, SLOT(destroyingItem(QQuickItem*)));
3756 QQuickItem *item = visualModel->item(requestIndex, true);
3759 QVERIFY(!requester.itemInitialized);
3760 QVERIFY(!requester.itemCreated);
3761 QVERIFY(!requester.itemDestroyed);
3763 model.moveItems(from, to, count);
3765 item = visualModel->item(completeIndex, false);
3769 QCOMPARE(requester.itemInitialized, item);
3770 QCOMPARE(requester.indexInitialized, completeIndex);
3771 QCOMPARE(requester.itemCreated, item);
3772 QCOMPARE(requester.indexCreated, completeIndex);
3773 QVERIFY(!requester.itemDestroyed);
3775 QCOMPARE(controller.incubatingObjectCount(), 0);
3777 visualModel->release(item);
3779 QCOMPARE(requester.itemDestroyed, item);
3782 void tst_qquickvisualdatamodel::asynchronousCancel()
3784 const int requestIndex = 4;
3786 QCOMPARE(controller.incubatingObjectCount(), 0);
3788 QQmlComponent c(&engine, testFileUrl("visualdatamodel.qml"));
3791 for (int i = 0; i < 8; i++)
3792 model.addItem("Original item" + QString::number(i), "");
3794 engine.rootContext()->setContextProperty("myModel", &model);
3796 QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel*>(c.create());
3797 QVERIFY(visualModel);
3799 QQuickItem *item = visualModel->item(requestIndex, true);
3801 QCOMPARE(controller.incubatingObjectCount(), 1);
3803 visualModel->cancel(requestIndex);
3804 QCOMPARE(controller.incubatingObjectCount(), 0);
3807 QTEST_MAIN(tst_qquickvisualdatamodel)
3809 #include "tst_qquickvisualdatamodel.moc"