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"
43 #include <QtTest/QSignalSpy>
44 #include <QStandardItemModel>
45 #include <QtDeclarative/qdeclarativeengine.h>
46 #include <QtDeclarative/qdeclarativecomponent.h>
47 #include <QtDeclarative/qdeclarativecontext.h>
48 #include <QtDeclarative/qdeclarativeexpression.h>
49 #include <QtQuick/qquickview.h>
50 #include <private/qquicklistview_p.h>
51 #include <QtQuick/private/qquicktext_p.h>
52 #include <QtQuick/private/qquickvisualdatamodel_p.h>
53 #include <private/qdeclarativevaluetype_p.h>
54 #include <private/qdeclarativechangeset_p.h>
55 #include <private/qdeclarativeengine_p.h>
58 template <typename T, int N> int lengthOf(const T (&)[N]) { return N; }
60 static void initStandardTreeModel(QStandardItemModel *model)
63 item = new QStandardItem(QLatin1String("Row 1 Item"));
64 model->insertRow(0, item);
66 item = new QStandardItem(QLatin1String("Row 2 Item"));
67 item->setCheckable(true);
68 model->insertRow(1, item);
70 QStandardItem *childItem = new QStandardItem(QLatin1String("Row 2 Child Item"));
71 item->setChild(0, childItem);
73 item = new QStandardItem(QLatin1String("Row 3 Item"));
74 item->setIcon(QIcon());
75 model->insertRow(2, item);
78 class SingleRoleModel : public QAbstractListModel
81 Q_PROPERTY(QStringList values WRITE setList)
83 SingleRoleModel(const QByteArray &role = "name", QObject *parent = 0)
84 : QAbstractListModel(parent)
86 QHash<int, QByteArray> roles;
87 roles.insert(Qt::DisplayRole , role);
89 list << "one" << "two" << "three" << "four";
92 void emitMove(int sourceFirst, int sourceLast, int destinationChild) {
93 emit beginMoveRows(QModelIndex(), sourceFirst, sourceLast, QModelIndex(), destinationChild);
99 void setList(const QStringList &l) { list = l; }
102 void set(int idx, QString string) {
104 emit dataChanged(index(idx,0), index(idx,0));
108 int rowCount(const QModelIndex & /* parent */ = QModelIndex()) const {
111 QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const {
112 if (role == Qt::DisplayRole)
113 return list.at(index.row());
118 class StandardItem : public QObject, public QStandardItem
121 Q_PROPERTY(QString text WRITE setText)
124 void writeText(const QString &text) { setText(text); }
127 class StandardItemModel : public QStandardItemModel
130 Q_PROPERTY(QDeclarativeListProperty<StandardItem> items READ items CONSTANT)
131 Q_CLASSINFO("DefaultProperty", "items")
133 QDeclarativeListProperty<StandardItem> items() { return QDeclarativeListProperty<StandardItem>(this, 0, append); }
135 static void append(QDeclarativeListProperty<StandardItem> *property, StandardItem *item)
137 static_cast<QStandardItemModel *>(property->object)->appendRow(item);
141 class DataObject : public QObject
145 Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
146 Q_PROPERTY(QString color READ color WRITE setColor NOTIFY colorChanged)
149 DataObject(QObject *parent=0) : QObject(parent) {}
150 DataObject(const QString &name, const QString &color, QObject *parent=0)
151 : QObject(parent), m_name(name), m_color(color) { }
154 QString name() const { return m_name; }
155 void setName(const QString &name) {
156 if (name != m_name) {
162 QString color() const { return m_color; }
163 void setColor(const QString &color) {
164 if (color != m_color) {
179 QML_DECLARE_TYPE(SingleRoleModel)
180 QML_DECLARE_TYPE(StandardItem)
181 QML_DECLARE_TYPE(StandardItemModel)
182 QML_DECLARE_TYPE(DataObject)
184 class tst_qquickvisualdatamodel : public QDeclarativeDataTest
188 tst_qquickvisualdatamodel();
192 void cleanupTestCase();
194 void updateLayout_data();
196 void childChanged_data();
198 void objectListModel();
200 void modelProperties();
201 void noDelegate_data();
203 void itemsDestroyed_data();
204 void itemsDestroyed();
205 void packagesDestroyed();
206 void qaimRowsMoved();
207 void qaimRowsMoved_data();
214 void invalidGroups();
216 void onChanged_data();
219 void incompleteModel();
224 void warnings_data();
228 template <int N> void groups_verify(
229 const SingleRoleModel &model,
230 QQuickItem *contentItem,
231 const int (&mIndex)[N],
232 const int (&iIndex)[N],
233 const int (&vIndex)[N],
234 const int (&sIndex)[N],
235 const bool (&vMember)[N],
236 const bool (&sMember)[N]);
238 template <int N> void get_verify(
239 const SingleRoleModel &model,
240 QQuickVisualDataModel *visualModel,
241 QQuickVisualDataGroup *visibleItems,
242 QQuickVisualDataGroup *selectedItems,
243 const int (&mIndex)[N],
244 const int (&iIndex)[N],
245 const int (&vIndex)[N],
246 const int (&sIndex)[N],
247 const bool (&vMember)[N],
248 const bool (&sMember)[N]);
251 QDeclarativeEngine engine;
253 T *findItem(QQuickItem *parent, const QString &objectName, int index = -1);
256 Q_DECLARE_METATYPE(QDeclarativeChangeSet)
258 template <typename T> static T evaluate(QObject *scope, const QString &expression)
260 QDeclarativeExpression expr(qmlContext(scope), scope, expression);
261 T result = expr.evaluate().value<T>();
263 qWarning() << expr.error().toString();
267 template <> void evaluate<void>(QObject *scope, const QString &expression)
269 QDeclarativeExpression expr(qmlContext(scope), scope, expression);
272 qWarning() << expr.error().toString();
275 void tst_qquickvisualdatamodel::initTestCase()
277 QDeclarativeDataTest::initTestCase();
278 qRegisterMetaType<QDeclarativeChangeSet>();
280 qmlRegisterType<SingleRoleModel>("tst_qquickvisualdatamodel", 1, 0, "SingleRoleModel");
281 qmlRegisterType<StandardItem>("tst_qquickvisualdatamodel", 1, 0, "StandardItem");
282 qmlRegisterType<StandardItemModel>("tst_qquickvisualdatamodel", 1, 0, "StandardItemModel");
283 qmlRegisterType<DataObject>("tst_qquickvisualdatamodel", 1, 0, "DataObject");
286 void tst_qquickvisualdatamodel::cleanupTestCase()
291 tst_qquickvisualdatamodel::tst_qquickvisualdatamodel()
295 void tst_qquickvisualdatamodel::rootIndex()
297 QDeclarativeEngine engine;
298 QDeclarativeComponent c(&engine, testFileUrl("visualdatamodel.qml"));
300 QStandardItemModel model;
301 initStandardTreeModel(&model);
303 engine.rootContext()->setContextProperty("myModel", &model);
305 QQuickVisualDataModel *obj = qobject_cast<QQuickVisualDataModel*>(c.create());
308 QMetaObject::invokeMethod(obj, "setRoot");
309 QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == model.index(0,0));
311 QMetaObject::invokeMethod(obj, "setRootToParent");
312 QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == QModelIndex());
314 QMetaObject::invokeMethod(obj, "setRoot");
315 QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == model.index(0,0));
316 model.clear(); // will emit modelReset()
317 QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == QModelIndex());
322 void tst_qquickvisualdatamodel::updateLayout_data()
324 QTest::addColumn<QUrl>("source");
326 QTest::newRow("item delegate") << testFileUrl("datalist.qml");
327 QTest::newRow("package delegate") << testFileUrl("datalist-package.qml");
330 void tst_qquickvisualdatamodel::updateLayout()
332 QFETCH(QUrl, source);
336 QStandardItemModel model;
337 initStandardTreeModel(&model);
339 view.rootContext()->setContextProperty("myModel", &model);
341 view.setSource(source);
343 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
344 QVERIFY(listview != 0);
346 QQuickItem *contentItem = listview->contentItem();
347 QVERIFY(contentItem != 0);
349 QQuickText *name = findItem<QQuickText>(contentItem, "display", 0);
351 QCOMPARE(name->text(), QString("Row 1 Item"));
352 name = findItem<QQuickText>(contentItem, "display", 1);
354 QCOMPARE(name->text(), QString("Row 2 Item"));
355 name = findItem<QQuickText>(contentItem, "display", 2);
357 QCOMPARE(name->text(), QString("Row 3 Item"));
359 model.invisibleRootItem()->sortChildren(0, Qt::DescendingOrder);
361 name = findItem<QQuickText>(contentItem, "display", 0);
363 QCOMPARE(name->text(), QString("Row 3 Item"));
364 name = findItem<QQuickText>(contentItem, "display", 1);
366 QCOMPARE(name->text(), QString("Row 2 Item"));
367 name = findItem<QQuickText>(contentItem, "display", 2);
369 QCOMPARE(name->text(), QString("Row 1 Item"));
372 void tst_qquickvisualdatamodel::childChanged_data()
374 QTest::addColumn<QUrl>("source");
376 QTest::newRow("item delegate") << testFileUrl("datalist.qml");
377 QTest::newRow("package delegate") << testFileUrl("datalist-package.qml");
380 void tst_qquickvisualdatamodel::childChanged()
382 QFETCH(QUrl, source);
386 QStandardItemModel model;
387 initStandardTreeModel(&model);
389 view.rootContext()->setContextProperty("myModel", &model);
391 view.setSource(source);
393 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
394 QVERIFY(listview != 0);
396 QQuickItem *contentItem = listview->contentItem();
397 QVERIFY(contentItem != 0);
399 QQuickVisualDataModel *vdm = listview->findChild<QQuickVisualDataModel*>("visualModel");
400 vdm->setRootIndex(QVariant::fromValue(model.indexFromItem(model.item(1,0))));
401 QCOMPARE(listview->count(), 1);
403 QQuickText *name = findItem<QQuickText>(contentItem, "display", 0);
405 QCOMPARE(name->text(), QString("Row 2 Child Item"));
407 model.item(1,0)->child(0,0)->setText("Row 2 updated child");
409 name = findItem<QQuickText>(contentItem, "display", 0);
411 QCOMPARE(name->text(), QString("Row 2 updated child"));
413 model.item(1,0)->appendRow(new QStandardItem(QLatin1String("Row 2 Child Item 2")));
414 QCOMPARE(listview->count(), 2);
416 name = findItem<QQuickText>(contentItem, "display", 1);
418 QCOMPARE(name->text(), QString("Row 2 Child Item 2"));
420 model.item(1,0)->takeRow(1);
421 name = findItem<QQuickText>(contentItem, "display", 1);
424 vdm->setRootIndex(QVariant::fromValue(QModelIndex()));
425 QCOMPARE(listview->count(), 3);
426 name = findItem<QQuickText>(contentItem, "display", 0);
428 QCOMPARE(name->text(), QString("Row 1 Item"));
429 name = findItem<QQuickText>(contentItem, "display", 1);
431 QCOMPARE(name->text(), QString("Row 2 Item"));
432 name = findItem<QQuickText>(contentItem, "display", 2);
434 QCOMPARE(name->text(), QString("Row 3 Item"));
437 void tst_qquickvisualdatamodel::objectListModel()
441 QList<QObject*> dataList;
442 dataList.append(new DataObject("Item 1", "red"));
443 dataList.append(new DataObject("Item 2", "green"));
444 dataList.append(new DataObject("Item 3", "blue"));
445 dataList.append(new DataObject("Item 4", "yellow"));
447 QDeclarativeContext *ctxt = view.rootContext();
448 ctxt->setContextProperty("myModel", QVariant::fromValue(dataList));
450 view.setSource(testFileUrl("objectlist.qml"));
452 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
453 QVERIFY(listview != 0);
455 QQuickItem *contentItem = listview->contentItem();
456 QVERIFY(contentItem != 0);
458 QQuickText *name = findItem<QQuickText>(contentItem, "name", 0);
459 QCOMPARE(name->text(), QString("Item 1"));
461 QQuickText *section = findItem<QQuickText>(contentItem, "section", 0);
462 QCOMPARE(section->text(), QString("Item 1"));
464 dataList[0]->setProperty("name", QLatin1String("Changed"));
465 QCOMPARE(name->text(), QString("Changed"));
468 void tst_qquickvisualdatamodel::singleRole()
473 SingleRoleModel model;
475 QDeclarativeContext *ctxt = view.rootContext();
476 ctxt->setContextProperty("myModel", &model);
478 view.setSource(testFileUrl("singlerole1.qml"));
480 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
481 QVERIFY(listview != 0);
483 QQuickItem *contentItem = listview->contentItem();
484 QVERIFY(contentItem != 0);
486 QQuickText *name = findItem<QQuickText>(contentItem, "name", 1);
487 QCOMPARE(name->text(), QString("two"));
489 model.set(1, "Changed");
490 QCOMPARE(name->text(), QString("Changed"));
495 SingleRoleModel model;
497 QDeclarativeContext *ctxt = view.rootContext();
498 ctxt->setContextProperty("myModel", &model);
500 view.setSource(testFileUrl("singlerole2.qml"));
502 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
503 QVERIFY(listview != 0);
505 QQuickItem *contentItem = listview->contentItem();
506 QVERIFY(contentItem != 0);
508 QQuickText *name = findItem<QQuickText>(contentItem, "name", 1);
509 QCOMPARE(name->text(), QString("two"));
511 model.set(1, "Changed");
512 QCOMPARE(name->text(), QString("Changed"));
517 SingleRoleModel model("modelData");
519 QDeclarativeContext *ctxt = view.rootContext();
520 ctxt->setContextProperty("myModel", &model);
522 view.setSource(testFileUrl("singlerole2.qml"));
524 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
525 QVERIFY(listview != 0);
527 QQuickItem *contentItem = listview->contentItem();
528 QVERIFY(contentItem != 0);
530 QQuickText *name = findItem<QQuickText>(contentItem, "name", 1);
531 QCOMPARE(name->text(), QString("two"));
533 model.set(1, "Changed");
534 QCOMPARE(name->text(), QString("Changed"));
538 void tst_qquickvisualdatamodel::modelProperties()
543 SingleRoleModel model;
545 QDeclarativeContext *ctxt = view.rootContext();
546 ctxt->setContextProperty("myModel", &model);
548 view.setSource(testFileUrl("modelproperties.qml"));
550 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
551 QVERIFY(listview != 0);
553 QQuickItem *contentItem = listview->contentItem();
554 QVERIFY(contentItem != 0);
556 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", 1);
558 QCOMPARE(delegate->property("test1").toString(),QString("two"));
559 QCOMPARE(delegate->property("test2").toString(),QString("two"));
560 QCOMPARE(delegate->property("test3").toString(),QString("two"));
561 QCOMPARE(delegate->property("test4").toString(),QString("two"));
562 QVERIFY(!delegate->property("test9").isValid());
563 QCOMPARE(delegate->property("test5").toString(),QString(""));
564 QVERIFY(delegate->property("test6").value<QObject*>() != 0);
565 QCOMPARE(delegate->property("test7").toInt(),1);
566 QCOMPARE(delegate->property("test8").toInt(),1);
572 QList<QObject*> dataList;
573 dataList.append(new DataObject("Item 1", "red"));
574 dataList.append(new DataObject("Item 2", "green"));
575 dataList.append(new DataObject("Item 3", "blue"));
576 dataList.append(new DataObject("Item 4", "yellow"));
578 QDeclarativeContext *ctxt = view.rootContext();
579 ctxt->setContextProperty("myModel", QVariant::fromValue(dataList));
581 view.setSource(testFileUrl("modelproperties.qml"));
583 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
584 QVERIFY(listview != 0);
586 QQuickItem *contentItem = listview->contentItem();
587 QVERIFY(contentItem != 0);
589 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", 1);
591 QCOMPARE(delegate->property("test1").toString(),QString("Item 2"));
592 QCOMPARE(delegate->property("test2").toString(),QString("Item 2"));
593 QVERIFY(qobject_cast<DataObject*>(delegate->property("test3").value<QObject*>()) != 0);
594 QVERIFY(qobject_cast<DataObject*>(delegate->property("test4").value<QObject*>()) != 0);
595 QCOMPARE(delegate->property("test5").toString(),QString("Item 2"));
596 QCOMPARE(delegate->property("test9").toString(),QString("Item 2"));
597 QVERIFY(delegate->property("test6").value<QObject*>() != 0);
598 QCOMPARE(delegate->property("test7").toInt(),1);
599 QCOMPARE(delegate->property("test8").toInt(),1);
605 QStandardItemModel model;
606 initStandardTreeModel(&model);
608 view.rootContext()->setContextProperty("myModel", &model);
610 QUrl source(testFileUrl("modelproperties2.qml"));
613 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":13: ReferenceError: Can't find variable: modelData");
614 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":13: ReferenceError: Can't find variable: modelData");
615 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":13: ReferenceError: Can't find variable: modelData");
616 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":11: ReferenceError: Can't find variable: modelData");
617 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":11: ReferenceError: Can't find variable: modelData");
618 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":11: ReferenceError: Can't find variable: modelData");
619 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":17: TypeError: Cannot read property 'display' of undefined");
620 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":17: TypeError: Cannot read property 'display' of undefined");
621 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":17: TypeError: Cannot read property 'display' of undefined");
623 view.setSource(source);
625 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
626 QVERIFY(listview != 0);
628 QQuickItem *contentItem = listview->contentItem();
629 QVERIFY(contentItem != 0);
631 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", 1);
633 QCOMPARE(delegate->property("test1").toString(),QString("Row 2 Item"));
634 QCOMPARE(delegate->property("test2").toString(),QString("Row 2 Item"));
635 QVERIFY(!delegate->property("test3").isValid());
636 QVERIFY(!delegate->property("test4").isValid());
637 QVERIFY(!delegate->property("test5").isValid());
638 QVERIFY(!delegate->property("test9").isValid());
639 QVERIFY(delegate->property("test6").value<QObject*>() != 0);
640 QCOMPARE(delegate->property("test7").toInt(),1);
641 QCOMPARE(delegate->property("test8").toInt(),1);
644 //### should also test QStringList and QVariantList
647 void tst_qquickvisualdatamodel::noDelegate_data()
649 QTest::addColumn<QUrl>("source");
651 QTest::newRow("item delegate") << testFileUrl("datalist.qml");
652 QTest::newRow("package delegate") << testFileUrl("datalist-package.qml");
655 void tst_qquickvisualdatamodel::noDelegate()
657 QFETCH(QUrl, source);
661 QStandardItemModel model;
662 initStandardTreeModel(&model);
664 view.rootContext()->setContextProperty("myModel", &model);
666 view.setSource(source);
668 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
669 QVERIFY(listview != 0);
671 QQuickVisualDataModel *vdm = listview->findChild<QQuickVisualDataModel*>("visualModel");
673 QCOMPARE(vdm->count(), 3);
676 QCOMPARE(vdm->count(), 0);
679 void tst_qquickvisualdatamodel::itemsDestroyed_data()
681 QTest::addColumn<QUrl>("source");
683 QTest::newRow("listView") << testFileUrl("itemsDestroyed_listView.qml");
684 QTest::newRow("package") << testFileUrl("itemsDestroyed_package.qml");
685 QTest::newRow("pathView") << testFileUrl("itemsDestroyed_pathView.qml");
686 QTest::newRow("repeater") << testFileUrl("itemsDestroyed_repeater.qml");
689 void tst_qquickvisualdatamodel::itemsDestroyed()
691 QFETCH(QUrl, source);
693 QDeclarativeGuard<QQuickItem> delegate;
697 QStandardItemModel model;
698 initStandardTreeModel(&model);
699 view.rootContext()->setContextProperty("myModel", &model);
700 view.setSource(source);
703 QTest::qWaitForWindowShown(&view);
705 QVERIFY(delegate = findItem<QQuickItem>(view.rootItem(), "delegate", 1));
707 QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
711 void tst_qquickvisualdatamodel::packagesDestroyed()
713 SingleRoleModel model;
715 for (int i=0; i<30; i++)
716 model.list << ("item " + i);
719 view.rootContext()->setContextProperty("testModel", &model);
721 QString filename(testFile("packageView.qml"));
722 view.setSource(QUrl::fromLocalFile(filename));
724 qApp->processEvents();
726 QQuickListView *leftview = findItem<QQuickListView>(view.rootObject(), "leftList");
727 QTRY_VERIFY(leftview != 0);
729 QQuickListView *rightview = findItem<QQuickListView>(view.rootObject(), "rightList");
730 QTRY_VERIFY(rightview != 0);
732 QQuickItem *leftContent = leftview->contentItem();
733 QTRY_VERIFY(leftContent != 0);
735 QQuickItem *rightContent = rightview->contentItem();
736 QTRY_VERIFY(rightContent != 0);
738 QCOMPARE(leftview->currentIndex(), 0);
739 QCOMPARE(rightview->currentIndex(), 0);
741 rightview->setCurrentIndex(20);
742 QTRY_COMPARE(rightview->contentY(), 100.0);
744 QDeclarativeGuard<QQuickItem> left;
745 QDeclarativeGuard<QQuickItem> right;
747 QVERIFY(findItem<QQuickItem>(leftContent, "wrapper", 1));
748 QVERIFY(findItem<QQuickItem>(rightContent, "wrapper", 1));
750 QVERIFY(left = findItem<QQuickItem>(leftContent, "wrapper", 19));
751 QVERIFY(right = findItem<QQuickItem>(rightContent, "wrapper", 19));
753 rightview->setCurrentIndex(0);
754 QCOMPARE(rightview->currentIndex(), 0);
756 QTRY_COMPARE(rightview->contentY(), 0.0);
757 QCoreApplication::sendPostedEvents();
762 QVERIFY(left = findItem<QQuickItem>(leftContent, "wrapper", 1));
763 QVERIFY(right = findItem<QQuickItem>(rightContent, "wrapper", 1));
765 rightview->setCurrentIndex(20);
766 QTRY_COMPARE(rightview->contentY(), 100.0);
771 QVERIFY(findItem<QQuickItem>(leftContent, "wrapper", 19));
772 QVERIFY(findItem<QQuickItem>(rightContent, "wrapper", 19));
774 leftview->setCurrentIndex(20);
775 QTRY_COMPARE(leftview->contentY(), 100.0);
781 void tst_qquickvisualdatamodel::qaimRowsMoved()
783 // Test parameters passed in QAIM::rowsMoved() signal are converted correctly
784 // when translated and emitted as the QListModelInterface::itemsMoved() signal
785 QFETCH(int, sourceFirst);
786 QFETCH(int, sourceLast);
787 QFETCH(int, destinationChild);
788 QFETCH(int, expectFrom);
789 QFETCH(int, expectTo);
790 QFETCH(int, expectCount);
792 QDeclarativeEngine engine;
793 QDeclarativeComponent c(&engine, testFileUrl("visualdatamodel.qml"));
795 SingleRoleModel model;
797 for (int i=0; i<30; i++)
798 model.list << ("item " + i);
799 engine.rootContext()->setContextProperty("myModel", &model);
801 QQuickVisualDataModel *obj = qobject_cast<QQuickVisualDataModel*>(c.create());
804 QSignalSpy spy(obj, SIGNAL(modelUpdated(QDeclarativeChangeSet,bool)));
805 model.emitMove(sourceFirst, sourceLast, destinationChild);
806 QCOMPARE(spy.count(), 1);
808 QCOMPARE(spy[0].count(), 2);
809 QDeclarativeChangeSet changeSet = spy[0][0].value<QDeclarativeChangeSet>();
810 QCOMPARE(changeSet.removes().count(), 1);
811 QCOMPARE(changeSet.removes().at(0).index, expectFrom);
812 QCOMPARE(changeSet.removes().at(0).count, expectCount);
813 QCOMPARE(changeSet.inserts().count(), 1);
814 QCOMPARE(changeSet.inserts().at(0).index, expectTo);
815 QCOMPARE(changeSet.inserts().at(0).count, expectCount);
816 QCOMPARE(changeSet.removes().at(0).moveId, changeSet.inserts().at(0).moveId);
817 QCOMPARE(spy[0][1].toBool(), false);
822 void tst_qquickvisualdatamodel::qaimRowsMoved_data()
824 QTest::addColumn<int>("sourceFirst");
825 QTest::addColumn<int>("sourceLast");
826 QTest::addColumn<int>("destinationChild");
827 QTest::addColumn<int>("expectFrom");
828 QTest::addColumn<int>("expectTo");
829 QTest::addColumn<int>("expectCount");
831 QTest::newRow("move 1 forward")
835 QTest::newRow("move 1 backwards")
839 QTest::newRow("move multiple forwards")
843 QTest::newRow("move multiple forwards, with same to")
847 QTest::newRow("move multiple backwards")
852 void tst_qquickvisualdatamodel::remove_data()
854 QTest::addColumn<QUrl>("source");
855 QTest::addColumn<QString>("package delegate");
857 QTest::newRow("item delegate")
858 << testFileUrl("groups.qml")
860 QTest::newRow("package")
861 << testFileUrl("groups-package.qml")
862 << QString("package.");
865 void tst_qquickvisualdatamodel::remove()
869 SingleRoleModel model;
870 model.list = QStringList()
884 QDeclarativeContext *ctxt = view.rootContext();
885 ctxt->setContextProperty("myModel", &model);
887 view.setSource(testFileUrl("groups.qml"));
889 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
890 QVERIFY(listview != 0);
892 QQuickItem *contentItem = listview->contentItem();
893 QVERIFY(contentItem != 0);
895 QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel *>(qvariant_cast<QObject *>(listview->model()));
896 QVERIFY(visualModel);
899 QCOMPARE(listview->count(), 12);
900 QCOMPARE(visualModel->items()->count(), 12);
901 static const int mIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
902 static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
904 for (int i = 0; i < lengthOf(mIndex); ++i) {
905 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
907 QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
908 QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
909 QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
912 evaluate<void>(visualModel, "items.remove(2)");
913 QCOMPARE(listview->count(), 11);
914 QCOMPARE(visualModel->items()->count(), 11);
915 static const int mIndex[] = { 0, 1, 3, 4, 5, 6, 7, 8, 9,10,11 };
916 static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10 };
918 for (int i = 0; i < lengthOf(mIndex); ++i) {
919 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
921 QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
922 QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
923 QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
926 evaluate<void>(visualModel, "items.remove(1, 4)");
927 QCOMPARE(listview->count(), 7);
928 QCOMPARE(visualModel->items()->count(), 7);
929 static const int mIndex[] = { 0, 6, 7, 8, 9,10,11 };
930 static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6 };
932 for (int i = 0; i < lengthOf(mIndex); ++i) {
933 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
935 QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
936 QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
937 QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
940 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: remove: index out of range");
941 evaluate<void>(visualModel, "items.remove(-8, 4)");
942 QCOMPARE(listview->count(), 7);
943 QCOMPARE(visualModel->items()->count(), 7);
945 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: remove: index out of range");
946 evaluate<void>(visualModel, "items.remove(12, 2)");
947 QCOMPARE(listview->count(), 7);
948 QCOMPARE(visualModel->items()->count(), 7);
950 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: remove: invalid count");
951 evaluate<void>(visualModel, "items.remove(5, 3)");
952 QCOMPARE(listview->count(), 7);
953 QCOMPARE(visualModel->items()->count(), 7);
955 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: remove: invalid count");
956 evaluate<void>(visualModel, "items.remove(5, -2)");
957 QCOMPARE(listview->count(), 7);
958 QCOMPARE(visualModel->items()->count(), 7);
962 void tst_qquickvisualdatamodel::move_data()
964 QTest::addColumn<QUrl>("source");
965 QTest::addColumn<QString>("package delegate");
967 QTest::newRow("item delegate")
968 << testFileUrl("groups.qml")
970 QTest::newRow("package")
971 << testFileUrl("groups-package.qml")
972 << QString("package.");
975 void tst_qquickvisualdatamodel::move()
979 SingleRoleModel model;
980 model.list = QStringList()
994 QDeclarativeContext *ctxt = view.rootContext();
995 ctxt->setContextProperty("myModel", &model);
997 view.setSource(testFileUrl("groups.qml"));
999 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
1000 QVERIFY(listview != 0);
1002 QQuickItem *contentItem = listview->contentItem();
1003 QVERIFY(contentItem != 0);
1005 QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel *>(qvariant_cast<QObject *>(listview->model()));
1006 QVERIFY(visualModel);
1009 QCOMPARE(listview->count(), 12);
1010 QCOMPARE(visualModel->items()->count(), 12);
1011 static const int mIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1012 static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1014 for (int i = 0; i < lengthOf(mIndex); ++i) {
1015 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1017 QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
1018 QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
1019 QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
1022 evaluate<void>(visualModel, "items.move(2, 4)");
1023 QCOMPARE(listview->count(), 12);
1024 QCOMPARE(visualModel->items()->count(), 12);
1025 static const int mIndex[] = { 0, 1, 3, 4, 2, 5, 6, 7, 8, 9,10,11 };
1026 static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1028 for (int i = 0; i < lengthOf(mIndex); ++i) {
1029 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1031 QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
1032 QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
1033 QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
1036 evaluate<void>(visualModel, "items.move(4, 2)");
1037 QCOMPARE(listview->count(), 12);
1038 QCOMPARE(visualModel->items()->count(), 12);
1039 static const int mIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1040 static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1042 for (int i = 0; i < lengthOf(mIndex); ++i) {
1043 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1045 QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
1046 QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
1047 QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
1050 evaluate<void>(visualModel, "items.move(8, 0, 4)");
1051 QCOMPARE(listview->count(), 12);
1052 QCOMPARE(visualModel->items()->count(), 12);
1053 static const int mIndex[] = { 8, 9,10,11, 0, 1, 2, 3, 4, 5, 6, 7 };
1054 static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1056 for (int i = 0; i < lengthOf(mIndex); ++i) {
1057 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1059 QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
1060 QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
1061 QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
1064 evaluate<void>(visualModel, "items.move(3, 4, 5)");
1065 QCOMPARE(listview->count(), 12);
1066 QCOMPARE(visualModel->items()->count(), 12);
1067 static const int mIndex[] = { 8, 9,10,4, 11, 0, 1, 2, 3, 5, 6, 7 };
1068 static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1070 for (int i = 0; i < lengthOf(mIndex); ++i) {
1071 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1073 QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
1074 QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
1075 QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
1078 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: invalid count");
1079 evaluate<void>(visualModel, "items.move(5, 2, -2)");
1080 QCOMPARE(listview->count(), 12);
1081 QCOMPARE(visualModel->items()->count(), 12);
1083 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: from index out of range");
1084 evaluate<void>(visualModel, "items.move(-6, 2, 1)");
1085 QCOMPARE(listview->count(), 12);
1086 QCOMPARE(visualModel->items()->count(), 12);
1088 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: from index out of range");
1089 evaluate<void>(visualModel, "items.move(15, 2, 1)");
1090 QCOMPARE(listview->count(), 12);
1091 QCOMPARE(visualModel->items()->count(), 12);
1093 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: from index out of range");
1094 evaluate<void>(visualModel, "items.move(11, 1, 3)");
1095 QCOMPARE(listview->count(), 12);
1096 QCOMPARE(visualModel->items()->count(), 12);
1098 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: to index out of range");
1099 evaluate<void>(visualModel, "items.move(2, -5, 1)");
1100 QCOMPARE(listview->count(), 12);
1101 QCOMPARE(visualModel->items()->count(), 12);
1103 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: to index out of range");
1104 evaluate<void>(visualModel, "items.move(2, 14, 1)");
1105 QCOMPARE(listview->count(), 12);
1106 QCOMPARE(visualModel->items()->count(), 12);
1108 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: to index out of range");
1109 evaluate<void>(visualModel, "items.move(2, 11, 4)");
1110 QCOMPARE(listview->count(), 12);
1111 QCOMPARE(visualModel->items()->count(), 12);
1115 void tst_qquickvisualdatamodel::groups_data()
1117 QTest::addColumn<QUrl>("source");
1118 QTest::addColumn<QString>("part");
1120 QTest::newRow("item delegate")
1121 << testFileUrl("groups.qml")
1123 QTest::newRow("package")
1124 << testFileUrl("groups-package.qml")
1125 << QString("visualModel.parts.package.");
1128 template <int N> void tst_qquickvisualdatamodel::groups_verify(
1129 const SingleRoleModel &model,
1130 QQuickItem *contentItem,
1131 const int (&mIndex)[N],
1132 const int (&iIndex)[N],
1133 const int (&vIndex)[N],
1134 const int (&sIndex)[N],
1135 const bool (&vMember)[N],
1136 const bool (&sMember)[N])
1139 for (int i = 0; i < N; ++i) {
1140 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1142 QCOMPARE(evaluate<QString>(delegate, "test1"), model.list.at(mIndex[i]));
1143 QCOMPARE(evaluate<int>(delegate, "test2") , mIndex[i]);
1144 QCOMPARE(evaluate<int>(delegate, "test3") , iIndex[i]);
1145 QCOMPARE(evaluate<bool>(delegate, "test4"), true);
1146 QCOMPARE(evaluate<int>(delegate, "test5") , vIndex[i]);
1147 QCOMPARE(evaluate<bool>(delegate, "test6"), vMember[i]);
1148 QCOMPARE(evaluate<int>(delegate, "test7") , sIndex[i]);
1149 QCOMPARE(evaluate<bool>(delegate, "test8"), sMember[i]);
1150 QCOMPARE(evaluate<QStringList>(delegate, "test9").contains("items") , bool(true));
1151 QCOMPARE(evaluate<QStringList>(delegate, "test9").contains("visible") , bool(vMember[i]));
1152 QCOMPARE(evaluate<QStringList>(delegate, "test9").contains("selected"), bool(sMember[i]));
1157 #define VERIFY_GROUPS \
1158 groups_verify(model, contentItem, mIndex, iIndex, vIndex, sIndex, vMember, sMember); \
1162 void tst_qquickvisualdatamodel::groups()
1164 QFETCH(QUrl, source);
1165 QFETCH(QString, part);
1169 SingleRoleModel model;
1170 model.list = QStringList()
1184 QDeclarativeContext *ctxt = view.rootContext();
1185 ctxt->setContextProperty("myModel", &model);
1187 view.setSource(source);
1189 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
1190 QVERIFY(listview != 0);
1192 QQuickItem *contentItem = listview->contentItem();
1193 QVERIFY(contentItem != 0);
1195 QQuickVisualDataModel *visualModel = listview->findChild<QQuickVisualDataModel *>("visualModel");
1196 QVERIFY(visualModel);
1198 QQuickVisualDataGroup *visibleItems = listview->findChild<QQuickVisualDataGroup *>("visibleItems");
1199 QVERIFY(visibleItems);
1201 QQuickVisualDataGroup *selectedItems = listview->findChild<QQuickVisualDataGroup *>("selectedItems");
1202 QVERIFY(selectedItems);
1204 const bool f = false;
1205 const bool t = true;
1208 QCOMPARE(listview->count(), 12);
1209 QCOMPARE(visualModel->items()->count(), 12);
1210 QCOMPARE(visibleItems->count(), 12);
1211 QCOMPARE(selectedItems->count(), 0);
1212 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1213 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1214 static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1215 static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
1216 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1217 static const bool sMember[] = { f, f, f, f, f, f, f, f, f, f, f, f };
1220 evaluate<void>(visualModel, "items.addGroups(8, \"selected\")");
1221 QCOMPARE(listview->count(), 12);
1222 QCOMPARE(visualModel->items()->count(), 12);
1223 QCOMPARE(visibleItems->count(), 12);
1224 QCOMPARE(selectedItems->count(), 1);
1225 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1226 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1227 static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1228 static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
1229 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 };
1230 static const bool sMember[] = { f, f, f, f, f, f, f, f, t, f, f, f };
1233 evaluate<void>(visualModel, "items.addGroups(6, 4, [\"visible\", \"selected\"])");
1234 QCOMPARE(listview->count(), 12);
1235 QCOMPARE(visualModel->items()->count(), 12);
1236 QCOMPARE(visibleItems->count(), 12);
1237 QCOMPARE(selectedItems->count(), 4);
1238 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1239 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1240 static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1241 static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
1242 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 4 };
1243 static const bool sMember[] = { f, f, f, f, f, f, t, t, t, t, f, f };
1246 evaluate<void>(visualModel, "items.setGroups(2, [\"items\", \"selected\"])");
1247 QCOMPARE(listview->count(), 12);
1248 QCOMPARE(visualModel->items()->count(), 12);
1249 QCOMPARE(visibleItems->count(), 11);
1250 QCOMPARE(selectedItems->count(), 5);
1251 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1252 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1253 static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9,10 };
1254 static const bool vMember[] = { t, t, f, t, t, t, t, t, t, t, t, t };
1255 static const int sIndex [] = { 0, 0, 0, 1, 1, 1, 1, 2, 3, 4, 5, 5 };
1256 static const bool sMember[] = { f, f, t, f, f, f, t, t, t, t, f, f };
1259 evaluate<void>(selectedItems, "setGroups(0, 3, \"items\")");
1260 QCOMPARE(listview->count(), 12);
1261 QCOMPARE(visualModel->items()->count(), 12);
1262 QCOMPARE(visibleItems->count(), 9);
1263 QCOMPARE(selectedItems->count(), 2);
1264 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1265 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1266 static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 5, 5, 6, 7, 8 };
1267 static const bool vMember[] = { t, t, f, t, t, t, f, f, t, t, t, t };
1268 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 };
1269 static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f };
1272 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: addGroups: invalid count");
1273 evaluate<void>(visualModel, "items.addGroups(11, -4, \"items\")");
1274 QCOMPARE(listview->count(), 12);
1275 QCOMPARE(visualModel->items()->count(), 12);
1276 QCOMPARE(visibleItems->count(), 9);
1277 QCOMPARE(selectedItems->count(), 2);
1279 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: addGroups: index out of range");
1280 evaluate<void>(visualModel, "items.addGroups(-1, 3, \"items\")");
1281 QCOMPARE(listview->count(), 12);
1282 QCOMPARE(visualModel->items()->count(), 12);
1283 QCOMPARE(visibleItems->count(), 9);
1284 QCOMPARE(selectedItems->count(), 2);
1286 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: addGroups: index out of range");
1287 evaluate<void>(visualModel, "items.addGroups(14, 3, \"items\")");
1288 QCOMPARE(listview->count(), 12);
1289 QCOMPARE(visualModel->items()->count(), 12);
1290 QCOMPARE(visibleItems->count(), 9);
1291 QCOMPARE(selectedItems->count(), 2);
1293 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: addGroups: invalid count");
1294 evaluate<void>(visualModel, "items.addGroups(11, 5, \"items\")");
1295 QCOMPARE(listview->count(), 12);
1296 QCOMPARE(visualModel->items()->count(), 12);
1297 QCOMPARE(visibleItems->count(), 9);
1298 QCOMPARE(selectedItems->count(), 2);
1300 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: setGroups: invalid count");
1301 evaluate<void>(visualModel, "items.setGroups(11, -4, \"items\")");
1302 QCOMPARE(listview->count(), 12);
1303 QCOMPARE(visualModel->items()->count(), 12);
1304 QCOMPARE(visibleItems->count(), 9);
1305 QCOMPARE(selectedItems->count(), 2);
1307 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: setGroups: index out of range");
1308 evaluate<void>(visualModel, "items.setGroups(-1, 3, \"items\")");
1309 QCOMPARE(listview->count(), 12);
1310 QCOMPARE(visualModel->items()->count(), 12);
1311 QCOMPARE(visibleItems->count(), 9);
1312 QCOMPARE(selectedItems->count(), 2);
1314 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: setGroups: index out of range");
1315 evaluate<void>(visualModel, "items.setGroups(14, 3, \"items\")");
1316 QCOMPARE(listview->count(), 12);
1317 QCOMPARE(visualModel->items()->count(), 12);
1318 QCOMPARE(visibleItems->count(), 9);
1319 QCOMPARE(selectedItems->count(), 2);
1321 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: setGroups: invalid count");
1322 evaluate<void>(visualModel, "items.setGroups(11, 5, \"items\")");
1323 QCOMPARE(listview->count(), 12);
1324 QCOMPARE(visualModel->items()->count(), 12);
1325 QCOMPARE(visibleItems->count(), 9);
1326 QCOMPARE(selectedItems->count(), 2);
1328 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: removeGroups: invalid count");
1329 evaluate<void>(visualModel, "items.removeGroups(11, -4, \"items\")");
1330 QCOMPARE(listview->count(), 12);
1331 QCOMPARE(visualModel->items()->count(), 12);
1333 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: removeGroups: index out of range");
1334 evaluate<void>(visualModel, "items.removeGroups(-1, 3, \"items\")");
1335 QCOMPARE(listview->count(), 12);
1336 QCOMPARE(visualModel->items()->count(), 12);
1337 QCOMPARE(visibleItems->count(), 9);
1338 QCOMPARE(selectedItems->count(), 2);
1340 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: removeGroups: index out of range");
1341 evaluate<void>(visualModel, "items.removeGroups(14, 3, \"items\")");
1342 QCOMPARE(listview->count(), 12);
1343 QCOMPARE(visualModel->items()->count(), 12);
1344 QCOMPARE(visibleItems->count(), 9);
1345 QCOMPARE(selectedItems->count(), 2);
1347 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: removeGroups: invalid count");
1348 evaluate<void>(visualModel, "items.removeGroups(11, 5, \"items\")");
1349 QCOMPARE(listview->count(), 12);
1350 QCOMPARE(visualModel->items()->count(), 12);
1351 QCOMPARE(visibleItems->count(), 9);
1352 QCOMPARE(selectedItems->count(), 2);
1354 evaluate<void>(visualModel, part + "filterOnGroup = \"visible\"");
1355 QCOMPARE(listview->count(), 9);
1356 QCOMPARE(visualModel->items()->count(), 12);
1357 QCOMPARE(visibleItems->count(), 9);
1358 QCOMPARE(selectedItems->count(), 2);
1359 QCOMPARE(evaluate<QString>(visualModel, part + "filterOnGroup"), QString("visible"));
1361 evaluate<void>(visualModel, part + "filterOnGroup = \"selected\"");
1362 QCOMPARE(listview->count(), 2);
1363 QCOMPARE(visualModel->items()->count(), 12);
1364 QCOMPARE(visibleItems->count(), 9);
1365 QCOMPARE(selectedItems->count(), 2);
1366 QCOMPARE(evaluate<QString>(visualModel, part + "filterOnGroup"), QString("selected"));
1368 evaluate<void>(visualModel, part + "filterOnGroup = undefined");
1369 QCOMPARE(listview->count(), 12);
1370 QCOMPARE(visualModel->items()->count(), 12);
1371 QCOMPARE(visibleItems->count(), 9);
1372 QCOMPARE(selectedItems->count(), 2);
1373 QCOMPARE(evaluate<QString>(visualModel, part + "filterOnGroup"), QString("items"));
1375 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", 5);
1378 evaluate<void>(delegate, "hide()");
1379 QCOMPARE(listview->count(), 12);
1380 QCOMPARE(visualModel->items()->count(), 12);
1381 QCOMPARE(visibleItems->count(), 8);
1382 QCOMPARE(selectedItems->count(), 2);
1383 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1384 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1385 static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 6, 7 };
1386 static const bool vMember[] = { t, t, f, t, t, f, f, f, t, t, t, t };
1387 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 };
1388 static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f };
1391 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", 5);
1394 evaluate<void>(delegate, "select()");
1395 QCOMPARE(listview->count(), 12);
1396 QCOMPARE(visualModel->items()->count(), 12);
1397 QCOMPARE(visibleItems->count(), 8);
1398 QCOMPARE(selectedItems->count(), 3);
1399 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1400 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1401 static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 6, 7 };
1402 static const bool vMember[] = { t, t, f, t, t, f, f, f, t, t, t, t };
1403 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 3, 3 };
1404 static const bool sMember[] = { f, f, f, f, f, t, f, f, t, t, f, f };
1407 evaluate<void>(visualModel, "items.move(2, 6, 3)");
1408 QCOMPARE(listview->count(), 12);
1409 QCOMPARE(visualModel->items()->count(), 12);
1410 QCOMPARE(visibleItems->count(), 8);
1411 QCOMPARE(selectedItems->count(), 3);
1412 static const int mIndex [] = { 0, 1, 5, 6, 7, 8, 2, 3, 4, 9,10,11 };
1413 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1414 static const int vIndex [] = { 0, 1, 2, 2, 2, 2, 3, 3, 4, 5, 6, 7 };
1415 static const bool vMember[] = { t, t, f, f, f, t, f, t, t, t, t, t };
1416 static const int sIndex [] = { 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3 };
1417 static const bool sMember[] = { f, f, t, f, f, t, f, f, f, t, f, f };
1422 template <int N> void tst_qquickvisualdatamodel::get_verify(
1423 const SingleRoleModel &model,
1424 QQuickVisualDataModel *visualModel,
1425 QQuickVisualDataGroup *visibleItems,
1426 QQuickVisualDataGroup *selectedItems,
1427 const int (&mIndex)[N],
1428 const int (&iIndex)[N],
1429 const int (&vIndex)[N],
1430 const int (&sIndex)[N],
1431 const bool (&vMember)[N],
1432 const bool (&sMember)[N])
1435 for (int i = 0; i < N; ++i) {
1436 QCOMPARE(evaluate<QString>(visualModel, QString("items.get(%1).model.name").arg(i)), model.list.at(mIndex[i]));
1437 QCOMPARE(evaluate<QString>(visualModel, QString("items.get(%1).model.modelData").arg(i)), model.list.at(mIndex[i]));
1438 QCOMPARE(evaluate<int>(visualModel, QString("items.get(%1).model.index").arg(i)), mIndex[i]);
1439 QCOMPARE(evaluate<int>(visualModel, QString("items.get(%1).itemsIndex").arg(i)), iIndex[i]);
1440 QCOMPARE(evaluate<bool>(visualModel, QString("items.get(%1).inItems").arg(i)), true);
1441 QCOMPARE(evaluate<int>(visualModel, QString("items.get(%1).visibleIndex").arg(i)), vIndex[i]);
1442 QCOMPARE(evaluate<bool>(visualModel, QString("items.get(%1).inVisible").arg(i)), vMember[i]);
1443 QCOMPARE(evaluate<int>(visualModel, QString("items.get(%1).selectedIndex").arg(i)), sIndex[i]);
1444 QCOMPARE(evaluate<bool>(visualModel, QString("items.get(%1).inSelected").arg(i)), sMember[i]);
1445 QCOMPARE(evaluate<bool>(visualModel, QString("contains(items.get(%1).groups, \"items\")").arg(i)), true);
1446 QCOMPARE(evaluate<bool>(visualModel, QString("contains(items.get(%1).groups, \"visible\")").arg(i)), vMember[i]);
1447 QCOMPARE(evaluate<bool>(visualModel, QString("contains(items.get(%1).groups, \"selected\")").arg(i)), sMember[i]);
1450 QCOMPARE(evaluate<QString>(visibleItems, QString("get(%1).model.name").arg(vIndex[i])), model.list.at(mIndex[i]));
1451 QCOMPARE(evaluate<QString>(visibleItems, QString("get(%1).model.modelData").arg(vIndex[i])), model.list.at(mIndex[i]));
1452 QCOMPARE(evaluate<int>(visibleItems, QString("get(%1).model.index").arg(vIndex[i])), mIndex[i]);
1453 QCOMPARE(evaluate<int>(visibleItems, QString("get(%1).itemsIndex").arg(vIndex[i])), iIndex[i]);
1454 QCOMPARE(evaluate<bool>(visibleItems, QString("get(%1).inItems").arg(vIndex[i])), true);
1455 QCOMPARE(evaluate<int>(visibleItems, QString("get(%1).visibleIndex").arg(vIndex[i])), vIndex[i]);
1456 QCOMPARE(evaluate<bool>(visibleItems, QString("get(%1).inVisible").arg(vIndex[i])), vMember[i]);
1457 QCOMPARE(evaluate<int>(visibleItems, QString("get(%1).selectedIndex").arg(vIndex[i])), sIndex[i]);
1458 QCOMPARE(evaluate<bool>(visibleItems, QString("get(%1).inSelected").arg(vIndex[i])), sMember[i]);
1460 QCOMPARE(evaluate<bool>(visibleItems, QString("contains(get(%1).groups, \"items\")").arg(vIndex[i])), true);
1461 QCOMPARE(evaluate<bool>(visibleItems, QString("contains(get(%1).groups, \"visible\")").arg(vIndex[i])), vMember[i]);
1462 QCOMPARE(evaluate<bool>(visibleItems, QString("contains(get(%1).groups, \"selected\")").arg(vIndex[i])), sMember[i]);
1465 QCOMPARE(evaluate<QString>(selectedItems, QString("get(%1).model.name").arg(sIndex[i])), model.list.at(mIndex[i]));
1466 QCOMPARE(evaluate<QString>(selectedItems, QString("get(%1).model.modelData").arg(sIndex[i])), model.list.at(mIndex[i]));
1467 QCOMPARE(evaluate<int>(selectedItems, QString("get(%1).model.index").arg(sIndex[i])), mIndex[i]);
1468 QCOMPARE(evaluate<int>(selectedItems, QString("get(%1).itemsIndex").arg(sIndex[i])), iIndex[i]);
1469 QCOMPARE(evaluate<bool>(selectedItems, QString("get(%1).inItems").arg(sIndex[i])), true);
1470 QCOMPARE(evaluate<int>(selectedItems, QString("get(%1).visibleIndex").arg(sIndex[i])), vIndex[i]);
1471 QCOMPARE(evaluate<bool>(selectedItems, QString("get(%1).inVisible").arg(sIndex[i])), vMember[i]);
1472 QCOMPARE(evaluate<int>(selectedItems, QString("get(%1).selectedIndex").arg(sIndex[i])), sIndex[i]);
1473 QCOMPARE(evaluate<bool>(selectedItems, QString("get(%1).inSelected").arg(sIndex[i])), sMember[i]);
1474 QCOMPARE(evaluate<bool>(selectedItems, QString("contains(get(%1).groups, \"items\")").arg(sIndex[i])), true);
1475 QCOMPARE(evaluate<bool>(selectedItems, QString("contains(get(%1).groups, \"visible\")").arg(sIndex[i])), vMember[i]);
1476 QCOMPARE(evaluate<bool>(selectedItems, QString("contains(get(%1).groups, \"selected\")").arg(sIndex[i])), sMember[i]);
1482 #define VERIFY_GET \
1483 get_verify(model, visualModel, visibleItems, selectedItems, mIndex, iIndex, vIndex, sIndex, vMember, sMember); \
1486 void tst_qquickvisualdatamodel::get()
1490 SingleRoleModel model;
1491 model.list = QStringList()
1505 QDeclarativeContext *ctxt = view.rootContext();
1506 ctxt->setContextProperty("myModel", &model);
1508 view.setSource(testFileUrl("groups.qml"));
1510 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
1511 QVERIFY(listview != 0);
1513 QQuickItem *contentItem = listview->contentItem();
1514 QVERIFY(contentItem != 0);
1516 QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel *>(qvariant_cast<QObject *>(listview->model()));
1517 QVERIFY(visualModel);
1519 QQuickVisualDataGroup *visibleItems = visualModel->findChild<QQuickVisualDataGroup *>("visibleItems");
1520 QVERIFY(visibleItems);
1522 QQuickVisualDataGroup *selectedItems = visualModel->findChild<QQuickVisualDataGroup *>("selectedItems");
1523 QVERIFY(selectedItems);
1525 QV8Engine *v8Engine = QDeclarativeEnginePrivate::getV8Engine(ctxt->engine());
1528 const bool f = false;
1529 const bool t = true;
1532 QCOMPARE(listview->count(), 12);
1533 QCOMPARE(visualModel->items()->count(), 12);
1534 QCOMPARE(visibleItems->count(), 12);
1535 QCOMPARE(selectedItems->count(), 0);
1536 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1537 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1538 static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1539 static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
1540 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1541 static const bool sMember[] = { f, f, f, f, f, f, f, f, f, f, f, f };
1544 evaluate<void>(visualModel, "items.addGroups(8, \"selected\")");
1545 QCOMPARE(listview->count(), 12);
1546 QCOMPARE(visualModel->items()->count(), 12);
1547 QCOMPARE(visibleItems->count(), 12);
1548 QCOMPARE(selectedItems->count(), 1);
1549 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1550 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1551 static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1552 static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
1553 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 };
1554 static const bool sMember[] = { f, f, f, f, f, f, f, f, t, f, f, f };
1557 evaluate<void>(visualModel, "items.addGroups(6, 4, [\"visible\", \"selected\"])");
1558 QCOMPARE(listview->count(), 12);
1559 QCOMPARE(visualModel->items()->count(), 12);
1560 QCOMPARE(visibleItems->count(), 12);
1561 QCOMPARE(selectedItems->count(), 4);
1562 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1563 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1564 static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1565 static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
1566 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 4 };
1567 static const bool sMember[] = { f, f, f, f, f, f, t, t, t, t, f, f };
1570 evaluate<void>(visualModel, "items.setGroups(2, [\"items\", \"selected\"])");
1571 QCOMPARE(listview->count(), 12);
1572 QCOMPARE(visualModel->items()->count(), 12);
1573 QCOMPARE(visibleItems->count(), 11);
1574 QCOMPARE(selectedItems->count(), 5);
1575 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1576 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1577 static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9,10 };
1578 static const bool vMember[] = { t, t, f, t, t, t, t, t, t, t, t, t };
1579 static const int sIndex [] = { 0, 0, 0, 1, 1, 1, 1, 2, 3, 4, 5, 5 };
1580 static const bool sMember[] = { f, f, t, f, f, f, t, t, t, t, f, f };
1583 evaluate<void>(selectedItems, "setGroups(0, 3, \"items\")");
1584 QCOMPARE(listview->count(), 12);
1585 QCOMPARE(visualModel->items()->count(), 12);
1586 QCOMPARE(visibleItems->count(), 9);
1587 QCOMPARE(selectedItems->count(), 2);
1588 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1589 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1590 static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 5, 5, 6, 7, 8 };
1591 static const bool vMember[] = { t, t, f, t, t, t, f, f, t, t, t, t };
1592 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 };
1593 static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f };
1596 evaluate<void>(visualModel, "items.get(5).inVisible = false");
1597 QCOMPARE(listview->count(), 12);
1598 QCOMPARE(visualModel->items()->count(), 12);
1599 QCOMPARE(visibleItems->count(), 8);
1600 QCOMPARE(selectedItems->count(), 2);
1601 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1602 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1603 static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 6, 7 };
1604 static const bool vMember[] = { t, t, f, t, t, f, f, f, t, t, t, t };
1605 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 };
1606 static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f };
1609 evaluate<void>(visualModel, "items.get(5).inSelected = true");
1610 QCOMPARE(listview->count(), 12);
1611 QCOMPARE(visualModel->items()->count(), 12);
1612 QCOMPARE(visibleItems->count(), 8);
1613 QCOMPARE(selectedItems->count(), 3);
1614 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1615 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1616 static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 6, 7 };
1617 static const bool vMember[] = { t, t, f, t, t, f, f, f, t, t, t, t };
1618 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 3, 3 };
1619 static const bool sMember[] = { f, f, f, f, f, t, f, f, t, t, f, f };
1622 evaluate<void>(visualModel, "items.get(5).groups = [\"visible\", \"items\"]");
1623 QCOMPARE(listview->count(), 12);
1624 QCOMPARE(visualModel->items()->count(), 12);
1625 QCOMPARE(visibleItems->count(), 9);
1626 QCOMPARE(selectedItems->count(), 2);
1627 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1628 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1629 static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 5, 5, 6, 7, 8 };
1630 static const bool vMember[] = { t, t, f, t, t, t, f, f, t, t, t, t };
1631 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 };
1632 static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f };
1637 void tst_qquickvisualdatamodel::invalidGroups()
1639 QUrl source = testFileUrl("groups-invalid.qml");
1640 QTest::ignoreMessage(QtWarningMsg, (source.toString() + ":12:9: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("Group names must start with a lower case letter")).toUtf8());
1642 QDeclarativeComponent component(&engine, source);
1643 QScopedPointer<QObject> object(component.create());
1646 QCOMPARE(evaluate<int>(object.data(), "groups.length"), 4);
1647 QCOMPARE(evaluate<QString>(object.data(), "groups[0].name"), QString("items"));
1648 QCOMPARE(evaluate<QString>(object.data(), "groups[1].name"), QString("persistedItems"));
1649 QCOMPARE(evaluate<QString>(object.data(), "groups[2].name"), QString("visible"));
1650 QCOMPARE(evaluate<QString>(object.data(), "groups[3].name"), QString("selected"));
1653 void tst_qquickvisualdatamodel::onChanged_data()
1655 QTest::addColumn<QString>("expression");
1656 QTest::addColumn<QStringList>("tests");
1658 QTest::newRow("item appended")
1659 << QString("listModel.append({\"number\": \"five\"})")
1661 << "verify(vm.removed, [], [], [])"
1662 << "verify(vm.inserted, [4], [1], [undefined])"
1663 << "verify(vi.removed, [], [], [])"
1664 << "verify(vi.inserted, [4], [1], [undefined])"
1665 << "verify(si.removed, [], [], [])"
1666 << "verify(si.inserted, [], [], [])");
1667 QTest::newRow("item prepended")
1668 << QString("listModel.insert(0, {\"number\": \"five\"})")
1670 << "verify(vm.removed, [], [], [])"
1671 << "verify(vm.inserted, [0], [1], [undefined])"
1672 << "verify(vi.removed, [], [], [])"
1673 << "verify(vi.inserted, [0], [1], [undefined])"
1674 << "verify(si.removed, [], [], [])"
1675 << "verify(si.inserted, [], [], [])");
1676 QTest::newRow("item inserted")
1677 << QString("listModel.insert(2, {\"number\": \"five\"})")
1679 << "verify(vm.removed, [], [], [])"
1680 << "verify(vm.inserted, [2], [1], [undefined])"
1681 << "verify(vi.removed, [], [], [])"
1682 << "verify(vi.inserted, [2], [1], [undefined])"
1683 << "verify(si.removed, [], [], [])"
1684 << "verify(si.inserted, [], [], [])");
1686 QTest::newRow("item removed tail")
1687 << QString("listModel.remove(3)")
1689 << "verify(vm.removed, [3], [1], [undefined])"
1690 << "verify(vm.inserted, [], [], [])"
1691 << "verify(vi.removed, [3], [1], [undefined])"
1692 << "verify(vi.inserted, [], [], [])"
1693 << "verify(si.removed, [], [], [])"
1694 << "verify(si.inserted, [], [], [])");
1695 QTest::newRow("item removed head")
1696 << QString("listModel.remove(0)")
1698 << "verify(vm.removed, [0], [1], [undefined])"
1699 << "verify(vm.inserted, [], [], [])"
1700 << "verify(vi.removed, [0], [1], [undefined])"
1701 << "verify(vi.inserted, [], [], [])"
1702 << "verify(si.removed, [], [], [])"
1703 << "verify(si.inserted, [], [], [])");
1704 QTest::newRow("item removed middle")
1705 << QString("listModel.remove(1)")
1707 << "verify(vm.removed, [1], [1], [undefined])"
1708 << "verify(vm.inserted, [], [], [])"
1709 << "verify(vi.removed, [1], [1], [undefined])"
1710 << "verify(vi.inserted, [], [], [])"
1711 << "verify(si.removed, [], [], [])"
1712 << "verify(si.inserted, [], [], [])");
1715 QTest::newRow("item moved from tail")
1716 << QString("listModel.move(3, 0, 1)")
1718 << "verify(vm.removed, [3], [1], [vm.inserted[0].moveId])"
1719 << "verify(vm.inserted, [0], [1], [vm.removed[0].moveId])"
1720 << "verify(vi.removed, [3], [1], [vi.inserted[0].moveId])"
1721 << "verify(vi.inserted, [0], [1], [vi.removed[0].moveId])"
1722 << "verify(si.removed, [], [], [])"
1723 << "verify(si.inserted, [], [], [])");
1724 QTest::newRow("item moved from head")
1725 << QString("listModel.move(0, 2, 2)")
1727 << "verify(vm.removed, [0], [2], [vm.inserted[0].moveId])"
1728 << "verify(vm.inserted, [2], [2], [vm.removed[0].moveId])"
1729 << "verify(vi.removed, [0], [2], [vi.inserted[0].moveId])"
1730 << "verify(vi.inserted, [2], [2], [vi.removed[0].moveId])"
1731 << "verify(si.removed, [], [], [])"
1732 << "verify(si.inserted, [], [], [])");
1734 QTest::newRow("groups changed")
1735 << QString("items.setGroups(1, 2, [\"items\", \"selected\"])")
1737 << "verify(vm.inserted, [], [], [])"
1738 << "verify(vm.removed, [], [], [])"
1739 << "verify(vi.removed, [1], [2], [undefined])"
1740 << "verify(vi.inserted, [], [], [])"
1741 << "verify(si.removed, [], [], [])"
1742 << "verify(si.inserted, [0], [2], [undefined])");
1744 QTest::newRow("multiple removes")
1745 << QString("{ vi.remove(1, 1); "
1746 "vi.removeGroups(0, 2, \"items\") }")
1748 << "verify(vm.removed, [0, 1], [1, 1], [undefined, undefined])"
1749 << "verify(vm.inserted, [], [], [])"
1750 << "verify(vi.removed, [1], [1], [undefined])"
1751 << "verify(vi.inserted, [], [], [])"
1752 << "verify(si.removed, [], [], [])"
1753 << "verify(si.inserted, [], [], [])");
1756 void tst_qquickvisualdatamodel::onChanged()
1758 QFETCH(QString, expression);
1759 QFETCH(QStringList, tests);
1761 QDeclarativeComponent component(&engine, testFileUrl("onChanged.qml"));
1762 QScopedPointer<QObject> object(component.create());
1765 evaluate<void>(object.data(), expression);
1767 foreach (const QString &test, tests) {
1768 bool passed = evaluate<bool>(object.data(), test);
1775 void tst_qquickvisualdatamodel::create()
1779 SingleRoleModel model;
1780 model.list = QStringList()
1802 QDeclarativeContext *ctxt = view.rootContext();
1803 ctxt->setContextProperty("myModel", &model);
1805 view.setSource(testFileUrl("create.qml"));
1807 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
1808 QVERIFY(listview != 0);
1810 QQuickItem *contentItem = listview->contentItem();
1811 QVERIFY(contentItem != 0);
1813 QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel *>(qvariant_cast<QObject *>(listview->model()));
1814 QVERIFY(visualModel);
1816 QCOMPARE(listview->count(), 20);
1818 QDeclarativeGuard<QQuickItem> delegate;
1820 // persistedItems.includeByDefault is true, so all items belong to persistedItems initially.
1821 QVERIFY(delegate = findItem<QQuickItem>(contentItem, "delegate", 1));
1822 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
1824 // changing include by default doesn't remove persistance.
1825 evaluate<void>(visualModel, "persistedItems.includeByDefault = false");
1826 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
1828 // removing from persistedItems does.
1829 evaluate<void>(visualModel, "persistedItems.remove(0, 20)");
1830 QCOMPARE(listview->count(), 20);
1831 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), false);
1833 // Request an item instantiated by the view.
1834 QVERIFY(delegate = qobject_cast<QQuickItem *>(evaluate<QObject *>(visualModel, "items.create(1)")));
1835 QCOMPARE(delegate.data(), findItem<QQuickItem>(contentItem, "delegate", 1));
1836 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
1837 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 1);
1839 evaluate<void>(delegate, "VisualDataModel.inPersistedItems = false");
1840 QCOMPARE(listview->count(), 20);
1841 QCoreApplication::sendPostedEvents(delegate, QEvent::DeferredDelete);
1843 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), false);
1844 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 0);
1846 // Request an item not instantiated by the view.
1847 QVERIFY(!findItem<QQuickItem>(contentItem, "delegate", 15));
1848 QVERIFY(delegate = qobject_cast<QQuickItem *>(evaluate<QObject *>(visualModel, "items.create(15)")));
1849 QCOMPARE(delegate.data(), findItem<QQuickItem>(contentItem, "delegate", 15));
1850 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
1851 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 1);
1853 evaluate<void>(visualModel, "persistedItems.remove(0)");
1854 QCoreApplication::sendPostedEvents(delegate, QEvent::DeferredDelete);
1856 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 0);
1858 // Request an item not instantiated by the view, then scroll the view so it will request it.
1859 QVERIFY(!findItem<QQuickItem>(contentItem, "delegate", 16));
1860 QVERIFY(delegate = qobject_cast<QQuickItem *>(evaluate<QObject *>(visualModel, "items.create(16)")));
1861 QCOMPARE(delegate.data(), findItem<QQuickItem>(contentItem, "delegate", 16));
1862 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
1863 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 1);
1865 evaluate<void>(listview, "positionViewAtIndex(19, ListView.End)");
1866 QCOMPARE(listview->count(), 20);
1867 evaluate<void>(delegate, "VisualDataModel.groups = [\"items\"]");
1868 QCoreApplication::sendPostedEvents(delegate, QEvent::DeferredDelete);
1870 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), false);
1871 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 0);
1873 // Request and release an item instantiated by the view, then scroll the view so it releases it.
1874 QVERIFY(findItem<QQuickItem>(contentItem, "delegate", 17));
1875 QVERIFY(delegate = qobject_cast<QQuickItem *>(evaluate<QObject *>(visualModel, "items.create(17)")));
1876 QCOMPARE(delegate.data(), findItem<QQuickItem>(contentItem, "delegate", 17));
1877 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
1878 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 1);
1880 evaluate<void>(visualModel, "items.removeGroups(17, \"persistedItems\")");
1881 QCoreApplication::sendPostedEvents(delegate, QEvent::DeferredDelete);
1883 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), false);
1884 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 0);
1885 evaluate<void>(listview, "positionViewAtIndex(1, ListView.Beginning)");
1886 QCOMPARE(listview->count(), 20);
1887 QCoreApplication::sendPostedEvents(delegate, QEvent::DeferredDelete);
1890 // Adding an item to the persistedItems group won't instantiate it, but if later requested by
1891 // the view it will be persisted.
1892 evaluate<void>(visualModel, "items.addGroups(18, \"persistedItems\")");
1893 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 1);
1894 QVERIFY(!findItem<QQuickItem>(contentItem, "delegate", 18));
1895 evaluate<void>(listview, "positionViewAtIndex(19, ListView.End)");
1896 QCOMPARE(listview->count(), 20);
1897 QVERIFY(delegate = findItem<QQuickItem>(contentItem, "delegate", 18));
1898 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
1899 QCoreApplication::sendPostedEvents(delegate, QEvent::DeferredDelete);
1901 evaluate<void>(listview, "positionViewAtIndex(1, ListView.Beginning)");
1902 QCOMPARE(listview->count(), 20);
1903 QCoreApplication::sendPostedEvents(delegate, QEvent::DeferredDelete);
1906 // Remove an uninstantiated but cached item from the persistedItems group.
1907 evaluate<void>(visualModel, "items.addGroups(19, \"persistedItems\")");
1908 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 2);
1909 QVERIFY(!findItem<QQuickItem>(contentItem, "delegate", 19));
1910 // Store a reference to the item so it is retained in the cache.
1911 evaluate<void>(visualModel, "persistentHandle = items.get(19)");
1912 QCOMPARE(evaluate<bool>(visualModel, "persistentHandle.inPersistedItems"), true);
1913 evaluate<void>(visualModel, "items.removeGroups(19, \"persistedItems\")");
1914 QCOMPARE(evaluate<bool>(visualModel, "persistentHandle.inPersistedItems"), false);
1917 void tst_qquickvisualdatamodel::incompleteModel()
1919 // VisualDataModel is first populated in componentComplete. Verify various functions are
1920 // harmlessly ignored until then.
1922 QDeclarativeComponent component(&engine);
1923 component.setData("import QtQuick 2.0\n VisualDataModel {}", testFileUrl(""));
1925 QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
1927 QQuickVisualDataModel *model = qobject_cast<QQuickVisualDataModel *>(object.data());
1930 QSignalSpy itemsSpy(model->items(), SIGNAL(countChanged()));
1931 QSignalSpy persistedItemsSpy(model->items(), SIGNAL(countChanged()));
1933 evaluate<void>(model, "items.removeGroups(0, items.count, \"items\")");
1934 QCOMPARE(itemsSpy.count(), 0);
1935 QCOMPARE(persistedItemsSpy.count(), 0);
1937 evaluate<void>(model, "items.setGroups(0, items.count, \"persistedItems\")");
1938 QCOMPARE(itemsSpy.count(), 0);
1939 QCOMPARE(persistedItemsSpy.count(), 0);
1941 evaluate<void>(model, "items.addGroups(0, items.count, \"persistedItems\")");
1942 QCOMPARE(itemsSpy.count(), 0);
1943 QCOMPARE(persistedItemsSpy.count(), 0);
1945 evaluate<void>(model, "items.remove(0, items.count)");
1946 QCOMPARE(itemsSpy.count(), 0);
1947 QCOMPARE(persistedItemsSpy.count(), 0);
1949 evaluate<void>(model, "items.insert([ \"color\": \"blue\" ])");
1950 QCOMPARE(itemsSpy.count(), 0);
1951 QCOMPARE(persistedItemsSpy.count(), 0);
1953 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: get: index out of range");
1954 QVERIFY(evaluate<bool>(model, "items.get(0) === undefined"));
1956 component.completeCreate();
1959 void tst_qquickvisualdatamodel::insert_data()
1961 QTest::addColumn<QUrl>("source");
1962 QTest::addColumn<QString>("expression");
1963 QTest::addColumn<int>("modelCount");
1964 QTest::addColumn<int>("visualCount");
1965 QTest::addColumn<int>("index");
1966 QTest::addColumn<bool>("inItems");
1967 QTest::addColumn<bool>("persisted");
1968 QTest::addColumn<bool>("visible");
1969 QTest::addColumn<bool>("selected");
1970 QTest::addColumn<bool>("modelData");
1971 QTest::addColumn<QString>("property");
1972 QTest::addColumn<QStringList>("propertyData");
1974 const QUrl listModelSource[] = {
1975 testFileUrl("listmodelproperties.qml"),
1976 testFileUrl("listmodelproperties-package.qml") };
1977 const QUrl singleRoleSource[] = {
1978 testFileUrl("singleroleproperties.qml"),
1979 testFileUrl("singleroleproperties-package.qml") };
1980 const QUrl multipleRoleSource[] = {
1981 testFileUrl("multipleroleproperties.qml"),
1982 testFileUrl("multipleroleproperties-package.qml") };
1983 const QUrl stringListSource[] = {
1984 testFileUrl("stringlistproperties.qml"),
1985 testFileUrl("stringlistproperties-package.qml") };
1986 const QUrl objectListSource[] = {
1987 testFileUrl("objectlistproperties.qml"),
1988 testFileUrl("objectlistproperties-package.qml") };
1990 for (int i = 0; i < 2; ++i) {
1992 QTest::newRow("ListModel.items prepend")
1993 << listModelSource[i]
1994 << QString("items.insert(0, {\"number\": \"eight\"})")
1995 << 4 << 5 << 0 << true << false << false << false << true
1996 << QString("number")
1997 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
1999 QTest::newRow("ListModel.items append")
2000 << listModelSource[i]
2001 << QString("items.insert({\"number\": \"eight\"})")
2002 << 4 << 5 << 4 << true << false << false << false << true
2003 << QString("number")
2004 << (QStringList() << "one" << "two" << "three" << "four" << "eight");
2006 QTest::newRow("ListModel.items insert at 2")
2007 << listModelSource[i]
2008 << QString("items.insert(2, {\"number\": \"eight\"})")
2009 << 4 << 5 << 2 << true << false << false << false << true
2010 << QString("number")
2011 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2013 QTest::newRow("ListModel.items insert at items.get(2)")
2014 << listModelSource[i]
2015 << QString("items.insert(items.get(2), {\"number\": \"eight\"})")
2016 << 4 << 5 << 2 << true << false << false << false << true
2017 << QString("number")
2018 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2020 QTest::newRow("ListModel.items insert at visibleItems.get(2)")
2021 << listModelSource[i]
2022 << QString("items.insert(visibleItems.get(2), {\"number\": \"eight\"})")
2023 << 4 << 5 << 2 << true << false << false << false << true
2024 << QString("number")
2025 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2027 QTest::newRow("ListModel.selectedItems insert at items.get(2)")
2028 << listModelSource[i]
2029 << QString("selectedItems.insert(items.get(2), {\"number\": \"eight\"})")
2030 << 4 << 5 << 2 << false << false << false << true << true
2031 << QString("number")
2032 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2034 QTest::newRow("ListModel.selectedItems insert at visibleItems.get(2)")
2035 << listModelSource[i]
2036 << QString("selectedItems.insert(visibleItems.get(2), {\"number\": \"eight\"})")
2037 << 4 << 5 << 2 << false << false << false << true << true
2038 << QString("number")
2039 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2041 QTest::newRow("ListModel.items prepend modelData")
2042 << listModelSource[i]
2043 << QString("items.insert(0, {\"modelData\": \"eight\"})")
2044 << 4 << 5 << 0 << true << false << false << false << true
2045 << QString("number")
2046 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2048 QTest::newRow("ListModel.items prepend, edit number")
2049 << listModelSource[i]
2051 "items.insert(0, {\"number\": \"eight\"}); "
2052 "items.get(0).model.number = \"seven\"; }")
2053 << 4 << 5 << 0 << true << false << false << false << true
2054 << QString("number")
2055 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2057 QTest::newRow("ListModel.items prepend, edit modelData")
2058 << listModelSource[i]
2060 "items.insert(0, {\"number\": \"eight\"}); "
2061 "items.get(0).model.modelData = \"seven\"; }")
2062 << 4 << 5 << 0 << true << false << false << false << true
2063 << QString("number")
2064 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2066 QTest::newRow("ListModel.items prepend, edit resolved")
2067 << listModelSource[i]
2069 "items.insert(0, {\"number\": \"eight\"}); "
2070 "items.get(2).model.number = \"seven\"; }")
2071 << 4 << 5 << 0 << true << false << false << false << true
2072 << QString("number")
2073 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2075 QTest::newRow("ListModel.items prepend with groups")
2076 << listModelSource[i]
2077 << QString("items.insert(0, {\"number\": \"eight\"}, [\"visible\", \"truncheon\"])")
2078 << 4 << 5 << 0 << true << false << true << false << true
2079 << QString("number")
2080 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2082 QTest::newRow("ListModel.items append with groups")
2083 << listModelSource[i]
2084 << QString("items.insert({\"number\": \"eight\"}, [\"visible\", \"selected\"])")
2085 << 4 << 5 << 4 << true << false << true << true << true
2086 << QString("number")
2087 << (QStringList() << "one" << "two" << "three" << "four" << "eight");
2089 QTest::newRow("ListModel.items insert at 2 with groups")
2090 << listModelSource[i]
2091 << QString("items.insert(2, {\"number\": \"eight\"}, \"visible\")")
2092 << 4 << 5 << 2 << true << false << true << false << true
2093 << QString("number")
2094 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2097 QTest::newRow("ListModel.items prepend")
2098 << listModelSource[i]
2099 << QString("items.create(0, {\"number\": \"eight\"})")
2100 << 4 << 5 << 0 << true << true << false << false << true
2101 << QString("number")
2102 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2104 QTest::newRow("ListModel.items append")
2105 << listModelSource[i]
2106 << QString("items.create({\"number\": \"eight\"})")
2107 << 4 << 5 << 4 << true << true << false << false << true
2108 << QString("number")
2109 << (QStringList() << "one" << "two" << "three" << "four" << "eight");
2111 QTest::newRow("ListModel.items create at 2")
2112 << listModelSource[i]
2113 << QString("items.create(2, {\"number\": \"eight\"})")
2114 << 4 << 5 << 2 << true << true << false << false << true
2115 << QString("number")
2116 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2118 QTest::newRow("ListModel.items create at items.get(2)")
2119 << listModelSource[i]
2120 << QString("items.create(items.get(2), {\"number\": \"eight\"})")
2121 << 4 << 5 << 2 << true << true << false << false << true
2122 << QString("number")
2123 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2125 QTest::newRow("ListModel.items create at visibleItems.get(2)")
2126 << listModelSource[i]
2127 << QString("items.create(visibleItems.get(2), {\"number\": \"eight\"})")
2128 << 4 << 5 << 2 << true << true << false << false << true
2129 << QString("number")
2130 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2132 QTest::newRow("ListModel.selectedItems create at items.get(2)")
2133 << listModelSource[i]
2134 << QString("selectedItems.create(items.get(2), {\"number\": \"eight\"})")
2135 << 4 << 5 << 2 << false << true << false << true << true
2136 << QString("number")
2137 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2139 QTest::newRow("ListModel.selectedItems create at visibleItems.get(2)")
2140 << listModelSource[i]
2141 << QString("selectedItems.create(visibleItems.get(2), {\"number\": \"eight\"})")
2142 << 4 << 5 << 2 << false << true << false << true << true
2143 << QString("number")
2144 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2146 QTest::newRow("ListModel.items create prepended")
2147 << listModelSource[i]
2148 << QString("items.create(0, {\"number\": \"eight\"})")
2149 << 4 << 5 << 0 << true << true << false << false << true
2150 << QString("number")
2151 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2153 QTest::newRow("ListModel.items create appended")
2154 << listModelSource[i]
2155 << QString("items.create({\"number\": \"eight\"})")
2156 << 4 << 5 << 4 << true << true << false << false << true
2157 << QString("number")
2158 << (QStringList() << "one" << "two" << "three" << "four" << "eight");
2160 QTest::newRow("ListModel.items create at 2")
2161 << listModelSource[i]
2162 << QString("items.create(2, {\"number\": \"eight\"})")
2163 << 4 << 5 << 2 << true << true << false << false << true
2164 << QString("number")
2165 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2167 QTest::newRow("ListModel.items create at items.get(2)")
2168 << listModelSource[i]
2169 << QString("items.create(items.get(2), {\"number\": \"eight\"})")
2170 << 4 << 5 << 2 << true << true << false << false << true
2171 << QString("number")
2172 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2174 QTest::newRow("ListModel.items create at visibleItems.get(2)")
2175 << listModelSource[i]
2176 << QString("items.create(visibleItems.get(2), {\"number\": \"eight\"})")
2177 << 4 << 5 << 2 << true << true << false << false << true
2178 << QString("number")
2179 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2181 QTest::newRow("ListModel.create prepend modelData")
2182 << listModelSource[i]
2183 << QString("items.create(0, {\"modelData\": \"eight\"})")
2184 << 4 << 5 << 0 << true << true << false << false << true
2185 << QString("number")
2186 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2188 QTest::newRow("ListModel.items create prepended, edit number")
2189 << listModelSource[i]
2191 "var item = items.create(0, {\"number\": \"eight\"}); "
2192 "item.setTest3(\"seven\"); }")
2193 << 4 << 5 << 0 << true << true << false << false << true
2194 << QString("number")
2195 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2197 QTest::newRow("ListModel.items create prepended, edit model.number")
2198 << listModelSource[i]
2200 "var item = items.create(0, {\"number\": \"eight\"}); "
2201 "item.setTest4(\"seven\"); }")
2202 << 4 << 5 << 0 << true << true << false << false << true
2203 << QString("number")
2204 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2206 QTest::newRow("ListModel.items create prepended, edit modelData")
2207 << listModelSource[i]
2209 "var item = items.create(0, {\"number\": \"eight\"}); "
2210 "item.setTest5(\"seven\"); }")
2211 << 4 << 5 << 0 << true << true << false << false << true
2212 << QString("number")
2213 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2215 QTest::newRow("ListModel.items create prepended, edit model.modelData")
2216 << listModelSource[i]
2218 "var item = items.create(0, {\"number\": \"eight\"}); "
2219 "item.setTest6(\"seven\"); }")
2220 << 4 << 5 << 0 << true << true << false << false << true
2221 << QString("number")
2222 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2224 QTest::newRow("ListModel.items create prepended with groups")
2225 << listModelSource[i]
2226 << QString("items.create(0, {\"number\": \"eight\"}, [\"visible\", \"truncheon\"])")
2227 << 4 << 5 << 0 << true << true << true << false << true
2228 << QString("number")
2229 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2231 QTest::newRow("ListModel.items create appended with groups")
2232 << listModelSource[i]
2233 << QString("items.create({\"number\": \"eight\"}, [\"visible\", \"selected\"])")
2234 << 4 << 5 << 4 << true << true << true << true << true
2235 << QString("number")
2236 << (QStringList() << "one" << "two" << "three" << "four" << "eight");
2238 QTest::newRow("ListModel.items create inserted with groups")
2239 << listModelSource[i]
2240 << QString("items.create(2, {\"number\": \"eight\"}, \"visible\")")
2241 << 4 << 5 << 2 << true << true << true << false << true
2242 << QString("number")
2243 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2245 QTest::newRow("ListModel.items create prepended clear persistence")
2246 << listModelSource[i]
2247 << QString("{ items.create(0, {\"number\": \"eight\"}); "
2248 "items.get(0).inPersistedItems = false }")
2249 << 4 << 5 << 0 << true << false << false << false << true
2250 << QString("number")
2251 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2253 QTest::newRow("ListModel.items create appended clear persistence")
2254 << listModelSource[i]
2255 << QString("{ items.create({\"number\": \"eight\"}); "
2256 "items.get(4).inPersistedItems = false }")
2257 << 4 << 5 << 4 << true << false << false << false << true
2258 << QString("number")
2259 << (QStringList() << "one" << "two" << "three" << "four" << "eight");
2261 QTest::newRow("ListModel.items create inserted clear persistence")
2262 << listModelSource[i]
2263 << QString("{ items.create(2, {\"number\": \"eight\"}); "
2264 "items.get(2).inPersistedItems = false }")
2265 << 4 << 5 << 2 << true << false << false << false << true
2266 << QString("number")
2267 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2269 // AbstractItemModel (Single Role).
2270 QTest::newRow("AbstractItemModel.items prepend")
2271 << singleRoleSource[i]
2272 << QString("items.insert(0, {\"name\": \"eight\"})")
2273 << 4 << 5 << 0 << true << false << false << false << true
2275 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2277 QTest::newRow("AbstractItemModel.items append")
2278 << singleRoleSource[i]
2279 << QString("items.insert({\"name\": \"eight\"})")
2280 << 4 << 5 << 4 << true << false << false << false << true
2282 << (QStringList() << "one" << "two" << "three" << "four" << "eight");
2284 QTest::newRow("AbstractItemModel.items insert at 2")
2285 << singleRoleSource[i]
2286 << QString("items.insert(2, {\"name\": \"eight\"})")
2287 << 4 << 5 << 2 << true << false << false << false << true
2289 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2291 QTest::newRow("AbstractItemModel.items prepend modelData")
2292 << singleRoleSource[i]
2293 << QString("items.insert(0, {\"modelData\": \"eight\"})")
2294 << 4 << 5 << 0 << true << false << false << false << true
2296 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2298 QTest::newRow("AbstractItemModel.items prepend, edit name")
2299 << singleRoleSource[i]
2301 "items.insert(0, {\"name\": \"eight\"}); "
2302 "items.get(0).model.name = \"seven\"; }")
2303 << 4 << 5 << 0 << true << false << false << false << true
2305 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2307 QTest::newRow("AbstractItemModel.items prepend, edit modelData")
2308 << singleRoleSource[i]
2310 "items.insert(0, {\"name\": \"eight\"}); "
2311 "items.get(0).model.modelData = \"seven\"; }")
2312 << 4 << 5 << 0 << true << false << false << false << true
2314 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2316 QTest::newRow("AbstractItemModel.items prepend, edit resolved")
2317 << singleRoleSource[i]
2319 "items.insert(0, {\"name\": \"eight\"}); "
2320 "items.get(2).model.name = \"seven\"; }")
2321 << 4 << 5 << 0 << true << false << false << false << true
2323 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2325 QTest::newRow("AbstractItemModel.create prepend modelData")
2326 << singleRoleSource[i]
2327 << QString("items.create(0, {\"modelData\": \"eight\"})")
2328 << 4 << 5 << 0 << true << true << false << false << true
2330 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2332 QTest::newRow("AbstractItemModel.items create prepended, edit name")
2333 << singleRoleSource[i]
2335 "var item = items.create(0, {\"name\": \"eight\"}); "
2336 "item.setTest3(\"seven\"); }")
2337 << 4 << 5 << 0 << true << true << false << false << true
2339 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2341 QTest::newRow("AbstractItemModel.items create prepended, edit model.name")
2342 << singleRoleSource[i]
2344 "var item = items.create(0, {\"name\": \"eight\"}); "
2345 "item.setTest4(\"seven\"); }")
2346 << 4 << 5 << 0 << true << true << false << false << true
2348 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2350 QTest::newRow("AbstractItemModel.items create prepended, edit modelData")
2351 << singleRoleSource[i]
2353 "var item = items.create(0, {\"name\": \"eight\"}); "
2354 "item.setTest5(\"seven\"); }")
2355 << 4 << 5 << 0 << true << true << false << false << true
2357 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2359 QTest::newRow("AbstractItemModel.items create prepended, edit model.modelData")
2360 << singleRoleSource[i]
2362 "var item = items.create(0, {\"name\": \"eight\"}); "
2363 "item.setTest6(\"seven\"); }")
2364 << 4 << 5 << 0 << true << true << false << false << true
2366 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2368 // AbstractItemModel (Multiple Roles).
2369 QTest::newRow("StandardItemModel.items prepend")
2370 << multipleRoleSource[i]
2371 << QString("items.insert(0, {\"display\": \"Row 8 Item\"})")
2372 << 4 << 5 << 0 << true << false << false << false << false
2373 << QString("display")
2374 << (QStringList() << "Row 8 Item" << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2376 QTest::newRow("StandardItemModel.items append")
2377 << multipleRoleSource[i]
2378 << QString("items.insert({\"display\": \"Row 8 Item\"})")
2379 << 4 << 5 << 4 << true << false << false << false << false
2380 << QString("display")
2381 << (QStringList() << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item" << "Row 8 Item");
2383 QTest::newRow("StandardItemModel.items insert at 2")
2384 << multipleRoleSource[i]
2385 << QString("items.insert(2, {\"display\": \"Row 8 Item\"})")
2386 << 4 << 5 << 2 << true << false << false << false << false
2387 << QString("display")
2388 << (QStringList() << "Row 1 Item" << "Row 2 Item" << "Row 8 Item" << "Row 3 Item" << "Row 4 Item");
2390 QTest::newRow("StandardItemModel.items prepend modelData")
2391 << multipleRoleSource[i]
2392 << QString("items.insert(0, {\"modelData\": \"Row 8 Item\"})")
2393 << 4 << 5 << 0 << true << false << false << false << false
2394 << QString("display")
2395 << (QStringList() << QString() << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2397 QTest::newRow("StandardItemModel.items prepend, edit display")
2398 << multipleRoleSource[i]
2400 "items.insert(0, {\"display\": \"Row 8 Item\"}); "
2401 "items.get(0).model.display = \"Row 7 Item\"; }")
2402 << 4 << 5 << 0 << true << false << false << false << false
2403 << QString("display")
2404 << (QStringList() << "Row 7 Item" << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2406 QTest::newRow("StandardItemModel.items prepend, edit modelData")
2407 << multipleRoleSource[i]
2409 "items.insert(0, {\"display\": \"Row 8 Item\"}); "
2410 "items.get(0).model.modelData = \"Row 7 Item\"; }")
2411 << 4 << 5 << 0 << true << false << false << false << false
2412 << QString("display")
2413 << (QStringList() << "Row 8 Item" << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2415 QTest::newRow("StandardItemModel.items prepend, edit resolved")
2416 << multipleRoleSource[i]
2418 "items.insert(0, {\"display\": \"Row 8 Item\"}); "
2419 "items.get(2).model.display = \"Row 7 Item\"; }")
2420 << 4 << 5 << 0 << true << false << false << false << false
2421 << QString("display")
2422 << (QStringList() << "Row 8 Item" << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2424 QTest::newRow("StandardItemModel.create prepend modelData")
2425 << multipleRoleSource[i]
2426 << QString("items.create(0, {\"modelData\": \"Row 8 Item\"})")
2427 << 4 << 5 << 0 << true << true << false << false << false
2428 << QString("display")
2429 << (QStringList() << QString() << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2431 QTest::newRow("StandardItemModel.items create prepended, edit display")
2432 << multipleRoleSource[i]
2434 "var item = items.create(0, {\"display\": \"Row 8 Item\"}); "
2435 "item.setTest3(\"Row 7 Item\"); }")
2436 << 4 << 5 << 0 << true << true << false << false << false
2437 << QString("display")
2438 << (QStringList() << "Row 7 Item" << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2440 QTest::newRow("StandardItemModel.items create prepended, edit model.display")
2441 << multipleRoleSource[i]
2443 "var item = items.create(0, {\"display\": \"Row 8 Item\"}); "
2444 "item.setTest4(\"Row 7 Item\"); }")
2445 << 4 << 5 << 0 << true << true << false << false << false
2446 << QString("display")
2447 << (QStringList() << "Row 7 Item" << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2450 QTest::newRow("StringList.items prepend")
2451 << stringListSource[i]
2452 << QString("items.insert(0, {\"modelData\": \"eight\"})")
2453 << 4 << 5 << 0 << true << false << false << false << false
2454 << QString("modelData")
2455 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2457 QTest::newRow("StringList.items append")
2458 << stringListSource[i]
2459 << QString("items.insert({\"modelData\": \"eight\"})")
2460 << 4 << 5 << 4 << true << false << false << false << false
2461 << QString("modelData")
2462 << (QStringList() << "one" << "two" << "three" << "four" << "eight");
2464 QTest::newRow("StringList.items insert at 2")
2465 << stringListSource[i]
2466 << QString("items.insert(2, {\"modelData\": \"eight\"})")
2467 << 4 << 5 << 2 << true << false << false << false << false
2468 << QString("modelData")
2469 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2471 QTest::newRow("StringList.items prepend, edit modelData")
2472 << stringListSource[i]
2474 "items.insert(0, {\"modelData\": \"eight\"}); "
2475 "items.get(0).model.modelData = \"seven\"; }")
2476 << 4 << 5 << 0 << true << false << false << false << false
2477 << QString("modelData")
2478 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2480 QTest::newRow("StringList.items prepend, edit resolved")
2481 << stringListSource[i]
2483 "items.insert(0, {\"modelData\": \"eight\"}); "
2484 "items.get(2).model.modelData = \"seven\"; }")
2485 << 4 << 5 << 0 << true << false << false << false << false
2486 << QString("modelData")
2487 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2489 QTest::newRow("StringList.create prepend modelData")
2490 << stringListSource[i]
2491 << QString("items.create(0, {\"modelData\": \"eight\"})")
2492 << 4 << 5 << 0 << true << true << false << false << false
2493 << QString("modelData")
2494 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2496 QTest::newRow("StringList.items create prepended, edit modelData")
2497 << stringListSource[i]
2499 "var item = items.create(0, {\"modelData\": \"eight\"}); "
2500 "item.setTest3(\"seven\"); }")
2501 << 4 << 5 << 0 << true << true << false << false << false
2502 << QString("modelData")
2503 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2505 QTest::newRow("StringList.items create prepended, edit model.modelData")
2506 << stringListSource[i]
2508 "var item = items.create(0, {\"modelData\": \"eight\"}); "
2509 "item.setTest4(\"seven\"); }")
2510 << 4 << 5 << 0 << true << true << false << false << false
2511 << QString("modelData")
2512 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2515 QTest::newRow("ObjectList.items prepend")
2516 << objectListSource[i]
2517 << QString("items.insert(0, {\"name\": \"Item 8\"})")
2518 << 4 << 4 << 4 << false << false << false << false << false
2520 << (QStringList() << "Item 1" << "Item 2" << "Item 3" << "Item 4");
2522 QTest::newRow("ObjectList.items append")
2523 << objectListSource[i]
2524 << QString("items.insert({\"name\": \"Item 8\"})")
2525 << 4 << 4 << 4 << false << false << false << false << false
2527 << (QStringList() << "Item 1" << "Item 2" << "Item 3" << "Item 4");
2529 QTest::newRow("ObjectList.items insert at 2")
2530 << objectListSource[i]
2531 << QString("items.insert(2, {\"name\": \"Item 8\"})")
2532 << 4 << 4 << 4 << false << false << false << false << false
2534 << (QStringList() << "Item 1" << "Item 2" << "Item 3" << "Item 4");
2538 void tst_qquickvisualdatamodel::insert()
2540 QFETCH(QUrl, source);
2541 QFETCH(QString, expression);
2542 QFETCH(int, modelCount);
2543 QFETCH(int, visualCount);
2545 QFETCH(bool, inItems);
2546 QFETCH(bool, persisted);
2547 QFETCH(bool, visible);
2548 QFETCH(bool, selected);
2549 QFETCH(bool, modelData);
2550 QFETCH(QString, property);
2551 QFETCH(QStringList, propertyData);
2553 QQuickCanvas canvas;
2555 QDeclarativeComponent component(&engine);
2556 component.loadUrl(source);
2557 QScopedPointer<QObject> object(component.create());
2558 QQuickListView *listView = qobject_cast<QQuickListView *>(object.data());
2560 listView->setParentItem(canvas.rootItem());
2562 QQuickItem *contentItem = listView->contentItem();
2563 QVERIFY(contentItem);
2565 QObject *visualModel = listView->findChild<QObject *>("visualModel");
2566 QVERIFY(visualModel);
2568 evaluate<void>(visualModel, expression);
2570 QCOMPARE(evaluate<int>(listView, "count"), inItems ? visualCount : modelCount);
2571 QCOMPARE(evaluate<int>(visualModel, "count"), inItems ? visualCount : modelCount);
2572 QCOMPARE(evaluate<int>(visualModel, "items.count"), inItems ? visualCount : modelCount);
2573 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), persisted ? 1 : 0);
2574 QCOMPARE(evaluate<int>(visualModel, "visibleItems.count"), visible ? visualCount : modelCount);
2575 QCOMPARE(evaluate<int>(visualModel, "selectedItems.count"), selected ? 1 : 0);
2577 QCOMPARE(propertyData.count(), visualCount);
2578 for (int i = 0; i < visualCount; ++i) {
2580 if (modelIndex > index)
2582 else if (modelIndex == index)
2585 const int itemsIndex = inItems || i <= index ? i : i - 1;
2589 get = QString("items.get(%1)").arg(itemsIndex);
2591 QQuickItem *item = findItem<QQuickItem>(contentItem, "delegate", modelIndex);
2594 QCOMPARE(evaluate<int>(item, "test1"), modelIndex);
2595 QCOMPARE(evaluate<int>(item, "test2"), modelIndex);
2596 QCOMPARE(evaluate<QString>(item, "test3"), propertyData.at(i));
2597 QCOMPARE(evaluate<QString>(item, "test4"), propertyData.at(i));
2600 QCOMPARE(evaluate<QString>(item, "test5"), propertyData.at(i));
2601 QCOMPARE(evaluate<QString>(item, "test6"), propertyData.at(i));
2604 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inItems"), true);
2605 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inPersistedItems"), false);
2606 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inVisible"), true);
2607 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inSelected"), false);
2608 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.isUnresolved"), false);
2610 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.itemsIndex"), itemsIndex);
2611 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.persistedItemsIndex"), persisted && i > index ? 1 : 0);
2612 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.visibleIndex"), visible || i <= index ? i : i - 1);
2613 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.selectedIndex"), selected && i > index ? 1 : 0);
2614 } else if (inItems) {
2615 get = QString("items.get(%1)").arg(index);
2616 } else if (persisted) {
2617 get = "persistedItems.get(0)";
2618 } else if (visible) {
2619 get = QString("visibleItems.get(%1)").arg(index);
2620 } else if (selected) {
2621 get = "selectedItems.get(0)";
2626 QCOMPARE(evaluate<int>(visualModel, get + ".model.index"), modelIndex);
2628 QCOMPARE(evaluate<QString>(visualModel, get + ".model." + property), propertyData.at(i));
2630 QCOMPARE(evaluate<bool>(visualModel, get + ".inItems"), inItems || i != index);
2631 QCOMPARE(evaluate<bool>(visualModel, get + ".inPersistedItems"), persisted && i == index);
2632 QCOMPARE(evaluate<bool>(visualModel, get + ".inVisible"), visible || i != index);
2633 QCOMPARE(evaluate<bool>(visualModel, get + ".inSelected"), selected && i == index);
2634 QCOMPARE(evaluate<bool>(visualModel, get + ".isUnresolved"), i == index);
2636 QCOMPARE(evaluate<int>(visualModel, get + ".itemsIndex"), inItems || i <= index ? i : i - 1);
2637 QCOMPARE(evaluate<int>(visualModel, get + ".persistedItemsIndex"), persisted && i > index ? 1 : 0);
2638 QCOMPARE(evaluate<int>(visualModel, get + ".visibleIndex"), visible || i <= index ? i : i - 1);
2639 QCOMPARE(evaluate<int>(visualModel, get + ".selectedIndex"), selected && i > index ? 1 : 0);
2645 item = evaluate<QObject *>(visualModel, QString("items.create(%1)").arg(index));
2647 item = evaluate<QObject *>(visualModel, QString("persistedItems.create(%1)").arg(0));
2649 item = evaluate<QObject *>(visualModel, QString("visibleItems.create(%1)").arg(index));
2651 item = evaluate<QObject *>(visualModel, QString("selectedItems.create(%1)").arg(0));
2657 QCOMPARE(evaluate<int>(item, "test1"), -1);
2658 QCOMPARE(evaluate<int>(item, "test2"), -1);
2659 QCOMPARE(evaluate<QString>(item, "test3"), propertyData.at(index));
2660 QCOMPARE(evaluate<QString>(item, "test4"), propertyData.at(index));
2663 QCOMPARE(evaluate<QString>(item, "test5"), propertyData.at(index));
2664 QCOMPARE(evaluate<QString>(item, "test6"), propertyData.at(index));
2667 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inItems"), inItems);
2668 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inPersistedItems"), true);
2669 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inVisible"), visible);
2670 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inSelected"), selected);
2671 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.isUnresolved"), true);
2673 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.itemsIndex"), index);
2674 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.persistedItemsIndex"), 0);
2675 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.visibleIndex"), index);
2676 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.selectedIndex"), 0);
2679 void tst_qquickvisualdatamodel::resolve_data()
2681 QTest::addColumn<QUrl>("source");
2682 QTest::addColumn<QString>("setupExpression");
2683 QTest::addColumn<QString>("resolveExpression");
2684 QTest::addColumn<int>("unresolvedCount");
2685 QTest::addColumn<int>("modelCount");
2686 QTest::addColumn<int>("visualCount");
2687 QTest::addColumn<int>("index");
2688 QTest::addColumn<bool>("inItems");
2689 QTest::addColumn<bool>("persisted");
2690 QTest::addColumn<bool>("visible");
2691 QTest::addColumn<bool>("selected");
2692 QTest::addColumn<bool>("modelData");
2693 QTest::addColumn<QString>("property");
2694 QTest::addColumn<QStringList>("propertyData");
2696 const QUrl listModelSource[] = {
2697 testFileUrl("listmodelproperties.qml"),
2698 testFileUrl("listmodelproperties-package.qml") };
2699 const QUrl singleRoleSource[] = {
2700 testFileUrl("singleroleproperties.qml"),
2701 testFileUrl("singleroleproperties-package.qml") };
2702 const QUrl multipleRoleSource[] = {
2703 testFileUrl("multipleroleproperties.qml"),
2704 testFileUrl("multipleroleproperties-package.qml") };
2705 const QUrl stringListSource[] = {
2706 testFileUrl("stringlistproperties.qml"),
2707 testFileUrl("stringlistproperties-package.qml") };
2708 const QUrl objectListSource[] = {
2709 testFileUrl("objectlistproperties.qml"),
2710 testFileUrl("objectlistproperties-package.qml") };
2712 for (int i = 0; i < 2; ++i) {
2714 QTest::newRow("ListModel.items prepend, resolve prepended")
2715 << listModelSource[i]
2716 << QString("items.insert(0, {\"number\": \"eight\"})")
2717 << QString("{ listModel.insert(0, {\"number\": \"seven\"}); items.resolve(0, 1) }")
2718 << 5 << 5 << 5 << 0 << true << false << true << false << true
2719 << QString("number")
2720 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2722 QTest::newRow("ListModel.items prepend, resolve appended")
2723 << listModelSource[i]
2724 << QString("items.insert(0, {\"number\": \"eight\"})")
2725 << QString("{ listModel.append({\"number\": \"seven\"}); items.resolve(0, 5) }")
2726 << 5 << 5 << 5 << 4 << true << false << true << false << true
2727 << QString("number")
2728 << (QStringList() << "one" << "two" << "three" << "four" << "seven");
2730 QTest::newRow("ListModel.items prepend, resolve inserted")
2731 << listModelSource[i]
2732 << QString("items.insert(0, {\"number\": \"eight\"})")
2733 << QString("{ listModel.insert(2, {\"number\": \"seven\"}); items.resolve(0, 3) }")
2734 << 5 << 5 << 5 << 2 << true << false << true << false << true
2735 << QString("number")
2736 << (QStringList() << "one" << "two" << "seven" << "three" << "four");
2738 QTest::newRow("ListModel.items append, resolve prepended")
2739 << listModelSource[i]
2740 << QString("items.insert({\"number\": \"eight\"})")
2741 << QString("{ listModel.insert(0, {\"number\": \"seven\"}); items.resolve(5, 0) }")
2742 << 5 << 5 << 5 << 0 << true << false << true << false << true
2743 << QString("number")
2744 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2746 QTest::newRow("ListModel.items append, resolve appended")
2747 << listModelSource[i]
2748 << QString("items.insert({\"number\": \"eight\"})")
2749 << QString("{ listModel.append({\"number\": \"seven\"}); items.resolve(5, 4) }")
2750 << 5 << 5 << 5 << 4 << true << false << true << false << true
2751 << QString("number")
2752 << (QStringList() << "one" << "two" << "three" << "four" << "seven");
2754 QTest::newRow("ListModel.items append, resolve inserted")
2755 << listModelSource[i]
2756 << QString("items.insert({\"number\": \"eight\"})")
2757 << QString("{ listModel.insert(2, {\"number\": \"seven\"}); items.resolve(5, 2) }")
2758 << 5 << 5 << 5 << 2 << true << false << true << false << true
2759 << QString("number")
2760 << (QStringList() << "one" << "two" << "seven" << "three" << "four");
2762 QTest::newRow("ListModel.items insert, resolve prepended")
2763 << listModelSource[i]
2764 << QString("items.insert(2, {\"number\": \"eight\"})")
2765 << QString("{ listModel.insert(0, {\"number\": \"seven\"}); items.resolve(3, 0) }")
2766 << 5 << 5 << 5 << 0 << true << false << true << false << true
2767 << QString("number")
2768 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2770 QTest::newRow("ListModel.items insert, resolve appended")
2771 << listModelSource[i]
2772 << QString("items.insert(2, {\"number\": \"eight\"})")
2773 << QString("{ listModel.append({\"number\": \"seven\"}); items.resolve(2, 5) }")
2774 << 5 << 5 << 5 << 4 << true << false << true << false << true
2775 << QString("number")
2776 << (QStringList() << "one" << "two" << "three" << "four" << "seven");
2778 QTest::newRow("ListModel.items insert, resolve inserted")
2779 << listModelSource[i]
2780 << QString("items.insert(2, {\"number\": \"eight\"})")
2781 << QString("{ listModel.insert(2, {\"number\": \"seven\"}); items.resolve(2, 3) }")
2782 << 5 << 5 << 5 << 2 << true << false << true << false << true
2783 << QString("number")
2784 << (QStringList() << "one" << "two" << "seven" << "three" << "four");
2786 QTest::newRow("ListModel.items prepend, move resolved")
2787 << listModelSource[i]
2788 << QString("items.insert(0, {\"number\": \"eight\"})")
2789 << QString("{ listModel.insert(0, {\"number\": \"seven\"}); "
2790 "items.resolve(0, 1); "
2791 "listModel.move(0, 2, 1) }")
2792 << 5 << 5 << 5 << 2 << true << false << true << false << true
2793 << QString("number")
2794 << (QStringList() << "one" << "two" << "seven" << "three" << "four");
2796 QTest::newRow("ListModel.items append, move resolved")
2797 << listModelSource[i]
2798 << QString("items.insert({\"number\": \"eight\"})")
2799 << QString("{ listModel.append({\"number\": \"seven\"}); "
2800 "items.resolve(5, 4); "
2801 "listModel.move(4, 2, 1) }")
2802 << 5 << 5 << 5 << 2 << true << false << true << false << true
2803 << QString("number")
2804 << (QStringList() << "one" << "two" << "seven" << "three" << "four");
2806 QTest::newRow("ListModel.items insert, move resolved")
2807 << listModelSource[i]
2808 << QString("items.insert(2, {\"number\": \"eight\"})")
2809 << QString("{ listModel.insert(2, {\"number\": \"seven\"}); "
2810 "items.resolve(2, 3);"
2811 "listModel.move(2, 0, 1) }")
2812 << 5 << 5 << 5 << 0 << true << false << true << false << true
2813 << QString("number")
2814 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2816 QTest::newRow("ListModel.items prepend, remove resolved")
2817 << listModelSource[i]
2818 << QString("items.insert(0, {\"number\": \"eight\"})")
2819 << QString("{ listModel.insert(0, {\"number\": \"seven\"}); "
2820 "items.resolve(0, 1); "
2821 "listModel.remove(0, 1) }")
2822 << 5 << 4 << 4 << 4 << false << false << false << false << true
2823 << QString("number")
2824 << (QStringList() << "one" << "two" << "three" << "four");
2826 QTest::newRow("ListModel.items append, remove resolved")
2827 << listModelSource[i]
2828 << QString("items.insert({\"number\": \"eight\"})")
2829 << QString("{ listModel.append({\"number\": \"seven\"}); "
2830 "items.resolve(5, 4); "
2831 "listModel.remove(4, 1) }")
2832 << 5 << 4 << 4 << 4 << false << false << false << false << true
2833 << QString("number")
2834 << (QStringList() << "one" << "two" << "three" << "four");
2836 QTest::newRow("ListModel.items insert, remove resolved")
2837 << listModelSource[i]
2838 << QString("items.insert(2, {\"number\": \"eight\"})")
2839 << QString("{ listModel.insert(2, {\"number\": \"seven\"}); "
2840 "items.resolve(2, 3);"
2841 "listModel.remove(2, 1) }")
2842 << 5 << 4 << 4 << 4 << false << false << false << false << true
2843 << QString("number")
2844 << (QStringList() << "one" << "two" << "three" << "four");
2846 QTest::newRow("ListModel.selectedItems prepend, resolve prepended")
2847 << listModelSource[i]
2848 << QString("selectedItems.insert(0, {\"number\": \"eight\"})")
2849 << QString("{ listModel.insert(0, {\"number\": \"seven\"}); "
2850 "selectedItems.resolve(selectedItems.get(0), items.get(0)) }")
2851 << 4 << 5 << 5 << 0 << true << false << true << true << true
2852 << QString("number")
2853 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2855 QTest::newRow("ListModel.selectedItems prepend, resolve appended")
2856 << listModelSource[i]
2857 << QString("selectedItems.insert(0, {\"number\": \"eight\"})")
2858 << QString("{ listModel.append({\"number\": \"seven\"}); "
2859 "selectedItems.resolve(selectedItems.get(0), items.get(4)) }")
2860 << 4 << 5 << 5 << 4 << true << false << true << true << true
2861 << QString("number")
2862 << (QStringList() << "one" << "two" << "three" << "four" << "seven");
2864 QTest::newRow("ListModel.selectedItems prepend, resolve inserted")
2865 << listModelSource[i]
2866 << QString("selectedItems.insert(0, {\"number\": \"eight\"})")
2867 << QString("{ listModel.insert(2, {\"number\": \"seven\"}); "
2868 "selectedItems.resolve(selectedItems.get(0), items.get(2)) }")
2869 << 4 << 5 << 5 << 2 << true << false << true << true << true
2870 << QString("number")
2871 << (QStringList() << "one" << "two" << "seven" << "three" << "four");
2873 QTest::newRow("ListModel.selectedItems append, resolve prepended")
2874 << listModelSource[i]
2875 << QString("selectedItems.insert({\"number\": \"eight\"})")
2876 << QString("{ listModel.insert(0, {\"number\": \"seven\"}); "
2877 "selectedItems.resolve(selectedItems.get(0), items.get(0)) }")
2878 << 4 << 5 << 5 << 0 << true << false << true << true << true
2879 << QString("number")
2880 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2882 QTest::newRow("ListModel.selectedItems append, resolve appended")
2883 << listModelSource[i]
2884 << QString("selectedItems.insert({\"number\": \"eight\"})")
2885 << QString("{ listModel.append({\"number\": \"seven\"}); "
2886 "selectedItems.resolve(selectedItems.get(0), items.get(4)) }")
2887 << 4 << 5 << 5 << 4 << true << false << true << true << true
2888 << QString("number")
2889 << (QStringList() << "one" << "two" << "three" << "four" << "seven");
2891 QTest::newRow("ListModel.selectedItems append, resolve inserted")
2892 << listModelSource[i]
2893 << QString("selectedItems.insert({\"number\": \"eight\"})")
2894 << QString("{ listModel.insert(2, {\"number\": \"seven\"}); "
2895 "selectedItems.resolve(selectedItems.get(0), items.get(2)) }")
2896 << 4 << 5 << 5 << 2 << true << false << true << true << true
2897 << QString("number")
2898 << (QStringList() << "one" << "two" << "seven" << "three" << "four");
2900 // AbstractItemModel (Single Role)
2901 QTest::newRow("ListModel.items prepend, resolve prepended")
2902 << singleRoleSource[i]
2903 << QString("items.insert(0, {\"name\": \"eight\"})")
2904 << QString("{ items.resolve(0, 1) }")
2905 << 5 << 4 << 4 << 0 << true << false << true << false << true
2907 << (QStringList() << "one" << "two" << "three" << "four");
2910 QTest::newRow("ListModel.items append, resolve appended")
2911 << singleRoleSource[i]
2912 << QString("items.insert({\"name\": \"eight\"})")
2913 << QString("{ items.resolve(4, 3) }")
2914 << 5 << 4 << 4 << 3 << true << false << true << false << true
2916 << (QStringList() << "one" << "two" << "three" << "four");
2918 QTest::newRow("ListModel.items insert, resolve inserted")
2919 << singleRoleSource[i]
2920 << QString("items.insert(2, {\"name\": \"eight\"})")
2921 << QString("{ items.resolve(2, 3) }")
2922 << 5 << 4 << 4 << 2 << true << false << true << false << true
2924 << (QStringList() << "one" << "two" << "three" << "four");
2926 // AbstractItemModel (Single Role)
2927 QTest::newRow("AbstractItemModel.items prepend, resolve prepended")
2928 << singleRoleSource[i]
2929 << QString("items.insert(0, {\"name\": \"eight\"})")
2930 << QString("{ items.resolve(0, 1) }")
2931 << 5 << 4 << 4 << 0 << true << false << true << false << true
2933 << (QStringList() << "one" << "two" << "three" << "four");
2935 QTest::newRow("AbstractItemModel.items append, resolve appended")
2936 << singleRoleSource[i]
2937 << QString("items.insert({\"name\": \"eight\"})")
2938 << QString("{ items.resolve(4, 3) }")
2939 << 5 << 4 << 4 << 3 << true << false << true << false << true
2941 << (QStringList() << "one" << "two" << "three" << "four");
2943 QTest::newRow("AbstractItemModel.items insert, resolve inserted")
2944 << singleRoleSource[i]
2945 << QString("items.insert(2, {\"name\": \"eight\"})")
2946 << QString("{ items.resolve(2, 3) }")
2947 << 5 << 4 << 4 << 2 << true << false << true << false << true
2949 << (QStringList() << "one" << "two" << "three" << "four");
2951 // AbstractItemModel (Multiple Roles)
2952 QTest::newRow("StandardItemModel.items prepend, resolve prepended")
2953 << multipleRoleSource[i]
2954 << QString("items.insert(0, {\"display\": \"Row 8 Item\"})")
2955 << QString("{ items.resolve(0, 1) }")
2956 << 5 << 4 << 4 << 0 << true << false << true << false << false
2957 << QString("display")
2958 << (QStringList() << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2960 QTest::newRow("StandardItemModel.items append, resolve appended")
2961 << multipleRoleSource[i]
2962 << QString("items.insert({\"display\": \"Row 8 Item\"})")
2963 << QString("{ items.resolve(4, 3) }")
2964 << 5 << 4 << 4 << 3 << true << false << true << false << false
2965 << QString("display")
2966 << (QStringList() << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2968 QTest::newRow("StandardItemModel.items insert, resolve inserted")
2969 << multipleRoleSource[i]
2970 << QString("items.insert(2, {\"display\": \"Row 8 Item\"})")
2971 << QString("{ items.resolve(2, 3) }")
2972 << 5 << 4 << 4 << 2 << true << false << true << false << false
2973 << QString("display")
2974 << (QStringList() << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2977 QTest::newRow("StringList.items prepend, resolve prepended")
2978 << stringListSource[i]
2979 << QString("items.insert(0, {\"modelData\": \"eight\"})")
2980 << QString("{ items.resolve(0, 1) }")
2981 << 5 << 4 << 4 << 0 << true << false << true << false << false
2982 << QString("modelData")
2983 << (QStringList() << "one" << "two" << "three" << "four");
2985 QTest::newRow("StringList.items append, resolve appended")
2986 << stringListSource[i]
2987 << QString("items.insert({\"modelData\": \"eight\"})")
2988 << QString("{ items.resolve(4, 3) }")
2989 << 5 << 4 << 4 << 3 << true << false << true << false << false
2990 << QString("modelData")
2991 << (QStringList() << "one" << "two" << "three" << "four");
2993 QTest::newRow("StringList.items insert, resolve inserted")
2994 << stringListSource[i]
2995 << QString("items.insert(2, {\"modelData\": \"eight\"})")
2996 << QString("{ items.resolve(2, 3) }")
2997 << 5 << 4 << 4 << 2 << true << false << true << false << false
2998 << QString("modelData")
2999 << (QStringList() << "one" << "two" << "three" << "four");
3003 void tst_qquickvisualdatamodel::resolve()
3005 QFETCH(QUrl, source);
3006 QFETCH(QString, setupExpression);
3007 QFETCH(QString, resolveExpression);
3008 QFETCH(int, unresolvedCount);
3009 QFETCH(int, modelCount);
3010 QFETCH(int, visualCount);
3012 QFETCH(bool, inItems);
3013 QFETCH(bool, persisted);
3014 QFETCH(bool, visible);
3015 QFETCH(bool, selected);
3016 QFETCH(bool, modelData);
3017 QFETCH(QString, property);
3018 QFETCH(QStringList, propertyData);
3020 QQuickCanvas canvas;
3022 QDeclarativeComponent component(&engine);
3023 component.loadUrl(source);
3024 QScopedPointer<QObject> object(component.create());
3025 QQuickListView *listView = qobject_cast<QQuickListView *>(object.data());
3027 listView->setParentItem(canvas.rootItem());
3029 QQuickItem *contentItem = listView->contentItem();
3030 QVERIFY(contentItem);
3032 QObject *visualModel = listView->findChild<QObject *>("visualModel");
3033 QVERIFY(visualModel);
3035 evaluate<void>(visualModel, setupExpression);
3036 QCOMPARE(evaluate<int>(listView, "count"), unresolvedCount);
3038 evaluate<void>(visualModel, resolveExpression);
3040 QCOMPARE(evaluate<int>(listView, "count"), inItems ? visualCount : modelCount);
3041 QCOMPARE(evaluate<int>(visualModel, "count"), inItems ? visualCount : modelCount);
3042 QCOMPARE(evaluate<int>(visualModel, "items.count"), inItems ? visualCount : modelCount);
3043 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), persisted ? 1 : 0);
3044 QCOMPARE(evaluate<int>(visualModel, "visibleItems.count"), visible ? visualCount : modelCount);
3045 QCOMPARE(evaluate<int>(visualModel, "selectedItems.count"), selected ? 1 : 0);
3047 QCOMPARE(propertyData.count(), visualCount);
3048 for (int i = 0; i < visualCount; ++i) {
3051 const int itemsIndex = inItems || i <= index ? i : i - 1;
3055 get = QString("items.get(%1)").arg(itemsIndex);
3057 QQuickItem *item = findItem<QQuickItem>(contentItem, "delegate", modelIndex);
3060 QCOMPARE(evaluate<int>(item, "test1"), modelIndex);
3061 QCOMPARE(evaluate<int>(item, "test2"), modelIndex);
3062 QCOMPARE(evaluate<QString>(item, "test3"), propertyData.at(i));
3063 QCOMPARE(evaluate<QString>(item, "test4"), propertyData.at(i));
3066 QCOMPARE(evaluate<QString>(item, "test5"), propertyData.at(i));
3067 QCOMPARE(evaluate<QString>(item, "test6"), propertyData.at(i));
3070 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inItems"), true);
3071 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inPersistedItems"), false);
3072 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inVisible"), true);
3073 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inSelected"), false);
3074 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.isUnresolved"), false);
3076 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.itemsIndex"), itemsIndex);
3077 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.persistedItemsIndex"), persisted && i > index ? 1 : 0);
3078 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.visibleIndex"), visible || i <= index ? i : i - 1);
3079 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.selectedIndex"), selected && i > index ? 1 : 0);
3080 } else if (inItems) {
3081 get = QString("items.get(%1)").arg(index);
3082 } else if (persisted) {
3083 get = "persistedItems.get(0)";
3084 } else if (visible) {
3085 get = QString("visibleItems.get(%1)").arg(index);
3086 } else if (selected) {
3087 get = "selectedItems.get(0)";
3092 QCOMPARE(evaluate<int>(visualModel, get + ".model.index"), modelIndex);
3094 QCOMPARE(evaluate<QString>(visualModel, get + ".model." + property), propertyData.at(i));
3096 QCOMPARE(evaluate<bool>(visualModel, get + ".inItems"), inItems || i != index);
3097 QCOMPARE(evaluate<bool>(visualModel, get + ".inPersistedItems"), persisted && i == index);
3098 QCOMPARE(evaluate<bool>(visualModel, get + ".inVisible"), visible || i != index);
3099 QCOMPARE(evaluate<bool>(visualModel, get + ".inSelected"), selected && i == index);
3100 QCOMPARE(evaluate<bool>(visualModel, get + ".isUnresolved"), false);
3102 QCOMPARE(evaluate<int>(visualModel, get + ".itemsIndex"), inItems || i <= index ? i : i - 1);
3103 QCOMPARE(evaluate<int>(visualModel, get + ".persistedItemsIndex"), persisted && i > index ? 1 : 0);
3104 QCOMPARE(evaluate<int>(visualModel, get + ".visibleIndex"), visible || i <= index ? i : i - 1);
3105 QCOMPARE(evaluate<int>(visualModel, get + ".selectedIndex"), selected && i > index ? 1 : 0);
3111 item = evaluate<QObject *>(visualModel, QString("items.create(%1)").arg(index));
3113 item = evaluate<QObject *>(visualModel, QString("persistedItems.create(%1)").arg(0));
3115 item = evaluate<QObject *>(visualModel, QString("visibleItems.create(%1)").arg(index));
3117 item = evaluate<QObject *>(visualModel, QString("selectedItems.create(%1)").arg(0));
3123 QCOMPARE(evaluate<int>(item, "test1"), index);
3124 QCOMPARE(evaluate<int>(item, "test2"), index);
3125 QCOMPARE(evaluate<QString>(item, "test3"), propertyData.at(index));
3126 QCOMPARE(evaluate<QString>(item, "test4"), propertyData.at(index));
3129 QCOMPARE(evaluate<QString>(item, "test5"), propertyData.at(index));
3130 QCOMPARE(evaluate<QString>(item, "test6"), propertyData.at(index));
3133 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inItems"), inItems);
3134 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inPersistedItems"), true);
3135 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inVisible"), visible);
3136 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inSelected"), selected);
3137 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.isUnresolved"), false);
3139 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.itemsIndex"), index);
3140 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.persistedItemsIndex"), 0);
3141 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.visibleIndex"), index);
3142 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.selectedIndex"), 0);
3145 void tst_qquickvisualdatamodel::warnings_data()
3147 QTest::addColumn<QUrl>("source");
3148 QTest::addColumn<QString>("expression");
3149 QTest::addColumn<QString>("warning");
3150 QTest::addColumn<int>("count");
3152 QTest::newRow("insert < 0")
3153 << testFileUrl("listmodelproperties.qml")
3154 << QString("items.insert(-2, {\"number\": \"eight\"})")
3155 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("insert: index out of range"))
3158 QTest::newRow("insert > length")
3159 << testFileUrl("listmodelproperties.qml")
3160 << QString("items.insert(8, {\"number\": \"eight\"})")
3161 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("insert: index out of range"))
3164 QTest::newRow("create < 0")
3165 << testFileUrl("listmodelproperties.qml")
3166 << QString("items.create(-2, {\"number\": \"eight\"})")
3167 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("create: index out of range"))
3170 QTest::newRow("create > length")
3171 << testFileUrl("listmodelproperties.qml")
3172 << QString("items.create(8, {\"number\": \"eight\"})")
3173 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("create: index out of range"))
3176 QTest::newRow("resolve from < 0")
3177 << testFileUrl("listmodelproperties.qml")
3178 << QString("items.resolve(-2, 3)")
3179 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: from index out of range"))
3182 QTest::newRow("resolve from > length")
3183 << testFileUrl("listmodelproperties.qml")
3184 << QString("items.resolve(8, 3)")
3185 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: from index out of range"))
3188 QTest::newRow("resolve to < 0")
3189 << testFileUrl("listmodelproperties.qml")
3190 << QString("items.resolve(3, -2)")
3191 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: to index out of range"))
3194 QTest::newRow("resolve to > length")
3195 << testFileUrl("listmodelproperties.qml")
3196 << QString("items.resolve(3, 8)")
3197 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: to index out of range"))
3200 QTest::newRow("resolve from invalid index")
3201 << testFileUrl("listmodelproperties.qml")
3202 << QString("items.resolve(\"two\", 3)")
3203 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: from index invalid"))
3206 QTest::newRow("resolve to invalid index")
3207 << testFileUrl("listmodelproperties.qml")
3208 << QString("items.resolve(3, \"two\")")
3209 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: to index invalid"))
3212 QTest::newRow("resolve already resolved item")
3213 << testFileUrl("listmodelproperties.qml")
3214 << QString("items.resolve(3, 2)")
3215 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: from is not an unresolved item"))
3218 QTest::newRow("resolve already resolved item")
3219 << testFileUrl("listmodelproperties.qml")
3220 << QString("{ items.insert(0, {\"number\": \"eight\"});"
3221 "items.insert(1, {\"number\": \"seven\"});"
3222 "items.resolve(0, 1)}")
3223 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: to is not a model item"))
3226 QTest::newRow("remove index < 0")
3227 << testFileUrl("listmodelproperties.qml")
3228 << QString("items.remove(-2, 1)")
3229 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("remove: index out of range"))
3232 QTest::newRow("remove index == length")
3233 << testFileUrl("listmodelproperties.qml")
3234 << QString("items.remove(4, 1)")
3235 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("remove: index out of range"))
3238 QTest::newRow("remove index > length")
3239 << testFileUrl("listmodelproperties.qml")
3240 << QString("items.remove(9, 1)")
3241 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("remove: index out of range"))
3244 QTest::newRow("remove invalid index")
3245 << testFileUrl("listmodelproperties.qml")
3246 << QString("items.remove(\"nine\", 1)")
3247 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("remove: invalid index"))
3250 QTest::newRow("remove count < 0")
3251 << testFileUrl("listmodelproperties.qml")
3252 << QString("items.remove(1, -2)")
3253 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("remove: invalid count"))
3256 QTest::newRow("remove index + count > length")
3257 << testFileUrl("listmodelproperties.qml")
3258 << QString("items.remove(2, 4, \"selected\")")
3259 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("remove: invalid count"))
3262 QTest::newRow("addGroups index < 0")
3263 << testFileUrl("listmodelproperties.qml")
3264 << QString("items.addGroups(-2, 1, \"selected\")")
3265 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("addGroups: index out of range"))
3268 QTest::newRow("addGroups index == length")
3269 << testFileUrl("listmodelproperties.qml")
3270 << QString("items.addGroups(4, 1, \"selected\")")
3271 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("addGroups: index out of range"))
3274 QTest::newRow("addGroups index > length")
3275 << testFileUrl("listmodelproperties.qml")
3276 << QString("items.addGroups(9, 1, \"selected\")")
3277 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("addGroups: index out of range"))
3280 QTest::newRow("addGroups count < 0")
3281 << testFileUrl("listmodelproperties.qml")
3282 << QString("items.addGroups(1, -2, \"selected\")")
3283 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("addGroups: invalid count"))
3286 QTest::newRow("addGroups index + count > length")
3287 << testFileUrl("listmodelproperties.qml")
3288 << QString("items.addGroups(2, 4, \"selected\")")
3289 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("addGroups: invalid count"))
3292 QTest::newRow("removeGroups index < 0")
3293 << testFileUrl("listmodelproperties.qml")
3294 << QString("items.removeGroups(-2, 1, \"selected\")")
3295 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("removeGroups: index out of range"))
3298 QTest::newRow("removeGroups index == length")
3299 << testFileUrl("listmodelproperties.qml")
3300 << QString("items.removeGroups(4, 1, \"selected\")")
3301 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("removeGroups: index out of range"))
3304 QTest::newRow("removeGroups index > length")
3305 << testFileUrl("listmodelproperties.qml")
3306 << QString("items.removeGroups(9, 1, \"selected\")")
3307 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("removeGroups: index out of range"))
3310 QTest::newRow("removeGroups count < 0")
3311 << testFileUrl("listmodelproperties.qml")
3312 << QString("items.removeGroups(1, -2, \"selected\")")
3313 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("removeGroups: invalid count"))
3316 QTest::newRow("removeGroups index + count > length")
3317 << testFileUrl("listmodelproperties.qml")
3318 << QString("items.removeGroups(2, 4, \"selected\")")
3319 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("removeGroups: invalid count"))
3322 QTest::newRow("setGroups index < 0")
3323 << testFileUrl("listmodelproperties.qml")
3324 << QString("items.setGroups(-2, 1, \"selected\")")
3325 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("setGroups: index out of range"))
3328 QTest::newRow("setGroups index == length")
3329 << testFileUrl("listmodelproperties.qml")
3330 << QString("items.setGroups(4, 1, \"selected\")")
3331 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("setGroups: index out of range"))
3334 QTest::newRow("setGroups index > length")
3335 << testFileUrl("listmodelproperties.qml")
3336 << QString("items.setGroups(9, 1, \"selected\")")
3337 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("setGroups: index out of range"))
3340 QTest::newRow("setGroups count < 0")
3341 << testFileUrl("listmodelproperties.qml")
3342 << QString("items.setGroups(1, -2, \"selected\")")
3343 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("setGroups: invalid count"))
3346 QTest::newRow("setGroups index + count > length")
3347 << testFileUrl("listmodelproperties.qml")
3348 << QString("items.setGroups(2, 4, \"selected\")")
3349 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("setGroups: invalid count"))
3352 QTest::newRow("move from < 0")
3353 << testFileUrl("listmodelproperties.qml")
3354 << QString("items.move(-2, 1, 1)")
3355 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: from index out of range"))
3358 QTest::newRow("move from == length")
3359 << testFileUrl("listmodelproperties.qml")
3360 << QString("items.move(4, 1, 1)")
3361 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: from index out of range"))
3364 QTest::newRow("move from > length")
3365 << testFileUrl("listmodelproperties.qml")
3366 << QString("items.move(9, 1, 1)")
3367 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: from index out of range"))
3370 QTest::newRow("move invalid from")
3371 << testFileUrl("listmodelproperties.qml")
3372 << QString("items.move(\"nine\", 1, 1)")
3373 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: invalid from index"))
3376 QTest::newRow("move to < 0")
3377 << testFileUrl("listmodelproperties.qml")
3378 << QString("items.move(1, -2, 1)")
3379 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: to index out of range"))
3382 QTest::newRow("move to == length")
3383 << testFileUrl("listmodelproperties.qml")
3384 << QString("items.move(1, 4, 1)")
3385 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: to index out of range"))
3388 QTest::newRow("move to > length")
3389 << testFileUrl("listmodelproperties.qml")
3390 << QString("items.move(1, 9, 1)")
3391 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: to index out of range"))
3394 QTest::newRow("move invalid to")
3395 << testFileUrl("listmodelproperties.qml")
3396 << QString("items.move(1, \"nine\", 1)")
3397 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: invalid to index"))
3400 QTest::newRow("move count < 0")
3401 << testFileUrl("listmodelproperties.qml")
3402 << QString("items.move(1, 1, -2)")
3403 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: invalid count"))
3406 QTest::newRow("move from + count > length")
3407 << testFileUrl("listmodelproperties.qml")
3408 << QString("items.move(2, 1, 4)")
3409 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: from index out of range"))
3413 void tst_qquickvisualdatamodel::warnings()
3415 QFETCH(QUrl, source);
3416 QFETCH(QString, expression);
3417 QFETCH(QString, warning);
3420 QQuickCanvas canvas;
3422 QDeclarativeComponent component(&engine);
3423 component.loadUrl(source);
3424 QScopedPointer<QObject> object(component.create());
3425 QQuickListView *listView = qobject_cast<QQuickListView *>(object.data());
3427 listView->setParentItem(canvas.rootItem());
3429 QQuickItem *contentItem = listView->contentItem();
3430 QVERIFY(contentItem);
3432 QObject *visualModel = evaluate<QObject *>(listView, "model");
3433 QVERIFY(visualModel);
3435 QTest::ignoreMessage(QtWarningMsg, warning.toUtf8());
3437 evaluate<void>(visualModel, expression);
3438 QCOMPARE(evaluate<int>(listView, "count"), count);
3441 template<typename T>
3442 T *tst_qquickvisualdatamodel::findItem(QQuickItem *parent, const QString &objectName, int index)
3444 const QMetaObject &mo = T::staticMetaObject;
3445 //qDebug() << parent->childItems().count() << "children";
3446 for (int i = 0; i < parent->childItems().count(); ++i) {
3447 QQuickItem *item = qobject_cast<QQuickItem*>(parent->childItems().at(i));
3450 //qDebug() << "try" << item;
3451 if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
3453 QDeclarativeExpression e(qmlContext(item), item, "index");
3454 if (e.evaluate().toInt() == index)
3455 return static_cast<T*>(item);
3457 return static_cast<T*>(item);
3460 item = findItem<T>(item, objectName, index);
3462 return static_cast<T*>(item);
3468 QTEST_MAIN(tst_qquickvisualdatamodel)
3470 #include "tst_qquickvisualdatamodel.moc"