diff options
author | Alexandru Croitor <alexandru.croitor@qt.io> | 2019-10-14 18:46:38 +0200 |
---|---|---|
committer | Alexandru Croitor <alexandru.croitor@qt.io> | 2019-10-14 19:02:37 +0200 |
commit | c2f8b9535d34da6948ccf45b7d5fd90de2f1bc9e (patch) | |
tree | c6f7e058a985d7c18b51cadc76283caf555071c9 /tests/auto/quick/qquickpathview | |
parent | 9e633bbda7608ac0231809e2a6a97ae8f2d849d6 (diff) | |
parent | 803f18f02e5609a1ca00a5b78ea6d3613d44e1a0 (diff) |
Merge remote-tracking branch 'origin/dev' into wip/cmake
Removed dependencies.yaml because we don't use it yet in wip/cmake.
Fixed conflict in qmlcachegen.cpp.
Change-Id: Ie1060c737bee1daa85779903598e5b6d5020d922
Diffstat (limited to 'tests/auto/quick/qquickpathview')
6 files changed, 432 insertions, 0 deletions
diff --git a/tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.2.qml b/tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.2.qml new file mode 100644 index 0000000000..ae8ca784bc --- /dev/null +++ b/tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.2.qml @@ -0,0 +1,59 @@ +import QtQuick 2.14 + +Item { + id: root + width: 800 + height: 600 + property bool working: false + + ListModel { + id: myModel + ListElement { + name: "Bill Jones" + place: "Berlin" + } + ListElement { + name: "Jane Doe" + place: "Oslo" + } + ListElement { + name: "John Smith" + place: "Oulo" + } + } + + Component { + id: delegateComponent + Rectangle { + id: myDelegate + height: 50 + width: 50 + required property string name + required property int index + onNameChanged: () => {if (myDelegate.name === "You-know-who") root.working = true} + Text { + text: myDelegate.name + font.pointSize: 10 + anchors.fill: myDelegate + } + } + } + + PathView { + anchors.fill: parent + model: myModel + delegate: delegateComponent + path: Path { + startX: 80; startY: 100 + PathQuad { x: 120; y: 25; controlX: 260; controlY: 75 } + PathQuad { x: 140; y: 100; controlX: -20; controlY: 75 } + } + } + Timer { + interval: 1 + running: true + repeat: false + onTriggered: () => { myModel.setProperty(1, "name", "You-know-who"); } + } + +} diff --git a/tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.3.qml b/tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.3.qml new file mode 100644 index 0000000000..2996ba18fd --- /dev/null +++ b/tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.3.qml @@ -0,0 +1,64 @@ +import QtQuick 2.14 + +Item { + id: root + width: 800 + height: 600 + property bool working: false + + ListModel { + id: myModel + ListElement { + name: "Bill Jones" + place: "Berlin" + } + ListElement { + name: "Jane Doe" + place: "Oslo" + } + ListElement { + name: "John Smith" + place: "Oulo" + } + } + + Component { + id: delegateComponent + Rectangle { + id: myDelegate + height: 50 + width: 50 + required property string name + required property int index + onNameChanged: () => {if (myDelegate.name === "You-know-who") root.working = false} + Text { + text: myDelegate.name + font.pointSize: 10 + anchors.fill: myDelegate + } + Component.onCompleted: () => {myDelegate.name = "break binding"} + } + } + + PathView { + anchors.fill: parent + model: myModel + delegate: delegateComponent + path: Path { + startX: 80; startY: 100 + PathQuad { x: 120; y: 25; controlX: 260; controlY: 75 } + PathQuad { x: 140; y: 100; controlX: -20; controlY: 75 } + } + } + Timer { + interval: 1 + running: true + repeat: false + onTriggered: () => { + myModel.setProperty(1, "name", "You-know-who") + myModel.setProperty(2, "name", "You-know-who") + root.working = true + } + } + +} diff --git a/tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.qml b/tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.qml new file mode 100644 index 0000000000..5d721fd0c4 --- /dev/null +++ b/tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.qml @@ -0,0 +1,53 @@ +import QtQuick 2.14 + +Item { + width: 400 + height: 200 + + ListModel { + id: myModel + ListElement { + name: "Bill Jones" + place: "Berlin" + } + ListElement { + name: "Jane Doe" + place: "Oslo" + } + ListElement { + name: "John Smith" + place: "Oulo" + } + } + + Component { + id: delegateComponent + Rectangle { + id: myDelegate + required property int index + required property string name + required property string place + height: 100 + width: 100 + Text { + text: myDelegate.name + " lives in " + myDelegate.place + myDelegate.index + font.pointSize: 16 + anchors.fill: myDelegate + + Component.onCompleted: () => {console.info(myDelegate.name+myDelegate.place+myDelegate.index)} + } + } + } + + PathView { + anchors.fill: parent + model: myModel + delegate: delegateComponent + path: Path { + startX: 120; startY: 100 + PathQuad { x: 120; y: 25; controlX: 260; controlY: 75 } + PathQuad { x: 120; y: 100; controlX: -20; controlY: 75 } + } + } + +} diff --git a/tests/auto/quick/qquickpathview/data/delegatewithUnrelatedRequiredPreventsAccessToModel.qml b/tests/auto/quick/qquickpathview/data/delegatewithUnrelatedRequiredPreventsAccessToModel.qml new file mode 100644 index 0000000000..bf130a2d73 --- /dev/null +++ b/tests/auto/quick/qquickpathview/data/delegatewithUnrelatedRequiredPreventsAccessToModel.qml @@ -0,0 +1,52 @@ +import QtQuick 2.14 + +Item { + width: 400 + height: 200 + + ListModel { + id: myModel + ListElement { + name: "Bill Jones" + place: "Berlin" + } + ListElement { + name: "Jane Doe" + place: "Oslo" + } + ListElement { + name: "John Smith" + place: "Oulo" + } + } + + Component { + id: delegateComponent + Rectangle { + id: myDelegate + required property int set + set: 42 + height: 100 + width: 100 + Text { + text: "Test" + font.pointSize: 16 + anchors.fill: myDelegate + + Component.onCompleted: () => { try {index; console.log(index); console.log(name)} catch(ex) {console.info(ex.name)} } + } + } + } + + PathView { + anchors.fill: parent + model: myModel + delegate: delegateComponent + path: Path { + startX: 120; startY: 100 + PathQuad { x: 120; y: 25; controlX: 260; controlY: 75 } + PathQuad { x: 120; y: 100; controlX: -20; controlY: 75 } + } + } + +} diff --git a/tests/auto/quick/qquickpathview/data/nestedmousearea2.qml b/tests/auto/quick/qquickpathview/data/nestedmousearea2.qml new file mode 100644 index 0000000000..ff11002552 --- /dev/null +++ b/tests/auto/quick/qquickpathview/data/nestedmousearea2.qml @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2019 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:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +PathView { + id: view + width: 400; height: 240 + highlight: Rectangle { width: 80; height: 80; color: "lightsteelblue" } + preferredHighlightBegin: 0.5 + preferredHighlightEnd: 0.5 + model: ListModel { + id: appModel + ListElement { name: "Music" } + ListElement { name: "Movies" } + ListElement { name: "Camera" } + ListElement { name: "Calendar" } + ListElement { name: "Messaging" } + ListElement { name: "Todo List" } + ListElement { name: "Contacts" } + } + delegate: Rectangle { + width: 100; height: 100 + scale: PathView.iconScale + border.color: "lightgrey" + color: "transparent" + Text { + anchors { horizontalCenter: parent.horizontalCenter } + text: name + smooth: true + color: ma.pressed ? "red" : "black" + } + + MouseArea { + id: ma + anchors.fill: parent + onClicked: view.currentIndex = index + } + } + path: Path { + startX: 10 + startY: 50 + PathAttribute { name: "iconScale"; value: 0.5 } + PathQuad { x: 200; y: 150; controlX: 50; controlY: 200 } + PathAttribute { name: "iconScale"; value: 1.0 } + PathQuad { x: 390; y: 50; controlX: 350; controlY: 200 } + PathAttribute { name: "iconScale"; value: 0.5 } + } + Text { + anchors.horizontalCenter: parent.horizontalCenter + y: 20 + text: view.currentIndex + " @ " + offset.toFixed(2) + } +} diff --git a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp index 8b963117ed..a8e847a5c7 100644 --- a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp +++ b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp @@ -120,6 +120,7 @@ private slots: void undefinedPath(); void mouseDrag(); void nestedMouseAreaDrag(); + void flickNClick(); void treeModel(); void changePreferredHighlight(); void missingPercent(); @@ -149,6 +150,8 @@ private slots: void movementDirection(); void removePath(); void objectModelMove(); + void requiredPropertiesInDelegate(); + void requiredPropertiesInDelegatePreventUnrelated(); }; class TestObject : public QObject @@ -1601,6 +1604,71 @@ void tst_QQuickPathView::nestedMouseAreaDrag() QVERIFY(pathview->isMoving()); } +void tst_QQuickPathView::flickNClick() // QTBUG-77173 +{ + QScopedPointer<QQuickView> window(createView()); + QQuickViewTestUtil::moveMouseAway(window.data()); + window->setSource(testFileUrl("nestedmousearea2.qml")); + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window.data())); + QCOMPARE(window.data(), qGuiApp->focusWindow()); + + QQuickPathView *pathview = qobject_cast<QQuickPathView*>(window->rootObject()); + QVERIFY(pathview != nullptr); + QSignalSpy movingChangedSpy(pathview, SIGNAL(movingChanged())); + QSignalSpy draggingSpy(pathview, SIGNAL(draggingChanged())); + QSignalSpy dragStartedSpy(pathview, SIGNAL(dragStarted())); + QSignalSpy dragEndedSpy(pathview, SIGNAL(dragEnded())); + QSignalSpy currentIndexSpy(pathview, SIGNAL(currentIndexChanged())); + QSignalSpy moveStartedSpy(pathview, SIGNAL(movementStarted())); + QSignalSpy moveEndedSpy(pathview, SIGNAL(movementEnded())); + QSignalSpy flickingSpy(pathview, SIGNAL(flickingChanged())); + QSignalSpy flickStartedSpy(pathview, SIGNAL(flickStarted())); + QSignalSpy flickEndedSpy(pathview, SIGNAL(flickEnded())); + + for (int duration = 100; duration > 0; duration -= 20) { + movingChangedSpy.clear(); + draggingSpy.clear(); + dragStartedSpy.clear(); + dragEndedSpy.clear(); + currentIndexSpy.clear(); + moveStartedSpy.clear(); + moveEndedSpy.clear(); + flickingSpy.clear(); + flickStartedSpy.clear(); + flickEndedSpy.clear(); + // Dragging the child mouse area should animate the PathView (MA has no drag target) + flick(window.data(), QPoint(200,200), QPoint(400,200), duration); + QVERIFY(pathview->isMoving()); + QCOMPARE(movingChangedSpy.count(), 1); + QCOMPARE(draggingSpy.count(), 2); + QCOMPARE(dragStartedSpy.count(), 1); + QCOMPARE(dragEndedSpy.count(), 1); + QVERIFY(currentIndexSpy.count() > 0); + QCOMPARE(moveStartedSpy.count(), 1); + QCOMPARE(moveEndedSpy.count(), 0); + QCOMPARE(flickingSpy.count(), 1); + QCOMPARE(flickStartedSpy.count(), 1); + QCOMPARE(flickEndedSpy.count(), 0); + + // Now while it's still moving, click it. + // The PathView should stop at a position such that offset is a whole number. + QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, QPoint(200, 200)); + QTRY_VERIFY(!pathview->isMoving()); + QCOMPARE(movingChangedSpy.count(), 2); // QTBUG-78926 + QCOMPARE(draggingSpy.count(), 2); + QCOMPARE(dragStartedSpy.count(), 1); + QCOMPARE(dragEndedSpy.count(), 1); + QCOMPARE(moveStartedSpy.count(), 1); + QCOMPARE(moveEndedSpy.count(), 1); + QCOMPARE(flickingSpy.count(), 2); + QCOMPARE(flickStartedSpy.count(), 1); + QCOMPARE(flickEndedSpy.count(), 1); + QVERIFY(qFuzzyIsNull(pathview->offset() - int(pathview->offset()))); + } +} + void tst_QQuickPathView::treeModel() { QScopedPointer<QQuickView> window(createView()); @@ -2658,6 +2726,41 @@ void tst_QQuickPathView::objectModelMove() } } +void tst_QQuickPathView::requiredPropertiesInDelegate() +{ + { + QTest::ignoreMessage(QtMsgType::QtInfoMsg, "Bill JonesBerlin0"); + QTest::ignoreMessage(QtMsgType::QtInfoMsg, "Jane DoeOslo1"); + QTest::ignoreMessage(QtMsgType::QtInfoMsg, "John SmithOulo2"); + QScopedPointer<QQuickView> window(createView()); + window->setSource(testFileUrl("delegateWithRequiredProperties.qml")); + window->show(); + } + { + QScopedPointer<QQuickView> window(createView()); + window->setSource(testFileUrl("delegateWithRequiredProperties.2.qml")); + window->show(); + QTRY_VERIFY(window->rootObject()->property("working").toBool()); + } + { + QScopedPointer<QQuickView> window(createView()); + QTest::ignoreMessage(QtMsgType::QtWarningMsg, QRegularExpression("Writing to \"name\" broke the binding to the underlying model")); + window->setSource(testFileUrl("delegateWithRequiredProperties.3.qml")); + window->show(); + QTRY_VERIFY(window->rootObject()->property("working").toBool()); + } +} + +void tst_QQuickPathView::requiredPropertiesInDelegatePreventUnrelated() +{ + QTest::ignoreMessage(QtMsgType::QtInfoMsg, "ReferenceError"); + QTest::ignoreMessage(QtMsgType::QtInfoMsg, "ReferenceError"); + QTest::ignoreMessage(QtMsgType::QtInfoMsg, "ReferenceError"); + QScopedPointer<QQuickView> window(createView()); + window->setSource(testFileUrl("delegatewithUnrelatedRequiredPreventsAccessToModel.qml")); + window->show(); +} + QTEST_MAIN(tst_QQuickPathView) #include "tst_qquickpathview.moc" |