aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp')
-rw-r--r--tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp153
1 files changed, 153 insertions, 0 deletions
diff --git a/tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp b/tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp
index 27bf389891..1905c0f660 100644
--- a/tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp
+++ b/tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp
@@ -38,6 +38,8 @@
#include <QtQuickTestUtils/private/visualtestutils_p.h>
#include <QtQuickTestUtils/private/qmlutils_p.h>
+Q_LOGGING_CATEGORY(lcTests, "qt.quick.tests")
+
using namespace QQuickViewTestUtils;
using namespace QQuickVisualTestUtils;
@@ -60,6 +62,14 @@ private slots:
void sectionsNoOverlap();
void metaSequenceAsModel();
void noCrashOnIndexChange();
+ void tapDelegateDuringFlicking_data();
+ void tapDelegateDuringFlicking();
+ void flickDuringFlicking_data();
+ void flickDuringFlicking();
+
+private:
+ void flickWithTouch(QQuickWindow *window, const QPoint &from, const QPoint &to);
+ QScopedPointer<QPointingDevice> touchDevice = QScopedPointer<QPointingDevice>(QTest::createTouchDevice());
};
tst_QQuickListView2::tst_QQuickListView2()
@@ -307,6 +317,149 @@ void tst_QQuickListView2::noCrashOnIndexChange()
QCOMPARE(items->property("count").toInt(), 4);
}
+void tst_QQuickListView2::tapDelegateDuringFlicking_data()
+{
+ QTest::addColumn<QByteArray>("qmlFile");
+ QTest::addColumn<QQuickFlickable::BoundsBehavior>("boundsBehavior");
+
+ QTest::newRow("Button StopAtBounds") << QByteArray("buttonDelegate.qml")
+ << QQuickFlickable::BoundsBehavior(QQuickFlickable::StopAtBounds);
+ QTest::newRow("MouseArea StopAtBounds") << QByteArray("mouseAreaDelegate.qml")
+ << QQuickFlickable::BoundsBehavior(QQuickFlickable::StopAtBounds);
+ QTest::newRow("Button DragOverBounds") << QByteArray("buttonDelegate.qml")
+ << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragOverBounds);
+ QTest::newRow("MouseArea DragOverBounds") << QByteArray("mouseAreaDelegate.qml")
+ << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragOverBounds);
+ QTest::newRow("Button OvershootBounds") << QByteArray("buttonDelegate.qml")
+ << QQuickFlickable::BoundsBehavior(QQuickFlickable::OvershootBounds);
+ QTest::newRow("MouseArea OvershootBounds") << QByteArray("mouseAreaDelegate.qml")
+ << QQuickFlickable::BoundsBehavior(QQuickFlickable::OvershootBounds);
+ QTest::newRow("Button DragAndOvershootBounds") << QByteArray("buttonDelegate.qml")
+ << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragAndOvershootBounds);
+ QTest::newRow("MouseArea DragAndOvershootBounds") << QByteArray("mouseAreaDelegate.qml")
+ << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragAndOvershootBounds);
+}
+
+void tst_QQuickListView2::tapDelegateDuringFlicking() // QTBUG-103832
+{
+ QFETCH(QByteArray, qmlFile);
+ QFETCH(QQuickFlickable::BoundsBehavior, boundsBehavior);
+
+ QQuickView window;
+ QVERIFY(QQuickTest::showView(window, testFileUrl(qmlFile.constData())));
+ QQuickListView *listView = qobject_cast<QQuickListView*>(window.rootObject());
+ QVERIFY(listView);
+ listView->setBoundsBehavior(boundsBehavior);
+
+ flickWithTouch(&window, {100, 400}, {100, 100});
+ QTRY_VERIFY(listView->contentY() > 501); // let it flick some distance
+ QVERIFY(listView->isFlicking()); // we want to test the case when it's still moving while we tap
+ // @y = 400 we pressed the 4th delegate; started flicking, and the press was canceled
+ QCOMPARE(listView->property("pressedDelegates").toList().first(), 4);
+ QCOMPARE(listView->property("canceledDelegates").toList().first(), 4);
+
+ // press a delegate during flicking (at y > 501 + 100, so likely delegate 6)
+ QTest::touchEvent(&window, touchDevice.data()).press(0, {100, 100});
+ QQuickTouchUtils::flush(&window);
+ QTest::touchEvent(&window, touchDevice.data()).release(0, {100, 100});
+ QQuickTouchUtils::flush(&window);
+
+ const QVariantList pressedDelegates = listView->property("pressedDelegates").toList();
+ const QVariantList releasedDelegates = listView->property("releasedDelegates").toList();
+ const QVariantList tappedDelegates = listView->property("tappedDelegates").toList();
+ const QVariantList canceledDelegates = listView->property("canceledDelegates").toList();
+
+ qCDebug(lcTests) << "pressed" << pressedDelegates; // usually [4, 6]
+ qCDebug(lcTests) << "released" << releasedDelegates;
+ qCDebug(lcTests) << "tapped" << tappedDelegates;
+ qCDebug(lcTests) << "canceled" << canceledDelegates;
+
+ // which delegate received the second press, during flicking?
+ const int lastPressed = pressedDelegates.last().toInt();
+ QVERIFY(lastPressed > 5);
+ QCOMPARE(releasedDelegates.last(), lastPressed);
+ QCOMPARE(tappedDelegates.last(), lastPressed);
+ QCOMPARE(canceledDelegates.count(), 1); // only the first press was canceled, not the second
+}
+
+void tst_QQuickListView2::flickDuringFlicking_data()
+{
+ QTest::addColumn<QByteArray>("qmlFile");
+ QTest::addColumn<QQuickFlickable::BoundsBehavior>("boundsBehavior");
+
+ QTest::newRow("Button StopAtBounds") << QByteArray("buttonDelegate.qml")
+ << QQuickFlickable::BoundsBehavior(QQuickFlickable::StopAtBounds);
+ QTest::newRow("MouseArea StopAtBounds") << QByteArray("mouseAreaDelegate.qml")
+ << QQuickFlickable::BoundsBehavior(QQuickFlickable::StopAtBounds);
+ QTest::newRow("Button DragOverBounds") << QByteArray("buttonDelegate.qml")
+ << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragOverBounds);
+ QTest::newRow("MouseArea DragOverBounds") << QByteArray("mouseAreaDelegate.qml")
+ << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragOverBounds);
+ QTest::newRow("Button OvershootBounds") << QByteArray("buttonDelegate.qml")
+ << QQuickFlickable::BoundsBehavior(QQuickFlickable::OvershootBounds);
+ QTest::newRow("MouseArea OvershootBounds") << QByteArray("mouseAreaDelegate.qml")
+ << QQuickFlickable::BoundsBehavior(QQuickFlickable::OvershootBounds);
+ QTest::newRow("Button DragAndOvershootBounds") << QByteArray("buttonDelegate.qml")
+ << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragAndOvershootBounds);
+ QTest::newRow("MouseArea DragAndOvershootBounds") << QByteArray("mouseAreaDelegate.qml")
+ << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragAndOvershootBounds);
+}
+
+void tst_QQuickListView2::flickDuringFlicking() // QTBUG-103832
+{
+ QFETCH(QByteArray, qmlFile);
+ QFETCH(QQuickFlickable::BoundsBehavior, boundsBehavior);
+
+ QQuickView window;
+ QVERIFY(QQuickTest::showView(window, testFileUrl(qmlFile.constData())));
+ QQuickListView *listView = qobject_cast<QQuickListView*>(window.rootObject());
+ QVERIFY(listView);
+ listView->setBoundsBehavior(boundsBehavior);
+
+ flickWithTouch(&window, {100, 400}, {100, 100});
+ // let it flick some distance
+ QTRY_VERIFY2(listView->contentY() > 1000, qPrintable(QString::fromLatin1(
+ "Expected ListView's contentY to be greater than 1000, but it's %1").arg(listView->contentY())));
+ QVERIFY(listView->isFlicking()); // we want to test the case when it's moving and then we flick again
+ const qreal posBeforeSecondFlick = listView->contentY();
+
+ // flick again during flicking, and make sure that it doesn't jump back to the first delegate,
+ // but flicks incrementally further from the position at that time
+ QTest::touchEvent(&window, touchDevice.data()).press(0, {100, 400});
+ QQuickTouchUtils::flush(&window);
+ qCDebug(lcTests) << "second press: contentY" << posBeforeSecondFlick << "->" << listView->contentY();
+ qCDebug(lcTests) << "pressed delegates" << listView->property("pressedDelegates").toList();
+ QVERIFY(listView->contentY() >= posBeforeSecondFlick);
+
+ QTest::qWait(20);
+ QTest::touchEvent(&window, touchDevice.data()).move(0, {100, 300});
+ QQuickTouchUtils::flush(&window);
+ qCDebug(lcTests) << "first move after second press: contentY" << posBeforeSecondFlick << "->" << listView->contentY();
+ QVERIFY(listView->contentY() >= posBeforeSecondFlick);
+
+ QTest::qWait(20);
+ QTest::touchEvent(&window, touchDevice.data()).move(0, {100, 200});
+ QQuickTouchUtils::flush(&window);
+ qCDebug(lcTests) << "second move after second press: contentY" << posBeforeSecondFlick << "->" << listView->contentY();
+ QVERIFY(listView->contentY() >= posBeforeSecondFlick + 100);
+
+ QTest::touchEvent(&window, touchDevice.data()).release(0, {100, 100});
+}
+
+void tst_QQuickListView2::flickWithTouch(QQuickWindow *window, const QPoint &from, const QPoint &to)
+{
+ QTest::touchEvent(window, touchDevice.data()).press(0, from, window);
+ QQuickTouchUtils::flush(window);
+
+ QPoint diff = to - from;
+ for (int i = 1; i <= 8; ++i) {
+ QTest::touchEvent(window, touchDevice.data()).move(0, from + i * diff / 8, window);
+ QQuickTouchUtils::flush(window);
+ }
+ QTest::touchEvent(window, touchDevice.data()).release(0, to, window);
+ QQuickTouchUtils::flush(window);
+}
+
class SingletonModel : public QStringListModel
{
Q_OBJECT