diff options
Diffstat (limited to 'tests/auto/quick')
7 files changed, 341 insertions, 9 deletions
diff --git a/tests/auto/quick/qquicklistview/data/qtbug61537_modelChangesAsync.qml b/tests/auto/quick/qquicklistview/data/qtbug61537_modelChangesAsync.qml new file mode 100644 index 0000000000..0dc9e6fdb5 --- /dev/null +++ b/tests/auto/quick/qquicklistview/data/qtbug61537_modelChangesAsync.qml @@ -0,0 +1,125 @@ +/**************************************************************************** +** +** 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: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 + +Item { + visible: true + width: 640 + height: 480 + + property ListView listView + + Loader { + id: loader + anchors.fill: parent + asynchronous: true + sourceComponent: comp + + onStatusChanged: { + if (status == Loader.Ready) { + // Assign the listview to the root prop late, so + // that the c++ part doesn't start before everything is ready. + listView = item.listView + } + } + } + + Component { + id: comp + Item { + property alias listView: listView + + ListView { + id: listView + + model: ListModel { + id: listModel + ListElement { title: "one" } + ListElement { title: "two" } + } + + anchors.fill: parent + orientation: ListView.Horizontal + + delegate: Item { + id: delegateRoot + objectName: "delegate" + + width: 200 + height: 200 + + Component.onCompleted: { + if (index === listModel.count - 1) { + // Add a new item while the outer Loader is still incubating async. If the new model item + // incubates using e.g QQmlIncubator::AsynchronousIfNested, it will also be loaded async, which + // is not currently supported (the item will not be added to the listview, or end up the wrong + // position, depending on its index and the current state of the refill/layout logic in + // QQuickListView). + // We add the new item here at the last delegates Component.onCompleted to hit the point in time + // when the listview is not expecting any more async items. In that case, the item will only be + // added to the list of visible items if incubated synchronously, which gives us something we + // can test for in the auto-test. + listModel.insert(0, {title: "zero"}); + } + } + + Rectangle { + anchors.fill: parent + border.width: 1 + Text { + anchors.centerIn: parent + text: index + } + } + } + } + } + } +} diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp index f06a118976..223f6004ff 100644 --- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp +++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp @@ -261,6 +261,7 @@ private slots: void releaseItems(); void QTBUG_34576_velocityZero(); + void QTBUG_61537_modelChangesAsync(); private: template <class T> void items(const QUrl &source); @@ -8694,6 +8695,33 @@ void tst_QQuickListView::QTBUG_34576_velocityZero() delete window; } +void tst_QQuickListView::QTBUG_61537_modelChangesAsync() +{ + // The purpose of this test if to check that any model changes that happens + // during start-up, while a loader higher up in the chain is still incubating + // async, will not fail. + QQuickView window; + window.setGeometry(0,0,640,480); + + QString filename(testFile("qtbug61537_modelChangesAsync.qml")); + window.setSource(QUrl::fromLocalFile(filename)); + window.show(); + QVERIFY(QTest::qWaitForWindowExposed(&window)); + + // The qml file will assign the listview to the 'listView' property once the + // loader is ready with async incubation. So we need to wait for it. + QObject *root = window.rootObject(); + QTRY_VERIFY(root->property("listView").value<QQuickListView *>()); + QQuickListView *listView = root->property("listView").value<QQuickListView *>(); + QVERIFY(listView); + + // Check that the number of delegates we expect to be visible in + // the listview matches the number of items we find if we count. + int reportedCount = listView->count(); + int actualCount = findItems<QQuickItem>(listView, "delegate").count(); + QCOMPARE(reportedCount, actualCount); +} + QTEST_MAIN(tst_QQuickListView) #include "tst_qquicklistview.moc" diff --git a/tests/auto/quick/qquickmousearea/data/twoMouseAreas.qml b/tests/auto/quick/qquickmousearea/data/twoMouseAreas.qml new file mode 100644 index 0000000000..28f48c742a --- /dev/null +++ b/tests/auto/quick/qquickmousearea/data/twoMouseAreas.qml @@ -0,0 +1,33 @@ +import QtQuick 2.0 +import QtQuick.Window 2.0 + +Rectangle { + width: 400 + height: 300 + + property bool topPressed: top.pressed + property bool bottomPressed: bottom.pressed + + MouseArea { + id: top + objectName: "top" + width: parent.width + height: parent.height / 2 - 2 + Rectangle { + anchors.fill: parent + color: parent.pressed ? "MediumSeaGreen" : "beige" + } + } + + MouseArea { + id: bottom + objectName: "bottom" + y: parent.height / 2 + width: parent.width + height: parent.height / 2 + Rectangle { + anchors.fill: parent + color: parent.pressed ? "MediumSeaGreen" : "beige" + } + } +} diff --git a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp index 01bce46ccb..393a57e7e8 100644 --- a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp +++ b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp @@ -130,6 +130,8 @@ private slots: void notPressedAfterStolenGrab(); void pressAndHold_data(); void pressAndHold(); + void pressOneAndTapAnother_data(); + void pressOneAndTapAnother(); private: int startDragDistance() const { @@ -2173,6 +2175,74 @@ void tst_QQuickMouseArea::pressAndHold() QTest::mouseRelease(&window, Qt::LeftButton, Qt::NoModifier, QPoint(50, 50)); } +void tst_QQuickMouseArea::pressOneAndTapAnother_data() +{ + QTest::addColumn<bool>("pressMouseFirst"); + QTest::addColumn<bool>("releaseMouseFirst"); + + QTest::newRow("press mouse, tap touch, release mouse") << true << false; // QTBUG-64249 as written + QTest::newRow("press touch, press mouse, release touch, release mouse") << false << false; + QTest::newRow("press mouse, press touch, release mouse, release touch") << true << true; + // TODO fix in a separate patch after the 5.9->5.10 merge + // QTest::newRow("press touch, click mouse, release touch") << false << true; +} + +void tst_QQuickMouseArea::pressOneAndTapAnother() +{ + QFETCH(bool, pressMouseFirst); + QFETCH(bool, releaseMouseFirst); + + QQuickView window; + QByteArray errorMessage; + QVERIFY2(initView(window, testFileUrl("twoMouseAreas.qml"), true, &errorMessage), errorMessage.constData()); + window.show(); + window.requestActivate(); + QVERIFY(QTest::qWaitForWindowExposed(&window)); + QQuickItem *root = window.rootObject(); + QVERIFY(root); + QQuickMouseArea *bottomMA = window.rootObject()->findChild<QQuickMouseArea*>("bottom"); + QVERIFY(bottomMA); + QQuickMouseArea *topMA = window.rootObject()->findChild<QQuickMouseArea*>("top"); + QVERIFY(topMA); + + QPoint upper(32, 32); + QPoint lower(32, window.height() - 32); + + // press them both + if (pressMouseFirst) { + QTest::mousePress(&window, Qt::LeftButton, Qt::NoModifier, lower); + QTRY_COMPARE(bottomMA->pressed(), true); + + QTest::touchEvent(&window, device).press(0, lower, &window); + QQuickTouchUtils::flush(&window); + QTRY_COMPARE(bottomMA->pressed(), true); + } else { + QTest::touchEvent(&window, device).press(0, lower, &window); + QQuickTouchUtils::flush(&window); + QTRY_COMPARE(bottomMA->pressed(), true); + + QTest::mousePress(&window, Qt::LeftButton, Qt::NoModifier, lower); + QTRY_COMPARE(bottomMA->pressed(), true); + } + + // release them both and make sure neither one gets stuck + if (releaseMouseFirst) { + QTest::mouseRelease(&window, Qt::LeftButton, Qt::NoModifier, lower); + QTRY_COMPARE(bottomMA->pressed(), false); + + QTest::touchEvent(&window, device).release(0, upper, &window); + QQuickTouchUtils::flush(&window); + QTRY_COMPARE(topMA->pressed(), false); + } else { + QTest::touchEvent(&window, device).release(0, upper, &window); + QQuickTouchUtils::flush(&window); + + QTRY_COMPARE(topMA->pressed(), false); + QTest::mouseRelease(&window, Qt::LeftButton, Qt::NoModifier, lower); + QTRY_COMPARE(bottomMA->pressed(), false); + } +} + QTEST_MAIN(tst_QQuickMouseArea) #include "tst_qquickmousearea.moc" diff --git a/tests/auto/quick/qquickrepeater/data/asynchronousMove.qml b/tests/auto/quick/qquickrepeater/data/asynchronousMove.qml new file mode 100644 index 0000000000..02499c8531 --- /dev/null +++ b/tests/auto/quick/qquickrepeater/data/asynchronousMove.qml @@ -0,0 +1,51 @@ +import QtQuick 2.3 +import QtQuick.Window 2.2 + +Item { + property bool finished: loader.status === Loader.Ready && loader.progress === 1 + + ListModel { + id: listModel + ListElement { i:0 } + ListElement { i:1 } + ListElement { i:2 } + ListElement { i:3 } + } + + Timer { + running: true + interval: 1 + repeat: count < 5 + property int count : 0 + + onTriggered: { + listModel.move(listModel.count - 1, listModel.count - 2, 1) + ++count + } + } + + Loader { + id: loader + asynchronous: true + sourceComponent: Row { + spacing: 4 + Repeater { + model: listModel + delegate: Column { + spacing: 4 + Repeater { + model: 4 + delegate: Rectangle { + width: 30 + height: 30 + color: "blue" + Component.onCompleted: { + ctrl.wait() + } + } + } + } + } + } + } +} diff --git a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp index f7b04e9a30..3519c53cb7 100644 --- a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp +++ b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp @@ -75,6 +75,7 @@ private slots: void destroyCount(); void stackingOrder(); void objectModel(); + void QTBUG54859_asynchronousMove(); }; class TestObject : public QObject @@ -989,6 +990,30 @@ void tst_QQuickRepeater::objectModel() delete positioner; } +class Ctrl : public QObject +{ + Q_OBJECT +public: + + Q_INVOKABLE void wait() + { + QTest::qWait(200); + } +}; + +void tst_QQuickRepeater::QTBUG54859_asynchronousMove() +{ + Ctrl ctrl; + QQuickView* view = createView(); + view->rootContext()->setContextProperty("ctrl", &ctrl); + view->setSource(testFileUrl("asynchronousMove.qml")); + view->show(); + QQuickItem* item = view->rootObject(); + + + QTRY_COMPARE(item->property("finished"), QVariant(true)); +} + QTEST_MAIN(tst_QQuickRepeater) #include "tst_qquickrepeater.moc" diff --git a/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp b/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp index cabfb97914..2280f75518 100644 --- a/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp +++ b/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp @@ -4013,7 +4013,7 @@ void tst_qquickvisualdatamodel::asynchronousInsert() connect(visualModel, SIGNAL(createdItem(int,QObject*)), &requester, SLOT(createdItem(int,QObject*))); connect(visualModel, SIGNAL(destroyingItem(QObject*)), &requester, SLOT(destroyingItem(QObject*))); - QQuickItem *item = qobject_cast<QQuickItem*>(visualModel->object(requestIndex, true)); + QQuickItem *item = qobject_cast<QQuickItem*>(visualModel->object(requestIndex, QQmlIncubator::Asynchronous)); QVERIFY(!item); QVERIFY(!requester.itemInitialized); @@ -4025,7 +4025,7 @@ void tst_qquickvisualdatamodel::asynchronousInsert() newItems.append(qMakePair(QLatin1String("New item") + QString::number(i), QString(QLatin1String("")))); model.insertItems(insertIndex, newItems); - item = qobject_cast<QQuickItem*>(visualModel->object(completeIndex, false)); + item = qobject_cast<QQuickItem*>(visualModel->object(completeIndex)); QVERIFY(item); QCOMPARE(requester.itemInitialized, item); @@ -4078,7 +4078,7 @@ void tst_qquickvisualdatamodel::asynchronousRemove() connect(visualModel, SIGNAL(createdItem(int,QObject*)), &requester, SLOT(createdItem(int,QObject*))); connect(visualModel, SIGNAL(destroyingItem(QObject*)), &requester, SLOT(destroyingItem(QObject*))); - QQuickItem *item = qobject_cast<QQuickItem*>(visualModel->object(requestIndex, true)); + QQuickItem *item = qobject_cast<QQuickItem*>(visualModel->object(requestIndex, QQmlIncubator::Asynchronous)); QVERIFY(!item); QVERIFY(!requester.itemInitialized); @@ -4099,7 +4099,7 @@ void tst_qquickvisualdatamodel::asynchronousRemove() QVERIFY(!requester.itemCreated); QVERIFY(!requester.itemDestroyed); } else { - item = qobject_cast<QQuickItem*>(visualModel->object(completeIndex, false)); + item = qobject_cast<QQuickItem*>(visualModel->object(completeIndex)); QVERIFY(item); QCOMPARE(requester.itemInitialized, item); @@ -4157,7 +4157,7 @@ void tst_qquickvisualdatamodel::asynchronousMove() connect(visualModel, SIGNAL(createdItem(int,QObject*)), &requester, SLOT(createdItem(int,QObject*))); connect(visualModel, SIGNAL(destroyingItem(QObject*)), &requester, SLOT(destroyingItem(QObject*))); - QQuickItem *item = qobject_cast<QQuickItem*>(visualModel->object(requestIndex, true)); + QQuickItem *item = qobject_cast<QQuickItem*>(visualModel->object(requestIndex, QQmlIncubator::Asynchronous)); QVERIFY(!item); QVERIFY(!requester.itemInitialized); @@ -4166,7 +4166,7 @@ void tst_qquickvisualdatamodel::asynchronousMove() model.moveItems(from, to, count); - item = qobject_cast<QQuickItem*>(visualModel->object(completeIndex, false)); + item = qobject_cast<QQuickItem*>(visualModel->object(completeIndex)); QVERIFY(item); @@ -4200,7 +4200,7 @@ void tst_qquickvisualdatamodel::asynchronousCancel() QQmlDelegateModel *visualModel = qobject_cast<QQmlDelegateModel*>(c.create()); QVERIFY(visualModel); - QQuickItem *item = qobject_cast<QQuickItem*>(visualModel->object(requestIndex, true)); + QQuickItem *item = qobject_cast<QQuickItem*>(visualModel->object(requestIndex, QQmlIncubator::Asynchronous)); QVERIFY(!item); QCOMPARE(controller.incubatingObjectCount(), 1); @@ -4225,7 +4225,7 @@ void tst_qquickvisualdatamodel::invalidContext() QQmlDelegateModel *visualModel = qobject_cast<QQmlDelegateModel*>(c.create(context.data())); QVERIFY(visualModel); - QQuickItem *item = qobject_cast<QQuickItem*>(visualModel->object(4, false)); + QQuickItem *item = qobject_cast<QQuickItem*>(visualModel->object(4)); QVERIFY(item); visualModel->release(item); @@ -4233,7 +4233,7 @@ void tst_qquickvisualdatamodel::invalidContext() model.insertItem(4, "new item", ""); - item = qobject_cast<QQuickItem*>(visualModel->object(4, false)); + item = qobject_cast<QQuickItem*>(visualModel->object(4)); QVERIFY(!item); } |