aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/quick
diff options
context:
space:
mode:
authorTarja Sundqvist <tarja.sundqvist@qt.io>2025-08-22 09:33:17 +0300
committerTarja Sundqvist <tarja.sundqvist@qt.io>2025-08-22 09:33:17 +0300
commitc6fdadd916a7568c1d71b750e054ca9aa2fd5dfc (patch)
treebbd5690b38a5e0df66dd070a9e9f42b0d1b2b673 /tests/auto/quick
parenta7c766a9863605eb81e8f0cdb4d2b93e087b5bde (diff)
parente436dad999060b92965291b45c0e95a3b93f5866 (diff)
Merge tag 'v6.2.13-lts' into tqtc/lts-6.2-opensourcev6.2.13-lts-lgpl6.2
Qt 6.2.13-lts release Conflicts solved: dependencies.yaml Change-Id: I3cbe1ce4293179888e236dd1a3a299cd2c66c950
Diffstat (limited to 'tests/auto/quick')
-rw-r--r--tests/auto/quick/qquickanimations/tst_qquickanimations.cpp36
-rw-r--r--tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml47
-rw-r--r--tests/auto/quick/qquicklistview/data/snapToItemWithSectionAtStart.qml52
-rw-r--r--tests/auto/quick/qquicklistview/tst_qquicklistview.cpp22
-rw-r--r--tests/auto/quick/qquickmultipointtoucharea/BLACKLIST2
-rw-r--r--tests/auto/quick/qquicktableview/tst_qquicktableview.cpp81
-rw-r--r--tests/auto/quick/qquicktext/data/elideZeroWidthWithMargins.qml27
-rw-r--r--tests/auto/quick/qquicktext/tst_qquicktext.cpp12
8 files changed, 278 insertions, 1 deletions
diff --git a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp
index 30b934eeec..579eeb7c0a 100644
--- a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp
+++ b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp
@@ -119,6 +119,7 @@ private slots:
void cleanupWhenRenderThreadStops();
void infiniteLoopsWithoutFrom();
void targetsDeletedNotRemoved();
+ void alwaysRunToEndSetFalseRestartBug();
};
#define QTIMED_COMPARE(lhs, rhs) do { \
for (int ii = 0; ii < 5; ++ii) { \
@@ -2081,6 +2082,41 @@ void tst_qquickanimations::targetsDeletedNotRemoved()
}
}
+//QTBUG-125224
+void tst_qquickanimations::alwaysRunToEndSetFalseRestartBug()
+{
+ QQuickRectangle rect;
+ QQuickSequentialAnimation sequential;
+ QQuickPropertyAnimation beginAnim;
+ QQuickPropertyAnimation endAnim;
+
+ beginAnim.setTargetObject(&rect);
+ beginAnim.setProperty("x");
+ beginAnim.setTo(200);
+ beginAnim.setDuration(1000);
+
+ endAnim.setTargetObject(&rect);
+ endAnim.setProperty("x");
+ endAnim.setFrom(200);
+ endAnim.setDuration(1000);
+
+ beginAnim.setGroup(&sequential);
+ endAnim.setGroup(&sequential);
+
+ sequential.setLoops(-1);
+ sequential.setAlwaysRunToEnd(true);
+
+ QCOMPARE(sequential.loops(), -1);
+ QVERIFY(sequential.alwaysRunToEnd());
+ sequential.start();
+ sequential.stop();
+ sequential.setAlwaysRunToEnd(false);
+ sequential.start();
+ QCOMPARE(sequential.isRunning(), true);
+ sequential.stop();
+ QCOMPARE(sequential.isRunning(), false);
+}
+
QTEST_MAIN(tst_qquickanimations)
#include "tst_qquickanimations.moc"
diff --git a/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml b/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml
index 5e8f6f9bcf..37166af119 100644
--- a/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml
+++ b/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml
@@ -1308,6 +1308,53 @@ Item {
compare(rootRect.item1.width, 100)
}
+ //---------------------------
+ // Layout with negative size
+ Component {
+ id: negativeSize_Component
+ Item {
+ id: rootItem
+ width: 0
+ height: 0
+ // default width x height: (0 x 0)
+ RowLayout {
+ spacing: 0
+ anchors.fill: parent
+ anchors.leftMargin: 1 // since parent size == (0 x 0), it causes layout size
+ anchors.bottomMargin: 1 // to become (-1, -1)
+ Item {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ }
+ }
+ }
+ }
+
+ function test_negativeSize() {
+ let rootItem = createTemporaryObject(negativeSize_Component, container)
+ let rowLayout = rootItem.children[0]
+ let item = rowLayout.children[0]
+
+ // 1 doesn't work in 6.2 because that will make the layout of size 0x0
+ // Setting the geometry of a layout to 0x0 doesn't work because
+ // QQuickLayout::geometryChange() early returns if !newGeometry.isValid()
+ // This check has been later removed.
+ const arr = [7, /*1,*/ 7, 0]
+ arr.forEach((n) => {
+ rootItem.width = n
+ rootItem.height = n
+
+ // n === 0 is special: It will cause the layout to have a
+ // negative size. In this case it will simply not rearrange its
+ // child (and leave it at its previous size, 6)
+ const expectedItemExtent = n === 0 ? 6 : n - 1
+
+ compare(item.width, expectedItemExtent)
+ compare(item.height, expectedItemExtent)
+ });
+ }
+
+
//---------------------------
Component {
id: rowlayoutWithTextItems_Component
diff --git a/tests/auto/quick/qquicklistview/data/snapToItemWithSectionAtStart.qml b/tests/auto/quick/qquicklistview/data/snapToItemWithSectionAtStart.qml
new file mode 100644
index 0000000000..0d4c233345
--- /dev/null
+++ b/tests/auto/quick/qquicklistview/data/snapToItemWithSectionAtStart.qml
@@ -0,0 +1,52 @@
+import QtQuick
+
+ListView {
+ id: listView
+ width: 240
+ height: 300
+
+ model: ListModel {
+ ListElement { section: "section 1" }
+ ListElement { section: "section 1" }
+ ListElement { section: "section 1" }
+ ListElement { section: "section 2" }
+ ListElement { section: "section 2" }
+ ListElement { section: "section 2" }
+ ListElement { section: "section 3" }
+ ListElement { section: "section 3" }
+ ListElement { section: "section 3" }
+ ListElement { section: "section 4" }
+ ListElement { section: "section 4" }
+ ListElement { section: "section 4" }
+ ListElement { section: "section 5" }
+ ListElement { section: "section 5" }
+ ListElement { section: "section 5" }
+ }
+
+ section.property: "section"
+ section.labelPositioning: ViewSection.InlineLabels | ViewSection.CurrentLabelAtStart
+ section.delegate: Rectangle {
+ width: listView.width
+ height: 30
+ Text {
+ anchors.fill: parent
+ text: section
+ }
+ color: "lightblue"
+ }
+
+ snapMode: ListView.SnapToItem
+
+ delegate: Rectangle {
+ width: listView.width
+ height: 30
+ Text {
+ anchors.fill: parent
+ text: index
+ }
+ border {
+ width: 1
+ color: "black"
+ }
+ }
+}
diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
index 24196e2ba1..8f3aa551e1 100644
--- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
+++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
@@ -193,6 +193,7 @@ private slots:
void headerSnapToItem_data();
void headerSnapToItem();
void snapToItemWithSpacing_QTBUG_59852();
+ void snapToItemWithSectionAtStart();
void snapOneItemResize_QTBUG_43555();
void snapOneItem_data();
void snapOneItem();
@@ -5407,6 +5408,27 @@ void tst_QQuickListView::snapToItemWithSpacing_QTBUG_59852()
releaseView(window);
}
+void tst_QQuickListView::snapToItemWithSectionAtStart() // QTBUG-30768
+{
+ QQuickView window;
+ QVERIFY(QQuickTest::showView(window, testFileUrl("snapToItemWithSectionAtStart.qml")));
+ QQuickListView *listView = qobject_cast<QQuickListView *>(window.rootObject());
+ QTRY_VERIFY(listView);
+
+ // Both sections and elements are 30px high. The list height is 300px, so
+ // it fits exactly 10 elements. We can do some random flicks, but the
+ // content position always MUST be divisible by 30.
+ for (int i = 0; i < 10; ++i) {
+ const bool even = (i % 2 == 0);
+ const QPoint start = even ? QPoint(20, 100 + i * 5) : QPoint(20, 20 + i * 3);
+ const QPoint end = even ? start - QPoint(0, 50 + i * 10) : start + QPoint(0, 50 + i * 5);
+
+ flick(&window, start, end, 180);
+ QTRY_COMPARE(listView->isMoving(), false); // wait until it stops
+ QCOMPARE(int(listView->contentY()) % 30, 0);
+ }
+}
+
static void drag_helper(QWindow *window, QPoint *startPos, const QPoint &delta)
{
QPoint pos = *startPos;
diff --git a/tests/auto/quick/qquickmultipointtoucharea/BLACKLIST b/tests/auto/quick/qquickmultipointtoucharea/BLACKLIST
index 2488eff270..46db6477f5 100644
--- a/tests/auto/quick/qquickmultipointtoucharea/BLACKLIST
+++ b/tests/auto/quick/qquickmultipointtoucharea/BLACKLIST
@@ -4,3 +4,5 @@ ubuntu-22.04
[nested]
ubuntu-20.04
ubuntu-22.04
+[inFlickable]
+* # QTBUG-127628
diff --git a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
index 5991621376..5330d8d01f 100644
--- a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
+++ b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
@@ -185,6 +185,8 @@ private slots:
void checkSyncView_pageFlicking();
void checkSyncView_emptyModel();
void checkSyncView_topLeftChanged();
+ void checkSyncView_dontRelayoutWhileFlicking();
+ void checkSyncView_detectTopLeftPositionChanged();
void delegateWithRequiredProperties();
void checkThatFetchMoreIsCalledWhenScrolledToTheEndOfTable();
void replaceModel();
@@ -3108,6 +3110,85 @@ void tst_QQuickTableView::checkSyncView_topLeftChanged()
QCOMPARE(tableViewV->topRow(), tableView->topRow());
}
+void tst_QQuickTableView::checkSyncView_dontRelayoutWhileFlicking()
+{
+ // Check that we don't do a full relayout in a sync child when
+ // a new row or column is flicked into the view. Normal load
+ // and unload of edges should suffice, equal to how the main
+ // TableView (syncView) does it.
+ LOAD_TABLEVIEW("syncviewsimple.qml");
+ GET_QML_TABLEVIEW(tableViewHV);
+
+ auto model = TestModelAsVariant(100, 100);
+ tableView->setModel(model);
+ tableViewHV->setModel(model);
+
+ tableView->setColumnWidthProvider(QJSValue());
+ tableView->setRowHeightProvider(QJSValue());
+ view->rootObject()->setProperty("delegateWidth", 50);
+ view->rootObject()->setProperty("delegateHeight", 50);
+
+ WAIT_UNTIL_POLISHED;
+
+ // To check that we don't do a relayout when flicking horizontally, we use a "trick"
+ // where we check the rebuildOptions when we receive the rightColumnChanged
+ // signal. If this signal is emitted as a part of a relayout, rebuildOptions
+ // would still be different from RebuildOption::None at that point.
+ bool columnFlickedIn = false;
+ connect(tableViewHV, &QQuickTableView::rightColumnChanged, [&] {
+ columnFlickedIn = true;
+ QCOMPARE(tableViewHVPrivate->rebuildOptions, QQuickTableViewPrivate::RebuildOption::None);
+ });
+
+ // We do the same for vertical flicking
+ bool rowFlickedIn = false;
+ connect(tableViewHV, &QQuickTableView::bottomRowChanged, [&] {
+ rowFlickedIn = true;
+ QCOMPARE(tableViewHVPrivate->rebuildOptions, QQuickTableViewPrivate::RebuildOption::None);
+ });
+
+ // Move the main tableview so that a new column is flicked in
+ tableView->setContentX(60);
+ QTRY_VERIFY(columnFlickedIn);
+
+ // Move the main tableview so that a new row is flicked in
+ tableView->setContentY(60);
+ QTRY_VERIFY(rowFlickedIn);
+}
+
+void tst_QQuickTableView::checkSyncView_detectTopLeftPositionChanged()
+{
+ // It can happen that, during a resize of columns or rows from using a float-based
+ // slider, that the position of the top-left delegate item is shifted a bit left or
+ // right because of rounding issues. And this again can over time, as you flick, make
+ // the loadedTableOuterRect get slightly out of sync in the sync child compared to the
+ // sync view. TableView will detect if this happens (in syncSyncView), and correct for
+ // it. And this test will test that it works.
+ LOAD_TABLEVIEW("syncviewsimple.qml");
+ GET_QML_TABLEVIEW(tableViewHV);
+
+ auto model = TestModelAsVariant(100, 100);
+ tableView->setModel(model);
+ tableViewHV->setModel(model);
+
+ WAIT_UNTIL_POLISHED;
+
+ // Writing an auto test to trigger this rounding issue is very hard. So to keep it
+ // simple, we cheat by just moving the loadedTableOuterRect directly, and
+ // check that the syncView child detects it, and corrects it, upon doing a
+ // forceLayout()
+ tableViewPrivate->loadedTableOuterRect.moveLeft(20);
+ tableViewPrivate->loadedTableOuterRect.moveTop(30);
+ tableViewPrivate->relayoutTableItems();
+ tableViewHV->forceLayout();
+
+ QCOMPARE(tableViewPrivate->loadedTableOuterRect.left(), 20);
+ QCOMPARE(tableViewHVPrivate->loadedTableOuterRect.left(), 20);
+
+ QCOMPARE(tableViewPrivate->loadedTableOuterRect.top(), 30);
+ QCOMPARE(tableViewHVPrivate->loadedTableOuterRect.top(), 30);
+}
+
void tst_QQuickTableView::checkThatFetchMoreIsCalledWhenScrolledToTheEndOfTable()
{
LOAD_TABLEVIEW("plaintableview.qml");
diff --git a/tests/auto/quick/qquicktext/data/elideZeroWidthWithMargins.qml b/tests/auto/quick/qquicktext/data/elideZeroWidthWithMargins.qml
new file mode 100644
index 0000000000..bb269e6ad5
--- /dev/null
+++ b/tests/auto/quick/qquicktext/data/elideZeroWidthWithMargins.qml
@@ -0,0 +1,27 @@
+import QtQuick
+
+Item {
+ id: root
+ property bool ok: false
+ width: 640
+ height: 480
+
+ Text {
+ id: text
+ text: "This is a quite long text. Click me and i should remain visible!!! Sadly this doesn't happen"
+ elide: Text.ElideRight
+ anchors {
+ fill: parent
+ margins: 1
+ }
+ }
+
+ Component.onCompleted: {
+ text.width = 300;
+ text.height = 0;
+ text.width = 0;
+ text.height = 30;
+ text.width = 300;
+ root.ok = text.paintedWidth > 0 && text.paintedHeight > 0
+ }
+}
diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
index 476297918d..ea90fc74d6 100644
--- a/tests/auto/quick/qquicktext/tst_qquicktext.cpp
+++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
@@ -69,6 +69,7 @@ private slots:
void wrap();
void elide();
void elideParentChanged();
+ void elideRelayoutAfterZeroWidth_data();
void elideRelayoutAfterZeroWidth();
void multilineElide_data();
void multilineElide();
@@ -611,10 +612,19 @@ void tst_qquicktext::elideParentChanged()
QCOMPARE(actualItemImageGrab, expectedItemImageGrab);
}
+void tst_qquicktext::elideRelayoutAfterZeroWidth_data()
+{
+ QTest::addColumn<QByteArray>("fileName");
+
+ QTest::newRow("no_margins") << QByteArray("elideZeroWidth.qml");
+ QTest::newRow("with_margins") << QByteArray("elideZeroWidthWithMargins.qml");
+}
+
void tst_qquicktext::elideRelayoutAfterZeroWidth()
{
+ QFETCH(const QByteArray, fileName);
QQmlEngine engine;
- QQmlComponent component(&engine, testFileUrl("elideZeroWidth.qml"));
+ QQmlComponent component(&engine, testFileUrl(fileName.constData()));
QScopedPointer<QObject> root(component.create());
QVERIFY2(root, qPrintable(component.errorString()));
QVERIFY(root->property("ok").toBool());