diff options
Diffstat (limited to 'tests/auto')
7 files changed, 419 insertions, 9 deletions
diff --git a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp index d9a4777115..57e95f7b89 100644 --- a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp +++ b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp @@ -99,6 +99,8 @@ private: const QmlDebugObjectReference &oref, bool recursive) const; + void getContexts(); + QQmlDebugConnection *m_conn; QQmlEngineDebugClient *m_dbg; QQmlEngine *m_engine; @@ -138,6 +140,7 @@ private slots: void regression_QTCREATORBUG_7451(); void queryObjectWithNonStreamableTypes(); void asynchronousCreate(); + void invalidContexts(); }; QmlDebugObjectReference tst_QQmlEngineDebugService::findRootObject( @@ -248,6 +251,22 @@ void tst_QQmlEngineDebugService::recursiveObjectTest( } } +void tst_QQmlEngineDebugService::getContexts() +{ + bool success = false; + + m_dbg->queryAvailableEngines(&success); + QVERIFY(success); + QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); + + QList<QmlDebugEngineReference> engines = m_dbg->engines(); + QCOMPARE(engines.count(), 1); + m_dbg->queryRootContexts(engines.first().debugId, &success); + + QVERIFY(success); + QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); +} + void tst_QQmlEngineDebugService::initTestCase() { qmlRegisterType<NonScriptProperty>("Test", 1, 0, "NonScriptPropertyElement"); @@ -1289,6 +1308,26 @@ void tst_QQmlEngineDebugService::asynchronousCreate() { QTRY_COMPARE(m_dbg->object().idString, QLatin1String("asyncRect")); } +void tst_QQmlEngineDebugService::invalidContexts() +{ + getContexts(); + const int base = m_dbg->rootContext().contexts.count(); + QQmlContext context(m_engine); + getContexts(); + QCOMPARE(m_dbg->rootContext().contexts.count(), base + 1); + QQmlContextData *contextData = QQmlContextData::get(&context); + contextData->invalidate(); + getContexts(); + QCOMPARE(m_dbg->rootContext().contexts.count(), base); + QQmlContextData *rootData = QQmlContextData::get(m_engine->rootContext()); + rootData->invalidate(); + getContexts(); + QCOMPARE(m_dbg->rootContext().contexts.count(), 0); + contextData->setParent(rootData); // makes context valid again, but not root. + getContexts(); + QCOMPARE(m_dbg->rootContext().contexts.count(), 0); +} + int main(int argc, char *argv[]) { int _argc = argc + 1; diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp index 0bb913d104..3f66daf87f 100644 --- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp +++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp @@ -38,6 +38,7 @@ #include <private/qqmlvaluetype_p.h> #include <math.h> #include "../../shared/util.h" +#include "../shared/geometrytestutil.h" #include "../shared/viewtestutil.h" #include "../shared/visualtestutil.h" @@ -790,7 +791,14 @@ void tst_qquickflickable::resizeContent() QCOMPARE(obj->contentWidth(), 300.); QCOMPARE(obj->contentHeight(), 300.); + QQuickFlickablePrivate *fp = QQuickFlickablePrivate::get(obj); + QSizeChangeListener sizeListener(fp->contentItem); + QMetaObject::invokeMethod(root, "resizeContent"); + for (const QSize sizeOnGeometryChanged : sizeListener) { + // Check that we have the correct size on all signals + QCOMPARE(sizeOnGeometryChanged, QSize(600, 600)); + } QCOMPARE(obj->contentX(), 100.); QCOMPARE(obj->contentY(), 100.); diff --git a/tests/auto/quick/qquickgridview/data/qtbug57225.qml b/tests/auto/quick/qquickgridview/data/qtbug57225.qml new file mode 100644 index 0000000000..3871e5d273 --- /dev/null +++ b/tests/auto/quick/qquickgridview/data/qtbug57225.qml @@ -0,0 +1,95 @@ +import QtQuick 2.0 + +Rectangle { + id: root + width: 200 + height: 200 + + property int duration: 100 + property int count: grid.count + + Component { + id: myDelegate + Rectangle { + id: wrapper + + property string nameData: name + property bool removalStarted: false + property real minX: 0 + property real minY: 0 + + onXChanged: if (removalStarted) grid.recordPosition(x, y) + onYChanged: if (removalStarted) grid.recordPosition(x, y) + + objectName: "wrapper" + width: 80 + height: 80 + border.width: 1 + Column { + Text { text: index } + Text { + text: wrapper.x + ", " + wrapper.y + } + Text { + id: textName + objectName: "textName" + text: name + } + } + color: GridView.isCurrentItem ? "lightsteelblue" : "white" + + GridView.onRemove: SequentialAnimation { + PropertyAction { target: wrapper; property: "removalStarted"; value: true } + PropertyAction { target: wrapper; property: "GridView.delayRemove"; value: true } + NumberAnimation { target: wrapper; property: "scale"; to: 0.5; duration: root.duration; easing.type: Easing.InOutQuad } + PropertyAction { target: wrapper; property: "GridView.delayRemove"; value: false } + PropertyAction { target: grid; property: "animationDone"; value: true } + } + + } + } + + GridView { + id: grid + + property int displaceTransitionsDone: 0 + property bool animationDone: false + property point minimumPosition: Qt.point(0, 0) + + signal delegateMoved(real x, real y) + + objectName: "grid" + focus: true + anchors.fill: parent + cacheBuffer: 0 + cellWidth: 80 + cellHeight: 80 + model: testModel + delegate: myDelegate + + displaced: Transition { + id: transition + SequentialAnimation { + NumberAnimation { + properties: "x,y" + duration: root.duration + easing.type: Easing.OutBounce + } + ScriptAction { script: grid.displaceTransitionsDone += 1 } + } + } + + function recordPosition(index, x, y) { + if (x < minimumPosition.x || y < minimumPosition.y) { + minimumPosition = Qt.point(x, y) + } + } + } + + Rectangle { + anchors.fill: grid + color: "lightsteelblue" + opacity: 0.2 + } +} + diff --git a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp index 2b14842658..388ecc2ab8 100644 --- a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp +++ b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp @@ -153,6 +153,8 @@ private slots: void multipleTransitions(); void multipleTransitions_data(); void multipleDisplaced(); + void regression_QTBUG_57225(); + void regression_QTBUG_57225_data(); void inserted_leftToRight_RtL_TtB(); void inserted_leftToRight_RtL_TtB_data(); @@ -5798,6 +5800,65 @@ void tst_QQuickGridView::multipleDisplaced() delete window; } +void tst_QQuickGridView::regression_QTBUG_57225() +{ + QFETCH(int, initialCount); + QFETCH(int, removeIndex); + QFETCH(int, removeCount); + QFETCH(int, expectedDisplaceTransitions); + + // deleting all visible items should not cause a repositioning of said items. + + QaimModel model; + for (int i = 0; i < initialCount; i++) + model.addItem("Original item" + QString::number(i), ""); + + QQuickView *window = createView(); + QQmlContext *ctxt = window->rootContext(); + ctxt->setContextProperty("testModel", &model); + window->setSource(testFileUrl("qtbug57225.qml")); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickGridView *gridview = findItem<QQuickGridView>(window->rootObject(), "grid"); + QVERIFY(gridview != 0); + QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + + model.removeItems(removeIndex, removeCount); + QTRY_VERIFY(gridview->property("animationDone").toBool()); + + // verify that none of the removed items has moved to a negative position + QPoint minimumPosition = gridview->property("minimumPosition").toPoint(); + QVERIFY(minimumPosition.x() >= 0); + QVERIFY(minimumPosition.y() >= 0); + + // wait some more time to let the displaced transition happen + QTest::qWait(window->rootObject()->property("duration").toInt()); + QTRY_VERIFY2(gridview->property("displaceTransitionsDone").toInt() >= expectedDisplaceTransitions, + QByteArray::number(gridview->property("displaceTransitionsDone").toInt()).constData()); + + delete window; +} + +void tst_QQuickGridView::regression_QTBUG_57225_data() +{ + QTest::addColumn<int>("initialCount"); + QTest::addColumn<int>("removeIndex"); + QTest::addColumn<int>("removeCount"); + QTest::addColumn<int>("expectedDisplaceTransitions"); + + // no displace transitions should happen + QTest::newRow("remove all visible items") << + 20 << 0 << 8 << 0; + + // check that the removal animation is performed + QTest::newRow("remove items in between") << + 20 << 1 << 2 << 3; + + QTest::newRow("remove items in between - 2") << + 20 << 2 << 3 << 1; +} + void tst_QQuickGridView::cacheBuffer() { QQuickView *window = createView(); diff --git a/tests/auto/quick/qquicklistview/data/appendDuringScrollDown.qml b/tests/auto/quick/qquicklistview/data/appendDuringScrollDown.qml new file mode 100644 index 0000000000..af35c29143 --- /dev/null +++ b/tests/auto/quick/qquicklistview/data/appendDuringScrollDown.qml @@ -0,0 +1,28 @@ +import QtQuick 2.6 + +ListView { + width: 320; height: 240 + focus: true + delegate: Text { + height: 40; width: parent.width + text: model.text + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + } + highlight: Rectangle { color: "red" } + model: ListModel { + ListElement { text: "0" } + ListElement { text: "1" } + ListElement { text: "2" } + ListElement { text: "3" } + ListElement { text: "4" } + ListElement { text: "5" } + ListElement { text: "6" } + ListElement { text: "7" } + ListElement { text: "8" } + ListElement { text: "9" } + } + + readonly property Item topItem: itemAt(0, contentY) + onTopItemChanged: model.append({ "text": "new" }) +} diff --git a/tests/auto/quick/qquicklistview/data/qtbug34576.qml b/tests/auto/quick/qquicklistview/data/qtbug34576.qml new file mode 100644 index 0000000000..f407d8ebe3 --- /dev/null +++ b/tests/auto/quick/qquicklistview/data/qtbug34576.qml @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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$ +** +****************************************************************************/ + + +import QtQuick 2.7 + +Rectangle { + id: root + width: 320 + height: 240 + color: "black" + + property int current: list.currentIndex + property int horizontalVelocityZeroCount: 0 + + ListView { + id: list + objectName: "list" + anchors.fill: parent + + focus: true + + orientation: ListView.Horizontal + + snapMode: ListView.SnapToItem + flickableDirection: Flickable.HorizontalFlick + + model: 10 + delegate: Item { + width: root.width / 3 + height: root.height + Rectangle { + anchors.centerIn: parent + width: 50 + height: 50 + color: list.currentIndex === index ? "red" : "white" + } + } + + onHorizontalVelocityChanged: { + if (list.horizontalVelocity === 0.0) + root.horizontalVelocityZeroCount++ + } + + } + + Rectangle { + color: "red" + width: 50 + height: 50 + anchors.left: parent.left + anchors.bottom: parent.bottom + + MouseArea { + anchors.fill: parent + onClicked: { + list.currentIndex--; + } + } + } + + Rectangle { + color: "red" + width: 50 + height: 50 + anchors.right: parent.right + anchors.bottom: parent.bottom + + MouseArea { + anchors.fill: parent + onClicked: { + list.currentIndex++; + } + } + } +} + diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp index 0d0f234d33..a31cb37c16 100644 --- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp +++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp @@ -254,10 +254,13 @@ private slots: void QTBUG_50105(); void keyNavigationEnabled(); + void QTBUG_61269_appendDuringScrollDown(); void QTBUG_50097_stickyHeader_positionViewAtIndex(); void itemFiltered(); void releaseItems(); + void QTBUG_34576_velocityZero(); + private: template <class T> void items(const QUrl &source); template <class T> void changed(const QUrl &source); @@ -4681,29 +4684,24 @@ void tst_QQuickListView::indexAt_itemAt() void tst_QQuickListView::incrementalModel() { QScopedPointer<QQuickView> window(createView()); - QSKIP("QTBUG-30716"); IncrementalModel model; QQmlContext *ctxt = window->rootContext(); ctxt->setContextProperty("testModel", &model); window->setSource(testFileUrl("displaylist.qml")); - qApp->processEvents(); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); QQuickListView *listview = findItem<QQuickListView>(window->rootObject(), "list"); QTRY_VERIFY(listview != 0); - listview->forceLayout(); QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != 0); - - listview->forceLayout(); - QTRY_COMPARE(listview->count(), 20); + QTRY_COMPARE(listview->count(), 35); listview->positionViewAtIndex(10, QQuickListView::Beginning); - - listview->forceLayout(); - QTRY_COMPARE(listview->count(), 25); + QTRY_COMPARE(listview->count(), 45); } void tst_QQuickListView::onAdd() @@ -8468,6 +8466,37 @@ void tst_QQuickListView::keyNavigationEnabled() QCOMPARE(listView->currentIndex(), 1); } +void tst_QQuickListView::QTBUG_61269_appendDuringScrollDown() +{ + QScopedPointer<QQuickView> window(createView()); + window->setSource(testFileUrl("appendDuringScrollDown.qml")); + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window.data())); + + QQuickListView *listView = qobject_cast<QQuickListView *>(window->rootObject()); + QQuickItem *highlightItem = listView->highlightItem(); + QVERIFY(listView); + QCOMPARE(listView->isKeyNavigationEnabled(), true); + listView->setHighlightMoveVelocity(400); + listView->setHighlightMoveDuration(-1); // let it animate + listView->setFocus(true); + QVERIFY(listView->hasActiveFocus()); + qreal highlightYLimit = listView->height() - highlightItem->height(); // should be 200 + + for (int i = 1; i < 15; ++i) { + QTest::keyClick(window.data(), Qt::Key_Down); + + // Wait for the highlight movement animation to finish. + QTRY_COMPARE(highlightItem->y(), 40.0 * i); + + // As we scroll down, the QML will append rows to its own model. + // Make sure the highlighted row and highlight item stay within the view. + // In QTBUG-62864 and QTBUG-61269, it would go off the bottom. + QVERIFY(highlightItem->y() - listView->contentY() <= highlightYLimit); + } +} + void tst_QQuickListView::QTBUG_48870_fastModelUpdates() { StressTestModel model; @@ -8575,6 +8604,54 @@ void tst_QQuickListView::releaseItems() listview->setModel(123); } +void tst_QQuickListView::QTBUG_34576_velocityZero() +{ + QQuickView *window = new QQuickView(0); + window->setGeometry(0,0,240,320); + + QQmlContext *ctxt = window->rootContext(); + + QString filename(testFile("qtbug34576.qml")); + window->setSource(QUrl::fromLocalFile(filename)); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickListView *listview = findItem<QQuickListView>(window->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + + QSignalSpy horizontalVelocitySpy(listview, SIGNAL(horizontalVelocityChanged())); + + // currentIndex is initialized to 0 + QCOMPARE(listview->currentIndex(), 0); + + // set currentIndex to last item currently visible item + window->rootObject()->setProperty("horizontalVelocityZeroCount", QVariant(0)); + listview->setCurrentIndex(2); + QTRY_COMPARE(window->rootObject()->property("current").toInt(), 2); + QTRY_COMPARE(horizontalVelocitySpy.count(), 0); + QTRY_COMPARE(window->rootObject()->property("horizontalVelocityZeroCount").toInt(), 0); + + // click button which increases currentIndex + QTest::mousePress(window, Qt::LeftButton, 0, QPoint(295,215)); + QTest::mouseRelease(window, Qt::LeftButton, 0, QPoint(295,215)); + + // verify that currentIndexChanged is triggered + QVERIFY(horizontalVelocitySpy.wait()); + + // set currentIndex to item out of view to cause listview scroll + QTRY_COMPARE(window->rootObject()->property("current").toInt(), 3); + QTRY_COMPARE(horizontalVelocitySpy.count() > 0, true); + QVERIFY(horizontalVelocitySpy.wait(1000)); + + // velocity should be always > 0.0 + QTRY_COMPARE(window->rootObject()->property("horizontalVelocityZeroCount").toInt(), 0); + + delete window; +} + QTEST_MAIN(tst_QQuickListView) #include "tst_qquicklistview.moc" |