aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp')
-rw-r--r--tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp357
1 files changed, 233 insertions, 124 deletions
diff --git a/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp b/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp
index 7ae0476f15..0821669703 100644
--- a/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp
+++ b/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp
@@ -1,33 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include "../../shared/util.h"
-#include "../shared/visualtestutil.h"
-#include "../shared/viewtestutil.h"
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QtQuickTestUtils/private/qmlutils_p.h>
+#include <QtQuickTestUtils/private/visualtestutils_p.h>
+#include <QtQuickTestUtils/private/viewtestutils_p.h>
#include <qtest.h>
#include <QtCore/qregularexpression.h>
@@ -47,8 +23,8 @@
#include <math.h>
#include <QtGui/qstandarditemmodel.h>
-using namespace QQuickVisualTestUtil;
-using namespace QQuickViewTestUtil;
+using namespace QQuickVisualTestUtils;
+using namespace QQuickViewTestUtils;
template <typename T, int N> int lengthOf(const T (&)[N]) { return N; }
@@ -84,9 +60,9 @@ public:
struct Branch {
Branch(Branch *parent = nullptr) : parent(parent) {}
- ~Branch() { foreach (const Node &child, children) delete child.branch; }
+ ~Branch() { for (const Node &child : std::as_const(children)) delete child.branch; }
int indexOf(Branch *branch) const {
- for (int i = 0; i < children.count(); ++i) {
+ for (int i = 0; i < children.size(); ++i) {
if (children.at(i).branch == branch)
return i;
}
@@ -100,12 +76,12 @@ public:
SingleRoleModel(const QStringList &list = QStringList(), const QByteArray &role = "name", QObject *parent = nullptr)
: QAbstractItemModel(parent), m_role(role)
{
- foreach (const QString &string, list)
+ for (const QString &string : list)
trunk.children.append(Node(string));
}
~SingleRoleModel() {}
- QHash<int,QByteArray> roleNames() const
+ QHash<int,QByteArray> roleNames() const override
{
QHash<int,QByteArray> roles;
roles.insert(Qt::DisplayRole, m_role);
@@ -130,42 +106,42 @@ public:
}
}
- QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const {
+ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override {
if (row < 0 || column != 0)
return QModelIndex();
Branch * const branch = branchForIndex(parent);
- return branch && row < branch->children.count()
+ return branch && row < branch->children.size()
? createIndex(row, column, branch)
: QModelIndex();
}
- QModelIndex parent(const QModelIndex &child) const {
+ QModelIndex parent(const QModelIndex &child) const override {
Branch * const branch = static_cast<Branch *>(child.internalPointer());
return branch->parent
? createIndex(branch->parent->indexOf(branch), 0, branch->parent)
: QModelIndex();
}
- int rowCount(const QModelIndex &parent) const {
+ int rowCount(const QModelIndex &parent) const override {
Branch * const branch = branchForIndex(parent);
- return branch ? branch->children.count() : 0;
+ return branch ? branch->children.size() : 0;
}
- int columnCount(const QModelIndex &parent) const {
+ int columnCount(const QModelIndex &parent) const override {
Branch * const branch = branchForIndex(parent);
return branch ? 1 : 0;
}
- QVariant data(const QModelIndex &index, int role) const {
+ QVariant data(const QModelIndex &index, int role) const override {
return index.isValid() && role == Qt::DisplayRole
? static_cast<Branch *>(index.internalPointer())->children.at(index.row()).display
: QVariant();
}
void insert(const QModelIndex &parent, int index, const QStringList &data) {
- beginInsertRows(parent, index, index + data.count() - 1);
+ beginInsertRows(parent, index, index + data.size() - 1);
Branch * const branch = createBranchForIndex(parent);
- for (int i = 0; i < data.count(); ++i)
+ for (int i = 0; i < data.size(); ++i)
branch->children.insert(index + i, Node(data.at(i)));
endInsertRows();
}
@@ -207,21 +183,21 @@ public:
QStringList getList() const {
QStringList list;
- foreach (const Node &node, trunk.children)
+ for (const Node &node : trunk.children)
list.append(node.display);
return list;
}
void setList(const QStringList &l) {
- if (trunk.children.count() > 0) {
- beginRemoveRows(QModelIndex(), 0, trunk.children.count() - 1);
- foreach (const Node &child, trunk.children) delete child.branch;
+ if (trunk.children.size() > 0) {
+ beginRemoveRows(QModelIndex(), 0, trunk.children.size() - 1);
+ for (const Node &child : std::as_const(trunk.children)) delete child.branch;
trunk.children.clear();
endRemoveRows();
}
- if (l.count() > 0) {
- beginInsertRows(QModelIndex(), 0, l.count() -1);
- foreach (const QString &string, l)
+ if (l.size() > 0) {
+ beginInsertRows(QModelIndex(), 0, l.size() -1);
+ for (const QString &string : l)
trunk.children.append(Node(string));
endInsertRows();
}
@@ -424,6 +400,7 @@ private slots:
void warnings_data();
void warnings();
void invalidAttachment();
+ void declarativeAssignViaAttached();
void asynchronousInsert_data();
void asynchronousInsert();
void asynchronousRemove_data();
@@ -434,8 +411,10 @@ private slots:
void invalidContext();
void externalManagedModel();
void delegateModelChangeDelegate();
+ void noDoubleDelegateUpdate();
void checkFilterGroupForDelegate();
void readFromProxyObject();
+ void noWarningOnObjectDeletion();
private:
template <int N> void groups_verify(
@@ -502,6 +481,7 @@ void tst_qquickvisualdatamodel::cleanupTestCase()
}
tst_qquickvisualdatamodel::tst_qquickvisualdatamodel()
+ : QQmlDataTest(QT_QMLTEST_DATADIR)
{
}
@@ -624,7 +604,8 @@ void tst_qquickvisualdatamodel::childChanged()
QVERIFY(name);
QCOMPARE(name->text(), QString("Row 2 updated child"));
- model.item(1,0)->appendRow(new QStandardItem(QLatin1String("Row 2 Child Item 2")));
+ QStandardItem item(QLatin1String("Row 2 Child Item 2"));
+ model.item(1,0)->appendRow(&item);
QCOMPARE(listview->count(), 2);
listview->forceLayout();
@@ -656,10 +637,10 @@ void tst_qquickvisualdatamodel::objectListModel()
QQuickView view;
QList<QObject*> dataList;
- dataList.append(new DataObject("Item 1", "red"));
- dataList.append(new DataObject("Item 2", "green"));
- dataList.append(new DataObject("Item 3", "blue"));
- dataList.append(new DataObject("Item 4", "yellow"));
+ dataList.append(new DataObject("Item 1", "red", &view));
+ dataList.append(new DataObject("Item 2", "green", &view));
+ dataList.append(new DataObject("Item 3", "blue", &view));
+ dataList.append(new DataObject("Item 4", "yellow", &view));
QQmlContext *ctxt = view.rootContext();
ctxt->setContextProperty("myModel", QVariant::fromValue(dataList));
@@ -798,10 +779,10 @@ void tst_qquickvisualdatamodel::modelProperties()
QQuickView view;
QList<QObject*> dataList;
- dataList.append(new DataObject("Item 1", "red"));
- dataList.append(new DataObject("Item 2", "green"));
- dataList.append(new DataObject("Item 3", "blue"));
- dataList.append(new DataObject("Item 4", "yellow"));
+ dataList.append(new DataObject("Item 1", "red", &view));
+ dataList.append(new DataObject("Item 2", "green", &view));
+ dataList.append(new DataObject("Item 3", "blue", &view));
+ dataList.append(new DataObject("Item 4", "yellow", &view));
QQmlContext *ctxt = view.rootContext();
ctxt->setContextProperty("myModel", QVariant::fromValue(dataList));
@@ -867,12 +848,9 @@ void tst_qquickvisualdatamodel::modelProperties()
QUrl source(testFileUrl("modelproperties2.qml"));
//3 items, 3 i each
- QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":13: ReferenceError: modelData is not defined");
- QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":13: ReferenceError: modelData is not defined");
- QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":13: ReferenceError: modelData is not defined");
- QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":11: ReferenceError: modelData is not defined");
- QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":11: ReferenceError: modelData is not defined");
- QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":11: ReferenceError: modelData is not defined");
+ QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":13: TypeError: Cannot read property 'display' of undefined");
+ QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":13: TypeError: Cannot read property 'display' of undefined");
+ QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":13: TypeError: Cannot read property 'display' of undefined");
QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":17: TypeError: Cannot read property 'display' of undefined");
QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":17: TypeError: Cannot read property 'display' of undefined");
QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":17: TypeError: Cannot read property 'display' of undefined");
@@ -1061,14 +1039,14 @@ void tst_qquickvisualdatamodel::qaimRowsMoved()
QSignalSpy spy(obj, SIGNAL(modelUpdated(QQmlChangeSet,bool)));
model.emitMove(sourceFirst, sourceLast, destinationChild);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
- QCOMPARE(spy[0].count(), 2);
+ QCOMPARE(spy[0].size(), 2);
QQmlChangeSet changeSet = spy[0][0].value<QQmlChangeSet>();
- QCOMPARE(changeSet.removes().count(), 1);
+ QCOMPARE(changeSet.removes().size(), 1);
QCOMPARE(changeSet.removes().at(0).index, expectFrom);
QCOMPARE(changeSet.removes().at(0).count, expectCount);
- QCOMPARE(changeSet.inserts().count(), 1);
+ QCOMPARE(changeSet.inserts().size(), 1);
QCOMPARE(changeSet.inserts().at(0).index, expectTo);
QCOMPARE(changeSet.inserts().at(0).count, expectCount);
QCOMPARE(changeSet.removes().at(0).moveId, changeSet.inserts().at(0).moveId);
@@ -1130,33 +1108,33 @@ void tst_qquickvisualdatamodel::subtreeRowsMoved()
// Move items from the current root index to a sub tree.
model.move(QModelIndex(), 1, model.index(0, 0), 3, 2);
QCOMPARE(vdm->count(), 2);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
changeSet = spy.last().at(0).value<QQmlChangeSet>();
- QCOMPARE(changeSet.removes().count(), 1);
+ QCOMPARE(changeSet.removes().size(), 1);
QCOMPARE(changeSet.removes().at(0).index, 1);
QCOMPARE(changeSet.removes().at(0).count, 2);
- QCOMPARE(changeSet.inserts().count(), 0);
+ QCOMPARE(changeSet.inserts().size(), 0);
// Move items from a sub tree to the current root index.
model.move(model.index(0, 0), 4, QModelIndex(), 2, 1);
QCOMPARE(vdm->count(), 3);
- QCOMPARE(spy.count(), 2);
+ QCOMPARE(spy.size(), 2);
changeSet = spy.last().at(0).value<QQmlChangeSet>();
- QCOMPARE(changeSet.removes().count(), 0);
- QCOMPARE(changeSet.inserts().count(), 1);
+ QCOMPARE(changeSet.removes().size(), 0);
+ QCOMPARE(changeSet.inserts().size(), 1);
QCOMPARE(changeSet.inserts().at(0).index, 2);
QCOMPARE(changeSet.inserts().at(0).count, 1);
vdm->setRootIndex(QVariant::fromValue(model.index(2, 0)));
QCOMPARE(vdm->rootIndex().value<QModelIndex>(), model.index(2, 0));
QCOMPARE(vdm->count(), 3);
- QCOMPARE(spy.count(), 4);
+ QCOMPARE(spy.size(), 4);
changeSet = spy.at(2).at(0).value<QQmlChangeSet>();
- QCOMPARE(changeSet.removes().count(), 1);
+ QCOMPARE(changeSet.removes().size(), 1);
QCOMPARE(changeSet.removes().at(0).index, 0);
QCOMPARE(changeSet.removes().at(0).count, 3);
changeSet = spy.last().at(0).value<QQmlChangeSet>();
- QCOMPARE(changeSet.inserts().count(), 1);
+ QCOMPARE(changeSet.inserts().size(), 1);
QCOMPARE(changeSet.inserts().at(0).index, 0);
QCOMPARE(changeSet.inserts().at(0).count, 3);
@@ -1164,41 +1142,41 @@ void tst_qquickvisualdatamodel::subtreeRowsMoved()
model.move(QModelIndex(), 2, QModelIndex(), 0, 1);
QCOMPARE(vdm->rootIndex().value<QModelIndex>(), model.index(0, 0));
QCOMPARE(vdm->count(), 3);
- QCOMPARE(spy.count(), 4);
+ QCOMPARE(spy.size(), 4);
// Move the current root index, changing its parent.
model.move(QModelIndex(), 0, model.index(1, 0), 0, 1);
QCOMPARE(vdm->rootIndex().value<QModelIndex>(), model.index(0, 0, model.index(0, 0)));
QCOMPARE(vdm->count(), 3);
- QCOMPARE(spy.count(), 4);
+ QCOMPARE(spy.size(), 4);
model.insert(model.index(0, 0), 0, QStringList() << "new1" << "new2");
QCOMPARE(vdm->rootIndex().value<QModelIndex>(), model.index(2, 0, model.index(0, 0)));
QCOMPARE(vdm->count(), 3);
- QCOMPARE(spy.count(), 4);
+ QCOMPARE(spy.size(), 4);
model.remove(model.index(0, 0), 1, 1);
QCOMPARE(vdm->rootIndex().value<QModelIndex>(), model.index(1, 0, model.index(0, 0)));
QCOMPARE(vdm->count(), 3);
- QCOMPARE(spy.count(), 4);
+ QCOMPARE(spy.size(), 4);
model.remove(model.index(0, 0), 1, 1);
QCOMPARE(vdm->rootIndex().value<QModelIndex>(), QModelIndex());
QCOMPARE(vdm->count(), 0);
- QCOMPARE(spy.count(), 5);
+ QCOMPARE(spy.size(), 5);
changeSet = spy.last().at(0).value<QQmlChangeSet>();
- QCOMPARE(changeSet.removes().count(), 1);
+ QCOMPARE(changeSet.removes().size(), 1);
QCOMPARE(changeSet.removes().at(0).index, 0);
QCOMPARE(changeSet.removes().at(0).count, 3);
- QCOMPARE(changeSet.inserts().count(), 0);
+ QCOMPARE(changeSet.inserts().size(), 0);
vdm->setRootIndex(QVariant::fromValue(QModelIndex()));
QCOMPARE(vdm->rootIndex().value<QModelIndex>(), QModelIndex());
QCOMPARE(vdm->count(), 2);
- QCOMPARE(spy.count(), 6);
+ QCOMPARE(spy.size(), 6);
changeSet = spy.last().at(0).value<QQmlChangeSet>();
- QCOMPARE(changeSet.removes().count(), 0);
- QCOMPARE(changeSet.inserts().count(), 1);
+ QCOMPARE(changeSet.removes().size(), 0);
+ QCOMPARE(changeSet.inserts().size(), 1);
QCOMPARE(changeSet.inserts().at(0).index, 0);
QCOMPARE(changeSet.inserts().at(0).count, 2);
}
@@ -1230,44 +1208,44 @@ void tst_qquickvisualdatamodel::watchedRoles()
QCOMPARE(vdm->count(), 30);
emit model.dataChanged(model.index(0), model.index(4));
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
emit model.dataChanged(model.index(0), model.index(4), QVector<int>() << QaimModel::Name);
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
emit model.dataChanged(model.index(0), model.index(4), QVector<int>() << QaimModel::Number);
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
vdm->setWatchedRoles(QList<QByteArray>() << "name" << "dummy");
emit model.dataChanged(model.index(0), model.index(4));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
changeSet = spy.last().at(0).value<QQmlChangeSet>();
QCOMPARE(changeSet.changes().at(0).index, 0);
QCOMPARE(changeSet.changes().at(0).count, 5);
emit model.dataChanged(model.index(1), model.index(6), QVector<int>() << QaimModel::Name);
- QCOMPARE(spy.count(), 2);
+ QCOMPARE(spy.size(), 2);
changeSet = spy.last().at(0).value<QQmlChangeSet>();
QCOMPARE(changeSet.changes().at(0).index, 1);
QCOMPARE(changeSet.changes().at(0).count, 6);
emit model.dataChanged(model.index(8), model.index(8), QVector<int>() << QaimModel::Number);
- QCOMPARE(spy.count(), 2);
+ QCOMPARE(spy.size(), 2);
vdm->setWatchedRoles(QList<QByteArray>() << "number" << "dummy");
emit model.dataChanged(model.index(0), model.index(4));
- QCOMPARE(spy.count(), 3);
+ QCOMPARE(spy.size(), 3);
changeSet = spy.last().at(0).value<QQmlChangeSet>();
QCOMPARE(changeSet.changes().at(0).index, 0);
QCOMPARE(changeSet.changes().at(0).count, 5);
emit model.dataChanged(model.index(1), model.index(6), QVector<int>() << QaimModel::Name);
- QCOMPARE(spy.count(), 3);
+ QCOMPARE(spy.size(), 3);
emit model.dataChanged(model.index(8), model.index(8), QVector<int>() << QaimModel::Number);
- QCOMPARE(spy.count(), 4);
+ QCOMPARE(spy.size(), 4);
changeSet = spy.last().at(0).value<QQmlChangeSet>();
QCOMPARE(changeSet.changes().at(0).index, 8);
QCOMPARE(changeSet.changes().at(0).count, 1);
@@ -1275,19 +1253,19 @@ void tst_qquickvisualdatamodel::watchedRoles()
vdm->setWatchedRoles(QList<QByteArray>() << "number" << "name");
emit model.dataChanged(model.index(0), model.index(4));
- QCOMPARE(spy.count(), 5);
+ QCOMPARE(spy.size(), 5);
changeSet = spy.last().at(0).value<QQmlChangeSet>();
QCOMPARE(changeSet.changes().at(0).index, 0);
QCOMPARE(changeSet.changes().at(0).count, 5);
emit model.dataChanged(model.index(1), model.index(6), QVector<int>() << QaimModel::Name);
- QCOMPARE(spy.count(), 6);
+ QCOMPARE(spy.size(), 6);
changeSet = spy.last().at(0).value<QQmlChangeSet>();
QCOMPARE(changeSet.changes().at(0).index, 1);
QCOMPARE(changeSet.changes().at(0).count, 6);
emit model.dataChanged(model.index(8), model.index(8), QVector<int>() << QaimModel::Number);
- QCOMPARE(spy.count(), 7);
+ QCOMPARE(spy.size(), 7);
changeSet = spy.last().at(0).value<QQmlChangeSet>();
QCOMPARE(changeSet.changes().at(0).index, 8);
QCOMPARE(changeSet.changes().at(0).count, 1);
@@ -2282,7 +2260,7 @@ void tst_qquickvisualdatamodel::onChanged()
evaluate<void>(object.data(), expression);
- foreach (const QString &test, tests) {
+ for (const QString &test : std::as_const(tests)) {
bool passed = evaluate<bool>(object.data(), test);
if (!passed)
qWarning() << test;
@@ -2448,24 +2426,24 @@ void tst_qquickvisualdatamodel::incompleteModel()
QSignalSpy persistedItemsSpy(model->items(), SIGNAL(countChanged()));
evaluate<void>(model, "items.removeGroups(0, items.count, \"items\")");
- QCOMPARE(itemsSpy.count(), 0);
- QCOMPARE(persistedItemsSpy.count(), 0);
+ QCOMPARE(itemsSpy.size(), 0);
+ QCOMPARE(persistedItemsSpy.size(), 0);
evaluate<void>(model, "items.setGroups(0, items.count, \"persistedItems\")");
- QCOMPARE(itemsSpy.count(), 0);
- QCOMPARE(persistedItemsSpy.count(), 0);
+ QCOMPARE(itemsSpy.size(), 0);
+ QCOMPARE(persistedItemsSpy.size(), 0);
evaluate<void>(model, "items.addGroups(0, items.count, \"persistedItems\")");
- QCOMPARE(itemsSpy.count(), 0);
- QCOMPARE(persistedItemsSpy.count(), 0);
+ QCOMPARE(itemsSpy.size(), 0);
+ QCOMPARE(persistedItemsSpy.size(), 0);
evaluate<void>(model, "items.remove(0, items.count)");
- QCOMPARE(itemsSpy.count(), 0);
- QCOMPARE(persistedItemsSpy.count(), 0);
+ QCOMPARE(itemsSpy.size(), 0);
+ QCOMPARE(persistedItemsSpy.size(), 0);
evaluate<void>(model, "items.insert([ \"color\": \"blue\" ])");
- QCOMPARE(itemsSpy.count(), 0);
- QCOMPARE(persistedItemsSpy.count(), 0);
+ QCOMPARE(itemsSpy.size(), 0);
+ QCOMPARE(persistedItemsSpy.size(), 0);
QTest::ignoreMessage(QtWarningMsg, QRegularExpression(".*get: index out of range"));
QVERIFY(evaluate<bool>(model, "items.get(0) === undefined"));
@@ -3091,7 +3069,7 @@ void tst_qquickvisualdatamodel::insert()
QCOMPARE(evaluate<int>(visualModel, "visibleItems.count"), visible ? visualCount : modelCount);
QCOMPARE(evaluate<int>(visualModel, "selectedItems.count"), selected ? 1 : 0);
- QCOMPARE(propertyData.count(), visualCount);
+ QCOMPARE(propertyData.size(), visualCount);
for (int i = 0; i < visualCount; ++i) {
int modelIndex = i;
if (modelIndex > index)
@@ -3559,7 +3537,7 @@ void tst_qquickvisualdatamodel::resolve()
QCOMPARE(evaluate<int>(visualModel, "visibleItems.count"), visible ? visualCount : modelCount);
QCOMPARE(evaluate<int>(visualModel, "selectedItems.count"), selected ? 1 : 0);
- QCOMPARE(propertyData.count(), visualCount);
+ QCOMPARE(propertyData.size(), visualCount);
for (int i = 0; i < visualCount; ++i) {
int modelIndex = i;
@@ -3960,7 +3938,7 @@ void tst_qquickvisualdatamodel::invalidAttachment()
QScopedPointer<QObject> object(component.create());
QVERIFY(object);
- QCOMPARE(component.errors().count(), 0);
+ QCOMPARE(component.errors().size(), 0);
QVariant property = object->property("invalidVdm");
QCOMPARE(property.userType(), qMetaTypeId<QQmlDelegateModel *>());
@@ -3975,7 +3953,19 @@ void tst_qquickvisualdatamodel::invalidAttachment()
property = item->property("invalidVdm");
QCOMPARE(property.userType(), qMetaTypeId<QQmlDelegateModel *>());
- QVERIFY(!property.value<QQmlDelegateModel *>());
+ // has been explicitly requested by specifying the attached property
+ QVERIFY(property.value<QQmlDelegateModel *>());
+}
+
+void tst_qquickvisualdatamodel::declarativeAssignViaAttached()
+{
+ QQmlComponent component(&engine);
+ component.loadUrl(testFileUrl("attachedDeclarativelySet.qml"));
+
+ QScopedPointer<QObject> root(component.create());
+ QCOMPARE(root->property("count").toInt(), 6); // 1 (from instantiator + 5 from model)
+ root->setProperty("includeAll", true);
+ QCOMPARE(root->property("count").toInt(), 11); // 1 (from instantiator + 10 from model)
}
void tst_qquickvisualdatamodel::asynchronousInsert_data()
@@ -4007,7 +3997,8 @@ void tst_qquickvisualdatamodel::asynchronousInsert()
engine.rootContext()->setContextProperty("myModel", &model);
- QQmlDelegateModel *visualModel = qobject_cast<QQmlDelegateModel*>(c.create());
+ QScopedPointer<QObject> o(c.create());
+ QQmlDelegateModel *visualModel = qobject_cast<QQmlDelegateModel*>(o.data());
QVERIFY(visualModel);
ItemRequester requester;
@@ -4072,7 +4063,8 @@ void tst_qquickvisualdatamodel::asynchronousRemove()
engine.rootContext()->setContextProperty("myModel", &model);
- QQmlDelegateModel *visualModel = qobject_cast<QQmlDelegateModel*>(c.create());
+ QScopedPointer<QObject> o(c.create());
+ QQmlDelegateModel *visualModel = qobject_cast<QQmlDelegateModel*>(o.data());
QVERIFY(visualModel);
ItemRequester requester;
@@ -4151,7 +4143,8 @@ void tst_qquickvisualdatamodel::asynchronousMove()
engine.rootContext()->setContextProperty("myModel", &model);
- QQmlDelegateModel *visualModel = qobject_cast<QQmlDelegateModel*>(c.create());
+ QScopedPointer<QObject> o(c.create());
+ QQmlDelegateModel *visualModel = qobject_cast<QQmlDelegateModel*>(o.data());
QVERIFY(visualModel);
ItemRequester requester;
@@ -4199,7 +4192,8 @@ void tst_qquickvisualdatamodel::asynchronousCancel()
engine.rootContext()->setContextProperty("myModel", &model);
- QQmlDelegateModel *visualModel = qobject_cast<QQmlDelegateModel*>(c.create());
+ QScopedPointer<QObject> o(c.create());
+ QQmlDelegateModel *visualModel = qobject_cast<QQmlDelegateModel*>(o.data());
QVERIFY(visualModel);
QQuickItem *item = qobject_cast<QQuickItem*>(visualModel->object(requestIndex, QQmlIncubator::Asynchronous));
@@ -4235,7 +4229,7 @@ void tst_qquickvisualdatamodel::invalidContext()
QVERIFY(item);
visualModel->release(item);
- delete context.take();
+ context.reset();
model.insertItem(4, "new item", "");
@@ -4277,7 +4271,7 @@ public:
static qsizetype listLength(QQmlListProperty<QObject> *property)
{
auto objectsProvider = qobject_cast<ObjectsProvider*>(property->object);
- return objectsProvider ? objectsProvider->m_objects.length() : 0;
+ return objectsProvider ? objectsProvider->m_objects.size() : 0;
}
static QObject* listAt(QQmlListProperty<QObject> *property, qsizetype index)
@@ -4321,7 +4315,8 @@ void tst_qquickvisualdatamodel::delegateModelChangeDelegate()
c.setData("import QtQml.Models 2.2\nDelegateModel {}\n", QUrl());
QCOMPARE(c.status(), QQmlComponent::Ready);
- QQmlDelegateModel *visualModel = qobject_cast<QQmlDelegateModel*>(c.create(context.data()));
+ QScopedPointer<QObject> o(c.create(context.data()));
+ QQmlDelegateModel *visualModel = qobject_cast<QQmlDelegateModel*>(o.data());
QVERIFY(visualModel);
visualModel->setModel(QVariant(3));
@@ -4349,6 +4344,20 @@ void tst_qquickvisualdatamodel::delegateModelChangeDelegate()
QCOMPARE(visualModel->count(), 3);
}
+void tst_qquickvisualdatamodel::noDoubleDelegateUpdate()
+{
+ // changing a delegate only refreshes its instances once
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("setDelegateNoDoubleChange.qml"));
+
+ QScopedPointer<QObject> root(component.create());
+ QVERIFY(root);
+
+ bool ok = root->setProperty("testStarted", true);
+ QVERIFY(ok);
+ QCOMPARE(root->property("creationCount").toInt(), 1);
+}
+
void tst_qquickvisualdatamodel::checkFilterGroupForDelegate()
{
QQuickView view;
@@ -4377,6 +4386,106 @@ void tst_qquickvisualdatamodel::readFromProxyObject()
QTRY_VERIFY(window->property("name").toString() != QLatin1String("wrong"));
}
+
+class ComponentEntity : public QObject
+{
+ Q_OBJECT
+
+public:
+ ComponentEntity(QObject *parent = nullptr) : QObject(parent)
+ {
+ QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
+ }
+};
+
+class InventoryModel : public QAbstractListModel
+{
+ Q_OBJECT
+
+public:
+ InventoryModel() {
+ for (int i = 0; i < 10; ++i) {
+ QSharedPointer<ComponentEntity> entity(new ComponentEntity());
+ entity->setObjectName(QString::fromLatin1("Item %1").arg(i));
+ mContents.append(entity);
+ }
+ }
+
+ int rowCount(const QModelIndex &) const override { return mContents.size(); }
+
+ QVariant data(const QModelIndex &index, int role) const override
+ {
+ if (!checkIndex(index, CheckIndexOption::IndexIsValid))
+ return {};
+
+ auto entity = mContents.at(index.row()).data();
+ switch (role) {
+ case ItemNameRole: return entity->objectName();
+ case EntityRole: return QVariant::fromValue(entity);
+ }
+
+ return {};
+ }
+
+ Q_INVOKABLE void removeLast() {
+ const int index = rowCount(QModelIndex()) - 1;
+ if (index < 0)
+ return;
+
+ const auto item = mContents.at(index);
+ beginRemoveRows(QModelIndex(), index, index);
+ mContents.takeLast();
+ endRemoveRows();
+ }
+
+ enum InventoryModelRoles {
+ ItemNameRole = Qt::UserRole,
+ EntityRole
+ };
+
+ virtual QHash<int, QByteArray> roleNames() const override {
+ QHash<int, QByteArray> names;
+ names.insert(ItemNameRole, "itemName");
+ names.insert(EntityRole, "entity");
+ return names;
+ }
+
+private:
+ QVector<QSharedPointer<ComponentEntity>> mContents;
+};
+
+
+static QString lastWarning;
+static QtMessageHandler oldHandler;
+static void warningsHandler(QtMsgType type, const QMessageLogContext &ctxt, const QString &msg)
+{
+ if (type == QtWarningMsg)
+ lastWarning = msg;
+ else
+ oldHandler(type, ctxt, msg);
+}
+
+void tst_qquickvisualdatamodel::noWarningOnObjectDeletion()
+{
+ qmlRegisterType<InventoryModel>("TestTypes", 1, 0, "InventoryModel");
+ qmlRegisterUncreatableType<ComponentEntity>("TestTypes", 1, 0, "ComponentEntity", "no");
+
+ oldHandler = qInstallMessageHandler(warningsHandler);
+ const auto guard = qScopeGuard([&]() { qInstallMessageHandler(oldHandler); });
+
+ {
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("objectDeletion.qml"));
+ QVERIFY2(component.isReady(), qPrintable(component.errorString()));
+ QScopedPointer<QObject> o(component.create());
+ QVERIFY(!o.isNull());
+ for (int i = 0; i < 5; ++i)
+ o->metaObject()->invokeMethod(o.data(), "removeLast");
+ }
+
+ QVERIFY2(lastWarning.isEmpty(), qPrintable(lastWarning));
+}
+
QTEST_MAIN(tst_qquickvisualdatamodel)
#include "tst_qquickvisualdatamodel.moc"