aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/quick/qquickpathview
diff options
context:
space:
mode:
authorAlexandru Croitor <alexandru.croitor@qt.io>2019-10-14 18:46:38 +0200
committerAlexandru Croitor <alexandru.croitor@qt.io>2019-10-14 19:02:37 +0200
commitc2f8b9535d34da6948ccf45b7d5fd90de2f1bc9e (patch)
treec6f7e058a985d7c18b51cadc76283caf555071c9 /tests/auto/quick/qquickpathview
parent9e633bbda7608ac0231809e2a6a97ae8f2d849d6 (diff)
parent803f18f02e5609a1ca00a5b78ea6d3613d44e1a0 (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')
-rw-r--r--tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.2.qml59
-rw-r--r--tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.3.qml64
-rw-r--r--tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.qml53
-rw-r--r--tests/auto/quick/qquickpathview/data/delegatewithUnrelatedRequiredPreventsAccessToModel.qml52
-rw-r--r--tests/auto/quick/qquickpathview/data/nestedmousearea2.qml101
-rw-r--r--tests/auto/quick/qquickpathview/tst_qquickpathview.cpp103
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"