From 2302a50f816b2e1d8c8429f26076ce6da4acf11e Mon Sep 17 00:00:00 2001 From: Mate Barany Date: Tue, 6 May 2025 18:15:03 +0200 Subject: [PATCH] Add tests to QQmlTreeModel::setRow Also try some invalid indices and values. Task-number: QTBUG-130571 Change-Id: Ie24561a1e4fc1162d750f6690b307a6b8482493c Reviewed-by: Richard Moe Gustavsen --- tests/auto/qml/qqmltreemodel/data/common.qml | 102 +++++++++++++ .../qml/qqmltreemodel/tst_qqmltreemodel.cpp | 143 ++++++++++++++++++ 2 files changed, 245 insertions(+) diff --git a/tests/auto/qml/qqmltreemodel/data/common.qml b/tests/auto/qml/qqmltreemodel/data/common.qml index 931d67e904..461319dac7 100644 --- a/tests/auto/qml/qqmltreemodel/data/common.qml +++ b/tests/auto/qml/qqmltreemodel/data/common.qml @@ -206,6 +206,108 @@ Item { }) } + function setWithNegativeIndex() { + var index = testModel.index([0,1,-1], 0) + + testModel.setRow(index, { + checked: true, + amount: 1, + fruitType: "Pear", + fruitName: "Williams", + fruitPrice: 1.50, + color: "green" + }) + } + + function setWithInvalidIndex() { + var index = testModel.index([3,0,1], 0) + + testModel.setRow(index, { + checked: true, + amount: 1, + fruitType: "Pear", + fruitName: "Williams", + fruitPrice: 1.50, + color: "green" + }) + } + + function setInvalidData1() { + var index = testModel.index([0,1,1], 0) + testModel.setRow(index, 150) + } + + function setInvalidData2() { + var index = testModel.index([0,1,1], 0) + + testModel.setRow(index, { + checked: false, + amount: 4, + fruitType: "Peach", + fruitName: "Princess Peach", + fruitPrice: 1.45, + color: "yellow", + rows: [ + { + checked: true, + amount: 5, + fruitType: "Strawberry", + fruitName: "Perry the Berry", + fruitPrice: 3.80, + color: "red", + }, + { + checked: false, + amount: 6, + fruitType: "Pear", + fruitName: "Bear Pear", + fruitPrice: 1.50, + color: "green", + } + ] + }) + } + + function setInvalidData3() { + var index = testModel.index([0,1,1], 0) + + testModel.setRow(index, [{ + checked: true, + amount: 1, + fruitType: "Pear", + fruitName: "Bear Pear", + fruitPrice: 1.50, + color: "green" + }]) + } + + function setLeaf() { + var index = testModel.index([0,1,1], 0) + + testModel.setRow(index, { + checked: true, + amount: 1, + fruitType: "Pear", + fruitName: "Bear Pear", + fruitPrice: 1.50, + color: "green" + }) + } + + function setNodeWithExtraData() { + var index = testModel.index([1,0], 0) + + testModel.setRow(index, { + checked: true, + amount: 4, + fruitType: "Orange", + fruitName: "Navel", + fruitPrice: 2.50, + color: "orange", + extradata: "extradata" + }) + } + TreeView { id: treeView anchors.fill: parent diff --git a/tests/auto/qml/qqmltreemodel/tst_qqmltreemodel.cpp b/tests/auto/qml/qqmltreemodel/tst_qqmltreemodel.cpp index a26fe56fbb..99b9df505a 100644 --- a/tests/auto/qml/qqmltreemodel/tst_qqmltreemodel.cpp +++ b/tests/auto/qml/qqmltreemodel/tst_qqmltreemodel.cpp @@ -30,6 +30,7 @@ private slots: void appendRow(); void clear(); void getRow(); + void setRow(); }; void tst_QQmlTreeModel::appendToRoot() @@ -473,6 +474,148 @@ void tst_QQmlTreeModel::getRow() QCOMPARE(rowValues.value("fruitType"), "Banana"); } +void tst_QQmlTreeModel::setRow() +{ + QQuickView view; + QVERIFY(QQuickTest::showView(view, testFileUrl("common.qml"))); + + auto *model = view.rootObject()->property("testModel").value(); + QVERIFY(model); + + QCOMPARE(model->columnCount(), 5); + QCOMPARE(model->treeSize(), 8); + + QSignalSpy columnCountSpy(model, SIGNAL(columnCountChanged())); + QVERIFY(columnCountSpy.isValid()); + + QSignalSpy rowsChangedSpy(model, SIGNAL(rowsChanged())); + QVERIFY(rowsChangedSpy.isValid()); + int rowsChangedSignalEmissions = 0; + + const QHash roleNames = model->roleNames(); + QCOMPARE(roleNames.size(), 2); + QVERIFY(roleNames.values().contains("display")); + QVERIFY(roleNames.values().contains("decoration")); + + QQuickTreeView *treeView = view.rootObject()->property("treeView").value(); + QVERIFY(treeView); + QCOMPARE(treeView->columns(), 5); + QCOMPARE(treeView->rows(), 2); // treeView cannot call our treeSize + + // Try an invalid index - the index contains a negtive number + QTest::ignoreMessage(QtWarningMsg, QRegularExpression(".* could not find any node at the specified index")); + QTest::ignoreMessage(QtWarningMsg, QRegularExpression(".* invalid modelIndex")); + QVERIFY(QMetaObject::invokeMethod(view.rootObject(), "setWithNegativeIndex")); + // Nothing happens + QCOMPARE(model->columnCount(), 5); + QCOMPARE(model->treeSize(), 8); + QCOMPARE(columnCountSpy.size(), 0); + QCOMPARE(rowsChangedSpy.size(), rowsChangedSignalEmissions); + QCOMPARE(treeView->columns(), 5); + QCOMPARE(treeView->rows(), 2); + + // This index does not contain negative numbers but the node does not exist + QTest::ignoreMessage(QtWarningMsg, QRegularExpression(".* could not find any node at the specified index")); + QTest::ignoreMessage(QtWarningMsg, QRegularExpression(".* invalid modelIndex")); + QVERIFY(QMetaObject::invokeMethod(view.rootObject(), "setWithInvalidIndex")); + // Nothing happens + QCOMPARE(model->columnCount(), 5); + QCOMPARE(model->treeSize(), 8); + QCOMPARE(columnCountSpy.size(), 0); + QCOMPARE(rowsChangedSpy.size(), rowsChangedSignalEmissions); + QCOMPARE(treeView->columns(), 5); + QCOMPARE(treeView->rows(), 2); + + // This time the index is valid, but we are trying to insert an int + QTest::ignoreMessage(QtWarningMsg, QRegularExpression(".* got int instead")); + QVERIFY(QMetaObject::invokeMethod(view.rootObject(), "setInvalidData1")); + // Nothing happens + QCOMPARE(model->columnCount(), 5); + QCOMPARE(model->treeSize(), 8); + QCOMPARE(columnCountSpy.size(), 0); + QCOMPARE(rowsChangedSpy.size(), rowsChangedSignalEmissions); + QCOMPARE(treeView->columns(), 5); + QCOMPARE(treeView->rows(), 2); + + // The index is valid, but the row has children + QTest::ignoreMessage(QtWarningMsg, QRegularExpression(".* child rows are not allowed")); + QVERIFY(QMetaObject::invokeMethod(view.rootObject(), "setInvalidData2")); + // Nothing happens + QCOMPARE(model->columnCount(), 5); + QCOMPARE(model->treeSize(), 8); + QCOMPARE(columnCountSpy.size(), 0); + QCOMPARE(rowsChangedSpy.size(), rowsChangedSignalEmissions); + QCOMPARE(treeView->columns(), 5); + QCOMPARE(treeView->rows(), 2); + + // Valid index but the input is an array instead of a simple object. + QTest::ignoreMessage(QtWarningMsg, QRegularExpression(".* row manipulation functions do not support complex rows")); + QVERIFY(QMetaObject::invokeMethod(view.rootObject(), "setInvalidData3")); + // Nothing happens + QCOMPARE(model->columnCount(), 5); + QCOMPARE(model->treeSize(), 8); + QCOMPARE(columnCountSpy.size(), 0); + QCOMPARE(rowsChangedSpy.size(), rowsChangedSignalEmissions); + QCOMPARE(treeView->columns(), 5); + QCOMPARE(treeView->rows(), 2); + + // Check the leaf node at the index {0,1,1} + QCOMPARE(model->data(model->index({0,1,1}, 0), roleNames.key("display")).toBool(), false); + QCOMPARE(model->data(model->index({0,1,1}, 0), roleNames.key("decoration")).toString(), u"yellow"_s); + QCOMPARE(model->data(model->index({0,1,1}, 1), roleNames.key("display")).toInt(), 1); + QCOMPARE(model->data(model->index({0,1,1}, 1), roleNames.key("decoration")).toString(), u"yellow"_s); + QCOMPARE(model->data(model->index({0,1,1}, 2), roleNames.key("display")).toString(), u"Banana"_s); + QCOMPARE(model->data(model->index({0,1,1}, 2), roleNames.key("decoration")).toString(), u"yellow"_s); + QCOMPARE(model->data(model->index({0,1,1}, 3), roleNames.key("display")).toString(), u"Cavendish"_s); + QCOMPARE(model->data(model->index({0,1,1}, 3), roleNames.key("decoration")).toString(), u"yellow"_s); + QCOMPARE(model->data(model->index({0,1,1}, 4), roleNames.key("display")).toDouble(), 3.5); + QCOMPARE(model->data(model->index({0,1,1}, 4), roleNames.key("decoration")).toString(), u"yellow"_s); + + // Call set and change the contents of this node + QVERIFY(QMetaObject::invokeMethod(view.rootObject(), "setLeaf")); + // the number of rows did not change, but the rows have changed + QCOMPARE(model->columnCount(), 5); + QCOMPARE(model->treeSize(), 8); + QCOMPARE(columnCountSpy.size(), 0); + QCOMPARE(rowsChangedSpy.size(), ++rowsChangedSignalEmissions); + QCOMPARE(treeView->columns(), 5); + QCOMPARE(treeView->rows(), 2); + + // The node after the change + QCOMPARE(model->data(model->index({0,1,1}, 0), roleNames.key("display")).toBool(), true); + QCOMPARE(model->data(model->index({0,1,1}, 0), roleNames.key("decoration")).toString(), u"green"_s); + QCOMPARE(model->data(model->index({0,1,1}, 1), roleNames.key("display")).toInt(), 1); + QCOMPARE(model->data(model->index({0,1,1}, 1), roleNames.key("decoration")).toString(), u"green"_s); + QCOMPARE(model->data(model->index({0,1,1}, 2), roleNames.key("display")).toString(), u"Pear"_s); + QCOMPARE(model->data(model->index({0,1,1}, 2), roleNames.key("decoration")).toString(), u"green"_s); + QCOMPARE(model->data(model->index({0,1,1}, 3), roleNames.key("display")).toString(), u"Bear Pear"_s); + QCOMPARE(model->data(model->index({0,1,1}, 3), roleNames.key("decoration")).toString(), u"green"_s); + QCOMPARE(model->data(model->index({0,1,1}, 4), roleNames.key("display")).toDouble(), 1.5); + QCOMPARE(model->data(model->index({0,1,1}, 4), roleNames.key("decoration")).toString(), u"green"_s); + + // Call set with a nonexistent role - that role is ignored + QVERIFY(QMetaObject::invokeMethod(view.rootObject(), "setNodeWithExtraData")); + + // the structure of the tree did not change, only one row did + QCOMPARE(model->columnCount(), 5); + QCOMPARE(model->treeSize(), 8); + QCOMPARE(columnCountSpy.size(), 0); + QCOMPARE(rowsChangedSpy.size(), ++rowsChangedSignalEmissions); + QCOMPARE(treeView->columns(), 5); + QCOMPARE(treeView->rows(), 2); + + QCOMPARE(model->data(model->index({1,0}, 0), roleNames.key("display")).toBool(), true); + QCOMPARE(model->data(model->index({1,0}, 0), roleNames.key("decoration")).toString(), u"orange"_s); + QCOMPARE(model->data(model->index({1,0}, 1), roleNames.key("display")).toInt(), 4); + QCOMPARE(model->data(model->index({1,0}, 1), roleNames.key("decoration")).toString(), u"orange"_s); + QCOMPARE(model->data(model->index({1,0}, 2), roleNames.key("display")).toString(), u"Orange"_s); + QCOMPARE(model->data(model->index({1,0}, 2), roleNames.key("decoration")).toString(), u"orange"_s); + QCOMPARE(model->data(model->index({1,0}, 3), roleNames.key("display")).toString(), u"Navel"_s); + QCOMPARE(model->data(model->index({1,0}, 3), roleNames.key("decoration")).toString(), u"orange"_s); + QCOMPARE(model->data(model->index({1,0}, 4), roleNames.key("display")).toDouble(), 2.5); + QCOMPARE(model->data(model->index({1,0}, 4), roleNames.key("decoration")).toString(), u"orange"_s); +} + QTEST_MAIN(tst_QQmlTreeModel) #include "tst_qqmltreemodel.moc"