1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the test suite of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
41 #include "../../shared/util.h"
42 #include "../shared/visualtestutil.h"
45 #include <QtTest/QSignalSpy>
46 #include <QStandardItemModel>
47 #include <QtDeclarative/qdeclarativeengine.h>
48 #include <QtDeclarative/qdeclarativecomponent.h>
49 #include <QtDeclarative/qdeclarativecontext.h>
50 #include <QtDeclarative/qdeclarativeexpression.h>
51 #include <QtQuick/qquickview.h>
52 #include <private/qquicklistview_p.h>
53 #include <QtQuick/private/qquicktext_p.h>
54 #include <QtQuick/private/qquickvisualdatamodel_p.h>
55 #include <private/qdeclarativevaluetype_p.h>
56 #include <private/qdeclarativechangeset_p.h>
57 #include <private/qdeclarativeengine_p.h>
60 using namespace QQuickVisualTestUtil;
62 template <typename T, int N> int lengthOf(const T (&)[N]) { return N; }
64 static void initStandardTreeModel(QStandardItemModel *model)
67 item = new QStandardItem(QLatin1String("Row 1 Item"));
68 model->insertRow(0, item);
70 item = new QStandardItem(QLatin1String("Row 2 Item"));
71 item->setCheckable(true);
72 model->insertRow(1, item);
74 QStandardItem *childItem = new QStandardItem(QLatin1String("Row 2 Child Item"));
75 item->setChild(0, childItem);
77 item = new QStandardItem(QLatin1String("Row 3 Item"));
78 item->setIcon(QIcon());
79 model->insertRow(2, item);
82 class SingleRoleModel : public QAbstractListModel
85 Q_PROPERTY(QStringList values WRITE setList)
87 SingleRoleModel(const QByteArray &role = "name", QObject *parent = 0)
88 : QAbstractListModel(parent)
90 QHash<int, QByteArray> roles;
91 roles.insert(Qt::DisplayRole , role);
93 list << "one" << "two" << "three" << "four";
96 void emitMove(int sourceFirst, int sourceLast, int destinationChild) {
97 emit beginMoveRows(QModelIndex(), sourceFirst, sourceLast, QModelIndex(), destinationChild);
103 void setList(const QStringList &l) { list = l; }
106 void set(int idx, QString string) {
108 emit dataChanged(index(idx,0), index(idx,0));
112 int rowCount(const QModelIndex & /* parent */ = QModelIndex()) const {
115 QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const {
116 if (role == Qt::DisplayRole)
117 return list.at(index.row());
122 class StandardItem : public QObject, public QStandardItem
125 Q_PROPERTY(QString text WRITE setText)
128 void writeText(const QString &text) { setText(text); }
131 class StandardItemModel : public QStandardItemModel
134 Q_PROPERTY(QDeclarativeListProperty<StandardItem> items READ items CONSTANT)
135 Q_CLASSINFO("DefaultProperty", "items")
137 QDeclarativeListProperty<StandardItem> items() { return QDeclarativeListProperty<StandardItem>(this, 0, append); }
139 static void append(QDeclarativeListProperty<StandardItem> *property, StandardItem *item)
141 static_cast<QStandardItemModel *>(property->object)->appendRow(item);
145 class DataObject : public QObject
149 Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
150 Q_PROPERTY(QString color READ color WRITE setColor NOTIFY colorChanged)
153 DataObject(QObject *parent=0) : QObject(parent) {}
154 DataObject(const QString &name, const QString &color, QObject *parent=0)
155 : QObject(parent), m_name(name), m_color(color) { }
158 QString name() const { return m_name; }
159 void setName(const QString &name) {
160 if (name != m_name) {
166 QString color() const { return m_color; }
167 void setColor(const QString &color) {
168 if (color != m_color) {
183 QML_DECLARE_TYPE(SingleRoleModel)
184 QML_DECLARE_TYPE(StandardItem)
185 QML_DECLARE_TYPE(StandardItemModel)
186 QML_DECLARE_TYPE(DataObject)
188 class tst_qquickvisualdatamodel : public QDeclarativeDataTest
192 tst_qquickvisualdatamodel();
196 void cleanupTestCase();
198 void updateLayout_data();
200 void childChanged_data();
202 void objectListModel();
204 void modelProperties();
205 void noDelegate_data();
207 void itemsDestroyed_data();
208 void itemsDestroyed();
209 void packagesDestroyed();
210 void qaimRowsMoved();
211 void qaimRowsMoved_data();
218 void invalidGroups();
220 void onChanged_data();
223 void incompleteModel();
228 void warnings_data();
232 template <int N> void groups_verify(
233 const SingleRoleModel &model,
234 QQuickItem *contentItem,
235 const int (&mIndex)[N],
236 const int (&iIndex)[N],
237 const int (&vIndex)[N],
238 const int (&sIndex)[N],
239 const bool (&vMember)[N],
240 const bool (&sMember)[N]);
242 template <int N> void get_verify(
243 const SingleRoleModel &model,
244 QQuickVisualDataModel *visualModel,
245 QQuickVisualDataGroup *visibleItems,
246 QQuickVisualDataGroup *selectedItems,
247 const int (&mIndex)[N],
248 const int (&iIndex)[N],
249 const int (&vIndex)[N],
250 const int (&sIndex)[N],
251 const bool (&vMember)[N],
252 const bool (&sMember)[N]);
255 QDeclarativeEngine engine;
258 Q_DECLARE_METATYPE(QDeclarativeChangeSet)
260 template <typename T> static T evaluate(QObject *scope, const QString &expression)
262 QDeclarativeExpression expr(qmlContext(scope), scope, expression);
263 T result = expr.evaluate().value<T>();
265 qWarning() << expr.error().toString();
269 template <> void evaluate<void>(QObject *scope, const QString &expression)
271 QDeclarativeExpression expr(qmlContext(scope), scope, expression);
274 qWarning() << expr.error().toString();
277 void tst_qquickvisualdatamodel::initTestCase()
279 QDeclarativeDataTest::initTestCase();
280 qRegisterMetaType<QDeclarativeChangeSet>();
282 qmlRegisterType<SingleRoleModel>("tst_qquickvisualdatamodel", 1, 0, "SingleRoleModel");
283 qmlRegisterType<StandardItem>("tst_qquickvisualdatamodel", 1, 0, "StandardItem");
284 qmlRegisterType<StandardItemModel>("tst_qquickvisualdatamodel", 1, 0, "StandardItemModel");
285 qmlRegisterType<DataObject>("tst_qquickvisualdatamodel", 1, 0, "DataObject");
288 void tst_qquickvisualdatamodel::cleanupTestCase()
293 tst_qquickvisualdatamodel::tst_qquickvisualdatamodel()
297 void tst_qquickvisualdatamodel::rootIndex()
299 QDeclarativeEngine engine;
300 QDeclarativeComponent c(&engine, testFileUrl("visualdatamodel.qml"));
302 QStandardItemModel model;
303 initStandardTreeModel(&model);
305 engine.rootContext()->setContextProperty("myModel", &model);
307 QQuickVisualDataModel *obj = qobject_cast<QQuickVisualDataModel*>(c.create());
310 QMetaObject::invokeMethod(obj, "setRoot");
311 QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == model.index(0,0));
313 QMetaObject::invokeMethod(obj, "setRootToParent");
314 QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == QModelIndex());
316 QMetaObject::invokeMethod(obj, "setRoot");
317 QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == model.index(0,0));
318 model.clear(); // will emit modelReset()
319 QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == QModelIndex());
324 void tst_qquickvisualdatamodel::updateLayout_data()
326 QTest::addColumn<QUrl>("source");
328 QTest::newRow("item delegate") << testFileUrl("datalist.qml");
329 QTest::newRow("package delegate") << testFileUrl("datalist-package.qml");
332 void tst_qquickvisualdatamodel::updateLayout()
334 QFETCH(QUrl, source);
338 QStandardItemModel model;
339 initStandardTreeModel(&model);
341 view.rootContext()->setContextProperty("myModel", &model);
343 view.setSource(source);
345 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
346 QVERIFY(listview != 0);
348 QQuickItem *contentItem = listview->contentItem();
349 QVERIFY(contentItem != 0);
351 QQuickText *name = findItem<QQuickText>(contentItem, "display", 0);
353 QCOMPARE(name->text(), QString("Row 1 Item"));
354 name = findItem<QQuickText>(contentItem, "display", 1);
356 QCOMPARE(name->text(), QString("Row 2 Item"));
357 name = findItem<QQuickText>(contentItem, "display", 2);
359 QCOMPARE(name->text(), QString("Row 3 Item"));
361 model.invisibleRootItem()->sortChildren(0, Qt::DescendingOrder);
363 name = findItem<QQuickText>(contentItem, "display", 0);
365 QCOMPARE(name->text(), QString("Row 3 Item"));
366 name = findItem<QQuickText>(contentItem, "display", 1);
368 QCOMPARE(name->text(), QString("Row 2 Item"));
369 name = findItem<QQuickText>(contentItem, "display", 2);
371 QCOMPARE(name->text(), QString("Row 1 Item"));
374 void tst_qquickvisualdatamodel::childChanged_data()
376 QTest::addColumn<QUrl>("source");
378 QTest::newRow("item delegate") << testFileUrl("datalist.qml");
379 QTest::newRow("package delegate") << testFileUrl("datalist-package.qml");
382 void tst_qquickvisualdatamodel::childChanged()
384 QFETCH(QUrl, source);
388 QStandardItemModel model;
389 initStandardTreeModel(&model);
391 view.rootContext()->setContextProperty("myModel", &model);
393 view.setSource(source);
395 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
396 QVERIFY(listview != 0);
398 QQuickItem *contentItem = listview->contentItem();
399 QVERIFY(contentItem != 0);
401 QQuickVisualDataModel *vdm = listview->findChild<QQuickVisualDataModel*>("visualModel");
402 vdm->setRootIndex(QVariant::fromValue(model.indexFromItem(model.item(1,0))));
403 QCOMPARE(listview->count(), 1);
405 QQuickText *name = findItem<QQuickText>(contentItem, "display", 0);
407 QCOMPARE(name->text(), QString("Row 2 Child Item"));
409 model.item(1,0)->child(0,0)->setText("Row 2 updated child");
411 name = findItem<QQuickText>(contentItem, "display", 0);
413 QCOMPARE(name->text(), QString("Row 2 updated child"));
415 model.item(1,0)->appendRow(new QStandardItem(QLatin1String("Row 2 Child Item 2")));
416 QCOMPARE(listview->count(), 2);
418 name = findItem<QQuickText>(contentItem, "display", 1);
420 QCOMPARE(name->text(), QString("Row 2 Child Item 2"));
422 model.item(1,0)->takeRow(1);
423 name = findItem<QQuickText>(contentItem, "display", 1);
426 vdm->setRootIndex(QVariant::fromValue(QModelIndex()));
427 QCOMPARE(listview->count(), 3);
428 name = findItem<QQuickText>(contentItem, "display", 0);
430 QCOMPARE(name->text(), QString("Row 1 Item"));
431 name = findItem<QQuickText>(contentItem, "display", 1);
433 QCOMPARE(name->text(), QString("Row 2 Item"));
434 name = findItem<QQuickText>(contentItem, "display", 2);
436 QCOMPARE(name->text(), QString("Row 3 Item"));
439 void tst_qquickvisualdatamodel::objectListModel()
443 QList<QObject*> dataList;
444 dataList.append(new DataObject("Item 1", "red"));
445 dataList.append(new DataObject("Item 2", "green"));
446 dataList.append(new DataObject("Item 3", "blue"));
447 dataList.append(new DataObject("Item 4", "yellow"));
449 QDeclarativeContext *ctxt = view.rootContext();
450 ctxt->setContextProperty("myModel", QVariant::fromValue(dataList));
452 view.setSource(testFileUrl("objectlist.qml"));
454 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
455 QVERIFY(listview != 0);
457 QQuickItem *contentItem = listview->contentItem();
458 QVERIFY(contentItem != 0);
460 QQuickText *name = findItem<QQuickText>(contentItem, "name", 0);
461 QCOMPARE(name->text(), QString("Item 1"));
463 QQuickText *section = findItem<QQuickText>(contentItem, "section", 0);
464 QCOMPARE(section->text(), QString("Item 1"));
466 dataList[0]->setProperty("name", QLatin1String("Changed"));
467 QCOMPARE(name->text(), QString("Changed"));
470 void tst_qquickvisualdatamodel::singleRole()
475 SingleRoleModel model;
477 QDeclarativeContext *ctxt = view.rootContext();
478 ctxt->setContextProperty("myModel", &model);
480 view.setSource(testFileUrl("singlerole1.qml"));
482 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
483 QVERIFY(listview != 0);
485 QQuickItem *contentItem = listview->contentItem();
486 QVERIFY(contentItem != 0);
488 QQuickText *name = findItem<QQuickText>(contentItem, "name", 1);
489 QCOMPARE(name->text(), QString("two"));
491 model.set(1, "Changed");
492 QCOMPARE(name->text(), QString("Changed"));
497 SingleRoleModel model;
499 QDeclarativeContext *ctxt = view.rootContext();
500 ctxt->setContextProperty("myModel", &model);
502 view.setSource(testFileUrl("singlerole2.qml"));
504 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
505 QVERIFY(listview != 0);
507 QQuickItem *contentItem = listview->contentItem();
508 QVERIFY(contentItem != 0);
510 QQuickText *name = findItem<QQuickText>(contentItem, "name", 1);
511 QCOMPARE(name->text(), QString("two"));
513 model.set(1, "Changed");
514 QCOMPARE(name->text(), QString("Changed"));
519 SingleRoleModel model("modelData");
521 QDeclarativeContext *ctxt = view.rootContext();
522 ctxt->setContextProperty("myModel", &model);
524 view.setSource(testFileUrl("singlerole2.qml"));
526 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
527 QVERIFY(listview != 0);
529 QQuickItem *contentItem = listview->contentItem();
530 QVERIFY(contentItem != 0);
532 QQuickText *name = findItem<QQuickText>(contentItem, "name", 1);
533 QCOMPARE(name->text(), QString("two"));
535 model.set(1, "Changed");
536 QCOMPARE(name->text(), QString("Changed"));
540 void tst_qquickvisualdatamodel::modelProperties()
545 SingleRoleModel model;
547 QDeclarativeContext *ctxt = view.rootContext();
548 ctxt->setContextProperty("myModel", &model);
550 view.setSource(testFileUrl("modelproperties.qml"));
552 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
553 QVERIFY(listview != 0);
555 QQuickItem *contentItem = listview->contentItem();
556 QVERIFY(contentItem != 0);
558 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", 1);
560 QCOMPARE(delegate->property("test1").toString(),QString("two"));
561 QCOMPARE(delegate->property("test2").toString(),QString("two"));
562 QCOMPARE(delegate->property("test3").toString(),QString("two"));
563 QCOMPARE(delegate->property("test4").toString(),QString("two"));
564 QVERIFY(!delegate->property("test9").isValid());
565 QCOMPARE(delegate->property("test5").toString(),QString(""));
566 QVERIFY(delegate->property("test6").value<QObject*>() != 0);
567 QCOMPARE(delegate->property("test7").toInt(),1);
568 QCOMPARE(delegate->property("test8").toInt(),1);
574 QList<QObject*> dataList;
575 dataList.append(new DataObject("Item 1", "red"));
576 dataList.append(new DataObject("Item 2", "green"));
577 dataList.append(new DataObject("Item 3", "blue"));
578 dataList.append(new DataObject("Item 4", "yellow"));
580 QDeclarativeContext *ctxt = view.rootContext();
581 ctxt->setContextProperty("myModel", QVariant::fromValue(dataList));
583 view.setSource(testFileUrl("modelproperties.qml"));
585 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
586 QVERIFY(listview != 0);
588 QQuickItem *contentItem = listview->contentItem();
589 QVERIFY(contentItem != 0);
591 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", 1);
593 QCOMPARE(delegate->property("test1").toString(),QString("Item 2"));
594 QCOMPARE(delegate->property("test2").toString(),QString("Item 2"));
595 QVERIFY(qobject_cast<DataObject*>(delegate->property("test3").value<QObject*>()) != 0);
596 QVERIFY(qobject_cast<DataObject*>(delegate->property("test4").value<QObject*>()) != 0);
597 QCOMPARE(delegate->property("test5").toString(),QString("Item 2"));
598 QCOMPARE(delegate->property("test9").toString(),QString("Item 2"));
599 QVERIFY(delegate->property("test6").value<QObject*>() != 0);
600 QCOMPARE(delegate->property("test7").toInt(),1);
601 QCOMPARE(delegate->property("test8").toInt(),1);
607 QStandardItemModel model;
608 initStandardTreeModel(&model);
610 view.rootContext()->setContextProperty("myModel", &model);
612 QUrl source(testFileUrl("modelproperties2.qml"));
615 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":13: ReferenceError: Can't find variable: modelData");
616 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":13: ReferenceError: Can't find variable: modelData");
617 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":13: 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() + ":11: ReferenceError: Can't find variable: modelData");
620 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":11: ReferenceError: Can't find variable: modelData");
621 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":17: TypeError: Cannot read property 'display' of undefined");
622 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":17: TypeError: Cannot read property 'display' of undefined");
623 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":17: TypeError: Cannot read property 'display' of undefined");
625 view.setSource(source);
627 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
628 QVERIFY(listview != 0);
630 QQuickItem *contentItem = listview->contentItem();
631 QVERIFY(contentItem != 0);
633 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", 1);
635 QCOMPARE(delegate->property("test1").toString(),QString("Row 2 Item"));
636 QCOMPARE(delegate->property("test2").toString(),QString("Row 2 Item"));
637 QVERIFY(!delegate->property("test3").isValid());
638 QVERIFY(!delegate->property("test4").isValid());
639 QVERIFY(!delegate->property("test5").isValid());
640 QVERIFY(!delegate->property("test9").isValid());
641 QVERIFY(delegate->property("test6").value<QObject*>() != 0);
642 QCOMPARE(delegate->property("test7").toInt(),1);
643 QCOMPARE(delegate->property("test8").toInt(),1);
646 //### should also test QStringList and QVariantList
649 void tst_qquickvisualdatamodel::noDelegate_data()
651 QTest::addColumn<QUrl>("source");
653 QTest::newRow("item delegate") << testFileUrl("datalist.qml");
654 QTest::newRow("package delegate") << testFileUrl("datalist-package.qml");
657 void tst_qquickvisualdatamodel::noDelegate()
659 QFETCH(QUrl, source);
663 QStandardItemModel model;
664 initStandardTreeModel(&model);
666 view.rootContext()->setContextProperty("myModel", &model);
668 view.setSource(source);
670 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
671 QVERIFY(listview != 0);
673 QQuickVisualDataModel *vdm = listview->findChild<QQuickVisualDataModel*>("visualModel");
675 QCOMPARE(vdm->count(), 3);
678 QCOMPARE(vdm->count(), 0);
681 void tst_qquickvisualdatamodel::itemsDestroyed_data()
683 QTest::addColumn<QUrl>("source");
685 QTest::newRow("listView") << testFileUrl("itemsDestroyed_listView.qml");
686 QTest::newRow("package") << testFileUrl("itemsDestroyed_package.qml");
687 QTest::newRow("pathView") << testFileUrl("itemsDestroyed_pathView.qml");
688 QTest::newRow("repeater") << testFileUrl("itemsDestroyed_repeater.qml");
691 void tst_qquickvisualdatamodel::itemsDestroyed()
693 QFETCH(QUrl, source);
695 QDeclarativeGuard<QQuickItem> delegate;
699 QStandardItemModel model;
700 initStandardTreeModel(&model);
701 view.rootContext()->setContextProperty("myModel", &model);
702 view.setSource(source);
705 QTest::qWaitForWindowShown(&view);
707 QVERIFY(delegate = findItem<QQuickItem>(view.rootItem(), "delegate", 1));
709 QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
713 void tst_qquickvisualdatamodel::packagesDestroyed()
715 SingleRoleModel model;
717 for (int i=0; i<30; i++)
718 model.list << ("item " + i);
721 view.rootContext()->setContextProperty("testModel", &model);
723 QString filename(testFile("packageView.qml"));
724 view.setSource(QUrl::fromLocalFile(filename));
726 qApp->processEvents();
728 QQuickListView *leftview = findItem<QQuickListView>(view.rootObject(), "leftList");
729 QTRY_VERIFY(leftview != 0);
731 QQuickListView *rightview = findItem<QQuickListView>(view.rootObject(), "rightList");
732 QTRY_VERIFY(rightview != 0);
734 QQuickItem *leftContent = leftview->contentItem();
735 QTRY_VERIFY(leftContent != 0);
737 QQuickItem *rightContent = rightview->contentItem();
738 QTRY_VERIFY(rightContent != 0);
740 QCOMPARE(leftview->currentIndex(), 0);
741 QCOMPARE(rightview->currentIndex(), 0);
743 rightview->setCurrentIndex(20);
744 QTRY_COMPARE(rightview->contentY(), 100.0);
746 QDeclarativeGuard<QQuickItem> left;
747 QDeclarativeGuard<QQuickItem> right;
749 QVERIFY(findItem<QQuickItem>(leftContent, "wrapper", 1));
750 QVERIFY(findItem<QQuickItem>(rightContent, "wrapper", 1));
752 QVERIFY(left = findItem<QQuickItem>(leftContent, "wrapper", 19));
753 QVERIFY(right = findItem<QQuickItem>(rightContent, "wrapper", 19));
755 rightview->setCurrentIndex(0);
756 QCOMPARE(rightview->currentIndex(), 0);
758 QTRY_COMPARE(rightview->contentY(), 0.0);
759 QCoreApplication::sendPostedEvents();
764 QVERIFY(left = findItem<QQuickItem>(leftContent, "wrapper", 1));
765 QVERIFY(right = findItem<QQuickItem>(rightContent, "wrapper", 1));
767 rightview->setCurrentIndex(20);
768 QTRY_COMPARE(rightview->contentY(), 100.0);
773 QVERIFY(findItem<QQuickItem>(leftContent, "wrapper", 19));
774 QVERIFY(findItem<QQuickItem>(rightContent, "wrapper", 19));
776 leftview->setCurrentIndex(20);
777 QTRY_COMPARE(leftview->contentY(), 100.0);
783 void tst_qquickvisualdatamodel::qaimRowsMoved()
785 // Test parameters passed in QAIM::rowsMoved() signal are converted correctly
786 // when translated and emitted as the QListModelInterface::itemsMoved() signal
787 QFETCH(int, sourceFirst);
788 QFETCH(int, sourceLast);
789 QFETCH(int, destinationChild);
790 QFETCH(int, expectFrom);
791 QFETCH(int, expectTo);
792 QFETCH(int, expectCount);
794 QDeclarativeEngine engine;
795 QDeclarativeComponent c(&engine, testFileUrl("visualdatamodel.qml"));
797 SingleRoleModel model;
799 for (int i=0; i<30; i++)
800 model.list << ("item " + i);
801 engine.rootContext()->setContextProperty("myModel", &model);
803 QQuickVisualDataModel *obj = qobject_cast<QQuickVisualDataModel*>(c.create());
806 QSignalSpy spy(obj, SIGNAL(modelUpdated(QDeclarativeChangeSet,bool)));
807 model.emitMove(sourceFirst, sourceLast, destinationChild);
808 QCOMPARE(spy.count(), 1);
810 QCOMPARE(spy[0].count(), 2);
811 QDeclarativeChangeSet changeSet = spy[0][0].value<QDeclarativeChangeSet>();
812 QCOMPARE(changeSet.removes().count(), 1);
813 QCOMPARE(changeSet.removes().at(0).index, expectFrom);
814 QCOMPARE(changeSet.removes().at(0).count, expectCount);
815 QCOMPARE(changeSet.inserts().count(), 1);
816 QCOMPARE(changeSet.inserts().at(0).index, expectTo);
817 QCOMPARE(changeSet.inserts().at(0).count, expectCount);
818 QCOMPARE(changeSet.removes().at(0).moveId, changeSet.inserts().at(0).moveId);
819 QCOMPARE(spy[0][1].toBool(), false);
824 void tst_qquickvisualdatamodel::qaimRowsMoved_data()
826 QTest::addColumn<int>("sourceFirst");
827 QTest::addColumn<int>("sourceLast");
828 QTest::addColumn<int>("destinationChild");
829 QTest::addColumn<int>("expectFrom");
830 QTest::addColumn<int>("expectTo");
831 QTest::addColumn<int>("expectCount");
833 QTest::newRow("move 1 forward")
837 QTest::newRow("move 1 backwards")
841 QTest::newRow("move multiple forwards")
845 QTest::newRow("move multiple forwards, with same to")
849 QTest::newRow("move multiple backwards")
854 void tst_qquickvisualdatamodel::remove_data()
856 QTest::addColumn<QUrl>("source");
857 QTest::addColumn<QString>("package delegate");
859 QTest::newRow("item delegate")
860 << testFileUrl("groups.qml")
862 QTest::newRow("package")
863 << testFileUrl("groups-package.qml")
864 << QString("package.");
867 void tst_qquickvisualdatamodel::remove()
871 SingleRoleModel model;
872 model.list = QStringList()
886 QDeclarativeContext *ctxt = view.rootContext();
887 ctxt->setContextProperty("myModel", &model);
889 view.setSource(testFileUrl("groups.qml"));
891 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
892 QVERIFY(listview != 0);
894 QQuickItem *contentItem = listview->contentItem();
895 QVERIFY(contentItem != 0);
897 QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel *>(qvariant_cast<QObject *>(listview->model()));
898 QVERIFY(visualModel);
901 QCOMPARE(listview->count(), 12);
902 QCOMPARE(visualModel->items()->count(), 12);
903 static const int mIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
904 static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
906 for (int i = 0; i < lengthOf(mIndex); ++i) {
907 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
909 QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
910 QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
911 QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
914 evaluate<void>(visualModel, "items.remove(2)");
915 QCOMPARE(listview->count(), 11);
916 QCOMPARE(visualModel->items()->count(), 11);
917 static const int mIndex[] = { 0, 1, 3, 4, 5, 6, 7, 8, 9,10,11 };
918 static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10 };
920 for (int i = 0; i < lengthOf(mIndex); ++i) {
921 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
923 QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
924 QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
925 QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
928 evaluate<void>(visualModel, "items.remove(1, 4)");
929 QCOMPARE(listview->count(), 7);
930 QCOMPARE(visualModel->items()->count(), 7);
931 static const int mIndex[] = { 0, 6, 7, 8, 9,10,11 };
932 static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6 };
934 for (int i = 0; i < lengthOf(mIndex); ++i) {
935 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
937 QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
938 QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
939 QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
942 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: remove: index out of range");
943 evaluate<void>(visualModel, "items.remove(-8, 4)");
944 QCOMPARE(listview->count(), 7);
945 QCOMPARE(visualModel->items()->count(), 7);
947 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: remove: index out of range");
948 evaluate<void>(visualModel, "items.remove(12, 2)");
949 QCOMPARE(listview->count(), 7);
950 QCOMPARE(visualModel->items()->count(), 7);
952 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: remove: invalid count");
953 evaluate<void>(visualModel, "items.remove(5, 3)");
954 QCOMPARE(listview->count(), 7);
955 QCOMPARE(visualModel->items()->count(), 7);
957 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: remove: invalid count");
958 evaluate<void>(visualModel, "items.remove(5, -2)");
959 QCOMPARE(listview->count(), 7);
960 QCOMPARE(visualModel->items()->count(), 7);
964 void tst_qquickvisualdatamodel::move_data()
966 QTest::addColumn<QUrl>("source");
967 QTest::addColumn<QString>("package delegate");
969 QTest::newRow("item delegate")
970 << testFileUrl("groups.qml")
972 QTest::newRow("package")
973 << testFileUrl("groups-package.qml")
974 << QString("package.");
977 void tst_qquickvisualdatamodel::move()
981 SingleRoleModel model;
982 model.list = QStringList()
996 QDeclarativeContext *ctxt = view.rootContext();
997 ctxt->setContextProperty("myModel", &model);
999 view.setSource(testFileUrl("groups.qml"));
1001 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
1002 QVERIFY(listview != 0);
1004 QQuickItem *contentItem = listview->contentItem();
1005 QVERIFY(contentItem != 0);
1007 QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel *>(qvariant_cast<QObject *>(listview->model()));
1008 QVERIFY(visualModel);
1011 QCOMPARE(listview->count(), 12);
1012 QCOMPARE(visualModel->items()->count(), 12);
1013 static const int mIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1014 static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1016 for (int i = 0; i < lengthOf(mIndex); ++i) {
1017 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1019 QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
1020 QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
1021 QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
1024 evaluate<void>(visualModel, "items.move(2, 4)");
1025 QCOMPARE(listview->count(), 12);
1026 QCOMPARE(visualModel->items()->count(), 12);
1027 static const int mIndex[] = { 0, 1, 3, 4, 2, 5, 6, 7, 8, 9,10,11 };
1028 static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1030 for (int i = 0; i < lengthOf(mIndex); ++i) {
1031 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1033 QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
1034 QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
1035 QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
1038 evaluate<void>(visualModel, "items.move(4, 2)");
1039 QCOMPARE(listview->count(), 12);
1040 QCOMPARE(visualModel->items()->count(), 12);
1041 static const int mIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1042 static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1044 for (int i = 0; i < lengthOf(mIndex); ++i) {
1045 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1047 QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
1048 QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
1049 QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
1052 evaluate<void>(visualModel, "items.move(8, 0, 4)");
1053 QCOMPARE(listview->count(), 12);
1054 QCOMPARE(visualModel->items()->count(), 12);
1055 static const int mIndex[] = { 8, 9,10,11, 0, 1, 2, 3, 4, 5, 6, 7 };
1056 static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1058 for (int i = 0; i < lengthOf(mIndex); ++i) {
1059 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1061 QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
1062 QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
1063 QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
1066 evaluate<void>(visualModel, "items.move(3, 4, 5)");
1067 QCOMPARE(listview->count(), 12);
1068 QCOMPARE(visualModel->items()->count(), 12);
1069 static const int mIndex[] = { 8, 9,10,4, 11, 0, 1, 2, 3, 5, 6, 7 };
1070 static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1072 for (int i = 0; i < lengthOf(mIndex); ++i) {
1073 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1075 QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
1076 QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
1077 QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
1080 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: invalid count");
1081 evaluate<void>(visualModel, "items.move(5, 2, -2)");
1082 QCOMPARE(listview->count(), 12);
1083 QCOMPARE(visualModel->items()->count(), 12);
1085 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: from index out of range");
1086 evaluate<void>(visualModel, "items.move(-6, 2, 1)");
1087 QCOMPARE(listview->count(), 12);
1088 QCOMPARE(visualModel->items()->count(), 12);
1090 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: from index out of range");
1091 evaluate<void>(visualModel, "items.move(15, 2, 1)");
1092 QCOMPARE(listview->count(), 12);
1093 QCOMPARE(visualModel->items()->count(), 12);
1095 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: from index out of range");
1096 evaluate<void>(visualModel, "items.move(11, 1, 3)");
1097 QCOMPARE(listview->count(), 12);
1098 QCOMPARE(visualModel->items()->count(), 12);
1100 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: to index out of range");
1101 evaluate<void>(visualModel, "items.move(2, -5, 1)");
1102 QCOMPARE(listview->count(), 12);
1103 QCOMPARE(visualModel->items()->count(), 12);
1105 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: to index out of range");
1106 evaluate<void>(visualModel, "items.move(2, 14, 1)");
1107 QCOMPARE(listview->count(), 12);
1108 QCOMPARE(visualModel->items()->count(), 12);
1110 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: to index out of range");
1111 evaluate<void>(visualModel, "items.move(2, 11, 4)");
1112 QCOMPARE(listview->count(), 12);
1113 QCOMPARE(visualModel->items()->count(), 12);
1117 void tst_qquickvisualdatamodel::groups_data()
1119 QTest::addColumn<QUrl>("source");
1120 QTest::addColumn<QString>("part");
1122 QTest::newRow("item delegate")
1123 << testFileUrl("groups.qml")
1125 QTest::newRow("package")
1126 << testFileUrl("groups-package.qml")
1127 << QString("visualModel.parts.package.");
1130 template <int N> void tst_qquickvisualdatamodel::groups_verify(
1131 const SingleRoleModel &model,
1132 QQuickItem *contentItem,
1133 const int (&mIndex)[N],
1134 const int (&iIndex)[N],
1135 const int (&vIndex)[N],
1136 const int (&sIndex)[N],
1137 const bool (&vMember)[N],
1138 const bool (&sMember)[N])
1141 for (int i = 0; i < N; ++i) {
1142 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
1144 QCOMPARE(evaluate<QString>(delegate, "test1"), model.list.at(mIndex[i]));
1145 QCOMPARE(evaluate<int>(delegate, "test2") , mIndex[i]);
1146 QCOMPARE(evaluate<int>(delegate, "test3") , iIndex[i]);
1147 QCOMPARE(evaluate<bool>(delegate, "test4"), true);
1148 QCOMPARE(evaluate<int>(delegate, "test5") , vIndex[i]);
1149 QCOMPARE(evaluate<bool>(delegate, "test6"), vMember[i]);
1150 QCOMPARE(evaluate<int>(delegate, "test7") , sIndex[i]);
1151 QCOMPARE(evaluate<bool>(delegate, "test8"), sMember[i]);
1152 QCOMPARE(evaluate<QStringList>(delegate, "test9").contains("items") , bool(true));
1153 QCOMPARE(evaluate<QStringList>(delegate, "test9").contains("visible") , bool(vMember[i]));
1154 QCOMPARE(evaluate<QStringList>(delegate, "test9").contains("selected"), bool(sMember[i]));
1159 #define VERIFY_GROUPS \
1160 groups_verify(model, contentItem, mIndex, iIndex, vIndex, sIndex, vMember, sMember); \
1164 void tst_qquickvisualdatamodel::groups()
1166 QFETCH(QUrl, source);
1167 QFETCH(QString, part);
1171 SingleRoleModel model;
1172 model.list = QStringList()
1186 QDeclarativeContext *ctxt = view.rootContext();
1187 ctxt->setContextProperty("myModel", &model);
1189 view.setSource(source);
1191 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
1192 QVERIFY(listview != 0);
1194 QQuickItem *contentItem = listview->contentItem();
1195 QVERIFY(contentItem != 0);
1197 QQuickVisualDataModel *visualModel = listview->findChild<QQuickVisualDataModel *>("visualModel");
1198 QVERIFY(visualModel);
1200 QQuickVisualDataGroup *visibleItems = listview->findChild<QQuickVisualDataGroup *>("visibleItems");
1201 QVERIFY(visibleItems);
1203 QQuickVisualDataGroup *selectedItems = listview->findChild<QQuickVisualDataGroup *>("selectedItems");
1204 QVERIFY(selectedItems);
1206 const bool f = false;
1207 const bool t = true;
1210 QCOMPARE(listview->count(), 12);
1211 QCOMPARE(visualModel->items()->count(), 12);
1212 QCOMPARE(visibleItems->count(), 12);
1213 QCOMPARE(selectedItems->count(), 0);
1214 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1215 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1216 static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1217 static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
1218 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1219 static const bool sMember[] = { f, f, f, f, f, f, f, f, f, f, f, f };
1222 evaluate<void>(visualModel, "items.addGroups(8, \"selected\")");
1223 QCOMPARE(listview->count(), 12);
1224 QCOMPARE(visualModel->items()->count(), 12);
1225 QCOMPARE(visibleItems->count(), 12);
1226 QCOMPARE(selectedItems->count(), 1);
1227 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1228 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1229 static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1230 static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
1231 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 };
1232 static const bool sMember[] = { f, f, f, f, f, f, f, f, t, f, f, f };
1235 evaluate<void>(visualModel, "items.addGroups(6, 4, [\"visible\", \"selected\"])");
1236 QCOMPARE(listview->count(), 12);
1237 QCOMPARE(visualModel->items()->count(), 12);
1238 QCOMPARE(visibleItems->count(), 12);
1239 QCOMPARE(selectedItems->count(), 4);
1240 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1241 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1242 static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1243 static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
1244 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 4 };
1245 static const bool sMember[] = { f, f, f, f, f, f, t, t, t, t, f, f };
1248 evaluate<void>(visualModel, "items.setGroups(2, [\"items\", \"selected\"])");
1249 QCOMPARE(listview->count(), 12);
1250 QCOMPARE(visualModel->items()->count(), 12);
1251 QCOMPARE(visibleItems->count(), 11);
1252 QCOMPARE(selectedItems->count(), 5);
1253 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1254 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1255 static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9,10 };
1256 static const bool vMember[] = { t, t, f, t, t, t, t, t, t, t, t, t };
1257 static const int sIndex [] = { 0, 0, 0, 1, 1, 1, 1, 2, 3, 4, 5, 5 };
1258 static const bool sMember[] = { f, f, t, f, f, f, t, t, t, t, f, f };
1261 evaluate<void>(selectedItems, "setGroups(0, 3, \"items\")");
1262 QCOMPARE(listview->count(), 12);
1263 QCOMPARE(visualModel->items()->count(), 12);
1264 QCOMPARE(visibleItems->count(), 9);
1265 QCOMPARE(selectedItems->count(), 2);
1266 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1267 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1268 static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 5, 5, 6, 7, 8 };
1269 static const bool vMember[] = { t, t, f, t, t, t, f, f, t, t, t, t };
1270 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 };
1271 static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f };
1274 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: addGroups: invalid count");
1275 evaluate<void>(visualModel, "items.addGroups(11, -4, \"items\")");
1276 QCOMPARE(listview->count(), 12);
1277 QCOMPARE(visualModel->items()->count(), 12);
1278 QCOMPARE(visibleItems->count(), 9);
1279 QCOMPARE(selectedItems->count(), 2);
1281 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: addGroups: index out of range");
1282 evaluate<void>(visualModel, "items.addGroups(-1, 3, \"items\")");
1283 QCOMPARE(listview->count(), 12);
1284 QCOMPARE(visualModel->items()->count(), 12);
1285 QCOMPARE(visibleItems->count(), 9);
1286 QCOMPARE(selectedItems->count(), 2);
1288 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: addGroups: index out of range");
1289 evaluate<void>(visualModel, "items.addGroups(14, 3, \"items\")");
1290 QCOMPARE(listview->count(), 12);
1291 QCOMPARE(visualModel->items()->count(), 12);
1292 QCOMPARE(visibleItems->count(), 9);
1293 QCOMPARE(selectedItems->count(), 2);
1295 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: addGroups: invalid count");
1296 evaluate<void>(visualModel, "items.addGroups(11, 5, \"items\")");
1297 QCOMPARE(listview->count(), 12);
1298 QCOMPARE(visualModel->items()->count(), 12);
1299 QCOMPARE(visibleItems->count(), 9);
1300 QCOMPARE(selectedItems->count(), 2);
1302 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: setGroups: invalid count");
1303 evaluate<void>(visualModel, "items.setGroups(11, -4, \"items\")");
1304 QCOMPARE(listview->count(), 12);
1305 QCOMPARE(visualModel->items()->count(), 12);
1306 QCOMPARE(visibleItems->count(), 9);
1307 QCOMPARE(selectedItems->count(), 2);
1309 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: setGroups: index out of range");
1310 evaluate<void>(visualModel, "items.setGroups(-1, 3, \"items\")");
1311 QCOMPARE(listview->count(), 12);
1312 QCOMPARE(visualModel->items()->count(), 12);
1313 QCOMPARE(visibleItems->count(), 9);
1314 QCOMPARE(selectedItems->count(), 2);
1316 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: setGroups: index out of range");
1317 evaluate<void>(visualModel, "items.setGroups(14, 3, \"items\")");
1318 QCOMPARE(listview->count(), 12);
1319 QCOMPARE(visualModel->items()->count(), 12);
1320 QCOMPARE(visibleItems->count(), 9);
1321 QCOMPARE(selectedItems->count(), 2);
1323 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: setGroups: invalid count");
1324 evaluate<void>(visualModel, "items.setGroups(11, 5, \"items\")");
1325 QCOMPARE(listview->count(), 12);
1326 QCOMPARE(visualModel->items()->count(), 12);
1327 QCOMPARE(visibleItems->count(), 9);
1328 QCOMPARE(selectedItems->count(), 2);
1330 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: removeGroups: invalid count");
1331 evaluate<void>(visualModel, "items.removeGroups(11, -4, \"items\")");
1332 QCOMPARE(listview->count(), 12);
1333 QCOMPARE(visualModel->items()->count(), 12);
1335 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: removeGroups: index out of range");
1336 evaluate<void>(visualModel, "items.removeGroups(-1, 3, \"items\")");
1337 QCOMPARE(listview->count(), 12);
1338 QCOMPARE(visualModel->items()->count(), 12);
1339 QCOMPARE(visibleItems->count(), 9);
1340 QCOMPARE(selectedItems->count(), 2);
1342 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: removeGroups: index out of range");
1343 evaluate<void>(visualModel, "items.removeGroups(14, 3, \"items\")");
1344 QCOMPARE(listview->count(), 12);
1345 QCOMPARE(visualModel->items()->count(), 12);
1346 QCOMPARE(visibleItems->count(), 9);
1347 QCOMPARE(selectedItems->count(), 2);
1349 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: removeGroups: invalid count");
1350 evaluate<void>(visualModel, "items.removeGroups(11, 5, \"items\")");
1351 QCOMPARE(listview->count(), 12);
1352 QCOMPARE(visualModel->items()->count(), 12);
1353 QCOMPARE(visibleItems->count(), 9);
1354 QCOMPARE(selectedItems->count(), 2);
1356 evaluate<void>(visualModel, part + "filterOnGroup = \"visible\"");
1357 QCOMPARE(listview->count(), 9);
1358 QCOMPARE(visualModel->items()->count(), 12);
1359 QCOMPARE(visibleItems->count(), 9);
1360 QCOMPARE(selectedItems->count(), 2);
1361 QCOMPARE(evaluate<QString>(visualModel, part + "filterOnGroup"), QString("visible"));
1363 evaluate<void>(visualModel, part + "filterOnGroup = \"selected\"");
1364 QCOMPARE(listview->count(), 2);
1365 QCOMPARE(visualModel->items()->count(), 12);
1366 QCOMPARE(visibleItems->count(), 9);
1367 QCOMPARE(selectedItems->count(), 2);
1368 QCOMPARE(evaluate<QString>(visualModel, part + "filterOnGroup"), QString("selected"));
1370 evaluate<void>(visualModel, part + "filterOnGroup = undefined");
1371 QCOMPARE(listview->count(), 12);
1372 QCOMPARE(visualModel->items()->count(), 12);
1373 QCOMPARE(visibleItems->count(), 9);
1374 QCOMPARE(selectedItems->count(), 2);
1375 QCOMPARE(evaluate<QString>(visualModel, part + "filterOnGroup"), QString("items"));
1377 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", 5);
1380 evaluate<void>(delegate, "hide()");
1381 QCOMPARE(listview->count(), 12);
1382 QCOMPARE(visualModel->items()->count(), 12);
1383 QCOMPARE(visibleItems->count(), 8);
1384 QCOMPARE(selectedItems->count(), 2);
1385 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1386 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1387 static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 6, 7 };
1388 static const bool vMember[] = { t, t, f, t, t, f, f, f, t, t, t, t };
1389 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 };
1390 static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f };
1393 QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", 5);
1396 evaluate<void>(delegate, "select()");
1397 QCOMPARE(listview->count(), 12);
1398 QCOMPARE(visualModel->items()->count(), 12);
1399 QCOMPARE(visibleItems->count(), 8);
1400 QCOMPARE(selectedItems->count(), 3);
1401 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1402 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1403 static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 6, 7 };
1404 static const bool vMember[] = { t, t, f, t, t, f, f, f, t, t, t, t };
1405 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 3, 3 };
1406 static const bool sMember[] = { f, f, f, f, f, t, f, f, t, t, f, f };
1409 evaluate<void>(visualModel, "items.move(2, 6, 3)");
1410 QCOMPARE(listview->count(), 12);
1411 QCOMPARE(visualModel->items()->count(), 12);
1412 QCOMPARE(visibleItems->count(), 8);
1413 QCOMPARE(selectedItems->count(), 3);
1414 static const int mIndex [] = { 0, 1, 5, 6, 7, 8, 2, 3, 4, 9,10,11 };
1415 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1416 static const int vIndex [] = { 0, 1, 2, 2, 2, 2, 3, 3, 4, 5, 6, 7 };
1417 static const bool vMember[] = { t, t, f, f, f, t, f, t, t, t, t, t };
1418 static const int sIndex [] = { 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3 };
1419 static const bool sMember[] = { f, f, t, f, f, t, f, f, f, t, f, f };
1424 template <int N> void tst_qquickvisualdatamodel::get_verify(
1425 const SingleRoleModel &model,
1426 QQuickVisualDataModel *visualModel,
1427 QQuickVisualDataGroup *visibleItems,
1428 QQuickVisualDataGroup *selectedItems,
1429 const int (&mIndex)[N],
1430 const int (&iIndex)[N],
1431 const int (&vIndex)[N],
1432 const int (&sIndex)[N],
1433 const bool (&vMember)[N],
1434 const bool (&sMember)[N])
1437 for (int i = 0; i < N; ++i) {
1438 QCOMPARE(evaluate<QString>(visualModel, QString("items.get(%1).model.name").arg(i)), model.list.at(mIndex[i]));
1439 QCOMPARE(evaluate<QString>(visualModel, QString("items.get(%1).model.modelData").arg(i)), model.list.at(mIndex[i]));
1440 QCOMPARE(evaluate<int>(visualModel, QString("items.get(%1).model.index").arg(i)), mIndex[i]);
1441 QCOMPARE(evaluate<int>(visualModel, QString("items.get(%1).itemsIndex").arg(i)), iIndex[i]);
1442 QCOMPARE(evaluate<bool>(visualModel, QString("items.get(%1).inItems").arg(i)), true);
1443 QCOMPARE(evaluate<int>(visualModel, QString("items.get(%1).visibleIndex").arg(i)), vIndex[i]);
1444 QCOMPARE(evaluate<bool>(visualModel, QString("items.get(%1).inVisible").arg(i)), vMember[i]);
1445 QCOMPARE(evaluate<int>(visualModel, QString("items.get(%1).selectedIndex").arg(i)), sIndex[i]);
1446 QCOMPARE(evaluate<bool>(visualModel, QString("items.get(%1).inSelected").arg(i)), sMember[i]);
1447 QCOMPARE(evaluate<bool>(visualModel, QString("contains(items.get(%1).groups, \"items\")").arg(i)), true);
1448 QCOMPARE(evaluate<bool>(visualModel, QString("contains(items.get(%1).groups, \"visible\")").arg(i)), vMember[i]);
1449 QCOMPARE(evaluate<bool>(visualModel, QString("contains(items.get(%1).groups, \"selected\")").arg(i)), sMember[i]);
1452 QCOMPARE(evaluate<QString>(visibleItems, QString("get(%1).model.name").arg(vIndex[i])), model.list.at(mIndex[i]));
1453 QCOMPARE(evaluate<QString>(visibleItems, QString("get(%1).model.modelData").arg(vIndex[i])), model.list.at(mIndex[i]));
1454 QCOMPARE(evaluate<int>(visibleItems, QString("get(%1).model.index").arg(vIndex[i])), mIndex[i]);
1455 QCOMPARE(evaluate<int>(visibleItems, QString("get(%1).itemsIndex").arg(vIndex[i])), iIndex[i]);
1456 QCOMPARE(evaluate<bool>(visibleItems, QString("get(%1).inItems").arg(vIndex[i])), true);
1457 QCOMPARE(evaluate<int>(visibleItems, QString("get(%1).visibleIndex").arg(vIndex[i])), vIndex[i]);
1458 QCOMPARE(evaluate<bool>(visibleItems, QString("get(%1).inVisible").arg(vIndex[i])), vMember[i]);
1459 QCOMPARE(evaluate<int>(visibleItems, QString("get(%1).selectedIndex").arg(vIndex[i])), sIndex[i]);
1460 QCOMPARE(evaluate<bool>(visibleItems, QString("get(%1).inSelected").arg(vIndex[i])), sMember[i]);
1462 QCOMPARE(evaluate<bool>(visibleItems, QString("contains(get(%1).groups, \"items\")").arg(vIndex[i])), true);
1463 QCOMPARE(evaluate<bool>(visibleItems, QString("contains(get(%1).groups, \"visible\")").arg(vIndex[i])), vMember[i]);
1464 QCOMPARE(evaluate<bool>(visibleItems, QString("contains(get(%1).groups, \"selected\")").arg(vIndex[i])), sMember[i]);
1467 QCOMPARE(evaluate<QString>(selectedItems, QString("get(%1).model.name").arg(sIndex[i])), model.list.at(mIndex[i]));
1468 QCOMPARE(evaluate<QString>(selectedItems, QString("get(%1).model.modelData").arg(sIndex[i])), model.list.at(mIndex[i]));
1469 QCOMPARE(evaluate<int>(selectedItems, QString("get(%1).model.index").arg(sIndex[i])), mIndex[i]);
1470 QCOMPARE(evaluate<int>(selectedItems, QString("get(%1).itemsIndex").arg(sIndex[i])), iIndex[i]);
1471 QCOMPARE(evaluate<bool>(selectedItems, QString("get(%1).inItems").arg(sIndex[i])), true);
1472 QCOMPARE(evaluate<int>(selectedItems, QString("get(%1).visibleIndex").arg(sIndex[i])), vIndex[i]);
1473 QCOMPARE(evaluate<bool>(selectedItems, QString("get(%1).inVisible").arg(sIndex[i])), vMember[i]);
1474 QCOMPARE(evaluate<int>(selectedItems, QString("get(%1).selectedIndex").arg(sIndex[i])), sIndex[i]);
1475 QCOMPARE(evaluate<bool>(selectedItems, QString("get(%1).inSelected").arg(sIndex[i])), sMember[i]);
1476 QCOMPARE(evaluate<bool>(selectedItems, QString("contains(get(%1).groups, \"items\")").arg(sIndex[i])), true);
1477 QCOMPARE(evaluate<bool>(selectedItems, QString("contains(get(%1).groups, \"visible\")").arg(sIndex[i])), vMember[i]);
1478 QCOMPARE(evaluate<bool>(selectedItems, QString("contains(get(%1).groups, \"selected\")").arg(sIndex[i])), sMember[i]);
1484 #define VERIFY_GET \
1485 get_verify(model, visualModel, visibleItems, selectedItems, mIndex, iIndex, vIndex, sIndex, vMember, sMember); \
1488 void tst_qquickvisualdatamodel::get()
1492 SingleRoleModel model;
1493 model.list = QStringList()
1507 QDeclarativeContext *ctxt = view.rootContext();
1508 ctxt->setContextProperty("myModel", &model);
1510 view.setSource(testFileUrl("groups.qml"));
1512 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
1513 QVERIFY(listview != 0);
1515 QQuickItem *contentItem = listview->contentItem();
1516 QVERIFY(contentItem != 0);
1518 QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel *>(qvariant_cast<QObject *>(listview->model()));
1519 QVERIFY(visualModel);
1521 QQuickVisualDataGroup *visibleItems = visualModel->findChild<QQuickVisualDataGroup *>("visibleItems");
1522 QVERIFY(visibleItems);
1524 QQuickVisualDataGroup *selectedItems = visualModel->findChild<QQuickVisualDataGroup *>("selectedItems");
1525 QVERIFY(selectedItems);
1527 QV8Engine *v8Engine = QDeclarativeEnginePrivate::getV8Engine(ctxt->engine());
1530 const bool f = false;
1531 const bool t = true;
1534 QCOMPARE(listview->count(), 12);
1535 QCOMPARE(visualModel->items()->count(), 12);
1536 QCOMPARE(visibleItems->count(), 12);
1537 QCOMPARE(selectedItems->count(), 0);
1538 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1539 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1540 static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1541 static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
1542 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1543 static const bool sMember[] = { f, f, f, f, f, f, f, f, f, f, f, f };
1546 evaluate<void>(visualModel, "items.addGroups(8, \"selected\")");
1547 QCOMPARE(listview->count(), 12);
1548 QCOMPARE(visualModel->items()->count(), 12);
1549 QCOMPARE(visibleItems->count(), 12);
1550 QCOMPARE(selectedItems->count(), 1);
1551 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1552 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1553 static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1554 static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
1555 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 };
1556 static const bool sMember[] = { f, f, f, f, f, f, f, f, t, f, f, f };
1559 evaluate<void>(visualModel, "items.addGroups(6, 4, [\"visible\", \"selected\"])");
1560 QCOMPARE(listview->count(), 12);
1561 QCOMPARE(visualModel->items()->count(), 12);
1562 QCOMPARE(visibleItems->count(), 12);
1563 QCOMPARE(selectedItems->count(), 4);
1564 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1565 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1566 static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1567 static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
1568 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 4 };
1569 static const bool sMember[] = { f, f, f, f, f, f, t, t, t, t, f, f };
1572 evaluate<void>(visualModel, "items.setGroups(2, [\"items\", \"selected\"])");
1573 QCOMPARE(listview->count(), 12);
1574 QCOMPARE(visualModel->items()->count(), 12);
1575 QCOMPARE(visibleItems->count(), 11);
1576 QCOMPARE(selectedItems->count(), 5);
1577 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1578 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1579 static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9,10 };
1580 static const bool vMember[] = { t, t, f, t, t, t, t, t, t, t, t, t };
1581 static const int sIndex [] = { 0, 0, 0, 1, 1, 1, 1, 2, 3, 4, 5, 5 };
1582 static const bool sMember[] = { f, f, t, f, f, f, t, t, t, t, f, f };
1585 evaluate<void>(selectedItems, "setGroups(0, 3, \"items\")");
1586 QCOMPARE(listview->count(), 12);
1587 QCOMPARE(visualModel->items()->count(), 12);
1588 QCOMPARE(visibleItems->count(), 9);
1589 QCOMPARE(selectedItems->count(), 2);
1590 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1591 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1592 static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 5, 5, 6, 7, 8 };
1593 static const bool vMember[] = { t, t, f, t, t, t, f, f, t, t, t, t };
1594 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 };
1595 static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f };
1598 evaluate<void>(visualModel, "items.get(5).inVisible = false");
1599 QCOMPARE(listview->count(), 12);
1600 QCOMPARE(visualModel->items()->count(), 12);
1601 QCOMPARE(visibleItems->count(), 8);
1602 QCOMPARE(selectedItems->count(), 2);
1603 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1604 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1605 static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 6, 7 };
1606 static const bool vMember[] = { t, t, f, t, t, f, f, f, t, t, t, t };
1607 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 };
1608 static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f };
1611 evaluate<void>(visualModel, "items.get(5).inSelected = true");
1612 QCOMPARE(listview->count(), 12);
1613 QCOMPARE(visualModel->items()->count(), 12);
1614 QCOMPARE(visibleItems->count(), 8);
1615 QCOMPARE(selectedItems->count(), 3);
1616 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1617 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1618 static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 6, 7 };
1619 static const bool vMember[] = { t, t, f, t, t, f, f, f, t, t, t, t };
1620 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 3, 3 };
1621 static const bool sMember[] = { f, f, f, f, f, t, f, f, t, t, f, f };
1624 evaluate<void>(visualModel, "items.get(5).groups = [\"visible\", \"items\"]");
1625 QCOMPARE(listview->count(), 12);
1626 QCOMPARE(visualModel->items()->count(), 12);
1627 QCOMPARE(visibleItems->count(), 9);
1628 QCOMPARE(selectedItems->count(), 2);
1629 static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1630 static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
1631 static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 5, 5, 6, 7, 8 };
1632 static const bool vMember[] = { t, t, f, t, t, t, f, f, t, t, t, t };
1633 static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 };
1634 static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f };
1639 void tst_qquickvisualdatamodel::invalidGroups()
1641 QUrl source = testFileUrl("groups-invalid.qml");
1642 QTest::ignoreMessage(QtWarningMsg, (source.toString() + ":12:9: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("Group names must start with a lower case letter")).toUtf8());
1644 QDeclarativeComponent component(&engine, source);
1645 QScopedPointer<QObject> object(component.create());
1648 QCOMPARE(evaluate<int>(object.data(), "groups.length"), 4);
1649 QCOMPARE(evaluate<QString>(object.data(), "groups[0].name"), QString("items"));
1650 QCOMPARE(evaluate<QString>(object.data(), "groups[1].name"), QString("persistedItems"));
1651 QCOMPARE(evaluate<QString>(object.data(), "groups[2].name"), QString("visible"));
1652 QCOMPARE(evaluate<QString>(object.data(), "groups[3].name"), QString("selected"));
1655 void tst_qquickvisualdatamodel::onChanged_data()
1657 QTest::addColumn<QString>("expression");
1658 QTest::addColumn<QStringList>("tests");
1660 QTest::newRow("item appended")
1661 << QString("listModel.append({\"number\": \"five\"})")
1663 << "verify(vm.removed, [], [], [])"
1664 << "verify(vm.inserted, [4], [1], [undefined])"
1665 << "verify(vi.removed, [], [], [])"
1666 << "verify(vi.inserted, [4], [1], [undefined])"
1667 << "verify(si.removed, [], [], [])"
1668 << "verify(si.inserted, [], [], [])");
1669 QTest::newRow("item prepended")
1670 << QString("listModel.insert(0, {\"number\": \"five\"})")
1672 << "verify(vm.removed, [], [], [])"
1673 << "verify(vm.inserted, [0], [1], [undefined])"
1674 << "verify(vi.removed, [], [], [])"
1675 << "verify(vi.inserted, [0], [1], [undefined])"
1676 << "verify(si.removed, [], [], [])"
1677 << "verify(si.inserted, [], [], [])");
1678 QTest::newRow("item inserted")
1679 << QString("listModel.insert(2, {\"number\": \"five\"})")
1681 << "verify(vm.removed, [], [], [])"
1682 << "verify(vm.inserted, [2], [1], [undefined])"
1683 << "verify(vi.removed, [], [], [])"
1684 << "verify(vi.inserted, [2], [1], [undefined])"
1685 << "verify(si.removed, [], [], [])"
1686 << "verify(si.inserted, [], [], [])");
1688 QTest::newRow("item removed tail")
1689 << QString("listModel.remove(3)")
1691 << "verify(vm.removed, [3], [1], [undefined])"
1692 << "verify(vm.inserted, [], [], [])"
1693 << "verify(vi.removed, [3], [1], [undefined])"
1694 << "verify(vi.inserted, [], [], [])"
1695 << "verify(si.removed, [], [], [])"
1696 << "verify(si.inserted, [], [], [])");
1697 QTest::newRow("item removed head")
1698 << QString("listModel.remove(0)")
1700 << "verify(vm.removed, [0], [1], [undefined])"
1701 << "verify(vm.inserted, [], [], [])"
1702 << "verify(vi.removed, [0], [1], [undefined])"
1703 << "verify(vi.inserted, [], [], [])"
1704 << "verify(si.removed, [], [], [])"
1705 << "verify(si.inserted, [], [], [])");
1706 QTest::newRow("item removed middle")
1707 << QString("listModel.remove(1)")
1709 << "verify(vm.removed, [1], [1], [undefined])"
1710 << "verify(vm.inserted, [], [], [])"
1711 << "verify(vi.removed, [1], [1], [undefined])"
1712 << "verify(vi.inserted, [], [], [])"
1713 << "verify(si.removed, [], [], [])"
1714 << "verify(si.inserted, [], [], [])");
1717 QTest::newRow("item moved from tail")
1718 << QString("listModel.move(3, 0, 1)")
1720 << "verify(vm.removed, [3], [1], [vm.inserted[0].moveId])"
1721 << "verify(vm.inserted, [0], [1], [vm.removed[0].moveId])"
1722 << "verify(vi.removed, [3], [1], [vi.inserted[0].moveId])"
1723 << "verify(vi.inserted, [0], [1], [vi.removed[0].moveId])"
1724 << "verify(si.removed, [], [], [])"
1725 << "verify(si.inserted, [], [], [])");
1726 QTest::newRow("item moved from head")
1727 << QString("listModel.move(0, 2, 2)")
1729 << "verify(vm.removed, [0], [2], [vm.inserted[0].moveId])"
1730 << "verify(vm.inserted, [2], [2], [vm.removed[0].moveId])"
1731 << "verify(vi.removed, [0], [2], [vi.inserted[0].moveId])"
1732 << "verify(vi.inserted, [2], [2], [vi.removed[0].moveId])"
1733 << "verify(si.removed, [], [], [])"
1734 << "verify(si.inserted, [], [], [])");
1736 QTest::newRow("groups changed")
1737 << QString("items.setGroups(1, 2, [\"items\", \"selected\"])")
1739 << "verify(vm.inserted, [], [], [])"
1740 << "verify(vm.removed, [], [], [])"
1741 << "verify(vi.removed, [1], [2], [undefined])"
1742 << "verify(vi.inserted, [], [], [])"
1743 << "verify(si.removed, [], [], [])"
1744 << "verify(si.inserted, [0], [2], [undefined])");
1746 QTest::newRow("multiple removes")
1747 << QString("{ vi.remove(1, 1); "
1748 "vi.removeGroups(0, 2, \"items\") }")
1750 << "verify(vm.removed, [0, 1], [1, 1], [undefined, undefined])"
1751 << "verify(vm.inserted, [], [], [])"
1752 << "verify(vi.removed, [1], [1], [undefined])"
1753 << "verify(vi.inserted, [], [], [])"
1754 << "verify(si.removed, [], [], [])"
1755 << "verify(si.inserted, [], [], [])");
1758 void tst_qquickvisualdatamodel::onChanged()
1760 QFETCH(QString, expression);
1761 QFETCH(QStringList, tests);
1763 QDeclarativeComponent component(&engine, testFileUrl("onChanged.qml"));
1764 QScopedPointer<QObject> object(component.create());
1767 evaluate<void>(object.data(), expression);
1769 foreach (const QString &test, tests) {
1770 bool passed = evaluate<bool>(object.data(), test);
1777 void tst_qquickvisualdatamodel::create()
1781 SingleRoleModel model;
1782 model.list = QStringList()
1804 QDeclarativeContext *ctxt = view.rootContext();
1805 ctxt->setContextProperty("myModel", &model);
1807 view.setSource(testFileUrl("create.qml"));
1809 QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
1810 QVERIFY(listview != 0);
1812 QQuickItem *contentItem = listview->contentItem();
1813 QVERIFY(contentItem != 0);
1815 QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel *>(qvariant_cast<QObject *>(listview->model()));
1816 QVERIFY(visualModel);
1818 QCOMPARE(listview->count(), 20);
1820 QDeclarativeGuard<QQuickItem> delegate;
1822 // persistedItems.includeByDefault is true, so all items belong to persistedItems initially.
1823 QVERIFY(delegate = findItem<QQuickItem>(contentItem, "delegate", 1));
1824 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
1826 // changing include by default doesn't remove persistance.
1827 evaluate<void>(visualModel, "persistedItems.includeByDefault = false");
1828 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
1830 // removing from persistedItems does.
1831 evaluate<void>(visualModel, "persistedItems.remove(0, 20)");
1832 QCOMPARE(listview->count(), 20);
1833 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), false);
1835 // Request an item instantiated by the view.
1836 QVERIFY(delegate = qobject_cast<QQuickItem *>(evaluate<QObject *>(visualModel, "items.create(1)")));
1837 QCOMPARE(delegate.data(), findItem<QQuickItem>(contentItem, "delegate", 1));
1838 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
1839 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 1);
1841 evaluate<void>(delegate, "VisualDataModel.inPersistedItems = false");
1842 QCOMPARE(listview->count(), 20);
1843 QCoreApplication::sendPostedEvents(delegate, QEvent::DeferredDelete);
1845 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), false);
1846 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 0);
1848 // Request an item not instantiated by the view.
1849 QVERIFY(!findItem<QQuickItem>(contentItem, "delegate", 15));
1850 QVERIFY(delegate = qobject_cast<QQuickItem *>(evaluate<QObject *>(visualModel, "items.create(15)")));
1851 QCOMPARE(delegate.data(), findItem<QQuickItem>(contentItem, "delegate", 15));
1852 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
1853 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 1);
1855 evaluate<void>(visualModel, "persistedItems.remove(0)");
1856 QCoreApplication::sendPostedEvents(delegate, QEvent::DeferredDelete);
1858 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 0);
1860 // Request an item not instantiated by the view, then scroll the view so it will request it.
1861 QVERIFY(!findItem<QQuickItem>(contentItem, "delegate", 16));
1862 QVERIFY(delegate = qobject_cast<QQuickItem *>(evaluate<QObject *>(visualModel, "items.create(16)")));
1863 QCOMPARE(delegate.data(), findItem<QQuickItem>(contentItem, "delegate", 16));
1864 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
1865 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 1);
1867 evaluate<void>(listview, "positionViewAtIndex(19, ListView.End)");
1868 QCOMPARE(listview->count(), 20);
1869 evaluate<void>(delegate, "VisualDataModel.groups = [\"items\"]");
1870 QCoreApplication::sendPostedEvents(delegate, QEvent::DeferredDelete);
1872 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), false);
1873 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 0);
1875 // Request and release an item instantiated by the view, then scroll the view so it releases it.
1876 QVERIFY(findItem<QQuickItem>(contentItem, "delegate", 17));
1877 QVERIFY(delegate = qobject_cast<QQuickItem *>(evaluate<QObject *>(visualModel, "items.create(17)")));
1878 QCOMPARE(delegate.data(), findItem<QQuickItem>(contentItem, "delegate", 17));
1879 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
1880 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 1);
1882 evaluate<void>(visualModel, "items.removeGroups(17, \"persistedItems\")");
1883 QCoreApplication::sendPostedEvents(delegate, QEvent::DeferredDelete);
1885 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), false);
1886 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 0);
1887 evaluate<void>(listview, "positionViewAtIndex(1, ListView.Beginning)");
1888 QCOMPARE(listview->count(), 20);
1889 QCoreApplication::sendPostedEvents(delegate, QEvent::DeferredDelete);
1892 // Adding an item to the persistedItems group won't instantiate it, but if later requested by
1893 // the view it will be persisted.
1894 evaluate<void>(visualModel, "items.addGroups(18, \"persistedItems\")");
1895 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 1);
1896 QVERIFY(!findItem<QQuickItem>(contentItem, "delegate", 18));
1897 evaluate<void>(listview, "positionViewAtIndex(19, ListView.End)");
1898 QCOMPARE(listview->count(), 20);
1899 QVERIFY(delegate = findItem<QQuickItem>(contentItem, "delegate", 18));
1900 QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
1901 QCoreApplication::sendPostedEvents(delegate, QEvent::DeferredDelete);
1903 evaluate<void>(listview, "positionViewAtIndex(1, ListView.Beginning)");
1904 QCOMPARE(listview->count(), 20);
1905 QCoreApplication::sendPostedEvents(delegate, QEvent::DeferredDelete);
1908 // Remove an uninstantiated but cached item from the persistedItems group.
1909 evaluate<void>(visualModel, "items.addGroups(19, \"persistedItems\")");
1910 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 2);
1911 QVERIFY(!findItem<QQuickItem>(contentItem, "delegate", 19));
1912 // Store a reference to the item so it is retained in the cache.
1913 evaluate<void>(visualModel, "persistentHandle = items.get(19)");
1914 QCOMPARE(evaluate<bool>(visualModel, "persistentHandle.inPersistedItems"), true);
1915 evaluate<void>(visualModel, "items.removeGroups(19, \"persistedItems\")");
1916 QCOMPARE(evaluate<bool>(visualModel, "persistentHandle.inPersistedItems"), false);
1919 void tst_qquickvisualdatamodel::incompleteModel()
1921 // VisualDataModel is first populated in componentComplete. Verify various functions are
1922 // harmlessly ignored until then.
1924 QDeclarativeComponent component(&engine);
1925 component.setData("import QtQuick 2.0\n VisualDataModel {}", testFileUrl(""));
1927 QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
1929 QQuickVisualDataModel *model = qobject_cast<QQuickVisualDataModel *>(object.data());
1932 QSignalSpy itemsSpy(model->items(), SIGNAL(countChanged()));
1933 QSignalSpy persistedItemsSpy(model->items(), SIGNAL(countChanged()));
1935 evaluate<void>(model, "items.removeGroups(0, items.count, \"items\")");
1936 QCOMPARE(itemsSpy.count(), 0);
1937 QCOMPARE(persistedItemsSpy.count(), 0);
1939 evaluate<void>(model, "items.setGroups(0, items.count, \"persistedItems\")");
1940 QCOMPARE(itemsSpy.count(), 0);
1941 QCOMPARE(persistedItemsSpy.count(), 0);
1943 evaluate<void>(model, "items.addGroups(0, items.count, \"persistedItems\")");
1944 QCOMPARE(itemsSpy.count(), 0);
1945 QCOMPARE(persistedItemsSpy.count(), 0);
1947 evaluate<void>(model, "items.remove(0, items.count)");
1948 QCOMPARE(itemsSpy.count(), 0);
1949 QCOMPARE(persistedItemsSpy.count(), 0);
1951 evaluate<void>(model, "items.insert([ \"color\": \"blue\" ])");
1952 QCOMPARE(itemsSpy.count(), 0);
1953 QCOMPARE(persistedItemsSpy.count(), 0);
1955 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: get: index out of range");
1956 QVERIFY(evaluate<bool>(model, "items.get(0) === undefined"));
1958 component.completeCreate();
1961 void tst_qquickvisualdatamodel::insert_data()
1963 QTest::addColumn<QUrl>("source");
1964 QTest::addColumn<QString>("expression");
1965 QTest::addColumn<int>("modelCount");
1966 QTest::addColumn<int>("visualCount");
1967 QTest::addColumn<int>("index");
1968 QTest::addColumn<bool>("inItems");
1969 QTest::addColumn<bool>("persisted");
1970 QTest::addColumn<bool>("visible");
1971 QTest::addColumn<bool>("selected");
1972 QTest::addColumn<bool>("modelData");
1973 QTest::addColumn<QString>("property");
1974 QTest::addColumn<QStringList>("propertyData");
1976 const QUrl listModelSource[] = {
1977 testFileUrl("listmodelproperties.qml"),
1978 testFileUrl("listmodelproperties-package.qml") };
1979 const QUrl singleRoleSource[] = {
1980 testFileUrl("singleroleproperties.qml"),
1981 testFileUrl("singleroleproperties-package.qml") };
1982 const QUrl multipleRoleSource[] = {
1983 testFileUrl("multipleroleproperties.qml"),
1984 testFileUrl("multipleroleproperties-package.qml") };
1985 const QUrl stringListSource[] = {
1986 testFileUrl("stringlistproperties.qml"),
1987 testFileUrl("stringlistproperties-package.qml") };
1988 const QUrl objectListSource[] = {
1989 testFileUrl("objectlistproperties.qml"),
1990 testFileUrl("objectlistproperties-package.qml") };
1992 for (int i = 0; i < 2; ++i) {
1994 QTest::newRow("ListModel.items prepend")
1995 << listModelSource[i]
1996 << QString("items.insert(0, {\"number\": \"eight\"})")
1997 << 4 << 5 << 0 << true << false << false << false << true
1998 << QString("number")
1999 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2001 QTest::newRow("ListModel.items append")
2002 << listModelSource[i]
2003 << QString("items.insert({\"number\": \"eight\"})")
2004 << 4 << 5 << 4 << true << false << false << false << true
2005 << QString("number")
2006 << (QStringList() << "one" << "two" << "three" << "four" << "eight");
2008 QTest::newRow("ListModel.items insert at 2")
2009 << listModelSource[i]
2010 << QString("items.insert(2, {\"number\": \"eight\"})")
2011 << 4 << 5 << 2 << true << false << false << false << true
2012 << QString("number")
2013 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2015 QTest::newRow("ListModel.items insert at items.get(2)")
2016 << listModelSource[i]
2017 << QString("items.insert(items.get(2), {\"number\": \"eight\"})")
2018 << 4 << 5 << 2 << true << false << false << false << true
2019 << QString("number")
2020 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2022 QTest::newRow("ListModel.items insert at visibleItems.get(2)")
2023 << listModelSource[i]
2024 << QString("items.insert(visibleItems.get(2), {\"number\": \"eight\"})")
2025 << 4 << 5 << 2 << true << false << false << false << true
2026 << QString("number")
2027 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2029 QTest::newRow("ListModel.selectedItems insert at items.get(2)")
2030 << listModelSource[i]
2031 << QString("selectedItems.insert(items.get(2), {\"number\": \"eight\"})")
2032 << 4 << 5 << 2 << false << false << false << true << true
2033 << QString("number")
2034 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2036 QTest::newRow("ListModel.selectedItems insert at visibleItems.get(2)")
2037 << listModelSource[i]
2038 << QString("selectedItems.insert(visibleItems.get(2), {\"number\": \"eight\"})")
2039 << 4 << 5 << 2 << false << false << false << true << true
2040 << QString("number")
2041 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2043 QTest::newRow("ListModel.items prepend modelData")
2044 << listModelSource[i]
2045 << QString("items.insert(0, {\"modelData\": \"eight\"})")
2046 << 4 << 5 << 0 << true << false << false << false << true
2047 << QString("number")
2048 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2050 QTest::newRow("ListModel.items prepend, edit number")
2051 << listModelSource[i]
2053 "items.insert(0, {\"number\": \"eight\"}); "
2054 "items.get(0).model.number = \"seven\"; }")
2055 << 4 << 5 << 0 << true << false << false << false << true
2056 << QString("number")
2057 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2059 QTest::newRow("ListModel.items prepend, edit modelData")
2060 << listModelSource[i]
2062 "items.insert(0, {\"number\": \"eight\"}); "
2063 "items.get(0).model.modelData = \"seven\"; }")
2064 << 4 << 5 << 0 << true << false << false << false << true
2065 << QString("number")
2066 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2068 QTest::newRow("ListModel.items prepend, edit resolved")
2069 << listModelSource[i]
2071 "items.insert(0, {\"number\": \"eight\"}); "
2072 "items.get(2).model.number = \"seven\"; }")
2073 << 4 << 5 << 0 << true << false << false << false << true
2074 << QString("number")
2075 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2077 QTest::newRow("ListModel.items prepend with groups")
2078 << listModelSource[i]
2079 << QString("items.insert(0, {\"number\": \"eight\"}, [\"visible\", \"truncheon\"])")
2080 << 4 << 5 << 0 << true << false << true << false << true
2081 << QString("number")
2082 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2084 QTest::newRow("ListModel.items append with groups")
2085 << listModelSource[i]
2086 << QString("items.insert({\"number\": \"eight\"}, [\"visible\", \"selected\"])")
2087 << 4 << 5 << 4 << true << false << true << true << true
2088 << QString("number")
2089 << (QStringList() << "one" << "two" << "three" << "four" << "eight");
2091 QTest::newRow("ListModel.items insert at 2 with groups")
2092 << listModelSource[i]
2093 << QString("items.insert(2, {\"number\": \"eight\"}, \"visible\")")
2094 << 4 << 5 << 2 << true << false << true << false << true
2095 << QString("number")
2096 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2099 QTest::newRow("ListModel.items prepend")
2100 << listModelSource[i]
2101 << QString("items.create(0, {\"number\": \"eight\"})")
2102 << 4 << 5 << 0 << true << true << false << false << true
2103 << QString("number")
2104 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2106 QTest::newRow("ListModel.items append")
2107 << listModelSource[i]
2108 << QString("items.create({\"number\": \"eight\"})")
2109 << 4 << 5 << 4 << true << true << false << false << true
2110 << QString("number")
2111 << (QStringList() << "one" << "two" << "three" << "four" << "eight");
2113 QTest::newRow("ListModel.items create at 2")
2114 << listModelSource[i]
2115 << QString("items.create(2, {\"number\": \"eight\"})")
2116 << 4 << 5 << 2 << true << true << false << false << true
2117 << QString("number")
2118 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2120 QTest::newRow("ListModel.items create at items.get(2)")
2121 << listModelSource[i]
2122 << QString("items.create(items.get(2), {\"number\": \"eight\"})")
2123 << 4 << 5 << 2 << true << true << false << false << true
2124 << QString("number")
2125 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2127 QTest::newRow("ListModel.items create at visibleItems.get(2)")
2128 << listModelSource[i]
2129 << QString("items.create(visibleItems.get(2), {\"number\": \"eight\"})")
2130 << 4 << 5 << 2 << true << true << false << false << true
2131 << QString("number")
2132 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2134 QTest::newRow("ListModel.selectedItems create at items.get(2)")
2135 << listModelSource[i]
2136 << QString("selectedItems.create(items.get(2), {\"number\": \"eight\"})")
2137 << 4 << 5 << 2 << false << true << false << true << true
2138 << QString("number")
2139 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2141 QTest::newRow("ListModel.selectedItems create at visibleItems.get(2)")
2142 << listModelSource[i]
2143 << QString("selectedItems.create(visibleItems.get(2), {\"number\": \"eight\"})")
2144 << 4 << 5 << 2 << false << true << false << true << true
2145 << QString("number")
2146 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2148 QTest::newRow("ListModel.items create prepended")
2149 << listModelSource[i]
2150 << QString("items.create(0, {\"number\": \"eight\"})")
2151 << 4 << 5 << 0 << true << true << false << false << true
2152 << QString("number")
2153 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2155 QTest::newRow("ListModel.items create appended")
2156 << listModelSource[i]
2157 << QString("items.create({\"number\": \"eight\"})")
2158 << 4 << 5 << 4 << true << true << false << false << true
2159 << QString("number")
2160 << (QStringList() << "one" << "two" << "three" << "four" << "eight");
2162 QTest::newRow("ListModel.items create at 2")
2163 << listModelSource[i]
2164 << QString("items.create(2, {\"number\": \"eight\"})")
2165 << 4 << 5 << 2 << true << true << false << false << true
2166 << QString("number")
2167 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2169 QTest::newRow("ListModel.items create at items.get(2)")
2170 << listModelSource[i]
2171 << QString("items.create(items.get(2), {\"number\": \"eight\"})")
2172 << 4 << 5 << 2 << true << true << false << false << true
2173 << QString("number")
2174 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2176 QTest::newRow("ListModel.items create at visibleItems.get(2)")
2177 << listModelSource[i]
2178 << QString("items.create(visibleItems.get(2), {\"number\": \"eight\"})")
2179 << 4 << 5 << 2 << true << true << false << false << true
2180 << QString("number")
2181 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2183 QTest::newRow("ListModel.create prepend modelData")
2184 << listModelSource[i]
2185 << QString("items.create(0, {\"modelData\": \"eight\"})")
2186 << 4 << 5 << 0 << true << true << false << false << true
2187 << QString("number")
2188 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2190 QTest::newRow("ListModel.items create prepended, edit number")
2191 << listModelSource[i]
2193 "var item = items.create(0, {\"number\": \"eight\"}); "
2194 "item.setTest3(\"seven\"); }")
2195 << 4 << 5 << 0 << true << true << false << false << true
2196 << QString("number")
2197 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2199 QTest::newRow("ListModel.items create prepended, edit model.number")
2200 << listModelSource[i]
2202 "var item = items.create(0, {\"number\": \"eight\"}); "
2203 "item.setTest4(\"seven\"); }")
2204 << 4 << 5 << 0 << true << true << false << false << true
2205 << QString("number")
2206 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2208 QTest::newRow("ListModel.items create prepended, edit modelData")
2209 << listModelSource[i]
2211 "var item = items.create(0, {\"number\": \"eight\"}); "
2212 "item.setTest5(\"seven\"); }")
2213 << 4 << 5 << 0 << true << true << false << false << true
2214 << QString("number")
2215 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2217 QTest::newRow("ListModel.items create prepended, edit model.modelData")
2218 << listModelSource[i]
2220 "var item = items.create(0, {\"number\": \"eight\"}); "
2221 "item.setTest6(\"seven\"); }")
2222 << 4 << 5 << 0 << true << true << false << false << true
2223 << QString("number")
2224 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2226 QTest::newRow("ListModel.items create prepended with groups")
2227 << listModelSource[i]
2228 << QString("items.create(0, {\"number\": \"eight\"}, [\"visible\", \"truncheon\"])")
2229 << 4 << 5 << 0 << true << true << true << false << true
2230 << QString("number")
2231 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2233 QTest::newRow("ListModel.items create appended with groups")
2234 << listModelSource[i]
2235 << QString("items.create({\"number\": \"eight\"}, [\"visible\", \"selected\"])")
2236 << 4 << 5 << 4 << true << true << true << true << true
2237 << QString("number")
2238 << (QStringList() << "one" << "two" << "three" << "four" << "eight");
2240 QTest::newRow("ListModel.items create inserted with groups")
2241 << listModelSource[i]
2242 << QString("items.create(2, {\"number\": \"eight\"}, \"visible\")")
2243 << 4 << 5 << 2 << true << true << true << false << true
2244 << QString("number")
2245 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2247 QTest::newRow("ListModel.items create prepended clear persistence")
2248 << listModelSource[i]
2249 << QString("{ items.create(0, {\"number\": \"eight\"}); "
2250 "items.get(0).inPersistedItems = false }")
2251 << 4 << 5 << 0 << true << false << false << false << true
2252 << QString("number")
2253 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2255 QTest::newRow("ListModel.items create appended clear persistence")
2256 << listModelSource[i]
2257 << QString("{ items.create({\"number\": \"eight\"}); "
2258 "items.get(4).inPersistedItems = false }")
2259 << 4 << 5 << 4 << true << false << false << false << true
2260 << QString("number")
2261 << (QStringList() << "one" << "two" << "three" << "four" << "eight");
2263 QTest::newRow("ListModel.items create inserted clear persistence")
2264 << listModelSource[i]
2265 << QString("{ items.create(2, {\"number\": \"eight\"}); "
2266 "items.get(2).inPersistedItems = false }")
2267 << 4 << 5 << 2 << true << false << false << false << true
2268 << QString("number")
2269 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2271 // AbstractItemModel (Single Role).
2272 QTest::newRow("AbstractItemModel.items prepend")
2273 << singleRoleSource[i]
2274 << QString("items.insert(0, {\"name\": \"eight\"})")
2275 << 4 << 5 << 0 << true << false << false << false << true
2277 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2279 QTest::newRow("AbstractItemModel.items append")
2280 << singleRoleSource[i]
2281 << QString("items.insert({\"name\": \"eight\"})")
2282 << 4 << 5 << 4 << true << false << false << false << true
2284 << (QStringList() << "one" << "two" << "three" << "four" << "eight");
2286 QTest::newRow("AbstractItemModel.items insert at 2")
2287 << singleRoleSource[i]
2288 << QString("items.insert(2, {\"name\": \"eight\"})")
2289 << 4 << 5 << 2 << true << false << false << false << true
2291 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2293 QTest::newRow("AbstractItemModel.items prepend modelData")
2294 << singleRoleSource[i]
2295 << QString("items.insert(0, {\"modelData\": \"eight\"})")
2296 << 4 << 5 << 0 << true << false << false << false << true
2298 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2300 QTest::newRow("AbstractItemModel.items prepend, edit name")
2301 << singleRoleSource[i]
2303 "items.insert(0, {\"name\": \"eight\"}); "
2304 "items.get(0).model.name = \"seven\"; }")
2305 << 4 << 5 << 0 << true << false << false << false << true
2307 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2309 QTest::newRow("AbstractItemModel.items prepend, edit modelData")
2310 << singleRoleSource[i]
2312 "items.insert(0, {\"name\": \"eight\"}); "
2313 "items.get(0).model.modelData = \"seven\"; }")
2314 << 4 << 5 << 0 << true << false << false << false << true
2316 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2318 QTest::newRow("AbstractItemModel.items prepend, edit resolved")
2319 << singleRoleSource[i]
2321 "items.insert(0, {\"name\": \"eight\"}); "
2322 "items.get(2).model.name = \"seven\"; }")
2323 << 4 << 5 << 0 << true << false << false << false << true
2325 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2327 QTest::newRow("AbstractItemModel.create prepend modelData")
2328 << singleRoleSource[i]
2329 << QString("items.create(0, {\"modelData\": \"eight\"})")
2330 << 4 << 5 << 0 << true << true << false << false << true
2332 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2334 QTest::newRow("AbstractItemModel.items create prepended, edit name")
2335 << singleRoleSource[i]
2337 "var item = items.create(0, {\"name\": \"eight\"}); "
2338 "item.setTest3(\"seven\"); }")
2339 << 4 << 5 << 0 << true << true << false << false << true
2341 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2343 QTest::newRow("AbstractItemModel.items create prepended, edit model.name")
2344 << singleRoleSource[i]
2346 "var item = items.create(0, {\"name\": \"eight\"}); "
2347 "item.setTest4(\"seven\"); }")
2348 << 4 << 5 << 0 << true << true << false << false << true
2350 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2352 QTest::newRow("AbstractItemModel.items create prepended, edit modelData")
2353 << singleRoleSource[i]
2355 "var item = items.create(0, {\"name\": \"eight\"}); "
2356 "item.setTest5(\"seven\"); }")
2357 << 4 << 5 << 0 << true << true << false << false << true
2359 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2361 QTest::newRow("AbstractItemModel.items create prepended, edit model.modelData")
2362 << singleRoleSource[i]
2364 "var item = items.create(0, {\"name\": \"eight\"}); "
2365 "item.setTest6(\"seven\"); }")
2366 << 4 << 5 << 0 << true << true << false << false << true
2368 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2370 // AbstractItemModel (Multiple Roles).
2371 QTest::newRow("StandardItemModel.items prepend")
2372 << multipleRoleSource[i]
2373 << QString("items.insert(0, {\"display\": \"Row 8 Item\"})")
2374 << 4 << 5 << 0 << true << false << false << false << false
2375 << QString("display")
2376 << (QStringList() << "Row 8 Item" << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2378 QTest::newRow("StandardItemModel.items append")
2379 << multipleRoleSource[i]
2380 << QString("items.insert({\"display\": \"Row 8 Item\"})")
2381 << 4 << 5 << 4 << true << false << false << false << false
2382 << QString("display")
2383 << (QStringList() << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item" << "Row 8 Item");
2385 QTest::newRow("StandardItemModel.items insert at 2")
2386 << multipleRoleSource[i]
2387 << QString("items.insert(2, {\"display\": \"Row 8 Item\"})")
2388 << 4 << 5 << 2 << true << false << false << false << false
2389 << QString("display")
2390 << (QStringList() << "Row 1 Item" << "Row 2 Item" << "Row 8 Item" << "Row 3 Item" << "Row 4 Item");
2392 QTest::newRow("StandardItemModel.items prepend modelData")
2393 << multipleRoleSource[i]
2394 << QString("items.insert(0, {\"modelData\": \"Row 8 Item\"})")
2395 << 4 << 5 << 0 << true << false << false << false << false
2396 << QString("display")
2397 << (QStringList() << QString() << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2399 QTest::newRow("StandardItemModel.items prepend, edit display")
2400 << multipleRoleSource[i]
2402 "items.insert(0, {\"display\": \"Row 8 Item\"}); "
2403 "items.get(0).model.display = \"Row 7 Item\"; }")
2404 << 4 << 5 << 0 << true << false << false << false << false
2405 << QString("display")
2406 << (QStringList() << "Row 7 Item" << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2408 QTest::newRow("StandardItemModel.items prepend, edit modelData")
2409 << multipleRoleSource[i]
2411 "items.insert(0, {\"display\": \"Row 8 Item\"}); "
2412 "items.get(0).model.modelData = \"Row 7 Item\"; }")
2413 << 4 << 5 << 0 << true << false << false << false << false
2414 << QString("display")
2415 << (QStringList() << "Row 8 Item" << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2417 QTest::newRow("StandardItemModel.items prepend, edit resolved")
2418 << multipleRoleSource[i]
2420 "items.insert(0, {\"display\": \"Row 8 Item\"}); "
2421 "items.get(2).model.display = \"Row 7 Item\"; }")
2422 << 4 << 5 << 0 << true << false << false << false << false
2423 << QString("display")
2424 << (QStringList() << "Row 8 Item" << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2426 QTest::newRow("StandardItemModel.create prepend modelData")
2427 << multipleRoleSource[i]
2428 << QString("items.create(0, {\"modelData\": \"Row 8 Item\"})")
2429 << 4 << 5 << 0 << true << true << false << false << false
2430 << QString("display")
2431 << (QStringList() << QString() << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2433 QTest::newRow("StandardItemModel.items create prepended, edit display")
2434 << multipleRoleSource[i]
2436 "var item = items.create(0, {\"display\": \"Row 8 Item\"}); "
2437 "item.setTest3(\"Row 7 Item\"); }")
2438 << 4 << 5 << 0 << true << true << false << false << false
2439 << QString("display")
2440 << (QStringList() << "Row 7 Item" << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2442 QTest::newRow("StandardItemModel.items create prepended, edit model.display")
2443 << multipleRoleSource[i]
2445 "var item = items.create(0, {\"display\": \"Row 8 Item\"}); "
2446 "item.setTest4(\"Row 7 Item\"); }")
2447 << 4 << 5 << 0 << true << true << false << false << false
2448 << QString("display")
2449 << (QStringList() << "Row 7 Item" << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2452 QTest::newRow("StringList.items prepend")
2453 << stringListSource[i]
2454 << QString("items.insert(0, {\"modelData\": \"eight\"})")
2455 << 4 << 5 << 0 << true << false << false << false << false
2456 << QString("modelData")
2457 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2459 QTest::newRow("StringList.items append")
2460 << stringListSource[i]
2461 << QString("items.insert({\"modelData\": \"eight\"})")
2462 << 4 << 5 << 4 << true << false << false << false << false
2463 << QString("modelData")
2464 << (QStringList() << "one" << "two" << "three" << "four" << "eight");
2466 QTest::newRow("StringList.items insert at 2")
2467 << stringListSource[i]
2468 << QString("items.insert(2, {\"modelData\": \"eight\"})")
2469 << 4 << 5 << 2 << true << false << false << false << false
2470 << QString("modelData")
2471 << (QStringList() << "one" << "two" << "eight" << "three" << "four");
2473 QTest::newRow("StringList.items prepend, edit modelData")
2474 << stringListSource[i]
2476 "items.insert(0, {\"modelData\": \"eight\"}); "
2477 "items.get(0).model.modelData = \"seven\"; }")
2478 << 4 << 5 << 0 << true << false << false << false << false
2479 << QString("modelData")
2480 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2482 QTest::newRow("StringList.items prepend, edit resolved")
2483 << stringListSource[i]
2485 "items.insert(0, {\"modelData\": \"eight\"}); "
2486 "items.get(2).model.modelData = \"seven\"; }")
2487 << 4 << 5 << 0 << true << false << false << false << false
2488 << QString("modelData")
2489 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2491 QTest::newRow("StringList.create prepend modelData")
2492 << stringListSource[i]
2493 << QString("items.create(0, {\"modelData\": \"eight\"})")
2494 << 4 << 5 << 0 << true << true << false << false << false
2495 << QString("modelData")
2496 << (QStringList() << "eight" << "one" << "two" << "three" << "four");
2498 QTest::newRow("StringList.items create prepended, edit modelData")
2499 << stringListSource[i]
2501 "var item = items.create(0, {\"modelData\": \"eight\"}); "
2502 "item.setTest3(\"seven\"); }")
2503 << 4 << 5 << 0 << true << true << false << false << false
2504 << QString("modelData")
2505 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2507 QTest::newRow("StringList.items create prepended, edit model.modelData")
2508 << stringListSource[i]
2510 "var item = items.create(0, {\"modelData\": \"eight\"}); "
2511 "item.setTest4(\"seven\"); }")
2512 << 4 << 5 << 0 << true << true << false << false << false
2513 << QString("modelData")
2514 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2517 QTest::newRow("ObjectList.items prepend")
2518 << objectListSource[i]
2519 << QString("items.insert(0, {\"name\": \"Item 8\"})")
2520 << 4 << 4 << 4 << false << false << false << false << false
2522 << (QStringList() << "Item 1" << "Item 2" << "Item 3" << "Item 4");
2524 QTest::newRow("ObjectList.items append")
2525 << objectListSource[i]
2526 << QString("items.insert({\"name\": \"Item 8\"})")
2527 << 4 << 4 << 4 << false << false << false << false << false
2529 << (QStringList() << "Item 1" << "Item 2" << "Item 3" << "Item 4");
2531 QTest::newRow("ObjectList.items insert at 2")
2532 << objectListSource[i]
2533 << QString("items.insert(2, {\"name\": \"Item 8\"})")
2534 << 4 << 4 << 4 << false << false << false << false << false
2536 << (QStringList() << "Item 1" << "Item 2" << "Item 3" << "Item 4");
2540 void tst_qquickvisualdatamodel::insert()
2542 QFETCH(QUrl, source);
2543 QFETCH(QString, expression);
2544 QFETCH(int, modelCount);
2545 QFETCH(int, visualCount);
2547 QFETCH(bool, inItems);
2548 QFETCH(bool, persisted);
2549 QFETCH(bool, visible);
2550 QFETCH(bool, selected);
2551 QFETCH(bool, modelData);
2552 QFETCH(QString, property);
2553 QFETCH(QStringList, propertyData);
2555 QQuickCanvas canvas;
2557 QDeclarativeComponent component(&engine);
2558 component.loadUrl(source);
2559 QScopedPointer<QObject> object(component.create());
2560 QQuickListView *listView = qobject_cast<QQuickListView *>(object.data());
2562 listView->setParentItem(canvas.rootItem());
2564 QQuickItem *contentItem = listView->contentItem();
2565 QVERIFY(contentItem);
2567 QObject *visualModel = listView->findChild<QObject *>("visualModel");
2568 QVERIFY(visualModel);
2570 evaluate<void>(visualModel, expression);
2572 QCOMPARE(evaluate<int>(listView, "count"), inItems ? visualCount : modelCount);
2573 QCOMPARE(evaluate<int>(visualModel, "count"), inItems ? visualCount : modelCount);
2574 QCOMPARE(evaluate<int>(visualModel, "items.count"), inItems ? visualCount : modelCount);
2575 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), persisted ? 1 : 0);
2576 QCOMPARE(evaluate<int>(visualModel, "visibleItems.count"), visible ? visualCount : modelCount);
2577 QCOMPARE(evaluate<int>(visualModel, "selectedItems.count"), selected ? 1 : 0);
2579 QCOMPARE(propertyData.count(), visualCount);
2580 for (int i = 0; i < visualCount; ++i) {
2582 if (modelIndex > index)
2584 else if (modelIndex == index)
2587 const int itemsIndex = inItems || i <= index ? i : i - 1;
2591 get = QString("items.get(%1)").arg(itemsIndex);
2593 QQuickItem *item = findItem<QQuickItem>(contentItem, "delegate", modelIndex);
2596 QCOMPARE(evaluate<int>(item, "test1"), modelIndex);
2597 QCOMPARE(evaluate<int>(item, "test2"), modelIndex);
2598 QCOMPARE(evaluate<QString>(item, "test3"), propertyData.at(i));
2599 QCOMPARE(evaluate<QString>(item, "test4"), propertyData.at(i));
2602 QCOMPARE(evaluate<QString>(item, "test5"), propertyData.at(i));
2603 QCOMPARE(evaluate<QString>(item, "test6"), propertyData.at(i));
2606 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inItems"), true);
2607 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inPersistedItems"), false);
2608 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inVisible"), true);
2609 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inSelected"), false);
2610 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.isUnresolved"), false);
2612 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.itemsIndex"), itemsIndex);
2613 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.persistedItemsIndex"), persisted && i > index ? 1 : 0);
2614 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.visibleIndex"), visible || i <= index ? i : i - 1);
2615 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.selectedIndex"), selected && i > index ? 1 : 0);
2616 } else if (inItems) {
2617 get = QString("items.get(%1)").arg(index);
2618 } else if (persisted) {
2619 get = "persistedItems.get(0)";
2620 } else if (visible) {
2621 get = QString("visibleItems.get(%1)").arg(index);
2622 } else if (selected) {
2623 get = "selectedItems.get(0)";
2628 QCOMPARE(evaluate<int>(visualModel, get + ".model.index"), modelIndex);
2630 QCOMPARE(evaluate<QString>(visualModel, get + ".model." + property), propertyData.at(i));
2632 QCOMPARE(evaluate<bool>(visualModel, get + ".inItems"), inItems || i != index);
2633 QCOMPARE(evaluate<bool>(visualModel, get + ".inPersistedItems"), persisted && i == index);
2634 QCOMPARE(evaluate<bool>(visualModel, get + ".inVisible"), visible || i != index);
2635 QCOMPARE(evaluate<bool>(visualModel, get + ".inSelected"), selected && i == index);
2636 QCOMPARE(evaluate<bool>(visualModel, get + ".isUnresolved"), i == index);
2638 QCOMPARE(evaluate<int>(visualModel, get + ".itemsIndex"), inItems || i <= index ? i : i - 1);
2639 QCOMPARE(evaluate<int>(visualModel, get + ".persistedItemsIndex"), persisted && i > index ? 1 : 0);
2640 QCOMPARE(evaluate<int>(visualModel, get + ".visibleIndex"), visible || i <= index ? i : i - 1);
2641 QCOMPARE(evaluate<int>(visualModel, get + ".selectedIndex"), selected && i > index ? 1 : 0);
2647 item = evaluate<QObject *>(visualModel, QString("items.create(%1)").arg(index));
2649 item = evaluate<QObject *>(visualModel, QString("persistedItems.create(%1)").arg(0));
2651 item = evaluate<QObject *>(visualModel, QString("visibleItems.create(%1)").arg(index));
2653 item = evaluate<QObject *>(visualModel, QString("selectedItems.create(%1)").arg(0));
2659 QCOMPARE(evaluate<int>(item, "test1"), -1);
2660 QCOMPARE(evaluate<int>(item, "test2"), -1);
2661 QCOMPARE(evaluate<QString>(item, "test3"), propertyData.at(index));
2662 QCOMPARE(evaluate<QString>(item, "test4"), propertyData.at(index));
2665 QCOMPARE(evaluate<QString>(item, "test5"), propertyData.at(index));
2666 QCOMPARE(evaluate<QString>(item, "test6"), propertyData.at(index));
2669 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inItems"), inItems);
2670 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inPersistedItems"), true);
2671 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inVisible"), visible);
2672 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inSelected"), selected);
2673 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.isUnresolved"), true);
2675 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.itemsIndex"), index);
2676 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.persistedItemsIndex"), 0);
2677 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.visibleIndex"), index);
2678 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.selectedIndex"), 0);
2681 void tst_qquickvisualdatamodel::resolve_data()
2683 QTest::addColumn<QUrl>("source");
2684 QTest::addColumn<QString>("setupExpression");
2685 QTest::addColumn<QString>("resolveExpression");
2686 QTest::addColumn<int>("unresolvedCount");
2687 QTest::addColumn<int>("modelCount");
2688 QTest::addColumn<int>("visualCount");
2689 QTest::addColumn<int>("index");
2690 QTest::addColumn<bool>("inItems");
2691 QTest::addColumn<bool>("persisted");
2692 QTest::addColumn<bool>("visible");
2693 QTest::addColumn<bool>("selected");
2694 QTest::addColumn<bool>("modelData");
2695 QTest::addColumn<QString>("property");
2696 QTest::addColumn<QStringList>("propertyData");
2698 const QUrl listModelSource[] = {
2699 testFileUrl("listmodelproperties.qml"),
2700 testFileUrl("listmodelproperties-package.qml") };
2701 const QUrl singleRoleSource[] = {
2702 testFileUrl("singleroleproperties.qml"),
2703 testFileUrl("singleroleproperties-package.qml") };
2704 const QUrl multipleRoleSource[] = {
2705 testFileUrl("multipleroleproperties.qml"),
2706 testFileUrl("multipleroleproperties-package.qml") };
2707 const QUrl stringListSource[] = {
2708 testFileUrl("stringlistproperties.qml"),
2709 testFileUrl("stringlistproperties-package.qml") };
2710 const QUrl objectListSource[] = {
2711 testFileUrl("objectlistproperties.qml"),
2712 testFileUrl("objectlistproperties-package.qml") };
2714 for (int i = 0; i < 2; ++i) {
2716 QTest::newRow("ListModel.items prepend, resolve prepended")
2717 << listModelSource[i]
2718 << QString("items.insert(0, {\"number\": \"eight\"})")
2719 << QString("{ listModel.insert(0, {\"number\": \"seven\"}); items.resolve(0, 1) }")
2720 << 5 << 5 << 5 << 0 << true << false << true << false << true
2721 << QString("number")
2722 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2724 QTest::newRow("ListModel.items prepend, resolve appended")
2725 << listModelSource[i]
2726 << QString("items.insert(0, {\"number\": \"eight\"})")
2727 << QString("{ listModel.append({\"number\": \"seven\"}); items.resolve(0, 5) }")
2728 << 5 << 5 << 5 << 4 << true << false << true << false << true
2729 << QString("number")
2730 << (QStringList() << "one" << "two" << "three" << "four" << "seven");
2732 QTest::newRow("ListModel.items prepend, resolve inserted")
2733 << listModelSource[i]
2734 << QString("items.insert(0, {\"number\": \"eight\"})")
2735 << QString("{ listModel.insert(2, {\"number\": \"seven\"}); items.resolve(0, 3) }")
2736 << 5 << 5 << 5 << 2 << true << false << true << false << true
2737 << QString("number")
2738 << (QStringList() << "one" << "two" << "seven" << "three" << "four");
2740 QTest::newRow("ListModel.items append, resolve prepended")
2741 << listModelSource[i]
2742 << QString("items.insert({\"number\": \"eight\"})")
2743 << QString("{ listModel.insert(0, {\"number\": \"seven\"}); items.resolve(5, 0) }")
2744 << 5 << 5 << 5 << 0 << true << false << true << false << true
2745 << QString("number")
2746 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2748 QTest::newRow("ListModel.items append, resolve appended")
2749 << listModelSource[i]
2750 << QString("items.insert({\"number\": \"eight\"})")
2751 << QString("{ listModel.append({\"number\": \"seven\"}); items.resolve(5, 4) }")
2752 << 5 << 5 << 5 << 4 << true << false << true << false << true
2753 << QString("number")
2754 << (QStringList() << "one" << "two" << "three" << "four" << "seven");
2756 QTest::newRow("ListModel.items append, resolve inserted")
2757 << listModelSource[i]
2758 << QString("items.insert({\"number\": \"eight\"})")
2759 << QString("{ listModel.insert(2, {\"number\": \"seven\"}); items.resolve(5, 2) }")
2760 << 5 << 5 << 5 << 2 << true << false << true << false << true
2761 << QString("number")
2762 << (QStringList() << "one" << "two" << "seven" << "three" << "four");
2764 QTest::newRow("ListModel.items insert, resolve prepended")
2765 << listModelSource[i]
2766 << QString("items.insert(2, {\"number\": \"eight\"})")
2767 << QString("{ listModel.insert(0, {\"number\": \"seven\"}); items.resolve(3, 0) }")
2768 << 5 << 5 << 5 << 0 << true << false << true << false << true
2769 << QString("number")
2770 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2772 QTest::newRow("ListModel.items insert, resolve appended")
2773 << listModelSource[i]
2774 << QString("items.insert(2, {\"number\": \"eight\"})")
2775 << QString("{ listModel.append({\"number\": \"seven\"}); items.resolve(2, 5) }")
2776 << 5 << 5 << 5 << 4 << true << false << true << false << true
2777 << QString("number")
2778 << (QStringList() << "one" << "two" << "three" << "four" << "seven");
2780 QTest::newRow("ListModel.items insert, resolve inserted")
2781 << listModelSource[i]
2782 << QString("items.insert(2, {\"number\": \"eight\"})")
2783 << QString("{ listModel.insert(2, {\"number\": \"seven\"}); items.resolve(2, 3) }")
2784 << 5 << 5 << 5 << 2 << true << false << true << false << true
2785 << QString("number")
2786 << (QStringList() << "one" << "two" << "seven" << "three" << "four");
2788 QTest::newRow("ListModel.items prepend, move resolved")
2789 << listModelSource[i]
2790 << QString("items.insert(0, {\"number\": \"eight\"})")
2791 << QString("{ listModel.insert(0, {\"number\": \"seven\"}); "
2792 "items.resolve(0, 1); "
2793 "listModel.move(0, 2, 1) }")
2794 << 5 << 5 << 5 << 2 << true << false << true << false << true
2795 << QString("number")
2796 << (QStringList() << "one" << "two" << "seven" << "three" << "four");
2798 QTest::newRow("ListModel.items append, move resolved")
2799 << listModelSource[i]
2800 << QString("items.insert({\"number\": \"eight\"})")
2801 << QString("{ listModel.append({\"number\": \"seven\"}); "
2802 "items.resolve(5, 4); "
2803 "listModel.move(4, 2, 1) }")
2804 << 5 << 5 << 5 << 2 << true << false << true << false << true
2805 << QString("number")
2806 << (QStringList() << "one" << "two" << "seven" << "three" << "four");
2808 QTest::newRow("ListModel.items insert, move resolved")
2809 << listModelSource[i]
2810 << QString("items.insert(2, {\"number\": \"eight\"})")
2811 << QString("{ listModel.insert(2, {\"number\": \"seven\"}); "
2812 "items.resolve(2, 3);"
2813 "listModel.move(2, 0, 1) }")
2814 << 5 << 5 << 5 << 0 << true << false << true << false << true
2815 << QString("number")
2816 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2818 QTest::newRow("ListModel.items prepend, remove resolved")
2819 << listModelSource[i]
2820 << QString("items.insert(0, {\"number\": \"eight\"})")
2821 << QString("{ listModel.insert(0, {\"number\": \"seven\"}); "
2822 "items.resolve(0, 1); "
2823 "listModel.remove(0, 1) }")
2824 << 5 << 4 << 4 << 4 << false << false << false << false << true
2825 << QString("number")
2826 << (QStringList() << "one" << "two" << "three" << "four");
2828 QTest::newRow("ListModel.items append, remove resolved")
2829 << listModelSource[i]
2830 << QString("items.insert({\"number\": \"eight\"})")
2831 << QString("{ listModel.append({\"number\": \"seven\"}); "
2832 "items.resolve(5, 4); "
2833 "listModel.remove(4, 1) }")
2834 << 5 << 4 << 4 << 4 << false << false << false << false << true
2835 << QString("number")
2836 << (QStringList() << "one" << "two" << "three" << "four");
2838 QTest::newRow("ListModel.items insert, remove resolved")
2839 << listModelSource[i]
2840 << QString("items.insert(2, {\"number\": \"eight\"})")
2841 << QString("{ listModel.insert(2, {\"number\": \"seven\"}); "
2842 "items.resolve(2, 3);"
2843 "listModel.remove(2, 1) }")
2844 << 5 << 4 << 4 << 4 << false << false << false << false << true
2845 << QString("number")
2846 << (QStringList() << "one" << "two" << "three" << "four");
2848 QTest::newRow("ListModel.selectedItems prepend, resolve prepended")
2849 << listModelSource[i]
2850 << QString("selectedItems.insert(0, {\"number\": \"eight\"})")
2851 << QString("{ listModel.insert(0, {\"number\": \"seven\"}); "
2852 "selectedItems.resolve(selectedItems.get(0), items.get(0)) }")
2853 << 4 << 5 << 5 << 0 << true << false << true << true << true
2854 << QString("number")
2855 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2857 QTest::newRow("ListModel.selectedItems prepend, resolve appended")
2858 << listModelSource[i]
2859 << QString("selectedItems.insert(0, {\"number\": \"eight\"})")
2860 << QString("{ listModel.append({\"number\": \"seven\"}); "
2861 "selectedItems.resolve(selectedItems.get(0), items.get(4)) }")
2862 << 4 << 5 << 5 << 4 << true << false << true << true << true
2863 << QString("number")
2864 << (QStringList() << "one" << "two" << "three" << "four" << "seven");
2866 QTest::newRow("ListModel.selectedItems prepend, resolve inserted")
2867 << listModelSource[i]
2868 << QString("selectedItems.insert(0, {\"number\": \"eight\"})")
2869 << QString("{ listModel.insert(2, {\"number\": \"seven\"}); "
2870 "selectedItems.resolve(selectedItems.get(0), items.get(2)) }")
2871 << 4 << 5 << 5 << 2 << true << false << true << true << true
2872 << QString("number")
2873 << (QStringList() << "one" << "two" << "seven" << "three" << "four");
2875 QTest::newRow("ListModel.selectedItems append, resolve prepended")
2876 << listModelSource[i]
2877 << QString("selectedItems.insert({\"number\": \"eight\"})")
2878 << QString("{ listModel.insert(0, {\"number\": \"seven\"}); "
2879 "selectedItems.resolve(selectedItems.get(0), items.get(0)) }")
2880 << 4 << 5 << 5 << 0 << true << false << true << true << true
2881 << QString("number")
2882 << (QStringList() << "seven" << "one" << "two" << "three" << "four");
2884 QTest::newRow("ListModel.selectedItems append, resolve appended")
2885 << listModelSource[i]
2886 << QString("selectedItems.insert({\"number\": \"eight\"})")
2887 << QString("{ listModel.append({\"number\": \"seven\"}); "
2888 "selectedItems.resolve(selectedItems.get(0), items.get(4)) }")
2889 << 4 << 5 << 5 << 4 << true << false << true << true << true
2890 << QString("number")
2891 << (QStringList() << "one" << "two" << "three" << "four" << "seven");
2893 QTest::newRow("ListModel.selectedItems append, resolve inserted")
2894 << listModelSource[i]
2895 << QString("selectedItems.insert({\"number\": \"eight\"})")
2896 << QString("{ listModel.insert(2, {\"number\": \"seven\"}); "
2897 "selectedItems.resolve(selectedItems.get(0), items.get(2)) }")
2898 << 4 << 5 << 5 << 2 << true << false << true << true << true
2899 << QString("number")
2900 << (QStringList() << "one" << "two" << "seven" << "three" << "four");
2902 // AbstractItemModel (Single Role)
2903 QTest::newRow("ListModel.items prepend, resolve prepended")
2904 << singleRoleSource[i]
2905 << QString("items.insert(0, {\"name\": \"eight\"})")
2906 << QString("{ items.resolve(0, 1) }")
2907 << 5 << 4 << 4 << 0 << true << false << true << false << true
2909 << (QStringList() << "one" << "two" << "three" << "four");
2912 QTest::newRow("ListModel.items append, resolve appended")
2913 << singleRoleSource[i]
2914 << QString("items.insert({\"name\": \"eight\"})")
2915 << QString("{ items.resolve(4, 3) }")
2916 << 5 << 4 << 4 << 3 << true << false << true << false << true
2918 << (QStringList() << "one" << "two" << "three" << "four");
2920 QTest::newRow("ListModel.items insert, resolve inserted")
2921 << singleRoleSource[i]
2922 << QString("items.insert(2, {\"name\": \"eight\"})")
2923 << QString("{ items.resolve(2, 3) }")
2924 << 5 << 4 << 4 << 2 << true << false << true << false << true
2926 << (QStringList() << "one" << "two" << "three" << "four");
2928 // AbstractItemModel (Single Role)
2929 QTest::newRow("AbstractItemModel.items prepend, resolve prepended")
2930 << singleRoleSource[i]
2931 << QString("items.insert(0, {\"name\": \"eight\"})")
2932 << QString("{ items.resolve(0, 1) }")
2933 << 5 << 4 << 4 << 0 << true << false << true << false << true
2935 << (QStringList() << "one" << "two" << "three" << "four");
2937 QTest::newRow("AbstractItemModel.items append, resolve appended")
2938 << singleRoleSource[i]
2939 << QString("items.insert({\"name\": \"eight\"})")
2940 << QString("{ items.resolve(4, 3) }")
2941 << 5 << 4 << 4 << 3 << true << false << true << false << true
2943 << (QStringList() << "one" << "two" << "three" << "four");
2945 QTest::newRow("AbstractItemModel.items insert, resolve inserted")
2946 << singleRoleSource[i]
2947 << QString("items.insert(2, {\"name\": \"eight\"})")
2948 << QString("{ items.resolve(2, 3) }")
2949 << 5 << 4 << 4 << 2 << true << false << true << false << true
2951 << (QStringList() << "one" << "two" << "three" << "four");
2953 // AbstractItemModel (Multiple Roles)
2954 QTest::newRow("StandardItemModel.items prepend, resolve prepended")
2955 << multipleRoleSource[i]
2956 << QString("items.insert(0, {\"display\": \"Row 8 Item\"})")
2957 << QString("{ items.resolve(0, 1) }")
2958 << 5 << 4 << 4 << 0 << true << false << true << false << false
2959 << QString("display")
2960 << (QStringList() << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2962 QTest::newRow("StandardItemModel.items append, resolve appended")
2963 << multipleRoleSource[i]
2964 << QString("items.insert({\"display\": \"Row 8 Item\"})")
2965 << QString("{ items.resolve(4, 3) }")
2966 << 5 << 4 << 4 << 3 << true << false << true << false << false
2967 << QString("display")
2968 << (QStringList() << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2970 QTest::newRow("StandardItemModel.items insert, resolve inserted")
2971 << multipleRoleSource[i]
2972 << QString("items.insert(2, {\"display\": \"Row 8 Item\"})")
2973 << QString("{ items.resolve(2, 3) }")
2974 << 5 << 4 << 4 << 2 << true << false << true << false << false
2975 << QString("display")
2976 << (QStringList() << "Row 1 Item" << "Row 2 Item" << "Row 3 Item" << "Row 4 Item");
2979 QTest::newRow("StringList.items prepend, resolve prepended")
2980 << stringListSource[i]
2981 << QString("items.insert(0, {\"modelData\": \"eight\"})")
2982 << QString("{ items.resolve(0, 1) }")
2983 << 5 << 4 << 4 << 0 << true << false << true << false << false
2984 << QString("modelData")
2985 << (QStringList() << "one" << "two" << "three" << "four");
2987 QTest::newRow("StringList.items append, resolve appended")
2988 << stringListSource[i]
2989 << QString("items.insert({\"modelData\": \"eight\"})")
2990 << QString("{ items.resolve(4, 3) }")
2991 << 5 << 4 << 4 << 3 << true << false << true << false << false
2992 << QString("modelData")
2993 << (QStringList() << "one" << "two" << "three" << "four");
2995 QTest::newRow("StringList.items insert, resolve inserted")
2996 << stringListSource[i]
2997 << QString("items.insert(2, {\"modelData\": \"eight\"})")
2998 << QString("{ items.resolve(2, 3) }")
2999 << 5 << 4 << 4 << 2 << true << false << true << false << false
3000 << QString("modelData")
3001 << (QStringList() << "one" << "two" << "three" << "four");
3005 void tst_qquickvisualdatamodel::resolve()
3007 QFETCH(QUrl, source);
3008 QFETCH(QString, setupExpression);
3009 QFETCH(QString, resolveExpression);
3010 QFETCH(int, unresolvedCount);
3011 QFETCH(int, modelCount);
3012 QFETCH(int, visualCount);
3014 QFETCH(bool, inItems);
3015 QFETCH(bool, persisted);
3016 QFETCH(bool, visible);
3017 QFETCH(bool, selected);
3018 QFETCH(bool, modelData);
3019 QFETCH(QString, property);
3020 QFETCH(QStringList, propertyData);
3022 QQuickCanvas canvas;
3024 QDeclarativeComponent component(&engine);
3025 component.loadUrl(source);
3026 QScopedPointer<QObject> object(component.create());
3027 QQuickListView *listView = qobject_cast<QQuickListView *>(object.data());
3029 listView->setParentItem(canvas.rootItem());
3031 QQuickItem *contentItem = listView->contentItem();
3032 QVERIFY(contentItem);
3034 QObject *visualModel = listView->findChild<QObject *>("visualModel");
3035 QVERIFY(visualModel);
3037 evaluate<void>(visualModel, setupExpression);
3038 QCOMPARE(evaluate<int>(listView, "count"), unresolvedCount);
3040 evaluate<void>(visualModel, resolveExpression);
3042 QCOMPARE(evaluate<int>(listView, "count"), inItems ? visualCount : modelCount);
3043 QCOMPARE(evaluate<int>(visualModel, "count"), inItems ? visualCount : modelCount);
3044 QCOMPARE(evaluate<int>(visualModel, "items.count"), inItems ? visualCount : modelCount);
3045 QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), persisted ? 1 : 0);
3046 QCOMPARE(evaluate<int>(visualModel, "visibleItems.count"), visible ? visualCount : modelCount);
3047 QCOMPARE(evaluate<int>(visualModel, "selectedItems.count"), selected ? 1 : 0);
3049 QCOMPARE(propertyData.count(), visualCount);
3050 for (int i = 0; i < visualCount; ++i) {
3053 const int itemsIndex = inItems || i <= index ? i : i - 1;
3057 get = QString("items.get(%1)").arg(itemsIndex);
3059 QQuickItem *item = findItem<QQuickItem>(contentItem, "delegate", modelIndex);
3062 QCOMPARE(evaluate<int>(item, "test1"), modelIndex);
3063 QCOMPARE(evaluate<int>(item, "test2"), modelIndex);
3064 QCOMPARE(evaluate<QString>(item, "test3"), propertyData.at(i));
3065 QCOMPARE(evaluate<QString>(item, "test4"), propertyData.at(i));
3068 QCOMPARE(evaluate<QString>(item, "test5"), propertyData.at(i));
3069 QCOMPARE(evaluate<QString>(item, "test6"), propertyData.at(i));
3072 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inItems"), true);
3073 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inPersistedItems"), false);
3074 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inVisible"), true);
3075 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inSelected"), false);
3076 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.isUnresolved"), false);
3078 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.itemsIndex"), itemsIndex);
3079 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.persistedItemsIndex"), persisted && i > index ? 1 : 0);
3080 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.visibleIndex"), visible || i <= index ? i : i - 1);
3081 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.selectedIndex"), selected && i > index ? 1 : 0);
3082 } else if (inItems) {
3083 get = QString("items.get(%1)").arg(index);
3084 } else if (persisted) {
3085 get = "persistedItems.get(0)";
3086 } else if (visible) {
3087 get = QString("visibleItems.get(%1)").arg(index);
3088 } else if (selected) {
3089 get = "selectedItems.get(0)";
3094 QCOMPARE(evaluate<int>(visualModel, get + ".model.index"), modelIndex);
3096 QCOMPARE(evaluate<QString>(visualModel, get + ".model." + property), propertyData.at(i));
3098 QCOMPARE(evaluate<bool>(visualModel, get + ".inItems"), inItems || i != index);
3099 QCOMPARE(evaluate<bool>(visualModel, get + ".inPersistedItems"), persisted && i == index);
3100 QCOMPARE(evaluate<bool>(visualModel, get + ".inVisible"), visible || i != index);
3101 QCOMPARE(evaluate<bool>(visualModel, get + ".inSelected"), selected && i == index);
3102 QCOMPARE(evaluate<bool>(visualModel, get + ".isUnresolved"), false);
3104 QCOMPARE(evaluate<int>(visualModel, get + ".itemsIndex"), inItems || i <= index ? i : i - 1);
3105 QCOMPARE(evaluate<int>(visualModel, get + ".persistedItemsIndex"), persisted && i > index ? 1 : 0);
3106 QCOMPARE(evaluate<int>(visualModel, get + ".visibleIndex"), visible || i <= index ? i : i - 1);
3107 QCOMPARE(evaluate<int>(visualModel, get + ".selectedIndex"), selected && i > index ? 1 : 0);
3113 item = evaluate<QObject *>(visualModel, QString("items.create(%1)").arg(index));
3115 item = evaluate<QObject *>(visualModel, QString("persistedItems.create(%1)").arg(0));
3117 item = evaluate<QObject *>(visualModel, QString("visibleItems.create(%1)").arg(index));
3119 item = evaluate<QObject *>(visualModel, QString("selectedItems.create(%1)").arg(0));
3125 QCOMPARE(evaluate<int>(item, "test1"), index);
3126 QCOMPARE(evaluate<int>(item, "test2"), index);
3127 QCOMPARE(evaluate<QString>(item, "test3"), propertyData.at(index));
3128 QCOMPARE(evaluate<QString>(item, "test4"), propertyData.at(index));
3131 QCOMPARE(evaluate<QString>(item, "test5"), propertyData.at(index));
3132 QCOMPARE(evaluate<QString>(item, "test6"), propertyData.at(index));
3135 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inItems"), inItems);
3136 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inPersistedItems"), true);
3137 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inVisible"), visible);
3138 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.inSelected"), selected);
3139 QCOMPARE(evaluate<bool>(item, "delegate.VisualDataModel.isUnresolved"), false);
3141 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.itemsIndex"), index);
3142 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.persistedItemsIndex"), 0);
3143 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.visibleIndex"), index);
3144 QCOMPARE(evaluate<int>(item, "delegate.VisualDataModel.selectedIndex"), 0);
3147 void tst_qquickvisualdatamodel::warnings_data()
3149 QTest::addColumn<QUrl>("source");
3150 QTest::addColumn<QString>("expression");
3151 QTest::addColumn<QString>("warning");
3152 QTest::addColumn<int>("count");
3154 QTest::newRow("insert < 0")
3155 << testFileUrl("listmodelproperties.qml")
3156 << QString("items.insert(-2, {\"number\": \"eight\"})")
3157 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("insert: index out of range"))
3160 QTest::newRow("insert > length")
3161 << testFileUrl("listmodelproperties.qml")
3162 << QString("items.insert(8, {\"number\": \"eight\"})")
3163 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("insert: index out of range"))
3166 QTest::newRow("create < 0")
3167 << testFileUrl("listmodelproperties.qml")
3168 << QString("items.create(-2, {\"number\": \"eight\"})")
3169 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("create: index out of range"))
3172 QTest::newRow("create > length")
3173 << testFileUrl("listmodelproperties.qml")
3174 << QString("items.create(8, {\"number\": \"eight\"})")
3175 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("create: index out of range"))
3178 QTest::newRow("resolve from < 0")
3179 << testFileUrl("listmodelproperties.qml")
3180 << QString("items.resolve(-2, 3)")
3181 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: from index out of range"))
3184 QTest::newRow("resolve from > length")
3185 << testFileUrl("listmodelproperties.qml")
3186 << QString("items.resolve(8, 3)")
3187 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: from index out of range"))
3190 QTest::newRow("resolve to < 0")
3191 << testFileUrl("listmodelproperties.qml")
3192 << QString("items.resolve(3, -2)")
3193 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: to index out of range"))
3196 QTest::newRow("resolve to > length")
3197 << testFileUrl("listmodelproperties.qml")
3198 << QString("items.resolve(3, 8)")
3199 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: to index out of range"))
3202 QTest::newRow("resolve from invalid index")
3203 << testFileUrl("listmodelproperties.qml")
3204 << QString("items.resolve(\"two\", 3)")
3205 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: from index invalid"))
3208 QTest::newRow("resolve to invalid index")
3209 << testFileUrl("listmodelproperties.qml")
3210 << QString("items.resolve(3, \"two\")")
3211 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: to index invalid"))
3214 QTest::newRow("resolve already resolved item")
3215 << testFileUrl("listmodelproperties.qml")
3216 << QString("items.resolve(3, 2)")
3217 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: from is not an unresolved item"))
3220 QTest::newRow("resolve already resolved item")
3221 << testFileUrl("listmodelproperties.qml")
3222 << QString("{ items.insert(0, {\"number\": \"eight\"});"
3223 "items.insert(1, {\"number\": \"seven\"});"
3224 "items.resolve(0, 1)}")
3225 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("resolve: to is not a model item"))
3228 QTest::newRow("remove index < 0")
3229 << testFileUrl("listmodelproperties.qml")
3230 << QString("items.remove(-2, 1)")
3231 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("remove: index out of range"))
3234 QTest::newRow("remove index == length")
3235 << testFileUrl("listmodelproperties.qml")
3236 << QString("items.remove(4, 1)")
3237 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("remove: index out of range"))
3240 QTest::newRow("remove index > length")
3241 << testFileUrl("listmodelproperties.qml")
3242 << QString("items.remove(9, 1)")
3243 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("remove: index out of range"))
3246 QTest::newRow("remove invalid index")
3247 << testFileUrl("listmodelproperties.qml")
3248 << QString("items.remove(\"nine\", 1)")
3249 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("remove: invalid index"))
3252 QTest::newRow("remove count < 0")
3253 << testFileUrl("listmodelproperties.qml")
3254 << QString("items.remove(1, -2)")
3255 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("remove: invalid count"))
3258 QTest::newRow("remove index + count > length")
3259 << testFileUrl("listmodelproperties.qml")
3260 << QString("items.remove(2, 4, \"selected\")")
3261 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("remove: invalid count"))
3264 QTest::newRow("addGroups index < 0")
3265 << testFileUrl("listmodelproperties.qml")
3266 << QString("items.addGroups(-2, 1, \"selected\")")
3267 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("addGroups: index out of range"))
3270 QTest::newRow("addGroups index == length")
3271 << testFileUrl("listmodelproperties.qml")
3272 << QString("items.addGroups(4, 1, \"selected\")")
3273 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("addGroups: index out of range"))
3276 QTest::newRow("addGroups index > length")
3277 << testFileUrl("listmodelproperties.qml")
3278 << QString("items.addGroups(9, 1, \"selected\")")
3279 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("addGroups: index out of range"))
3282 QTest::newRow("addGroups count < 0")
3283 << testFileUrl("listmodelproperties.qml")
3284 << QString("items.addGroups(1, -2, \"selected\")")
3285 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("addGroups: invalid count"))
3288 QTest::newRow("addGroups index + count > length")
3289 << testFileUrl("listmodelproperties.qml")
3290 << QString("items.addGroups(2, 4, \"selected\")")
3291 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("addGroups: invalid count"))
3294 QTest::newRow("removeGroups index < 0")
3295 << testFileUrl("listmodelproperties.qml")
3296 << QString("items.removeGroups(-2, 1, \"selected\")")
3297 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("removeGroups: index out of range"))
3300 QTest::newRow("removeGroups index == length")
3301 << testFileUrl("listmodelproperties.qml")
3302 << QString("items.removeGroups(4, 1, \"selected\")")
3303 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("removeGroups: index out of range"))
3306 QTest::newRow("removeGroups index > length")
3307 << testFileUrl("listmodelproperties.qml")
3308 << QString("items.removeGroups(9, 1, \"selected\")")
3309 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("removeGroups: index out of range"))
3312 QTest::newRow("removeGroups count < 0")
3313 << testFileUrl("listmodelproperties.qml")
3314 << QString("items.removeGroups(1, -2, \"selected\")")
3315 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("removeGroups: invalid count"))
3318 QTest::newRow("removeGroups index + count > length")
3319 << testFileUrl("listmodelproperties.qml")
3320 << QString("items.removeGroups(2, 4, \"selected\")")
3321 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("removeGroups: invalid count"))
3324 QTest::newRow("setGroups index < 0")
3325 << testFileUrl("listmodelproperties.qml")
3326 << QString("items.setGroups(-2, 1, \"selected\")")
3327 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("setGroups: index out of range"))
3330 QTest::newRow("setGroups index == length")
3331 << testFileUrl("listmodelproperties.qml")
3332 << QString("items.setGroups(4, 1, \"selected\")")
3333 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("setGroups: index out of range"))
3336 QTest::newRow("setGroups index > length")
3337 << testFileUrl("listmodelproperties.qml")
3338 << QString("items.setGroups(9, 1, \"selected\")")
3339 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("setGroups: index out of range"))
3342 QTest::newRow("setGroups count < 0")
3343 << testFileUrl("listmodelproperties.qml")
3344 << QString("items.setGroups(1, -2, \"selected\")")
3345 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("setGroups: invalid count"))
3348 QTest::newRow("setGroups index + count > length")
3349 << testFileUrl("listmodelproperties.qml")
3350 << QString("items.setGroups(2, 4, \"selected\")")
3351 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("setGroups: invalid count"))
3354 QTest::newRow("move from < 0")
3355 << testFileUrl("listmodelproperties.qml")
3356 << QString("items.move(-2, 1, 1)")
3357 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: from index out of range"))
3360 QTest::newRow("move from == length")
3361 << testFileUrl("listmodelproperties.qml")
3362 << QString("items.move(4, 1, 1)")
3363 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: from index out of range"))
3366 QTest::newRow("move from > length")
3367 << testFileUrl("listmodelproperties.qml")
3368 << QString("items.move(9, 1, 1)")
3369 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: from index out of range"))
3372 QTest::newRow("move invalid from")
3373 << testFileUrl("listmodelproperties.qml")
3374 << QString("items.move(\"nine\", 1, 1)")
3375 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: invalid from index"))
3378 QTest::newRow("move to < 0")
3379 << testFileUrl("listmodelproperties.qml")
3380 << QString("items.move(1, -2, 1)")
3381 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: to index out of range"))
3384 QTest::newRow("move to == length")
3385 << testFileUrl("listmodelproperties.qml")
3386 << QString("items.move(1, 4, 1)")
3387 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: to index out of range"))
3390 QTest::newRow("move to > length")
3391 << testFileUrl("listmodelproperties.qml")
3392 << QString("items.move(1, 9, 1)")
3393 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: to index out of range"))
3396 QTest::newRow("move invalid to")
3397 << testFileUrl("listmodelproperties.qml")
3398 << QString("items.move(1, \"nine\", 1)")
3399 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: invalid to index"))
3402 QTest::newRow("move count < 0")
3403 << testFileUrl("listmodelproperties.qml")
3404 << QString("items.move(1, 1, -2)")
3405 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: invalid count"))
3408 QTest::newRow("move from + count > length")
3409 << testFileUrl("listmodelproperties.qml")
3410 << QString("items.move(2, 1, 4)")
3411 << ("<Unknown File>: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("move: from index out of range"))
3415 void tst_qquickvisualdatamodel::warnings()
3417 QFETCH(QUrl, source);
3418 QFETCH(QString, expression);
3419 QFETCH(QString, warning);
3422 QQuickCanvas canvas;
3424 QDeclarativeComponent component(&engine);
3425 component.loadUrl(source);
3426 QScopedPointer<QObject> object(component.create());
3427 QQuickListView *listView = qobject_cast<QQuickListView *>(object.data());
3429 listView->setParentItem(canvas.rootItem());
3431 QQuickItem *contentItem = listView->contentItem();
3432 QVERIFY(contentItem);
3434 QObject *visualModel = evaluate<QObject *>(listView, "model");
3435 QVERIFY(visualModel);
3437 QTest::ignoreMessage(QtWarningMsg, warning.toUtf8());
3439 evaluate<void>(visualModel, expression);
3440 QCOMPARE(evaluate<int>(listView, "count"), count);
3444 QTEST_MAIN(tst_qquickvisualdatamodel)
3446 #include "tst_qquickvisualdatamodel.moc"