aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/quick
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/quick')
-rw-r--r--tests/auto/quick/examples/tst_examples.cpp4
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/data/GrooveDragSlider.qml123
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/data/KnobDragSlider.qml (renamed from tests/auto/quick/pointerhandlers/flickableinterop/data/Slider.qml)16
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/data/flickableWithHandlers.qml19
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp133
-rw-r--r--tests/auto/quick/pointerhandlers/multipointtoucharea_interop/tst_multipointtoucharea_interop.cpp4
-rw-r--r--tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp13
-rw-r--r--tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp23
-rw-r--r--tests/auto/quick/qquickanimatedsprite/data/infiniteLoops.qml38
-rw-r--r--tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp33
-rw-r--r--tests/auto/quick/qquickanimations/data/finished.qml95
-rw-r--r--tests/auto/quick/qquickanimations/tst_qquickanimations.cpp74
-rw-r--r--tests/auto/quick/qquickcanvasitem/data/tst_line.qml91
-rw-r--r--tests/auto/quick/qquickdesignersupport/data/TestComponent.qml4
-rw-r--r--tests/auto/quick/qquickdesignersupport/data/test.qml4
-rw-r--r--tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp8
-rw-r--r--tests/auto/quick/qquickflickable/BLACKLIST1
-rw-r--r--tests/auto/quick/qquickflickable/tst_qquickflickable.cpp66
-rw-r--r--tests/auto/quick/qquickframebufferobject/tst_qquickframebufferobject.cpp4
-rw-r--r--tests/auto/quick/qquickgridview/tst_qquickgridview.cpp31
-rw-r--r--tests/auto/quick/qquickimageprovider/tst_qquickimageprovider.cpp65
-rw-r--r--tests/auto/quick/qquicklistview/tst_qquicklistview.cpp70
-rw-r--r--tests/auto/quick/qquickloader/tst_qquickloader.cpp4
-rw-r--r--tests/auto/quick/qquickmultipointtoucharea/BLACKLIST2
-rw-r--r--tests/auto/quick/qquickpathview/tst_qquickpathview.cpp8
-rw-r--r--tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp20
-rw-r--r--tests/auto/quick/qquickrectangle/data/gradient-preset.qml16
-rw-r--r--tests/auto/quick/qquickrectangle/tst_qquickrectangle.cpp28
-rw-r--r--tests/auto/quick/qquickrepeater/data/ownership.qml4
-rw-r--r--tests/auto/quick/qquickrepeater/data/package.qml35
-rw-r--r--tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp88
-rw-r--r--tests/auto/quick/qquickshape/qquickshape.pro24
-rw-r--r--tests/auto/quick/qquickshape/tst_qquickshape.cpp2
-rw-r--r--tests/auto/quick/qquicktableview/data/countingtableview.qml85
-rw-r--r--tests/auto/quick/qquicktableview/data/plaintableview.qml80
-rw-r--r--tests/auto/quick/qquicktableview/data/tableviewimplicitsize.qml66
-rw-r--r--tests/auto/quick/qquicktableview/qquicktableview.pro14
-rw-r--r--tests/auto/quick/qquicktableview/testmodel.h89
-rw-r--r--tests/auto/quick/qquicktableview/tst_qquicktableview.cpp791
-rw-r--r--tests/auto/quick/qquicktext/data/implicitSizeChangeRewrap.qml27
-rw-r--r--tests/auto/quick/qquicktext/tst_qquicktext.cpp23
-rw-r--r--tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp5
-rw-r--r--tests/auto/quick/qquickwindow/tst_qquickwindow.cpp45
-rw-r--r--tests/auto/quick/qquickxmllistmodel/tst_qquickxmllistmodel.cpp13
-rw-r--r--tests/auto/quick/quick.pro3
-rw-r--r--tests/auto/quick/shared/viewtestutil.cpp8
-rw-r--r--tests/auto/quick/shared/viewtestutil.h3
-rw-r--r--tests/auto/quick/touchmouse/tst_touchmouse.cpp50
48 files changed, 2240 insertions, 212 deletions
diff --git a/tests/auto/quick/examples/tst_examples.cpp b/tests/auto/quick/examples/tst_examples.cpp
index eee8dfcf26..ea8830fefa 100644
--- a/tests/auto/quick/examples/tst_examples.cpp
+++ b/tests/auto/quick/examples/tst_examples.cpp
@@ -74,7 +74,6 @@ tst_examples::tst_examples()
{
// Add files to exclude here
excludedFiles << "snippets/qml/listmodel/listmodel.qml"; //Just a ListModel, no root QQuickItem
- excludedFiles << "examples/quick/demos/photosurface/photosurface.qml"; // root item is Window rather than Item
// Add directories you want excluded here
excludedDirs << "shared"; //Not an example
@@ -91,9 +90,6 @@ tst_examples::tst_examples()
excludedFiles << "examples/quick/shapes/content/interactive.qml"; // relies on resources
#ifdef QT_NO_XMLPATTERNS
- excludedDirs << "demos/twitter";
- excludedDirs << "demos/flickr";
- excludedDirs << "demos/photoviewer";
excludedFiles << "snippets/qml/xmlrole.qml";
excludedFiles << "particles/itemparticle/particleview.qml";
excludedFiles << "views/visualdatamodel/slideshow.qml";
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/GrooveDragSlider.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/GrooveDragSlider.qml
new file mode 100644
index 0000000000..485c6ce914
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/GrooveDragSlider.qml
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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.8
+import Qt.labs.handlers 1.0
+
+Item {
+ id: root
+ property int value: 50
+ property int maximumValue: 99
+ property alias label: label.text
+ property alias tapEnabled: tap.enabled
+ property alias pressed: tap.pressed
+ signal tapped
+
+ DragHandler {
+ id: dragHandler
+ objectName: root.objectName + " DragHandler"
+ target: knob
+ xAxis.enabled: false
+ yAxis.minimum: slot.y
+ yAxis.maximum: slot.height + slot.y - knob.height
+ }
+
+ Rectangle {
+ id: slot
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ anchors.margins: 10
+ anchors.topMargin: 30
+ anchors.bottomMargin: 30
+ anchors.horizontalCenter: parent.horizontalCenter
+ width: 10
+ color: "black"
+ radius: width / 2
+ smooth: true
+ }
+
+ Rectangle {
+ id: glow
+ anchors.fill: knob
+ anchors.margins: -5
+ anchors.leftMargin: -2
+ anchors.horizontalCenterOffset: 1
+ radius: 5
+ color: "#4400FFFF"
+ opacity: tap.pressed || tapFlash.running ? 1 : 0
+ FlashAnimation on visible {
+ id: tapFlash
+ }
+ }
+ Rectangle {
+ id: knob
+ objectName: "Slider Knob"
+ width: parent.width - 2
+ height: 20
+ radius: 5
+ color: "darkgray"
+ border.color: "black"
+ property bool programmatic: false
+ property real multiplier: root.maximumValue / (dragHandler.yAxis.maximum - dragHandler.yAxis.minimum)
+ onYChanged: if (!programmatic) root.value = root.maximumValue - (knob.y - dragHandler.yAxis.minimum) * multiplier
+ transformOrigin: Item.Center
+ function setValue(value) { knob.y = dragHandler.yAxis.maximum - value / knob.multiplier }
+ TapHandler {
+ id: tap
+ objectName: root.objectName + " TapHandler"
+ gesturePolicy: TapHandler.DragThreshold
+ onTapped: {
+ tapFlash.start()
+ root.tapped
+ }
+ }
+ }
+
+ Text {
+ color: "red"
+ anchors.top: slot.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ text: root.value
+ }
+
+ Text {
+ id: label
+ font.pointSize: 9
+ color: "red"
+ anchors.bottom: slot.top
+ anchors.bottomMargin: 5
+ anchors.horizontalCenter: parent.horizontalCenter
+ verticalAlignment: Text.AlignBottom
+ }
+
+ Component.onCompleted: {
+ knob.programmatic = true
+ knob.setValue(root.value)
+ knob.programmatic = false
+ }
+}
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/Slider.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/KnobDragSlider.qml
index f6acd53615..7f6535651c 100644
--- a/tests/auto/quick/pointerhandlers/flickableinterop/data/Slider.qml
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/KnobDragSlider.qml
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
@@ -80,14 +80,14 @@ Item {
function setValue(value) { knob.y = dragHandler.yAxis.maximum - value / knob.multiplier }
DragHandler {
id: dragHandler
- objectName: label.text + " DragHandler"
+ objectName: root.objectName + " DragHandler"
xAxis.enabled: false
yAxis.minimum: slot.y
yAxis.maximum: slot.height + slot.y - knob.height
}
TapHandler {
id: tap
- objectName: label.text + " TapHandler"
+ objectName: root.objectName + " TapHandler"
gesturePolicy: TapHandler.DragThreshold
onTapped: {
tapFlash.start()
@@ -97,20 +97,20 @@ Item {
}
Text {
- font.pointSize: 16
color: "red"
- anchors.bottom: parent.bottom
+ anchors.top: slot.bottom
anchors.horizontalCenter: parent.horizontalCenter
text: root.value
}
Text {
id: label
- font.pointSize: 12
+ font.pointSize: 9
color: "red"
- anchors.top: parent.top
- anchors.topMargin: 5
+ anchors.bottom: slot.top
+ anchors.bottomMargin: 5
anchors.horizontalCenter: parent.horizontalCenter
+ verticalAlignment: Text.AlignBottom
}
Component.onCompleted: {
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/flickableWithHandlers.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/flickableWithHandlers.qml
index 7d7f53dd15..8adec58621 100644
--- a/tests/auto/quick/pointerhandlers/flickableinterop/data/flickableWithHandlers.qml
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/flickableWithHandlers.qml
@@ -46,10 +46,15 @@ Rectangle {
Row {
spacing: 6
- Slider {
- label: "DragHandler"
- objectName: "Slider"
- value: 49; width: 100; height: 400
+ KnobDragSlider {
+ label: "Slider with\nDH on knob"
+ objectName: "knobSlider"
+ value: 49; width: 120; height: 400
+ }
+ GrooveDragSlider {
+ label: "Slider with\nDH on root"
+ objectName: "grooveSlider"
+ value: 49; width: 120; height: 400
}
Column {
spacing: 6
@@ -80,6 +85,7 @@ Rectangle {
objectName: "drag"
DragHandler {
id: drag1
+ objectName: "drag1"
}
Text {
anchors.centerIn: parent
@@ -96,6 +102,7 @@ Rectangle {
border.width: 3
TapHandler {
id: tap1
+ objectName: "tap1"
gesturePolicy: TapHandler.DragThreshold
}
Text {
@@ -113,9 +120,11 @@ Rectangle {
objectName: "dragAndTap"
DragHandler {
id: drag2
+ objectName: "drag2"
}
TapHandler {
id: tap2
+ objectName: "tap2"
gesturePolicy: TapHandler.DragThreshold
}
Text {
@@ -133,10 +142,12 @@ Rectangle {
objectName: "tapAndDrag"
TapHandler {
id: tap3
+ objectName: "tap3"
gesturePolicy: TapHandler.DragThreshold
}
DragHandler {
id: drag3
+ objectName: "drag3"
}
Text {
anchors.centerIn: parent
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp b/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp
index f3513881cd..6aa2eaa3cb 100644
--- a/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp
@@ -69,6 +69,7 @@ private slots:
void mouseDragFlickableBehindButton();
void touchDragSlider();
void touchDragFlickableBehindSlider();
+ void mouseDragSlider_data();
void mouseDragSlider();
void mouseDragFlickableBehindSlider();
void touchDragFlickableBehindItemWithHandlers_data();
@@ -293,7 +294,7 @@ void tst_FlickableInterop::touchDragSlider()
createView(windowPtr, "flickableWithHandlers.qml");
QQuickView * window = windowPtr.data();
- QQuickItem *slider = window->rootObject()->findChild<QQuickItem*>("Slider");
+ QQuickItem *slider = window->rootObject()->findChild<QQuickItem*>("knobSlider");
QVERIFY(slider);
QQuickDragHandler *drag = slider->findChild<QQuickDragHandler*>();
QVERIFY(drag);
@@ -339,6 +340,26 @@ void tst_FlickableInterop::touchDragSlider()
QCOMPARE(translationChangedSpy.count(), 1);
}
+void tst_FlickableInterop::mouseDragSlider_data()
+{
+ QTest::addColumn<QString>("nameOfSliderToDrag");
+ QTest::addColumn<QPoint>("pressPositionRelativeToKnob");
+ QTest::addColumn<QPoint>("dragDirection"); // a unit vector
+ QTest::addColumn<bool>("expectedTapHandlerPressed");
+ QTest::addColumn<bool>("expectedDragHandlerActive");
+ QTest::addColumn<bool>("expectedFlickableMoving");
+
+ QTest::newRow("drag down on knob of knobSlider") << "knobSlider" << QPoint(0, 0) << QPoint(0, 1) << true << true << false;
+ QTest::newRow("drag sideways on knob of knobSlider") << "knobSlider" << QPoint(0, 0) << QPoint(1, 0) << true << false << true;
+ QTest::newRow("drag down on groove of knobSlider") << "knobSlider" << QPoint(0, 20) << QPoint(0, 1) << false << false << true;
+ QTest::newRow("drag sideways on groove of knobSlider") << "knobSlider" << QPoint(0, 20) << QPoint(1, 0) << false << false << true;
+
+ QTest::newRow("drag down on knob of grooveSlider") << "grooveSlider" << QPoint(0, 0) << QPoint(0, 1) << true << true << false;
+ QTest::newRow("drag sideways on knob of grooveSlider") << "grooveSlider" << QPoint(0, 0) << QPoint(1, 0) << true << false << true;
+ QTest::newRow("drag down on groove of grooveSlider") << "grooveSlider" << QPoint(0, 20) << QPoint(0, 1) << false << true << false;
+ QTest::newRow("drag sideways on groove of grooveSlider") << "grooveSlider" << QPoint(0, 20) << QPoint(1, 0) << false << false << true;
+}
+
void tst_FlickableInterop::mouseDragSlider()
{
const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
@@ -346,7 +367,14 @@ void tst_FlickableInterop::mouseDragSlider()
createView(windowPtr, "flickableWithHandlers.qml");
QQuickView * window = windowPtr.data();
- QQuickItem *slider = window->rootObject()->findChild<QQuickItem*>("Slider");
+ QFETCH(QString, nameOfSliderToDrag);
+ QFETCH(QPoint, pressPositionRelativeToKnob);
+ QFETCH(QPoint, dragDirection); // a unit vector
+ QFETCH(bool, expectedTapHandlerPressed);
+ QFETCH(bool, expectedDragHandlerActive);
+ QFETCH(bool, expectedFlickableMoving);
+
+ QQuickItem *slider = window->rootObject()->findChild<QQuickItem*>(nameOfSliderToDrag);
QVERIFY(slider);
QQuickDragHandler *drag = slider->findChild<QQuickDragHandler*>();
QVERIFY(drag);
@@ -357,33 +385,40 @@ void tst_FlickableInterop::mouseDragSlider()
QSignalSpy tappedSpy(knob->parent(), SIGNAL(tapped()));
QSignalSpy translationChangedSpy(drag, SIGNAL(translationChanged()));
- // Drag the slider in the allowed (vertical) direction
+ // Drag the slider
tappedSpy.clear();
- QPoint p1 = knob->mapToScene(knob->clipRect().center()).toPoint();
+ QPoint p1 = knob->mapToScene(knob->clipRect().center()).toPoint() + pressPositionRelativeToKnob;
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1);
- QTRY_VERIFY(slider->property("pressed").toBool());
- p1 += QPoint(0, dragThreshold);
+ QTRY_COMPARE(slider->property("pressed").toBool(), expectedTapHandlerPressed);
+ p1 += QPoint(dragThreshold * dragDirection.x(), dragThreshold * dragDirection.y());
QTest::mouseMove(window, p1);
- QVERIFY(slider->property("pressed").toBool());
+ QCOMPARE(drag->active(), false);
+ QCOMPARE(slider->property("pressed").toBool(), expectedTapHandlerPressed);
QCOMPARE(slider->property("value").toInt(), 49);
- p1 += QPoint(0, 1);
+ p1 += dragDirection; // one more pixel
QTest::mouseMove(window, p1);
- p1 += QPoint(0, 10);
+ QCOMPARE(drag->active(), expectedDragHandlerActive);
+ // drag farther, to make sure the knob gets adjusted significantly
+ p1 += QPoint(10 * dragDirection.x(), 10 * dragDirection.y());
QTest::mouseMove(window, p1);
- QVERIFY(slider->property("value").toInt() < 49);
- QVERIFY(!flickable->isMoving());
- QVERIFY(!slider->property("pressed").toBool());
+ if (expectedDragHandlerActive && dragDirection.y() > 0)
+ QVERIFY(slider->property("value").toInt() < 49);
+ // by now, Flickable will have stolen the grab, if it decided that it wanted to during filtering of the last event
+ QCOMPARE(flickable->isMoving(), expectedFlickableMoving);
+ QCOMPARE(slider->property("pressed").toBool(), false);
- // Now that the DragHandler is active, the Flickable will not steal the grab
+ // If the DragHandler is active, the Flickable will not steal the grab
// even if we move a large distance horizontally
- p1 += QPoint(dragThreshold * 2, 0);
- QTest::mouseMove(window, p1);
- QVERIFY(!flickable->isMoving());
+ if (expectedDragHandlerActive) {
+ p1 += QPoint(dragThreshold * 2, 0);
+ QTest::mouseMove(window, p1);
+ QCOMPARE(flickable->isMoving(), false);
+ }
// Release, and do not expect the tapped signal
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1);
QCOMPARE(tappedSpy.count(), 0);
- QCOMPARE(translationChangedSpy.count(), 1);
+ QCOMPARE(translationChangedSpy.count(), expectedDragHandlerActive ? 1 : 0);
}
void tst_FlickableInterop::touchDragFlickableBehindSlider()
@@ -393,7 +428,7 @@ void tst_FlickableInterop::touchDragFlickableBehindSlider()
createView(windowPtr, "flickableWithHandlers.qml");
QQuickView * window = windowPtr.data();
- QQuickItem *slider = window->rootObject()->findChild<QQuickItem*>("Slider");
+ QQuickItem *slider = window->rootObject()->findChild<QQuickItem*>("knobSlider");
QVERIFY(slider);
QQuickDragHandler *drag = slider->findChild<QQuickDragHandler*>();
QVERIFY(drag);
@@ -439,7 +474,7 @@ void tst_FlickableInterop::mouseDragFlickableBehindSlider()
createView(windowPtr, "flickableWithHandlers.qml");
QQuickView * window = windowPtr.data();
- QQuickItem *slider = window->rootObject()->findChild<QQuickItem*>("Slider");
+ QQuickItem *slider = window->rootObject()->findChild<QQuickItem*>("knobSlider");
QVERIFY(slider);
QQuickDragHandler *drag = slider->findChild<QQuickDragHandler*>();
QVERIFY(drag);
@@ -568,7 +603,7 @@ void tst_FlickableInterop::touchDragSliderAndFlickable()
createView(windowPtr, "flickableWithHandlers.qml");
QQuickView * window = windowPtr.data();
- QQuickItem *slider = window->rootObject()->findChild<QQuickItem*>("Slider");
+ QQuickItem *slider = window->rootObject()->findChild<QQuickItem*>("knobSlider");
QVERIFY(slider);
QQuickDragHandler *drag = slider->findChild<QQuickDragHandler*>();
QVERIFY(drag);
@@ -576,6 +611,7 @@ void tst_FlickableInterop::touchDragSliderAndFlickable()
QVERIFY(knob);
QQuickFlickable *flickable = window->rootObject()->findChild<QQuickFlickable*>();
QVERIFY(flickable);
+ QTest::QTouchEventSequence touchSeq = QTest::touchEvent(window, touchDevice, false);
// The knob is initially centered over the slider's "groove"
qreal initialXOffset = qAbs(knob->mapToScene(knob->clipRect().center()).x() - slider->mapToScene
@@ -584,57 +620,36 @@ void tst_FlickableInterop::touchDragSliderAndFlickable()
// Drag the slider in the allowed (vertical) direction with one finger
QPoint p1 = knob->mapToScene(knob->clipRect().center()).toPoint();
- QTest::touchEvent(window, touchDevice).press(1, p1, window);
+ touchSeq.press(1, p1, window).commit();
QQuickTouchUtils::flush(window);
p1 += QPoint(0, dragThreshold);
- QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ touchSeq.move(1, p1, window).commit();
QQuickTouchUtils::flush(window);
p1 += QPoint(0, dragThreshold);
- QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ touchSeq.move(1, p1, window).commit();
QQuickTouchUtils::flush(window);
p1 += QPoint(0, dragThreshold);
- QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ touchSeq.move(1, p1, window).commit();
QQuickTouchUtils::flush(window);
QTRY_VERIFY(slider->property("value").toInt() < 49);
QVERIFY(!flickable->isMoving());
// Drag the Flickable with a second finger
QPoint p2(300,300);
- QTest::touchEvent(window, touchDevice).stationary(1).press(2, p2, window);
- QQuickTouchUtils::flush(window);
- p1 += QPoint(-10, -10);
- p2 += QPoint(dragThreshold, 0);
- QTest::touchEvent(window, touchDevice).move(1, p1, window).stationary(2);
- QQuickTouchUtils::flush(window);
- p1 += QPoint(-10, -10);
- p2 += QPoint(dragThreshold, 0);
- QTest::touchEvent(window, touchDevice).stationary(1).move(2, p2, window);
+ touchSeq.stationary(1).press(2, p2, window).commit();
QQuickTouchUtils::flush(window);
- p1 += QPoint(-10, -10);
- p2 += QPoint(dragThreshold, 0);
- QTest::touchEvent(window, touchDevice).move(1, p1, window).stationary(2);
- QQuickTouchUtils::flush(window);
- p1 += QPoint(-10, -10);
- p2 += QPoint(dragThreshold, 0);
- QTest::touchEvent(window, touchDevice).stationary(1).move(2, p2, window);
- QQuickTouchUtils::flush(window);
- p1 += QPoint(-10, -10);
- p2 += QPoint(dragThreshold, 0);
- QTest::touchEvent(window, touchDevice).move(1, p1, window).stationary(2);
- QQuickTouchUtils::flush(window);
- p1 += QPoint(-10, -10);
- p2 += QPoint(dragThreshold, 0);
- QTest::touchEvent(window, touchDevice).stationary(1).move(2, p2, window);
- QQuickTouchUtils::flush(window);
- p1 += QPoint(-10, -10);
- p2 += QPoint(dragThreshold, 0);
- QTest::touchEvent(window, touchDevice).move(1, p1, window).stationary(2);
- QQuickTouchUtils::flush(window);
- p1 += QPoint(-10, -10);
- p2 += QPoint(dragThreshold, 0);
- QTest::touchEvent(window, touchDevice).stationary(1).move(2, p2, window);
- QQuickTouchUtils::flush(window);
- QTRY_VERIFY(flickable->isMoving());
+ for (int i = 0; i < 4; ++i) {
+ p1 += QPoint(-10, -10);
+ p2 += QPoint(dragThreshold, 0);
+ touchSeq.move(1, p1, window).stationary(2).commit();
+ QQuickTouchUtils::flush(window);
+ p1 += QPoint(-10, -10);
+ p2 += QPoint(dragThreshold, 0);
+ touchSeq.stationary(1).move(2, p2, window).commit();
+ QQuickTouchUtils::flush(window);
+ qCDebug(lcPointerTests) << "step" << i << ": fingers @" << p1 << p2 << "is Flickable moving yet?" << flickable->isMoving();
+ }
+ QVERIFY(flickable->isMoving());
qreal knobSliderXOffset = qAbs(knob->mapToScene(knob->clipRect().center()).toPoint().x() -
slider->mapToScene(slider->clipRect().center()).toPoint().x()) - initialXOffset;
if (knobSliderXOffset > 1)
@@ -643,7 +658,7 @@ void tst_FlickableInterop::touchDragSliderAndFlickable()
QVERIFY(qAbs(knobSliderXOffset) <= 1);
// Release
- QTest::touchEvent(window, touchDevice).release(1, p1, window).release(2, p2, window);
+ touchSeq.release(1, p1, window).release(2, p2, window).commit();
}
QTEST_MAIN(tst_FlickableInterop)
diff --git a/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/tst_multipointtoucharea_interop.cpp b/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/tst_multipointtoucharea_interop.cpp
index 4b096f9c3a..0561a9e4f1 100644
--- a/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/tst_multipointtoucharea_interop.cpp
+++ b/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/tst_multipointtoucharea_interop.cpp
@@ -210,9 +210,9 @@ void tst_MptaInterop::touchesThenPinch()
if (!pinchStoleGrab && pointerEvent->point(0)->exclusiveGrabber() == pinch)
pinchStoleGrab = i;
}
- qCDebug(lcPointerTests) << "pinch started after" << pinchStoleGrab << "moves; ended with scale" << pinch->scale() << "rot" << pinch->rotation();
+ qCDebug(lcPointerTests) << "pinch started after" << pinchStoleGrab << "moves; ended with scale" << pinch->activeScale() << "rot" << pinch->rotation();
QTRY_VERIFY(pinch->rotation() > 4);
- QVERIFY(pinch->scale() > 1);
+ QVERIFY(pinch->activeScale() > 1);
// Press one more point (pinkie finger)
QPoint p4 = mpta->mapToScene(QPointF(300, 200)).toPoint();
diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp b/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp
index 53bb10b7b8..0271924c9b 100644
--- a/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp
+++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp
@@ -256,8 +256,9 @@ void tst_DragHandler::touchDragMulti()
QPointF ball2Center = ball2->clipRect().center();
QPointF scenePressPos2 = ball2->mapToScene(ball2Center);
QPoint p2 = scenePressPos2.toPoint();
+ QTest::QTouchEventSequence touchSeq = QTest::touchEvent(window, touchDevice, false);
- QTest::touchEvent(window, touchDevice).press(1, p1, window).press(2, p2, window);
+ touchSeq.press(1, p1, window).press(2, p2, window).commit();
QQuickTouchUtils::flush(window);
QVERIFY(!dragHandler1->active());
QCOMPARE(dragHandler1->point().position(), ball1Center);
@@ -271,12 +272,12 @@ void tst_DragHandler::touchDragMulti()
QCOMPARE(dragHandler2->point().scenePressPosition(), scenePressPos2);
p1 += QPoint(dragThreshold, 0);
p2 += QPoint(0, dragThreshold);
- QTest::touchEvent(window, touchDevice).move(1, p1, window).move(2, p2, window);
+ touchSeq.move(1, p1, window).move(2, p2, window).commit();
QQuickTouchUtils::flush(window);
QVERIFY(!dragHandler1->active());
p1 += QPoint(1, 0);
p2 += QPoint(0, 1);
- QTest::touchEvent(window, touchDevice).move(1, p1, window).move(2, p2, window);
+ touchSeq.move(1, p1, window).move(2, p2, window).commit();
QQuickTouchUtils::flush(window);
QTRY_VERIFY(dragHandler1->active());
QVERIFY(dragHandler2->active());
@@ -292,7 +293,7 @@ void tst_DragHandler::touchDragMulti()
QCOMPARE(translationChangedSpy2.count(), 0);
QCOMPARE(dragHandler2->translation().x(), 0.0);
QCOMPARE(dragHandler2->point().sceneGrabPosition(), sceneGrabPos2);
- QTest::touchEvent(window, touchDevice).move(1, p1, window).move(2, p2, window);
+ touchSeq.move(1, p1, window).move(2, p2, window).commit();
QQuickTouchUtils::flush(window);
QVERIFY(dragHandler1->active());
QVERIFY(dragHandler2->active());
@@ -310,14 +311,14 @@ void tst_DragHandler::touchDragMulti()
QCOMPARE(dragHandler2->point().sceneGrabPosition(), sceneGrabPos2);
QCOMPARE(dragHandler2->translation().x(), 0.0);
QCOMPARE(dragHandler2->translation().y(), dragThreshold + 20.0);
- QTest::touchEvent(window, touchDevice).release(1, p1, window).stationary(2);
+ touchSeq.release(1, p1, window).stationary(2).commit();
QQuickTouchUtils::flush(window);
QTRY_VERIFY(!dragHandler1->active());
QVERIFY(dragHandler2->active());
QCOMPARE(dragHandler1->point().pressedButtons(), Qt::NoButton);
QCOMPARE(ball1->mapToScene(ball1Center).toPoint(), p1);
QCOMPARE(translationChangedSpy1.count(), 1);
- QTest::touchEvent(window, touchDevice).release(2, p2, window);
+ touchSeq.release(2, p2, window).commit();
QQuickTouchUtils::flush(window);
QTRY_VERIFY(!dragHandler2->active());
QCOMPARE(ball2->mapToScene(ball2Center).toPoint(), p2);
diff --git a/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp b/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp
index cf18b5eca1..f9970df9f0 100644
--- a/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp
+++ b/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp
@@ -526,23 +526,24 @@ void tst_TapHandler::buttonsMultiTouch()
QQuickItem *buttonReleaseWithinBounds = window->rootObject()->findChild<QQuickItem*>("ReleaseWithinBounds");
QVERIFY(buttonReleaseWithinBounds);
QSignalSpy releaseWithinBoundsTappedSpy(buttonReleaseWithinBounds, SIGNAL(tapped()));
+ QTest::QTouchEventSequence touchSeq = QTest::touchEvent(window, touchDevice, false);
// can press multiple buttons at the same time
QPoint p1 = buttonDragThreshold->mapToScene(QPointF(20, 20)).toPoint();
- QTest::touchEvent(window, touchDevice).press(1, p1, window);
+ touchSeq.press(1, p1, window).commit();
QQuickTouchUtils::flush(window);
QTRY_VERIFY(buttonDragThreshold->property("pressed").toBool());
QPoint p2 = buttonWithinBounds->mapToScene(QPointF(20, 20)).toPoint();
- QTest::touchEvent(window, touchDevice).stationary(1).press(2, p2, window);
+ touchSeq.stationary(1).press(2, p2, window).commit();
QQuickTouchUtils::flush(window);
QTRY_VERIFY(buttonWithinBounds->property("pressed").toBool());
QPoint p3 = buttonReleaseWithinBounds->mapToScene(QPointF(20, 20)).toPoint();
- QTest::touchEvent(window, touchDevice).stationary(1).stationary(2).press(3, p3, window);
+ touchSeq.stationary(1).stationary(2).press(3, p3, window).commit();
QQuickTouchUtils::flush(window);
QTRY_VERIFY(buttonReleaseWithinBounds->property("pressed").toBool());
// can release top button and press again: others stay pressed the whole time
- QTest::touchEvent(window, touchDevice).stationary(2).stationary(3).release(1, p1, window);
+ touchSeq.stationary(2).stationary(3).release(1, p1, window).commit();
QQuickTouchUtils::flush(window);
QTRY_VERIFY(!buttonDragThreshold->property("pressed").toBool());
QCOMPARE(dragThresholdTappedSpy.count(), 1);
@@ -550,14 +551,14 @@ void tst_TapHandler::buttonsMultiTouch()
QCOMPARE(withinBoundsTappedSpy.count(), 0);
QVERIFY(buttonReleaseWithinBounds->property("pressed").toBool());
QCOMPARE(releaseWithinBoundsTappedSpy.count(), 0);
- QTest::touchEvent(window, touchDevice).stationary(2).stationary(3).press(1, p1, window);
+ touchSeq.stationary(2).stationary(3).press(1, p1, window).commit();
QQuickTouchUtils::flush(window);
QTRY_VERIFY(buttonDragThreshold->property("pressed").toBool());
QVERIFY(buttonWithinBounds->property("pressed").toBool());
QVERIFY(buttonReleaseWithinBounds->property("pressed").toBool());
// can release middle button and press again: others stay pressed the whole time
- QTest::touchEvent(window, touchDevice).stationary(1).stationary(3).release(2, p2, window);
+ touchSeq.stationary(1).stationary(3).release(2, p2, window).commit();
QQuickTouchUtils::flush(window);
QTRY_VERIFY(!buttonWithinBounds->property("pressed").toBool());
QCOMPARE(withinBoundsTappedSpy.count(), 1);
@@ -565,21 +566,21 @@ void tst_TapHandler::buttonsMultiTouch()
QCOMPARE(dragThresholdTappedSpy.count(), 1);
QVERIFY(buttonReleaseWithinBounds->property("pressed").toBool());
QCOMPARE(releaseWithinBoundsTappedSpy.count(), 0);
- QTest::touchEvent(window, touchDevice).stationary(1).stationary(3).press(2, p2, window);
+ touchSeq.stationary(1).stationary(3).press(2, p2, window).commit();
QQuickTouchUtils::flush(window);
QVERIFY(buttonDragThreshold->property("pressed").toBool());
QVERIFY(buttonWithinBounds->property("pressed").toBool());
QVERIFY(buttonReleaseWithinBounds->property("pressed").toBool());
// can release bottom button and press again: others stay pressed the whole time
- QTest::touchEvent(window, touchDevice).stationary(1).stationary(2).release(3, p3, window);
+ touchSeq.stationary(1).stationary(2).release(3, p3, window).commit();
QQuickTouchUtils::flush(window);
QCOMPARE(releaseWithinBoundsTappedSpy.count(), 1);
QVERIFY(buttonWithinBounds->property("pressed").toBool());
QCOMPARE(withinBoundsTappedSpy.count(), 1);
QVERIFY(!buttonReleaseWithinBounds->property("pressed").toBool());
QCOMPARE(dragThresholdTappedSpy.count(), 1);
- QTest::touchEvent(window, touchDevice).stationary(1).stationary(2).press(3, p3, window);
+ touchSeq.stationary(1).stationary(2).press(3, p3, window).commit();
QQuickTouchUtils::flush(window);
QTRY_VERIFY(buttonDragThreshold->property("pressed").toBool());
QVERIFY(buttonWithinBounds->property("pressed").toBool());
@@ -599,8 +600,8 @@ void tst_TapHandler::componentUserBehavioralOverride()
QQuickTapHandler *userTapHandler = button->findChild<QQuickTapHandler*>("override");
QVERIFY(userTapHandler);
QSignalSpy tappedSpy(button, SIGNAL(tapped()));
- QSignalSpy innerGrabChangedSpy(innerTapHandler, SIGNAL(grabChanged(QQuickEventPoint *)));
- QSignalSpy userGrabChangedSpy(userTapHandler, SIGNAL(grabChanged(QQuickEventPoint *)));
+ QSignalSpy innerGrabChangedSpy(innerTapHandler, SIGNAL(grabChanged(QQuickEventPoint::GrabState, QQuickEventPoint *)));
+ QSignalSpy userGrabChangedSpy(userTapHandler, SIGNAL(grabChanged(QQuickEventPoint::GrabState, QQuickEventPoint *)));
QSignalSpy innerPressedChangedSpy(innerTapHandler, SIGNAL(pressedChanged()));
QSignalSpy userPressedChangedSpy(userTapHandler, SIGNAL(pressedChanged()));
diff --git a/tests/auto/quick/qquickanimatedsprite/data/infiniteLoops.qml b/tests/auto/quick/qquickanimatedsprite/data/infiniteLoops.qml
new file mode 100644
index 0000000000..551329a457
--- /dev/null
+++ b/tests/auto/quick/qquickanimatedsprite/data/infiniteLoops.qml
@@ -0,0 +1,38 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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.0
+
+AnimatedSprite {
+ loops: AnimatedSprite.Infinite
+ source: "squarefacesprite.png"
+ frameCount: 6
+ frameDuration: 240
+ width: 160
+ height: 160
+}
diff --git a/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp b/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp
index d24ebd9878..4ca31fd957 100644
--- a/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp
+++ b/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp
@@ -53,6 +53,7 @@ private slots:
void test_largeAnimation();
void test_reparenting();
void test_changeSourceToSmallerImgKeepingBigFrameSize();
+ void test_infiniteLoops();
void test_implicitSize();
};
@@ -79,8 +80,13 @@ void tst_qquickanimatedsprite::test_properties()
QVERIFY(sprite->interpolate());
QCOMPARE(sprite->loops(), 30);
+ QSignalSpy finishedSpy(sprite, SIGNAL(finished()));
+ QVERIFY(finishedSpy.isValid());
+
sprite->setRunning(false);
QVERIFY(!sprite->running());
+ // The finished() signal shouldn't be emitted when running is manually set to false.
+ QCOMPARE(finishedSpy.count(), 0);
sprite->setInterpolate(false);
QVERIFY(!sprite->interpolate());
}
@@ -100,10 +106,15 @@ void tst_qquickanimatedsprite::test_runningChangedSignal()
QVERIFY(!sprite->running());
QSignalSpy runningChangedSpy(sprite, SIGNAL(runningChanged(bool)));
+ QSignalSpy finishedSpy(sprite, SIGNAL(finished()));
+ QVERIFY(finishedSpy.isValid());
+
sprite->setRunning(true);
QTRY_COMPARE(runningChangedSpy.count(), 1);
+ QCOMPARE(finishedSpy.count(), 0);
QTRY_VERIFY(!sprite->running());
QTRY_COMPARE(runningChangedSpy.count(), 2);
+ QCOMPARE(finishedSpy.count(), 1);
}
template <typename T>
@@ -357,6 +368,28 @@ void tst_qquickanimatedsprite::test_implicitSize()
QCOMPARE(frameImplicitHeightChangedSpy.count(), 1);
}
+void tst_qquickanimatedsprite::test_infiniteLoops()
+{
+ QQuickView window;
+ window.setSource(testFileUrl("infiniteLoops.qml"));
+ window.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&window));
+ QVERIFY(window.rootObject());
+
+ QQuickAnimatedSprite* sprite = qobject_cast<QQuickAnimatedSprite*>(window.rootObject());
+ QVERIFY(sprite);
+
+ QTRY_VERIFY(sprite->running());
+
+ QSignalSpy finishedSpy(sprite, SIGNAL(finished()));
+ QVERIFY(finishedSpy.isValid());
+
+ // The finished() signal shouldn't be emitted for infinite animations.
+ const int previousFrame = sprite->currentFrame();
+ QTRY_VERIFY(sprite->currentFrame() != previousFrame);
+ QCOMPARE(finishedSpy.count(), 0);
+}
+
QTEST_MAIN(tst_qquickanimatedsprite)
#include "tst_qquickanimatedsprite.moc"
diff --git a/tests/auto/quick/qquickanimations/data/finished.qml b/tests/auto/quick/qquickanimations/data/finished.qml
new file mode 100644
index 0000000000..a18b321501
--- /dev/null
+++ b/tests/auto/quick/qquickanimations/data/finished.qml
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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.12
+
+Item {
+ id: root
+ width: 400
+ height: 400
+
+ property bool finishedUsableInQml: false
+
+ property alias simpleTopLevelAnimation: simpleTopLevelAnimation
+ property real foo: 0
+
+ property alias transitionRect: transitionRect
+ property alias transition: transition
+ property alias animationWithinTransition: animationWithinTransition
+
+ property real bar: 0
+ property alias animationWithinBehavior: animationWithinBehavior
+ property alias behavior: behavior
+
+ NumberAnimation {
+ id: simpleTopLevelAnimation
+ target: root
+ property: "foo"
+ from: 0
+ to: 1
+ duration: 10
+
+ onFinished: finishedUsableInQml = true
+ }
+
+ Rectangle {
+ id: transitionRect
+ color: "green"
+ width: 50
+ height: 50
+ anchors.centerIn: parent
+
+ states: State {
+ name: "go"
+ }
+ transitions: Transition {
+ id: transition
+ to: "go"
+ SequentialAnimation {
+ NumberAnimation {
+ id: animationWithinTransition
+ duration: 10
+ property: "foo"
+ from: 1
+ to: 2
+ }
+ }
+ }
+ }
+
+ Behavior on bar {
+ id: behavior
+ NumberAnimation {
+ id: animationWithinBehavior
+ duration: 10
+ property: "bar"
+ from: 0
+ to: 1
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp
index de86bb16db..3cfe03a376 100644
--- a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp
+++ b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp
@@ -105,6 +105,7 @@ private slots:
void pathSvgAnimation();
void pathLineUnspecifiedXYBug();
void unsetAnimatorProxyJobWindow();
+ void finished();
};
#define QTIMED_COMPARE(lhs, rhs) do { \
@@ -1612,6 +1613,79 @@ void tst_qquickanimations::unsetAnimatorProxyJobWindow()
QCOMPARE(proxy.job().data(), job);
}
+void tst_qquickanimations::finished()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("finished.qml"));
+ QScopedPointer<QObject> root(component.create());
+ QVERIFY(root);
+
+ // Test that finished() is emitted for a simple top-level animation.
+ // (Each test is in its own block so that we can reuse the nice signal names :))
+ {
+ QQuickAbstractAnimation *simpleTopLevelAnimation
+ = root->property("simpleTopLevelAnimation").value<QQuickAbstractAnimation*>();
+ QVERIFY(simpleTopLevelAnimation);
+
+ QSignalSpy stoppedSpy(simpleTopLevelAnimation, SIGNAL(stopped()));
+ QVERIFY(stoppedSpy.isValid());
+
+ QSignalSpy finishedSpy(simpleTopLevelAnimation, SIGNAL(finished()));
+ QVERIFY(finishedSpy.isValid());
+
+ QVERIFY(simpleTopLevelAnimation->setProperty("running", QVariant(true)));
+ QTRY_COMPARE(stoppedSpy.count(), 1);
+ QCOMPARE(finishedSpy.count(), 1);
+
+ // Test that the signal is properly revisioned and hence accessible from QML.
+ QCOMPARE(root->property("finishedUsableInQml").toBool(), true);
+ }
+
+ // Test that finished() is not emitted for animations within a Transition.
+ {
+ QObject *transition = root->property("transition").value<QObject*>();
+ QVERIFY(transition);
+
+ QSignalSpy runningChangedSpy(transition, SIGNAL(runningChanged()));
+ QVERIFY(runningChangedSpy.isValid());
+
+ QQuickAbstractAnimation *animationWithinTransition
+ = root->property("animationWithinTransition").value<QQuickAbstractAnimation*>();
+ QVERIFY(animationWithinTransition);
+
+ QSignalSpy stoppedSpy(animationWithinTransition, SIGNAL(stopped()));
+ QVERIFY(stoppedSpy.isValid());
+
+ QSignalSpy finishedSpy(animationWithinTransition, SIGNAL(finished()));
+ QVERIFY(finishedSpy.isValid());
+
+ QObject *transitionRect = root->property("transitionRect").value<QObject*>();
+ QVERIFY(transitionRect);
+ QVERIFY(transitionRect->setProperty("state", QVariant(QLatin1String("go"))));
+ QTRY_COMPARE(runningChangedSpy.count(), 1);
+ QCOMPARE(stoppedSpy.count(), 0);
+ QCOMPARE(finishedSpy.count(), 0);
+ }
+
+ // Test that finished() is not emitted for animations within a Behavior.
+ {
+ QQuickAbstractAnimation *animationWithinBehavior
+ = root->property("animationWithinBehavior").value<QQuickAbstractAnimation*>();
+ QVERIFY(animationWithinBehavior);
+
+ QSignalSpy stoppedSpy(animationWithinBehavior, SIGNAL(stopped()));
+ QVERIFY(stoppedSpy.isValid());
+
+ QSignalSpy finishedSpy(animationWithinBehavior, SIGNAL(finished()));
+ QVERIFY(finishedSpy.isValid());
+
+ QVERIFY(root->setProperty("bar", QVariant(1.0)));
+ QTRY_COMPARE(root->property("bar").toReal(), 1.0);
+ QCOMPARE(stoppedSpy.count(), 0);
+ QCOMPARE(finishedSpy.count(), 0);
+ }
+}
+
QTEST_MAIN(tst_qquickanimations)
#include "tst_qquickanimations.moc"
diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_line.qml b/tests/auto/quick/qquickcanvasitem/data/tst_line.qml
index 750f37638d..dc960a24d0 100644
--- a/tests/auto/quick/qquickcanvasitem/data/tst_line.qml
+++ b/tests/auto/quick/qquickcanvasitem/data/tst_line.qml
@@ -834,5 +834,96 @@ CanvasTestCase {
ctx.lineCap = 'square';
compare(ctx.lineCap, 'square');
+ }
+
+ function test_lineDash(row) {
+ var canvas = createCanvasObject(row);
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.strokeStyle = "#fff";
+ ctx.lineWidth = 2;
+ var pattern = [2, 3, 5, 1, 6, 3]
+ ctx.setLineDash(pattern)
+
+ compare(ctx.getLineDash(), pattern);
+
+ ctx.beginPath();
+ ctx.moveTo(0, 0);
+ ctx.lineTo(40, 0);
+ ctx.stroke();
+
+ comparePixel(ctx, 0,0, 255,255,255,255);
+ comparePixel(ctx, 1,0, 255,255,255,255);
+ comparePixel(ctx, 2,0, 255,255,255,255);
+ comparePixel(ctx, 3,0, 255,255,255,255);
+ comparePixel(ctx, 4,0, 0,0,0,0);
+ comparePixel(ctx, 5,0, 0,0,0,0);
+ comparePixel(ctx, 6,0, 0,0,0,0);
+ comparePixel(ctx, 7,0, 0,0,0,0);
+ comparePixel(ctx, 8,0, 0,0,0,0);
+ comparePixel(ctx, 9,0, 0,0,0,0);
+ comparePixel(ctx, 10,0, 255,255,255,255);
+ comparePixel(ctx, 11,0, 255,255,255,255);
+ comparePixel(ctx, 12,0, 255,255,255,255);
+ comparePixel(ctx, 13,0, 255,255,255,255);
+ comparePixel(ctx, 14,0, 255,255,255,255);
+ comparePixel(ctx, 15,0, 255,255,255,255);
+ comparePixel(ctx, 16,0, 255,255,255,255);
+ comparePixel(ctx, 17,0, 255,255,255,255);
+ comparePixel(ctx, 18,0, 255,255,255,255);
+ comparePixel(ctx, 19,0, 255,255,255,255);
+ comparePixel(ctx, 20,0, 0,0,0,0);
+ comparePixel(ctx, 21,0, 0,0,0,0);
+ comparePixel(ctx, 22,0, 255,255,255,255);
+ comparePixel(ctx, 23,0, 255,255,255,255);
+ comparePixel(ctx, 24,0, 255,255,255,255);
+ comparePixel(ctx, 25,0, 255,255,255,255);
+ comparePixel(ctx, 26,0, 255,255,255,255);
+ comparePixel(ctx, 27,0, 255,255,255,255);
+ comparePixel(ctx, 28,0, 255,255,255,255);
+ comparePixel(ctx, 29,0, 255,255,255,255);
+ comparePixel(ctx, 30,0, 255,255,255,255);
+ comparePixel(ctx, 31,0, 255,255,255,255);
+ comparePixel(ctx, 32,0, 255,255,255,255);
+ comparePixel(ctx, 33,0, 255,255,255,255);
+ comparePixel(ctx, 34,0, 0,0,0,0);
+ comparePixel(ctx, 35,0, 0,0,0,0);
+ comparePixel(ctx, 36,0, 0,0,0,0);
+ comparePixel(ctx, 37,0, 0,0,0,0);
+ comparePixel(ctx, 38,0, 0,0,0,0);
+ comparePixel(ctx, 39,0, 0,0,0,0);
+ }
+
+ function test_lineDashOffset(row) {
+ var canvas = createCanvasObject(row);
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.strokeStyle = "#fff";
+ ctx.lineWidth = 2;
+ var pattern = [2,2]
+ ctx.setLineDash(pattern)
+ ctx.lineDashOffset = 1
+ compare(ctx.getLineDash(), pattern);
+
+ ctx.beginPath();
+ ctx.moveTo(0, 0);
+ ctx.lineTo(40, 0);
+ ctx.stroke();
+
+
+ comparePixel(ctx, 0,0, 255,255,255,255);
+ comparePixel(ctx, 1,0, 255,255,255,255);
+ comparePixel(ctx, 2,0, 0,0,0,0);
+ comparePixel(ctx, 3,0, 0,0,0,0);
+ comparePixel(ctx, 4,0, 0,0,0,0);
+ comparePixel(ctx, 5,0, 0,0,0,0);
+ comparePixel(ctx, 6,0, 255,255,255,255);
+ comparePixel(ctx, 7,0, 255,255,255,255);
+ comparePixel(ctx, 8,0, 255,255,255,255);
+ comparePixel(ctx, 9,0, 255,255,255,255);
+ comparePixel(ctx, 10,0, 0,0,0,0);
+ comparePixel(ctx, 11,0, 0,0,0,0);
+ comparePixel(ctx, 12,0, 0,0,0,0);
+ comparePixel(ctx, 13,0, 0,0,0,0);
}
}
diff --git a/tests/auto/quick/qquickdesignersupport/data/TestComponent.qml b/tests/auto/quick/qquickdesignersupport/data/TestComponent.qml
index 68f456af99..63d65b435c 100644
--- a/tests/auto/quick/qquickdesignersupport/data/TestComponent.qml
+++ b/tests/auto/quick/qquickdesignersupport/data/TestComponent.qml
@@ -4,6 +4,8 @@ Item {
width: 100
height: 62
- x: Math.max(0, 200)
+ // Add a dummy dependency to parent.x to ensure that the
+ // binding stays for the test.
+ x: parent.x + Math.max(0, 200) - parent.x
}
diff --git a/tests/auto/quick/qquickdesignersupport/data/test.qml b/tests/auto/quick/qquickdesignersupport/data/test.qml
index 1d43cb3b7e..6c89f15257 100644
--- a/tests/auto/quick/qquickdesignersupport/data/test.qml
+++ b/tests/auto/quick/qquickdesignersupport/data/test.qml
@@ -1,4 +1,4 @@
-import QtQuick 2.0
+import QtQuick 2.11
Rectangle {
objectName: "rootItem"
@@ -13,7 +13,7 @@ Rectangle {
Rectangle {
objectName: "rectangleItem"
- gradient: Gradient {
+ containmentMask: Item {
}
}
diff --git a/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp b/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp
index 96a11e16e9..3e0765552a 100644
--- a/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp
+++ b/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp
@@ -209,15 +209,15 @@ void tst_qquickdesignersupport::objectProperties()
//Read gradient property as QObject
- int propertyIndex = rectangleItem->metaObject()->indexOfProperty("gradient");
+ int propertyIndex = rectangleItem->metaObject()->indexOfProperty("containmentMask");
QVERIFY(propertyIndex > 0);
QMetaProperty metaProperty = rectangleItem->metaObject()->property(propertyIndex);
QVERIFY(metaProperty.isValid());
QVERIFY(QQuickDesignerSupportProperties::isPropertyQObject(metaProperty));
- QObject*gradient = QQuickDesignerSupportProperties::readQObjectProperty(metaProperty, rectangleItem);
- QVERIFY(gradient);
+ QObject *containmentItem = QQuickDesignerSupportProperties::readQObjectProperty(metaProperty, rectangleItem);
+ QVERIFY(containmentItem);
//The width property is not a QObject
@@ -450,7 +450,7 @@ void tst_qquickdesignersupport::testNotifyPropertyChangeCallBack()
QQuickDesignerSupportMetaInfo::registerNotifyPropertyChangeCallBack(notifyPropertyChangeCallBackPointer);
- rectangle->setProperty("gradient", QVariant::fromValue<QQuickGradient *>(gradient));
+ rectangle->setProperty("gradient", QVariant::fromValue<QJSValue>(view->engine()->newQObject(gradient)));
QVERIFY(s_object);
QCOMPARE(s_object, rootItem);
diff --git a/tests/auto/quick/qquickflickable/BLACKLIST b/tests/auto/quick/qquickflickable/BLACKLIST
index 826c024732..870bb2e1e9 100644
--- a/tests/auto/quick/qquickflickable/BLACKLIST
+++ b/tests/auto/quick/qquickflickable/BLACKLIST
@@ -20,3 +20,4 @@ osx-10.10
osx-10.10
[nestedSliderUsingTouch:keepNeither]
ubuntu-16.04
+ubuntu-18.04
diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
index 248f8447e0..ba266824e6 100644
--- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
+++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
@@ -203,6 +203,8 @@ private slots:
void overshoot();
void overshoot_data();
void overshoot_reentrant();
+ void synchronousDrag_data();
+ void synchronousDrag();
private:
void flickWithTouch(QQuickWindow *window, const QPoint &from, const QPoint &to);
@@ -2458,6 +2460,70 @@ void tst_qquickflickable::overshoot_reentrant()
QCOMPARE(flickable->verticalOvershoot(), 25.0);
}
+void tst_qquickflickable::synchronousDrag_data()
+{
+ QTest::addColumn<bool>("synchronousDrag");
+
+ QTest::newRow("default") << false;
+ QTest::newRow("synch") << true;
+}
+
+void tst_qquickflickable::synchronousDrag()
+{
+ QFETCH(bool, synchronousDrag);
+
+ QScopedPointer<QQuickView> scopedWindow(new QQuickView);
+ QQuickView *window = scopedWindow.data();
+ window->setSource(testFileUrl("longList.qml"));
+ QTRY_COMPARE(window->status(), QQuickView::Ready);
+ QQuickViewTestUtil::centerOnScreen(window);
+ QQuickViewTestUtil::moveMouseAway(window);
+ window->show();
+ QVERIFY(window->rootObject() != nullptr);
+
+ QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject());
+ QVERIFY(flickable != nullptr);
+ QCOMPARE(flickable->synchronousDrag(), false);
+ flickable->setSynchronousDrag(synchronousDrag);
+
+ QPoint p1(100, 100);
+ QPoint p2(95, 95);
+ QPoint p3(70, 70);
+ QPoint p4(50, 50);
+ QPoint p5(30, 30);
+ QCOMPARE(flickable->contentY(), 0.0f);
+
+ // Drag via mouse
+ moveAndPress(window, p1);
+ QTest::mouseMove(window, p2);
+ QTest::mouseMove(window, p3);
+ QTest::mouseMove(window, p4);
+ QCOMPARE(flickable->contentY(), synchronousDrag ? 50.0f : 0.0f);
+ QTest::mouseMove(window, p5);
+ if (!synchronousDrag)
+ QVERIFY(flickable->contentY() < 50.0f);
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p5);
+
+ // Reset to initial condition
+ flickable->setContentY(0);
+
+ // Drag via touch
+ QTest::touchEvent(window, touchDevice).press(0, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window, touchDevice).move(0, p2, window);
+ QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window, touchDevice).move(0, p3, window);
+ QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window, touchDevice).move(0, p4, window);
+ QQuickTouchUtils::flush(window);
+ QCOMPARE(flickable->contentY(), synchronousDrag ? 50.0f : 0.0f);
+ QTest::touchEvent(window, touchDevice).move(0, p5, window);
+ QQuickTouchUtils::flush(window);
+ if (!synchronousDrag)
+ QVERIFY(flickable->contentY() < 50.0f);
+ QTest::touchEvent(window, touchDevice).release(0, p5, window);
+}
+
QTEST_MAIN(tst_qquickflickable)
#include "tst_qquickflickable.moc"
diff --git a/tests/auto/quick/qquickframebufferobject/tst_qquickframebufferobject.cpp b/tests/auto/quick/qquickframebufferobject/tst_qquickframebufferobject.cpp
index 805baebc7a..6aff66d61e 100644
--- a/tests/auto/quick/qquickframebufferobject/tst_qquickframebufferobject.cpp
+++ b/tests/auto/quick/qquickframebufferobject/tst_qquickframebufferobject.cpp
@@ -193,7 +193,7 @@ void tst_QQuickFramebufferObject::testThatStuffWorks()
view.show();
view.requestActivate();
- QVERIFY(QTest::qWaitForWindowActive(&view));
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QImage result = view.grabWindow();
@@ -233,7 +233,7 @@ void tst_QQuickFramebufferObject::testInvalidate()
view.show();
view.requestActivate();
- QVERIFY(QTest::qWaitForWindowActive(&view));
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QCOMPARE(frameInfo.fboSize, QSize(200, 200));
diff --git a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp
index 915b9b43ea..7deed8c5a8 100644
--- a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp
+++ b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp
@@ -4387,24 +4387,34 @@ void tst_QQuickGridView::snapOneRow_data()
QTest::addColumn<qreal>("snapAlignment");
QTest::addColumn<qreal>("endExtent");
QTest::addColumn<qreal>("startExtent");
+ QTest::addColumn<qreal>("flickSlowdown");
QTest::newRow("vertical, left to right") << QQuickGridView::FlowLeftToRight << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange)
- << QPoint(20, 160) << QPoint(20, 20) << 100.0 << 240.0 << 0.0;
+ << QPoint(20, 160) << QPoint(20, 20) << 100.0 << 240.0 << 0.0 << 1.0;
QTest::newRow("horizontal, left to right") << QQuickGridView::FlowTopToBottom << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange)
- << QPoint(160, 20) << QPoint(20, 20) << 100.0 << 240.0 << 0.0;
+ << QPoint(160, 20) << QPoint(20, 20) << 100.0 << 240.0 << 0.0 << 1.0;
QTest::newRow("horizontal, right to left") << QQuickGridView::FlowTopToBottom << Qt::RightToLeft << int(QQuickItemView::NoHighlightRange)
- << QPoint(20, 20) << QPoint(160, 20) << -340.0 << -240.0 - 240.0 << -240.0;
+ << QPoint(20, 20) << QPoint(160, 20) << -340.0 << -240.0 - 240.0 << -240.0 << 1.0;
QTest::newRow("vertical, left to right, enforce range") << QQuickGridView::FlowLeftToRight << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange)
- << QPoint(20, 160) << QPoint(20, 20) << 100.0 << 340.0 << -20.0;
+ << QPoint(20, 160) << QPoint(20, 20) << 100.0 << 340.0 << -20.0 << 1.0;
QTest::newRow("horizontal, left to right, enforce range") << QQuickGridView::FlowTopToBottom << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange)
- << QPoint(160, 20) << QPoint(20, 20) << 100.0 << 340.0 << -20.0;
+ << QPoint(160, 20) << QPoint(20, 20) << 100.0 << 340.0 << -20.0 << 1.0;
QTest::newRow("horizontal, right to left, enforce range") << QQuickGridView::FlowTopToBottom << Qt::RightToLeft << int(QQuickItemView::StrictlyEnforceRange)
- << QPoint(20, 20) << QPoint(160, 20) << -340.0 << -240.0 - 240.0 - 100.0 << -220.0;
+ << QPoint(20, 20) << QPoint(160, 20) << -340.0 << -240.0 - 240.0 - 100.0 << -220.0 << 1.0;
+
+ // Using e.g. 120 rather than 95 always went to the next row.
+ // Ensure this further movement has the same behavior
+ QTest::newRow("vertical, left to right, no more blindspot") << QQuickGridView::FlowLeftToRight << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange)
+ << QPoint(20, 160) << QPoint(20, 95) << 100.0 << 240.0 << 0.0 << 4.0;
+
+ // StrictlyEnforceRange should not override valid SnapOneItem decisions
+ QTest::newRow("vertical, left to right, no more blindspot, enforce range") << QQuickGridView::FlowLeftToRight << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange)
+ << QPoint(20, 160) << QPoint(20, 95) << 100.0 << 340.0 << -20.0 << 4.0;
}
void tst_QQuickGridView::snapOneRow()
@@ -4417,6 +4427,9 @@ void tst_QQuickGridView::snapOneRow()
QFETCH(qreal, snapAlignment);
QFETCH(qreal, endExtent);
QFETCH(qreal, startExtent);
+ QFETCH(qreal, flickSlowdown);
+
+ qreal flickDuration = 180 * flickSlowdown;
QQuickView *window = getView();
QQuickViewTestUtil::moveMouseAway(window);
@@ -4439,7 +4452,7 @@ void tst_QQuickGridView::snapOneRow()
QSignalSpy currentIndexSpy(gridview, SIGNAL(currentIndexChanged()));
// confirm that a flick hits next row boundary
- flick(window, flickStart, flickEnd, 180);
+ flick(window, flickStart, flickEnd, flickDuration);
QTRY_VERIFY(gridview->isMoving() == false); // wait until it stops
if (flow == QQuickGridView::FlowLeftToRight)
QCOMPARE(gridview->contentY(), snapAlignment);
@@ -4453,7 +4466,7 @@ void tst_QQuickGridView::snapOneRow()
// flick to end
do {
- flick(window, flickStart, flickEnd, 180);
+ flick(window, flickStart, flickEnd, flickDuration);
QTRY_VERIFY(gridview->isMoving() == false); // wait until it stops
} while (flow == QQuickGridView::FlowLeftToRight
? !gridview->isAtYEnd()
@@ -4471,7 +4484,7 @@ void tst_QQuickGridView::snapOneRow()
// flick to start
do {
- flick(window, flickEnd, flickStart, 180);
+ flick(window, flickEnd, flickStart, flickDuration);
QTRY_VERIFY(gridview->isMoving() == false); // wait until it stops
} while (flow == QQuickGridView::FlowLeftToRight
? !gridview->isAtYBeginning()
diff --git a/tests/auto/quick/qquickimageprovider/tst_qquickimageprovider.cpp b/tests/auto/quick/qquickimageprovider/tst_qquickimageprovider.cpp
index d8464ebc74..4b75a7e008 100644
--- a/tests/auto/quick/qquickimageprovider/tst_qquickimageprovider.cpp
+++ b/tests/auto/quick/qquickimageprovider/tst_qquickimageprovider.cpp
@@ -65,6 +65,7 @@ private slots:
void threadTest();
void asyncTextureTest();
+ void instantAsyncTextureTest();
private:
QString newImageFileName() const;
@@ -550,6 +551,70 @@ void tst_qquickimageprovider::asyncTextureTest()
}
}
+class InstantAsyncImageResponse : public QQuickImageResponse
+{
+ public:
+ InstantAsyncImageResponse(const QString &id, const QSize &requestedSize)
+ {
+ QImage image(50, 50, QImage::Format_RGB32);
+ image.fill(QColor(id).rgb());
+ if (requestedSize.isValid())
+ image = image.scaled(requestedSize);
+ m_texture = QQuickTextureFactory::textureFactoryForImage(image);
+ emit finished();
+ }
+
+ QQuickTextureFactory *textureFactory() const
+ {
+ return m_texture;
+ }
+
+ QQuickTextureFactory *m_texture;
+};
+
+class InstancAsyncProvider : public QQuickAsyncImageProvider
+{
+ public:
+ InstancAsyncProvider()
+ {
+ }
+
+ ~InstancAsyncProvider() {}
+
+ QQuickImageResponse *requestImageResponse(const QString &id, const QSize &requestedSize)
+ {
+ return new InstantAsyncImageResponse(id, requestedSize);
+ }
+};
+
+void tst_qquickimageprovider::instantAsyncTextureTest()
+{
+ QQmlEngine engine;
+
+ InstancAsyncProvider *provider = new InstancAsyncProvider;
+
+ engine.addImageProvider("test_instantasync", provider);
+ QVERIFY(engine.imageProvider("test_instantasync") != nullptr);
+
+ QString componentStr = "import QtQuick 2.0\nItem { \n"
+ "Image { source: \"image://test_instantasync/blue\"; }\n"
+ "Image { source: \"image://test_instantasync/red\"; }\n"
+ "Image { source: \"image://test_instantasync/green\"; }\n"
+ "Image { source: \"image://test_instantasync/yellow\"; }\n"
+ " }";
+ QQmlComponent component(&engine);
+ component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QScopedPointer<QObject> obj(component.create());
+
+ QVERIFY(!obj.isNull());
+ const QList<QQuickImage *> images = obj->findChildren<QQuickImage *>();
+ QCOMPARE(images.count(), 4);
+
+ for (QQuickImage *img: images) {
+ QTRY_COMPARE(img->status(), QQuickImage::Ready);
+ }
+}
+
QTEST_MAIN(tst_qquickimageprovider)
diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
index c1daddb561..64a186eade 100644
--- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
+++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
@@ -118,6 +118,7 @@ private slots:
void noCurrentIndex();
void keyNavigation();
void keyNavigation_data();
+ void checkCountForMultiColumnModels();
void enforceRange();
void enforceRange_withoutHighlight();
void spacing();
@@ -1855,6 +1856,38 @@ void tst_QQuickListView::swapWithFirstItem()
delete testObject;
}
+void tst_QQuickListView::checkCountForMultiColumnModels()
+{
+ // Check that a list view will only load items for the first
+ // column, even if the model reports that it got several columns.
+ // We test this since QQmlDelegateModel has been changed to
+ // also understand multi-column models, but this should not affect ListView.
+ QScopedPointer<QQuickView> window(createView());
+
+ const int rowCount = 10;
+ const int columnCount = 10;
+
+ QaimModel model;
+ model.columns = columnCount;
+ for (int i = 0; i < rowCount; i++)
+ model.addItem("Item" + QString::number(i), "");
+
+ QQmlContext *ctxt = window->rootContext();
+ ctxt->setContextProperty("testModel", &model);
+
+ QScopedPointer<TestObject> testObject(new TestObject);
+ ctxt->setContextProperty("testObject", testObject.data());
+
+ window->setSource(testFileUrl("listviewtest.qml"));
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
+
+ QQuickListView *listview = findItem<QQuickListView>(window->rootObject(), "list");
+ QTRY_VERIFY(listview != nullptr);
+
+ QCOMPARE(listview->count(), rowCount);
+}
+
void tst_QQuickListView::enforceRange()
{
QScopedPointer<QQuickView> window(createView());
@@ -5481,38 +5514,50 @@ void tst_QQuickListView::snapOneItem_data()
QTest::addColumn<qreal>("snapAlignment");
QTest::addColumn<qreal>("endExtent");
QTest::addColumn<qreal>("startExtent");
+ QTest::addColumn<qreal>("flickSlowdown");
QTest::newRow("vertical, top to bottom")
<< QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::TopToBottom << int(QQuickItemView::NoHighlightRange)
- << QPoint(20, 200) << QPoint(20, 20) << 180.0 << 560.0 << 0.0;
+ << QPoint(20, 200) << QPoint(20, 20) << 180.0 << 560.0 << 0.0 << 1.0;
QTest::newRow("vertical, bottom to top")
<< QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::BottomToTop << int(QQuickItemView::NoHighlightRange)
- << QPoint(20, 20) << QPoint(20, 200) << -420.0 << -560.0 - 240.0 << -240.0;
+ << QPoint(20, 20) << QPoint(20, 200) << -420.0 << -560.0 - 240.0 << -240.0 << 1.0;
QTest::newRow("horizontal, left to right")
<< QQuickListView::Horizontal << Qt::LeftToRight << QQuickItemView::TopToBottom << int(QQuickItemView::NoHighlightRange)
- << QPoint(200, 20) << QPoint(20, 20) << 180.0 << 560.0 << 0.0;
+ << QPoint(200, 20) << QPoint(20, 20) << 180.0 << 560.0 << 0.0 << 1.0;
QTest::newRow("horizontal, right to left")
<< QQuickListView::Horizontal << Qt::RightToLeft << QQuickItemView::TopToBottom << int(QQuickItemView::NoHighlightRange)
- << QPoint(20, 20) << QPoint(200, 20) << -420.0 << -560.0 - 240.0 << -240.0;
+ << QPoint(20, 20) << QPoint(200, 20) << -420.0 << -560.0 - 240.0 << -240.0 << 1.0;
QTest::newRow("vertical, top to bottom, enforce range")
<< QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::TopToBottom << int(QQuickItemView::StrictlyEnforceRange)
- << QPoint(20, 200) << QPoint(20, 20) << 180.0 << 580.0 << -20.0;
+ << QPoint(20, 200) << QPoint(20, 20) << 180.0 << 580.0 << -20.0 << 1.0;
QTest::newRow("vertical, bottom to top, enforce range")
<< QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::BottomToTop << int(QQuickItemView::StrictlyEnforceRange)
- << QPoint(20, 20) << QPoint(20, 200) << -420.0 << -580.0 - 240.0 << -220.0;
+ << QPoint(20, 20) << QPoint(20, 200) << -420.0 << -580.0 - 240.0 << -220.0 << 1.0;
QTest::newRow("horizontal, left to right, enforce range")
<< QQuickListView::Horizontal << Qt::LeftToRight << QQuickItemView::TopToBottom << int(QQuickItemView::StrictlyEnforceRange)
- << QPoint(200, 20) << QPoint(20, 20) << 180.0 << 580.0 << -20.0;
+ << QPoint(200, 20) << QPoint(20, 20) << 180.0 << 580.0 << -20.0 << 1.0;
QTest::newRow("horizontal, right to left, enforce range")
<< QQuickListView::Horizontal << Qt::RightToLeft << QQuickItemView::TopToBottom << int(QQuickItemView::StrictlyEnforceRange)
- << QPoint(20, 20) << QPoint(200, 20) << -420.0 << -580.0 - 240.0 << -220.0;
+ << QPoint(20, 20) << QPoint(200, 20) << -420.0 << -580.0 - 240.0 << -220.0 << 1.0;
+
+ // Using e.g. 120 rather than 95 always went to the next item.
+ // Ensure this further movement has the same behavior
+ QTest::newRow("vertical, top to bottom, no more blindspot")
+ << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::TopToBottom << int(QQuickItemView::NoHighlightRange)
+ << QPoint(20, 200) << QPoint(20, 95) << 180.0 << 560.0 << 0.0 << 6.0;
+
+ // StrictlyEnforceRange should not override valid SnapOneItem decisions
+ QTest::newRow("vertical, top to bottom, no more blindspot, enforce range")
+ << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::TopToBottom << int(QQuickItemView::StrictlyEnforceRange)
+ << QPoint(20, 200) << QPoint(20, 95) << 180.0 << 580.0 << -20.0 << 6.0;
}
void tst_QQuickListView::snapOneItem()
@@ -5526,6 +5571,9 @@ void tst_QQuickListView::snapOneItem()
QFETCH(qreal, snapAlignment);
QFETCH(qreal, endExtent);
QFETCH(qreal, startExtent);
+ QFETCH(qreal, flickSlowdown);
+
+ qreal flickDuration = 180 * flickSlowdown;
QQuickView *window = getView();
QQuickViewTestUtil::moveMouseAway(window);
@@ -5550,7 +5598,7 @@ void tst_QQuickListView::snapOneItem()
QSignalSpy currentIndexSpy(listview, SIGNAL(currentIndexChanged()));
// confirm that a flick hits the next item boundary
- flick(window, flickStart, flickEnd, 180);
+ flick(window, flickStart, flickEnd, flickDuration);
QTRY_VERIFY(listview->isMoving() == false); // wait until it stops
if (orientation == QQuickListView::Vertical)
QCOMPARE(listview->contentY(), snapAlignment);
@@ -5564,7 +5612,7 @@ void tst_QQuickListView::snapOneItem()
// flick to end
do {
- flick(window, flickStart, flickEnd, 180);
+ flick(window, flickStart, flickEnd, flickDuration);
QTRY_VERIFY(listview->isMoving() == false); // wait until it stops
} while (orientation == QQuickListView::Vertical
? verticalLayoutDirection == QQuickItemView::TopToBottom ? !listview->isAtYEnd() : !listview->isAtYBeginning()
@@ -5582,7 +5630,7 @@ void tst_QQuickListView::snapOneItem()
// flick to start
do {
- flick(window, flickEnd, flickStart, 180);
+ flick(window, flickEnd, flickStart, flickDuration);
QTRY_VERIFY(listview->isMoving() == false); // wait until it stops
} while (orientation == QQuickListView::Vertical
? verticalLayoutDirection == QQuickItemView::TopToBottom ? !listview->isAtYBeginning() : !listview->isAtYEnd()
diff --git a/tests/auto/quick/qquickloader/tst_qquickloader.cpp b/tests/auto/quick/qquickloader/tst_qquickloader.cpp
index 5c3729a8cd..fbdd87905b 100644
--- a/tests/auto/quick/qquickloader/tst_qquickloader.cpp
+++ b/tests/auto/quick/qquickloader/tst_qquickloader.cpp
@@ -739,7 +739,7 @@ void tst_QQuickLoader::initialPropertyValuesError_data()
<< (QStringList() << QString(testFileUrl("NonexistentSourceComponent.qml").toString() + ": No such file or directory"));
QTest::newRow("invalid source url") << testFileUrl("initialPropertyValues.error.3.qml")
- << (QStringList() << QString(testFileUrl("InvalidSourceComponent.qml").toString() + ":5:1: Syntax error"));
+ << (QStringList() << QString(testFileUrl("InvalidSourceComponent.qml").toString() + ":5:1: Expected token `:'"));
QTest::newRow("invalid initial property values object with invalid property access") << testFileUrl("initialPropertyValues.error.4.qml")
<< (QStringList() << QString(testFileUrl("initialPropertyValues.error.4.qml").toString() + ":7:5: QML Loader: setSource: value is not an object")
@@ -885,7 +885,7 @@ void tst_QQuickLoader::asynchronous_data()
<< (QStringList() << QString(testFileUrl("IDoNotExist.qml").toString() + ": No such file or directory"));
QTest::newRow("Invalid component") << testFileUrl("InvalidSourceComponent.qml")
- << (QStringList() << QString(testFileUrl("InvalidSourceComponent.qml").toString() + ":5:1: Syntax error"));
+ << (QStringList() << QString(testFileUrl("InvalidSourceComponent.qml").toString() + ":5:1: Expected token `:'"));
}
void tst_QQuickLoader::asynchronous()
diff --git a/tests/auto/quick/qquickmultipointtoucharea/BLACKLIST b/tests/auto/quick/qquickmultipointtoucharea/BLACKLIST
index cab6e2f7bf..cdb3e7733b 100644
--- a/tests/auto/quick/qquickmultipointtoucharea/BLACKLIST
+++ b/tests/auto/quick/qquickmultipointtoucharea/BLACKLIST
@@ -1,4 +1,6 @@
[nonOverlapping]
ubuntu-16.04
+ubuntu-18.04
[nested]
ubuntu-16.04
+ubuntu-18.04
diff --git a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp
index e6c03d052c..7d297d3fa2 100644
--- a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp
+++ b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp
@@ -367,6 +367,10 @@ void tst_QQuickPathView::insertModel_data()
void tst_QQuickPathView::insertModel()
{
+#ifdef Q_OS_MACOS
+ QSKIP("this test currently crashes on MacOS. See QTBUG-68048");
+#endif
+
QFETCH(int, mode);
QFETCH(int, idx);
QFETCH(int, count);
@@ -773,6 +777,10 @@ void tst_QQuickPathView::path()
void tst_QQuickPathView::dataModel()
{
+#ifdef Q_OS_MACOS
+ QSKIP("this test currently crashes on MacOS. See QTBUG-68047");
+#endif
+
QScopedPointer<QQuickView> window(createView());
window->show();
diff --git a/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp b/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp
index 0395b08f10..ec31acf035 100644
--- a/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp
+++ b/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp
@@ -40,6 +40,8 @@
using namespace QQuickViewTestUtil;
using namespace QQuickVisualTestUtil;
+Q_LOGGING_CATEGORY(lcTests, "qt.quick.tests")
+
class tst_qquickpositioners : public QQmlDataTest
{
Q_OBJECT
@@ -3772,6 +3774,10 @@ void tst_qquickpositioners::test_mirroring()
QList<QString> objectNames;
objectNames << "one" << "two" << "three" << "four" << "five";
+#ifdef Q_OS_MACOS
+ qputenv("QSG_RENDER_LOOP","basic"); // QTBUG-69040
+#endif
+
foreach (const QString qmlFile, qmlFiles) {
QScopedPointer<QQuickView> windowA(createView(testFile(qmlFile)));
QQuickItem *rootA = qobject_cast<QQuickItem*>(windowA->rootObject());
@@ -4007,15 +4013,19 @@ void tst_qquickpositioners::test_attachedproperties_dynamic()
QQuickView *tst_qquickpositioners::createView(const QString &filename, bool wait)
{
QQuickView *window = new QQuickView(nullptr);
- qDebug() << "1";
+ qCDebug(lcTests) << "created window";
window->setSource(QUrl::fromLocalFile(filename));
- qDebug() << "2";
+ qCDebug(lcTests) << "loaded content from" << filename;
window->show();
- qDebug() << "3";
+ qCDebug(lcTests) << "window shown";
+ bool exposed = true;
if (wait)
- QTest::qWaitForWindowExposed(window); //It may not relayout until the next frame, so it needs to be drawn
- qDebug() << "4";
+ exposed = QTest::qWaitForWindowExposed(window); //It may not relayout until the next frame, so it needs to be drawn
+ if (exposed)
+ qCDebug(lcTests) << "window exposed";
+ else
+ qCWarning(lcTests) << "window NOT exposed";
return window;
}
diff --git a/tests/auto/quick/qquickrectangle/data/gradient-preset.qml b/tests/auto/quick/qquickrectangle/data/gradient-preset.qml
new file mode 100644
index 0000000000..b740bdd610
--- /dev/null
+++ b/tests/auto/quick/qquickrectangle/data/gradient-preset.qml
@@ -0,0 +1,16 @@
+import QtQuick 2.0
+
+Item {
+ Rectangle {
+ objectName: "enum"
+ gradient: Gradient.NightFade
+ }
+ Rectangle {
+ objectName: "string"
+ gradient: "NightFade"
+ }
+ Rectangle {
+ objectName: "invalid"
+ gradient: -1
+ }
+}
diff --git a/tests/auto/quick/qquickrectangle/tst_qquickrectangle.cpp b/tests/auto/quick/qquickrectangle/tst_qquickrectangle.cpp
index 2aaad867bf..f6ca999cf5 100644
--- a/tests/auto/quick/qquickrectangle/tst_qquickrectangle.cpp
+++ b/tests/auto/quick/qquickrectangle/tst_qquickrectangle.cpp
@@ -49,6 +49,7 @@ private slots:
void gradient_border();
void gradient_separate();
void gradient_multiple();
+ void gradient_preset();
void antialiasing();
private:
@@ -84,7 +85,7 @@ void tst_qquickrectangle::gradient()
QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(component.create());
QVERIFY(rect);
- QQuickGradient *grad = rect->gradient();
+ QQuickGradient *grad = qobject_cast<QQuickGradient *>(rect->gradient().toQObject());
QVERIFY(grad);
QQmlListProperty<QQuickGradientStop> stops = grad->stops();
@@ -103,7 +104,7 @@ void tst_qquickrectangle::gradient()
QMetaObject::invokeMethod(rect, "resetGradient");
- grad = rect->gradient();
+ grad = qobject_cast<QQuickGradient *>(rect->gradient().toQObject());
QVERIFY(!grad);
delete rect;
@@ -174,6 +175,29 @@ void tst_qquickrectangle::gradient_multiple()
QVERIFY(secondIsDirty);
}
+void tst_qquickrectangle::gradient_preset()
+{
+ QQuickView view;
+ view.setSource(testFileUrl("gradient-preset.qml"));
+ view.show();
+
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ QQuickRectangle *enumRect = view.rootObject()->findChild<QQuickRectangle *>("enum");
+ QVERIFY(enumRect);
+ QVERIFY(enumRect->gradient().isNumber());
+ QCOMPARE(enumRect->gradient().toUInt(), QGradient::NightFade);
+
+ QQuickRectangle *stringRect = view.rootObject()->findChild<QQuickRectangle *>("string");
+ QVERIFY(stringRect);
+ QVERIFY(stringRect->gradient().isString());
+ QCOMPARE(stringRect->gradient().toString(), QLatin1String("NightFade"));
+
+ QQuickRectangle *invalidRect = view.rootObject()->findChild<QQuickRectangle *>("invalid");
+ QVERIFY(invalidRect);
+ QVERIFY(invalidRect->gradient().isUndefined());
+}
+
void tst_qquickrectangle::antialiasing()
{
QQmlComponent component(&engine);
diff --git a/tests/auto/quick/qquickrepeater/data/ownership.qml b/tests/auto/quick/qquickrepeater/data/ownership.qml
new file mode 100644
index 0000000000..e13df3ab3a
--- /dev/null
+++ b/tests/auto/quick/qquickrepeater/data/ownership.qml
@@ -0,0 +1,4 @@
+import QtQuick 2.0
+
+Repeater {
+}
diff --git a/tests/auto/quick/qquickrepeater/data/package.qml b/tests/auto/quick/qquickrepeater/data/package.qml
new file mode 100644
index 0000000000..1f9eb0d970
--- /dev/null
+++ b/tests/auto/quick/qquickrepeater/data/package.qml
@@ -0,0 +1,35 @@
+import QtQuick 2.0
+import QtQml.Models 2.2
+import QtQuick.Window 2.0
+
+Window {
+ width: 300
+ height: 300
+ visible: true
+ DelegateModel {
+ id: mdl
+
+ model: 1
+ delegate: Package {
+ Item {
+ id: first
+ Package.name: "first"
+ objectName: "firstItem"
+ }
+ Item{
+ id: second
+ Package.name: "second"
+ objectName: "secondItem"
+ }
+ }
+ }
+
+ Repeater {
+ id: repeater1
+ model: mdl.parts.first
+ }
+ Repeater {
+ id: repeater2
+ model: mdl.parts.second
+ }
+}
diff --git a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
index 0499e2f9a6..0860956224 100644
--- a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
+++ b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
@@ -37,6 +37,7 @@
#include <QtQuick/private/qquicktext_p.h>
#include <QtQml/private/qqmllistmodel_p.h>
#include <QtQml/private/qqmlobjectmodel_p.h>
+#include <QtGui/qstandarditemmodel.h>
#include "../../shared/util.h"
#include "../shared/viewtestutil.h"
@@ -76,6 +77,8 @@ private slots:
void stackingOrder();
void objectModel();
void QTBUG54859_asynchronousMove();
+ void package();
+ void ownership();
};
class TestObject : public QObject
@@ -1014,6 +1017,91 @@ void tst_QQuickRepeater::QTBUG54859_asynchronousMove()
QTRY_COMPARE(item->property("finished"), QVariant(true));
}
+void tst_QQuickRepeater::package()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("package.qml"));
+
+ QScopedPointer<QObject>o(component.create()); // don't crash!
+ QVERIFY(o != nullptr);
+
+ {
+ QQuickRepeater *repeater1 = qobject_cast<QQuickRepeater*>(qmlContext(o.data())->contextProperty("repeater1").value<QObject*>());
+ QVERIFY(repeater1);
+ QCOMPARE(repeater1->count(), 1);
+ QCOMPARE(repeater1->itemAt(0)->objectName(), "firstItem");
+ }
+
+ {
+ QQuickRepeater *repeater2 = qobject_cast<QQuickRepeater*>(qmlContext(o.data())->contextProperty("repeater2").value<QObject*>());
+ QVERIFY(repeater2);
+ QCOMPARE(repeater2->count(), 1);
+ QCOMPARE(repeater2->itemAt(0)->objectName(), "secondItem");
+ }
+}
+
+void tst_QQuickRepeater::ownership()
+{
+ QQmlEngine engine;
+
+ QQmlComponent component(&engine, testFileUrl("ownership.qml"));
+
+ QScopedPointer<QAbstractItemModel> aim(new QStandardItemModel);
+ QPointer<QAbstractItemModel> modelGuard(aim.data());
+ QQmlEngine::setObjectOwnership(aim.data(), QQmlEngine::JavaScriptOwnership);
+ {
+ QJSValue wrapper = engine.newQObject(aim.data());
+ }
+
+ QScopedPointer<QObject> repeater(component.create());
+ QVERIFY(!repeater.isNull());
+
+ QVERIFY(!QQmlData::keepAliveDuringGarbageCollection(aim.data()));
+
+ repeater->setProperty("model", QVariant::fromValue<QObject*>(aim.data()));
+
+ QVERIFY(!QQmlData::keepAliveDuringGarbageCollection(aim.data()));
+
+ engine.collectGarbage();
+ QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
+
+ QVERIFY(modelGuard);
+
+ QScopedPointer<QQmlComponent> delegate(new QQmlComponent(&engine));
+ delegate->setData(QByteArrayLiteral("import QtQuick 2.0\nItem{}"), dataDirectoryUrl().resolved(QUrl("inline.qml")));
+ QPointer<QQmlComponent> delegateGuard(delegate.data());
+ QQmlEngine::setObjectOwnership(delegate.data(), QQmlEngine::JavaScriptOwnership);
+ {
+ QJSValue wrapper = engine.newQObject(delegate.data());
+ }
+
+ QVERIFY(!QQmlData::keepAliveDuringGarbageCollection(delegate.data()));
+
+ repeater->setProperty("delegate", QVariant::fromValue<QObject*>(delegate.data()));
+
+ QVERIFY(!QQmlData::keepAliveDuringGarbageCollection(delegate.data()));
+
+ engine.collectGarbage();
+ QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
+
+ QVERIFY(delegateGuard);
+
+ repeater->setProperty("model", QVariant());
+ repeater->setProperty("delegate", QVariant());
+
+ QVERIFY(delegateGuard);
+ QVERIFY(modelGuard);
+
+ delegate.take();
+ aim.take();
+
+ engine.collectGarbage();
+ QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
+
+ QVERIFY(!delegateGuard);
+ QVERIFY(!modelGuard);
+}
+
QTEST_MAIN(tst_QQuickRepeater)
#include "tst_qquickrepeater.moc"
diff --git a/tests/auto/quick/qquickshape/qquickshape.pro b/tests/auto/quick/qquickshape/qquickshape.pro
index 29c3502b86..a0e5c002e0 100644
--- a/tests/auto/quick/qquickshape/qquickshape.pro
+++ b/tests/auto/quick/qquickshape/qquickshape.pro
@@ -9,27 +9,5 @@ include (../shared/util.pri)
TESTDATA = data/*
-HEADERS += \
- ../../../../src/imports/shapes/qquickshape_p.h \
- ../../../../src/imports/shapes/qquickshape_p_p.h \
- ../../../../src/imports/shapes/qquickshapegenericrenderer_p.h \
- ../../../../src/imports/shapes/qquickshapesoftwarerenderer_p.h
-
-SOURCES += \
- ../../../../src/imports/shapes/qquickshape.cpp \
- ../../../../src/imports/shapes/qquickshapegenericrenderer.cpp \
- ../../../../src/imports/shapes/qquickshapesoftwarerenderer.cpp
-
-qtConfig(opengl) {
- HEADERS += \
- ../../../../src/imports/shapes/qquicknvprfunctions_p.h \
- ../../../../src/imports/shapes/qquicknvprfunctions_p_p.h \
- ../../../../src/imports/shapes/qquickshapenvprrenderer_p.h
-
- SOURCES += \
- ../../../../src/imports/shapes/qquicknvprfunctions.cpp \
- ../../../../src/imports/shapes/qquickshapenvprrenderer.cpp
-}
-
-QT += core-private gui-private qml-private quick-private testlib
+QT += core-private gui-private qml-private quick-private testlib quickshapes-private
qtHaveModule(widgets): QT += widgets
diff --git a/tests/auto/quick/qquickshape/tst_qquickshape.cpp b/tests/auto/quick/qquickshape/tst_qquickshape.cpp
index 2a349d2013..72f987ce4a 100644
--- a/tests/auto/quick/qquickshape/tst_qquickshape.cpp
+++ b/tests/auto/quick/qquickshape/tst_qquickshape.cpp
@@ -33,7 +33,7 @@
#include <QtQml/qqmlcontext.h>
#include <QtQml/qqmlexpression.h>
#include <QtQml/qqmlincubator.h>
-#include "../../../../src/imports/shapes/qquickshape_p.h"
+#include <QtQuickShapes/private/qquickshape_p.h>
#include "../../shared/util.h"
#include "../shared/viewtestutil.h"
diff --git a/tests/auto/quick/qquicktableview/data/countingtableview.qml b/tests/auto/quick/qquicktableview/data/countingtableview.qml
new file mode 100644
index 0000000000..d8315be54f
--- /dev/null
+++ b/tests/auto/quick/qquicktableview/data/countingtableview.qml
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** 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-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Window 2.3
+import Qt.labs.tableview 1.0
+
+Item {
+ id: root
+ width: 640
+ height: 450
+
+ property alias tableView: tableView
+ property int currentDelegateCount: 0
+ property int maxDelegateCount: 0
+
+ TableView {
+ id: tableView
+ width: 600
+ height: 400
+ anchors.margins: 1
+ clip: true
+ delegate: tableViewDelegate
+ cacheBuffer: 0
+ }
+
+ Component {
+ id: tableViewDelegate
+ Rectangle {
+ objectName: "tableViewDelegate"
+ TableView.cellWidth: 100
+ TableView.cellHeight: 50
+ color: "lightgray"
+ border.width: 1
+ Text {
+ anchors.centerIn: parent
+ text: modelData
+ }
+ Component.onCompleted: {
+ currentDelegateCount++;
+ maxDelegateCount = Math.max(maxDelegateCount, currentDelegateCount);
+ }
+ Component.onDestruction: {
+ currentDelegateCount--;
+ }
+ }
+ }
+
+}
diff --git a/tests/auto/quick/qquicktableview/data/plaintableview.qml b/tests/auto/quick/qquicktableview/data/plaintableview.qml
new file mode 100644
index 0000000000..7668f0ca01
--- /dev/null
+++ b/tests/auto/quick/qquicktableview/data/plaintableview.qml
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** 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-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Window 2.3
+import Qt.labs.tableview 1.0
+
+Item {
+ width: 640
+ height: 450
+
+ property alias tableView: tableView
+ property real delegateWidth: 100
+ property real delegateHeight: 50
+ property Component delegate: tableViewDelegate
+
+ TableView {
+ id: tableView
+ width: 600
+ height: 400
+ anchors.margins: 1
+ clip: true
+ delegate: tableViewDelegate
+ cacheBuffer: 0
+ columnSpacing: 1
+ rowSpacing: 1
+ }
+
+ Component {
+ id: tableViewDelegate
+ Rectangle {
+ objectName: "tableViewDelegate"
+ TableView.cellWidth: delegateWidth
+ TableView.cellHeight: delegateHeight
+ color: "lightgray"
+ border.width: 1
+ Text {
+ anchors.centerIn: parent
+ text: modelData
+ }
+ }
+ }
+
+}
diff --git a/tests/auto/quick/qquicktableview/data/tableviewimplicitsize.qml b/tests/auto/quick/qquicktableview/data/tableviewimplicitsize.qml
new file mode 100644
index 0000000000..65e4d0861c
--- /dev/null
+++ b/tests/auto/quick/qquicktableview/data/tableviewimplicitsize.qml
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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.12
+import QtQuick.Window 2.3
+import Qt.labs.tableview 1.0
+
+Item {
+ width: 640
+ height: 450
+
+ property alias tableView: tableView
+
+ TableView {
+ id: tableView
+ width: 600
+ height: 400
+ anchors.margins: 1
+ clip: true
+ delegate: tableViewDelegate
+ cacheBuffer: 0
+ columnSpacing: 1
+ rowSpacing: 1
+ }
+
+ Component {
+ id: tableViewDelegate
+ Rectangle {
+ objectName: "tableViewDelegate"
+ color: "lightgray"
+ border.width: 1
+ implicitWidth: 90
+ implicitHeight: 60
+ Text {
+ anchors.centerIn: parent
+ text: modelData
+ }
+ }
+ }
+
+}
diff --git a/tests/auto/quick/qquicktableview/qquicktableview.pro b/tests/auto/quick/qquicktableview/qquicktableview.pro
new file mode 100644
index 0000000000..f4d0265dd3
--- /dev/null
+++ b/tests/auto/quick/qquicktableview/qquicktableview.pro
@@ -0,0 +1,14 @@
+CONFIG += testcase
+TARGET = tst_qquicktableview
+macos:CONFIG -= app_bundle
+
+HEADERS += testmodel.h
+SOURCES += tst_qquicktableview.cpp
+
+include (../../shared/util.pri)
+include (../shared/util.pri)
+
+TESTDATA = data/*
+
+QT += core-private gui-private qml-private quick-private testlib
+
diff --git a/tests/auto/quick/qquicktableview/testmodel.h b/tests/auto/quick/qquicktableview/testmodel.h
new file mode 100644
index 0000000000..06384f7a5e
--- /dev/null
+++ b/tests/auto/quick/qquicktableview/testmodel.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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$
+**
+****************************************************************************/
+
+#include <QtCore/QtCore>
+#include <QtGui/QStandardItemModel>
+
+class TestModel : public QAbstractTableModel
+{
+ Q_OBJECT
+ Q_PROPERTY(int rowCount READ rowCount WRITE setRowCount NOTIFY rowCountChanged)
+ Q_PROPERTY(int columnCount READ columnCount WRITE setColumnCount NOTIFY columnCountChanged)
+
+public:
+ TestModel(QObject *parent = nullptr)
+ : QAbstractTableModel(parent)
+ {}
+
+ TestModel(int rows, int columns, QObject *parent = nullptr)
+ : QAbstractTableModel(parent)
+ , m_rows(rows)
+ , m_columns(columns)
+ {}
+
+ int rowCount(const QModelIndex & = QModelIndex()) const override { return m_rows; }
+ void setRowCount(int count) { beginResetModel(); m_rows = count; emit rowCountChanged(); endResetModel(); }
+
+ int columnCount(const QModelIndex & = QModelIndex()) const override { return m_columns; }
+ void setColumnCount(int count) { beginResetModel(); m_columns = count; emit columnCountChanged(); endResetModel(); }
+
+ QVariant data(const QModelIndex &index, int role) const override
+ {
+ if (!index.isValid() || role != Qt::DisplayRole)
+ return QVariant();
+
+ int cell = index.row() + (index.column() * m_columns);
+ if (selectedCells.contains(cell))
+ return QStringLiteral("selected");
+ return QString("%1").arg(index.row());
+ }
+
+ QHash<int, QByteArray> roleNames() const override
+ {
+ return { {Qt::DisplayRole, "display"} };
+ }
+
+ Q_INVOKABLE void selectCell(int row, int column)
+ {
+ int cell = row + (column * m_columns);
+ selectedCells.insert(cell);
+ auto index = createIndex(row, column, nullptr);
+ emit dataChanged(index, index);
+ }
+
+signals:
+ void rowCountChanged();
+ void columnCountChanged();
+
+private:
+ int m_rows = 0;
+ int m_columns = 0;
+ QSet<int> selectedCells;
+};
+
+#define TestModelAsVariant(...) QVariant::fromValue(QSharedPointer<TestModel>(new TestModel(__VA_ARGS__)))
diff --git a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
new file mode 100644
index 0000000000..8caced4396
--- /dev/null
+++ b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
@@ -0,0 +1,791 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+
+#include <QtQuick/qquickview.h>
+#include <QtQuick/private/qquicktableview_p.h>
+#include <QtQuick/private/qquicktableview_p_p.h>
+
+#include <QtQml/qqmlengine.h>
+#include <QtQml/qqmlcontext.h>
+#include <QtQml/qqmlexpression.h>
+#include <QtQml/qqmlincubator.h>
+#include <QtQml/private/qqmlobjectmodel_p.h>
+#include <QtQml/private/qqmllistmodel_p.h>
+#include <QtQml/private/qqmldelegatemodel_p.h>
+
+#include "testmodel.h"
+
+#include "../../shared/util.h"
+#include "../shared/viewtestutil.h"
+#include "../shared/visualtestutil.h"
+
+using namespace QQuickViewTestUtil;
+using namespace QQuickVisualTestUtil;
+
+static const char* kTableViewPropName = "tableView";
+static const char* kDelegateObjectName = "tableViewDelegate";
+
+Q_DECLARE_METATYPE(QMarginsF);
+
+#define LOAD_TABLEVIEW(fileName) \
+ QScopedPointer<QQuickView> view(createView()); \
+ view->setSource(testFileUrl(fileName)); \
+ view->show(); \
+ QVERIFY(QTest::qWaitForWindowActive(view.data())); \
+ auto tableView = view->rootObject()->property(kTableViewPropName).value<QQuickTableView *>(); \
+ QVERIFY(tableView); \
+ auto tableViewPrivate = QQuickTableViewPrivate::get(tableView); \
+ Q_UNUSED(tableViewPrivate)
+
+#define WAIT_UNTIL_POLISHED \
+ QVERIFY(tableViewPrivate->polishScheduled); \
+ QTRY_VERIFY(!tableViewPrivate->polishScheduled)
+
+class tst_QQuickTableView : public QQmlDataTest
+{
+ Q_OBJECT
+public:
+ tst_QQuickTableView();
+
+ QQuickTableViewAttached *getAttachedObject(const QObject *object) const;
+ QPoint getContextRowAndColumn(const QQuickItem *item) const;
+
+private slots:
+ void initTestCase() override;
+
+ void setAndGetModel_data();
+ void setAndGetModel();
+ void emptyModel_data();
+ void emptyModel();
+ void checkZeroSizedDelegate();
+ void checkImplicitSizeDelegate();
+ void noDelegate();
+ void countDelegateItems_data();
+ void countDelegateItems();
+ void checkLayoutOfEqualSizedDelegateItems_data();
+ void checkLayoutOfEqualSizedDelegateItems();
+ void checkTableMargins_data();
+ void checkTableMargins();
+ void fillTableViewButNothingMore_data();
+ void fillTableViewButNothingMore();
+ void checkInitialAttachedProperties_data();
+ void checkInitialAttachedProperties();
+ void flick_data();
+ void flick();
+ void flickOvershoot_data();
+ void flickOvershoot();
+ void checkRowColumnCount();
+};
+
+tst_QQuickTableView::tst_QQuickTableView()
+{
+}
+
+void tst_QQuickTableView::initTestCase()
+{
+ QQmlDataTest::initTestCase();
+ qmlRegisterType<TestModel>("TestModel", 0, 1, "TestModel");
+}
+
+QQuickTableViewAttached *tst_QQuickTableView::getAttachedObject(const QObject *object) const
+{
+ QObject *attachedObject = qmlAttachedPropertiesObject<QQuickTableView>(object);
+ return static_cast<QQuickTableViewAttached *>(attachedObject);
+}
+
+QPoint tst_QQuickTableView::getContextRowAndColumn(const QQuickItem *item) const
+{
+ const auto context = qmlContext(item);
+ const int row = context->contextProperty("row").toInt();
+ const int column = context->contextProperty("column").toInt();
+ return QPoint(column, row);
+}
+
+void tst_QQuickTableView::setAndGetModel_data()
+{
+ QTest::addColumn<QVariant>("model");
+
+ QTest::newRow("QAIM 1x1") << TestModelAsVariant(1, 1);
+ QTest::newRow("Number model 1") << QVariant::fromValue(1);
+ QTest::newRow("QStringList 1") << QVariant::fromValue(QStringList() << "one");
+}
+
+void tst_QQuickTableView::setAndGetModel()
+{
+ // Test that we can set and get different kind of models
+ QFETCH(QVariant, model);
+ LOAD_TABLEVIEW("plaintableview.qml");
+
+ tableView->setModel(model);
+ QCOMPARE(model, tableView->model());
+}
+
+void tst_QQuickTableView::emptyModel_data()
+{
+ QTest::addColumn<QVariant>("model");
+
+ QTest::newRow("QAIM") << TestModelAsVariant(0, 0);
+ QTest::newRow("Number model") << QVariant::fromValue(0);
+ QTest::newRow("QStringList") << QVariant::fromValue(QStringList());
+}
+
+void tst_QQuickTableView::emptyModel()
+{
+ // Check that if we assign an empty model to
+ // TableView, no delegate items will be created.
+ QFETCH(QVariant, model);
+ LOAD_TABLEVIEW("plaintableview.qml");
+
+ tableView->setModel(model);
+ WAIT_UNTIL_POLISHED;
+ QCOMPARE(tableViewPrivate->loadedItems.count(), 0);
+}
+
+void tst_QQuickTableView::checkZeroSizedDelegate()
+{
+ // Check that if we assign a delegate with empty width and height, we
+ // fall back to use kDefaultColumnWidth and kDefaultRowHeight as
+ // column/row sizes.
+ LOAD_TABLEVIEW("plaintableview.qml");
+
+ auto model = TestModelAsVariant(100, 100);
+ tableView->setModel(model);
+
+ view->rootObject()->setProperty("delegateWidth", 0);
+ view->rootObject()->setProperty("delegateHeight", 0);
+
+ WAIT_UNTIL_POLISHED;
+
+ auto items = tableViewPrivate->loadedItems;
+ QVERIFY(!items.isEmpty());
+
+ for (auto fxItem : tableViewPrivate->loadedItems) {
+ auto item = fxItem->item;
+ QCOMPARE(item->width(), kDefaultColumnWidth);
+ QCOMPARE(item->height(), kDefaultRowHeight);
+ }
+}
+
+void tst_QQuickTableView::checkImplicitSizeDelegate()
+{
+ // Check that we can set the size of delegate items using
+ // implicit width/height, instead of forcing the user to
+ // create an attached object by using TableView.cellWidth/Height.
+ LOAD_TABLEVIEW("tableviewimplicitsize.qml");
+
+ auto model = TestModelAsVariant(100, 100);
+ tableView->setModel(model);
+
+ WAIT_UNTIL_POLISHED;
+
+ auto items = tableViewPrivate->loadedItems;
+ QVERIFY(!items.isEmpty());
+
+ for (auto fxItem : tableViewPrivate->loadedItems) {
+ auto item = fxItem->item;
+ QCOMPARE(item->width(), 90);
+ QCOMPARE(item->height(), 60);
+ }
+}
+
+void tst_QQuickTableView::noDelegate()
+{
+ // Check that you can skip setting a delegate without
+ // it causing any problems (like crashing or asserting).
+ // And then set a delegate, and do a quick check that the
+ // view gets populated as expected.
+ LOAD_TABLEVIEW("plaintableview.qml");
+
+ const int rows = 5;
+ const int columns = 5;
+ auto model = TestModelAsVariant(columns, rows);
+ tableView->setModel(model);
+
+ // Start with no delegate, and check
+ // that we end up with no items in the table.
+ tableView->setDelegate(nullptr);
+
+ WAIT_UNTIL_POLISHED;
+
+ auto items = tableViewPrivate->loadedItems;
+ QVERIFY(items.isEmpty());
+
+ // Set a delegate, and check that we end
+ // up with the expected number of items.
+ auto delegate = view->rootObject()->property("delegate").value<QQmlComponent *>();
+ QVERIFY(delegate);
+ tableView->setDelegate(delegate);
+
+ WAIT_UNTIL_POLISHED;
+
+ items = tableViewPrivate->loadedItems;
+ QCOMPARE(items.count(), rows * columns);
+
+ // And then unset the delegate again, and check
+ // that we end up with no items.
+ tableView->setDelegate(nullptr);
+
+ WAIT_UNTIL_POLISHED;
+
+ items = tableViewPrivate->loadedItems;
+ QVERIFY(items.isEmpty());
+}
+
+void tst_QQuickTableView::countDelegateItems_data()
+{
+ QTest::addColumn<QVariant>("model");
+ QTest::addColumn<int>("count");
+
+ QTest::newRow("QAIM 1x1") << TestModelAsVariant(1, 1) << 1;
+ QTest::newRow("QAIM 2x1") << TestModelAsVariant(2, 1) << 2;
+ QTest::newRow("QAIM 1x2") << TestModelAsVariant(1, 2) << 2;
+ QTest::newRow("QAIM 2x2") << TestModelAsVariant(2, 2) << 4;
+ QTest::newRow("QAIM 4x4") << TestModelAsVariant(4, 4) << 16;
+
+ QTest::newRow("Number model 1") << QVariant::fromValue(1) << 1;
+ QTest::newRow("Number model 4") << QVariant::fromValue(4) << 4;
+
+ QTest::newRow("QStringList 1") << QVariant::fromValue(QStringList() << "one") << 1;
+ QTest::newRow("QStringList 4") << QVariant::fromValue(QStringList() << "one" << "two" << "three" << "four") << 4;
+}
+
+void tst_QQuickTableView::countDelegateItems()
+{
+ // Assign different models of various sizes, and check that the number of
+ // delegate items in the view matches the size of the model. Note that for
+ // this test to be valid, all items must be within the visible area of the view.
+ QFETCH(QVariant, model);
+ QFETCH(int, count);
+ LOAD_TABLEVIEW("plaintableview.qml");
+
+ tableView->setModel(model);
+ WAIT_UNTIL_POLISHED;
+
+ // Check that tableview internals contain the expected number of items
+ auto const items = tableViewPrivate->loadedItems;
+ QCOMPARE(items.count(), count);
+
+ // Check that this also matches the items found in the view
+ auto foundItems = findItems<QQuickItem>(tableView, kDelegateObjectName);
+ QCOMPARE(foundItems.count(), count);
+}
+
+void tst_QQuickTableView::checkLayoutOfEqualSizedDelegateItems_data()
+{
+ QTest::addColumn<QVariant>("model");
+ QTest::addColumn<QSize>("tableSize");
+ QTest::addColumn<QSizeF>("spacing");
+ QTest::addColumn<QMarginsF>("margins");
+
+ // Check spacing together with different table setups
+ QTest::newRow("QAIM 1x1 1,1") << TestModelAsVariant(1, 1) << QSize(1, 1) << QSizeF(1, 1) << QMarginsF(0, 0, 0, 0);
+ QTest::newRow("QAIM 5x5 0,0") << TestModelAsVariant(5, 5) << QSize(5, 5) << QSizeF(0, 0) << QMarginsF(0, 0, 0, 0);
+ QTest::newRow("QAIM 5x5 1,0") << TestModelAsVariant(5, 5) << QSize(5, 5) << QSizeF(1, 0) << QMarginsF(0, 0, 0, 0);
+ QTest::newRow("QAIM 5x5 0,1") << TestModelAsVariant(5, 5) << QSize(5, 5) << QSizeF(0, 1) << QMarginsF(0, 0, 0, 0);
+
+ // Check spacing together with margins
+ QTest::newRow("QAIM 1x1 1,1 5555") << TestModelAsVariant(1, 1) << QSize(1, 1) << QSizeF(1, 1) << QMarginsF(5, 5, 5, 5);
+ QTest::newRow("QAIM 4x4 0,0 3333") << TestModelAsVariant(4, 4) << QSize(4, 4) << QSizeF(0, 0) << QMarginsF(3, 3, 3, 3);
+ QTest::newRow("QAIM 4x4 2,2 1234") << TestModelAsVariant(4, 4) << QSize(4, 4) << QSizeF(2, 2) << QMarginsF(1, 2, 3, 4);
+
+ // Check "list" models
+ QTest::newRow("NumberModel 1x4, 0000") << QVariant::fromValue(4) << QSize(1, 4) << QSizeF(1, 1) << QMarginsF(0, 0, 0, 0);
+ QTest::newRow("QStringList 1x4, 0,0 1111") << QVariant::fromValue(QStringList() << "one" << "two" << "three" << "four")
+ << QSize(1, 4) << QSizeF(0, 0) << QMarginsF(1, 1, 1, 1);
+}
+
+void tst_QQuickTableView::checkLayoutOfEqualSizedDelegateItems()
+{
+ // Check that the geometry of the delegate items are correct
+ QFETCH(QVariant, model);
+ QFETCH(QSize, tableSize);
+ QFETCH(QSizeF, spacing);
+ QFETCH(QMarginsF, margins);
+ LOAD_TABLEVIEW("plaintableview.qml");
+
+ const qreal expectedItemWidth = 100;
+ const qreal expectedItemHeight = 50;
+ const int expectedItemCount = tableSize.width() * tableSize.height();
+
+ tableView->setModel(model);
+ tableView->setRowSpacing(spacing.height());
+ tableView->setColumnSpacing(spacing.width());
+ tableView->setLeftMargin(margins.left());
+ tableView->setTopMargin(margins.top());
+ tableView->setRightMargin(margins.right());
+ tableView->setBottomMargin(margins.bottom());
+
+ WAIT_UNTIL_POLISHED;
+
+ auto const items = tableViewPrivate->loadedItems;
+ QVERIFY(!items.isEmpty());
+
+ for (int i = 0; i < expectedItemCount; ++i) {
+ const QQuickItem *item = items[i]->item;
+ QVERIFY(item);
+ QCOMPARE(item->parentItem(), tableView->contentItem());
+
+ const QPoint cell = getContextRowAndColumn(item);
+ qreal expectedX = margins.left() + (cell.x() * (expectedItemWidth + spacing.width()));
+ qreal expectedY = margins.top() + (cell.y() * (expectedItemHeight + spacing.height()));
+ QCOMPARE(item->x(), expectedX);
+ QCOMPARE(item->y(), expectedY);
+ QCOMPARE(item->width(), expectedItemWidth);
+ QCOMPARE(item->height(), expectedItemHeight);
+ }
+}
+
+void tst_QQuickTableView::checkTableMargins_data()
+{
+ QTest::addColumn<QVariant>("model");
+ QTest::addColumn<QSize>("tableSize");
+ QTest::addColumn<QSizeF>("spacing");
+ QTest::addColumn<QMarginsF>("margins");
+
+ QTest::newRow("QAIM 1x1 1,1 0000") << TestModelAsVariant(1, 1) << QSize(1, 1) << QSizeF(1, 1) << QMarginsF(0, 0, 0, 0);
+ QTest::newRow("QAIM 4x4 1,1 0000") << TestModelAsVariant(4, 4) << QSize(4, 4) << QSizeF(1, 1) << QMarginsF(0, 0, 0, 0);
+ QTest::newRow("QAIM 1x1 1,1 5555") << TestModelAsVariant(1, 1) << QSize(1, 1) << QSizeF(1, 1) << QMarginsF(5, 5, 5, 5);
+ QTest::newRow("QAIM 4x4 0,0 3333") << TestModelAsVariant(4, 4) << QSize(4, 4) << QSizeF(0, 0) << QMarginsF(3, 3, 3, 3);
+ QTest::newRow("QAIM 4x4 2,2 1234") << TestModelAsVariant(4, 4) << QSize(4, 4) << QSizeF(2, 2) << QMarginsF(1, 2, 3, 4);
+ QTest::newRow("QAIM 1x1 0,0 3210") << TestModelAsVariant(1, 1) << QSize(1, 1) << QSizeF(0, 0) << QMarginsF(3, 2, 1, 0);
+}
+
+void tst_QQuickTableView::checkTableMargins()
+{
+ // Check that the space between the content view and
+ // the items matches the margins we set on the tableview.
+ QFETCH(QVariant, model);
+ QFETCH(QSize, tableSize);
+ QFETCH(QSizeF, spacing);
+ QFETCH(QMarginsF, margins);
+ LOAD_TABLEVIEW("plaintableview.qml");
+
+ tableView->setModel(model);
+ tableView->setRowSpacing(spacing.height());
+ tableView->setColumnSpacing(spacing.width());
+ tableView->setLeftMargin(margins.left());
+ tableView->setTopMargin(margins.top());
+ tableView->setRightMargin(margins.right());
+ tableView->setBottomMargin(margins.bottom());
+
+ WAIT_UNTIL_POLISHED;
+
+ QCOMPARE(tableViewPrivate->loadedTable.size(), tableSize);
+
+ auto const topLeftFxItem = tableViewPrivate->loadedTableItem(QPoint(0, 0));
+ auto const bottomRightFxItem = tableViewPrivate->loadedTableItem(tableViewPrivate->loadedTable.bottomRight());
+ auto const topLeftItem = topLeftFxItem->item;
+ auto const bottomRightItem = bottomRightFxItem->item;
+
+ qreal leftSpace = topLeftItem->x();
+ qreal topSpace = topLeftItem->y();
+ qreal rightSpace = tableView->contentWidth() - (bottomRightItem->x() + bottomRightItem->width());
+ qreal bottomSpace = tableView->contentHeight() - (bottomRightItem->y() + bottomRightItem->height());
+ QCOMPARE(leftSpace, margins.left());
+ QCOMPARE(topSpace, margins.top());
+ QCOMPARE(rightSpace, margins.right());
+ QCOMPARE(bottomSpace, margins.bottom());
+}
+
+void tst_QQuickTableView::fillTableViewButNothingMore_data()
+{
+ QTest::addColumn<QSizeF>("spacing");
+ QTest::addColumn<QMarginsF>("margins");
+
+ QTest::newRow("0 0,0 0") << QSizeF(0, 0) << QMarginsF(0, 0, 0, 0);
+ QTest::newRow("0 10,10 0") << QSizeF(10, 10) << QMarginsF(0, 0, 0, 0);
+ QTest::newRow("100 10,10 0") << QSizeF(10, 10) << QMarginsF(0, 0, 0, 0);
+ QTest::newRow("0 0,0 100") << QSizeF(0, 0) << QMarginsF(0, 0, 0, 0);
+ QTest::newRow("0 10,10 100") << QSizeF(10, 10) << QMarginsF(100, 100, 100, 100);
+ QTest::newRow("100 10,10 100") << QSizeF(10, 10) << QMarginsF(100, 100, 100, 100);
+}
+
+void tst_QQuickTableView::fillTableViewButNothingMore()
+{
+ // Check that we end up filling the whole visible part of
+ // the tableview with cells, but nothing more.
+ QFETCH(QSizeF, spacing);
+ QFETCH(QMarginsF, margins);
+ LOAD_TABLEVIEW("plaintableview.qml");
+
+ const int rows = 100;
+ const int columns = 100;
+ auto model = TestModelAsVariant(rows, columns);
+
+ tableView->setModel(model);
+ tableView->setRowSpacing(spacing.height());
+ tableView->setColumnSpacing(spacing.width());
+ tableView->setLeftMargin(margins.left());
+ tableView->setTopMargin(margins.top());
+ tableView->setRightMargin(margins.right());
+ tableView->setBottomMargin(margins.bottom());
+ tableView->setCacheBuffer(0);
+
+ WAIT_UNTIL_POLISHED;
+
+ auto const topLeftFxItem = tableViewPrivate->loadedTableItem(QPoint(0, 0));
+ auto const topLeftItem = topLeftFxItem->item;
+
+ // Check that the top-left item are at the corner of the view
+ QCOMPARE(topLeftItem->x(), margins.left());
+ QCOMPARE(topLeftItem->y(), margins.top());
+
+ auto const bottomRightFxItem = tableViewPrivate->loadedTableItem(tableViewPrivate->loadedTable.bottomRight());
+ auto const bottomRightItem = bottomRightFxItem->item;
+ const QPoint bottomRightCell = getContextRowAndColumn(bottomRightItem.data());
+
+ // Check that the right-most item is overlapping the right edge of the view
+ QVERIFY(bottomRightItem->x() < tableView->width());
+ QVERIFY(bottomRightItem->x() + bottomRightItem->width() >= tableView->width() - spacing.width());
+
+ // Check that the actual number of columns matches what we expect
+ qreal cellWidth = bottomRightItem->width() + spacing.width();
+ qreal availableWidth = tableView->width() - margins.left();
+ int expectedColumns = qCeil(availableWidth / cellWidth);
+ int actualColumns = bottomRightCell.x() + 1;
+ QCOMPARE(actualColumns, expectedColumns);
+
+ // Check that the bottom-most item is overlapping the bottom edge of the view
+ QVERIFY(bottomRightItem->y() < tableView->height());
+ QVERIFY(bottomRightItem->y() + bottomRightItem->height() >= tableView->height() - spacing.height());
+
+ // Check that the actual number of rows matches what we expect
+ qreal cellHeight = bottomRightItem->height() + spacing.height();
+ qreal availableHeight = tableView->height() - margins.top();
+ int expectedRows = qCeil(availableHeight / cellHeight);
+ int actualRows = bottomRightCell.y() + 1;
+ QCOMPARE(actualRows, expectedRows);
+}
+
+void tst_QQuickTableView::checkInitialAttachedProperties_data()
+{
+ QTest::addColumn<QVariant>("model");
+
+ QTest::newRow("QAIM") << TestModelAsVariant(4, 4);
+ QTest::newRow("Number model") << QVariant::fromValue(4);
+ QTest::newRow("QStringList") << QVariant::fromValue(QStringList() << "0" << "1" << "2" << "3");
+}
+
+void tst_QQuickTableView::checkInitialAttachedProperties()
+{
+ // Check that the context and attached properties inside
+ // the delegate items are what we expect at start-up.
+ QFETCH(QVariant, model);
+ LOAD_TABLEVIEW("plaintableview.qml");
+
+ tableView->setModel(model);
+
+ WAIT_UNTIL_POLISHED;
+
+ for (auto fxItem : tableViewPrivate->loadedItems) {
+ const int index = fxItem->index;
+ const auto item = fxItem->item;
+ const auto context = qmlContext(item.data());
+ const QPoint cell = tableViewPrivate->cellAtModelIndex(index);
+ const int contextIndex = context->contextProperty("index").toInt();
+ const QPoint contextCell = getContextRowAndColumn(item.data());
+ const QString contextModelData = context->contextProperty("modelData").toString();
+ const QQmlDelegateModelAttached *delegateModelAttached =
+ static_cast<QQmlDelegateModelAttached *>(
+ qmlAttachedPropertiesObject<QQmlDelegateModel>(item));
+ const int contextItemsIndex = delegateModelAttached->property("itemsIndex").toInt();
+
+ QCOMPARE(contextCell.y(), cell.y());
+ QCOMPARE(contextCell.x(), cell.x());
+ QCOMPARE(contextIndex, index);
+ QCOMPARE(contextModelData, QStringLiteral("%1").arg(cell.y()));
+ QCOMPARE(contextItemsIndex, index);
+ }
+}
+
+void tst_QQuickTableView::flick_data()
+{
+ QTest::addColumn<QSizeF>("spacing");
+ QTest::addColumn<QMarginsF>("margins");
+
+ QTest::newRow("s:0 m:0") << QSizeF(0, 0) << QMarginsF(0, 0, 0, 0);
+ QTest::newRow("s:5 m:0") << QSizeF(5, 5) << QMarginsF(0, 0, 0, 0);
+ QTest::newRow("s:0 m:20") << QSizeF(0, 0) << QMarginsF(20, 20, 20, 20);
+ QTest::newRow("s:5 m:20") << QSizeF(5, 5) << QMarginsF(20, 20, 20, 20);
+}
+
+void tst_QQuickTableView::flick()
+{
+ // Check that if we end up with the correct start and end column/row as we flick around
+ // with different table configurations.
+ QFETCH(QSizeF, spacing);
+ QFETCH(QMarginsF, margins);
+ LOAD_TABLEVIEW("plaintableview.qml");
+
+ const qreal delegateWidth = 100;
+ const qreal delegateHeight = 50;
+ const int visualColumnCount = 4;
+ const int visualRowCount = 4;
+ const qreal cellWidth = delegateWidth + spacing.width();
+ const qreal cellHeight = delegateHeight + spacing.height();
+ auto model = TestModelAsVariant(100, 100);
+
+ tableView->setModel(model);
+ tableView->setRowSpacing(spacing.height());
+ tableView->setColumnSpacing(spacing.width());
+ tableView->setLeftMargin(margins.left());
+ tableView->setTopMargin(margins.top());
+ tableView->setRightMargin(margins.right());
+ tableView->setBottomMargin(margins.bottom());
+ tableView->setCacheBuffer(0);
+ tableView->setWidth(margins.left() + (visualColumnCount * cellWidth) - spacing.width());
+ tableView->setHeight(margins.top() + (visualRowCount * cellHeight) - spacing.height());
+
+ WAIT_UNTIL_POLISHED;
+
+ // Check the "simple" case if the cells never lands egde-to-edge with the viewport. For
+ // that case we only accept that visible row/columns are loaded.
+ qreal flickValues[] = {0.5, 1.5, 4.5, 20.5, 10.5, 3.5, 1.5, 0.5};
+
+ for (qreal cellsToFlick : flickValues) {
+ // Flick to the beginning of the cell
+ tableView->setContentX(cellsToFlick * cellWidth);
+ tableView->setContentY(cellsToFlick * cellHeight);
+ tableView->polish();
+
+ WAIT_UNTIL_POLISHED;
+
+ const QRect loadedTable = tableViewPrivate->loadedTable;
+
+ const int expectedTableLeft = cellsToFlick - int((margins.left() + spacing.width()) / cellWidth);
+ const int expectedTableTop = cellsToFlick - int((margins.top() + spacing.height()) / cellHeight);
+
+ QCOMPARE(loadedTable.left(), expectedTableLeft);
+ QCOMPARE(loadedTable.right(), expectedTableLeft + visualColumnCount);
+ QCOMPARE(loadedTable.top(), expectedTableTop);
+ QCOMPARE(loadedTable.bottom(), expectedTableTop + visualRowCount);
+ }
+}
+
+void tst_QQuickTableView::flickOvershoot_data()
+{
+ QTest::addColumn<QSizeF>("spacing");
+ QTest::addColumn<QMarginsF>("margins");
+
+ QTest::newRow("s:0 m:0") << QSizeF(0, 0) << QMarginsF(0, 0, 0, 0);
+ QTest::newRow("s:5 m:0") << QSizeF(5, 5) << QMarginsF(0, 0, 0, 0);
+ QTest::newRow("s:0 m:20") << QSizeF(0, 0) << QMarginsF(20, 20, 20, 20);
+ QTest::newRow("s:5 m:20") << QSizeF(5, 5) << QMarginsF(20, 20, 20, 20);
+}
+
+void tst_QQuickTableView::flickOvershoot()
+{
+ // Flick the table completely out and then in again, and see
+ // that we still contains the expected rows/columns
+ // Note that TableView always keeps top-left item loaded, even
+ // when everything is flicked out of view.
+ QFETCH(QSizeF, spacing);
+ QFETCH(QMarginsF, margins);
+ LOAD_TABLEVIEW("plaintableview.qml");
+
+ const int rowCount = 5;
+ const int columnCount = 5;
+ const qreal delegateWidth = 100;
+ const qreal delegateHeight = 50;
+ const qreal cellWidth = delegateWidth + spacing.width();
+ const qreal cellHeight = delegateHeight + spacing.height();
+ const qreal tableWidth = margins.left() + margins.right() + (cellWidth * columnCount) - spacing.width();
+ const qreal tableHeight = margins.top() + margins.bottom() + (cellHeight * rowCount) - spacing.height();
+ const int outsideMargin = 10;
+ auto model = TestModelAsVariant(rowCount, columnCount);
+
+ tableView->setModel(model);
+ tableView->setRowSpacing(spacing.height());
+ tableView->setColumnSpacing(spacing.width());
+ tableView->setLeftMargin(margins.left());
+ tableView->setTopMargin(margins.top());
+ tableView->setRightMargin(margins.right());
+ tableView->setBottomMargin(margins.bottom());
+ tableView->setCacheBuffer(0);
+ tableView->setWidth(tableWidth - margins.right() - cellWidth / 2);
+ tableView->setHeight(tableHeight - margins.bottom() - cellHeight / 2);
+
+ WAIT_UNTIL_POLISHED;
+
+ // Flick table out of view left
+ tableView->setContentX(-tableView->width() - outsideMargin);
+ tableView->setContentY(0);
+ tableView->polish();
+
+ WAIT_UNTIL_POLISHED;
+
+ QCOMPARE(tableViewPrivate->loadedTable.left(), 0);
+ QCOMPARE(tableViewPrivate->loadedTable.right(), 0);
+ QCOMPARE(tableViewPrivate->loadedTable.top(), 0);
+ QCOMPARE(tableViewPrivate->loadedTable.bottom(), rowCount - 1);
+
+ // Flick table out of view right
+ tableView->setContentX(tableWidth + outsideMargin);
+ tableView->setContentY(0);
+ tableView->polish();
+
+ WAIT_UNTIL_POLISHED;
+
+ QCOMPARE(tableViewPrivate->loadedTable.left(), columnCount - 1);
+ QCOMPARE(tableViewPrivate->loadedTable.right(), columnCount - 1);
+ QCOMPARE(tableViewPrivate->loadedTable.top(), 0);
+ QCOMPARE(tableViewPrivate->loadedTable.bottom(), rowCount - 1);
+
+ // Flick table out of view on top
+ tableView->setContentX(0);
+ tableView->setContentY(-tableView->height() - outsideMargin);
+ tableView->polish();
+
+ WAIT_UNTIL_POLISHED;
+
+ QCOMPARE(tableViewPrivate->loadedTable.left(), 0);
+ QCOMPARE(tableViewPrivate->loadedTable.right(), columnCount - 1);
+ QCOMPARE(tableViewPrivate->loadedTable.top(), 0);
+ QCOMPARE(tableViewPrivate->loadedTable.bottom(), 0);
+
+ // Flick table out of view at the bottom
+ tableView->setContentX(0);
+ tableView->setContentY(tableHeight + outsideMargin);
+ tableView->polish();
+
+ WAIT_UNTIL_POLISHED;
+
+ QCOMPARE(tableViewPrivate->loadedTable.left(), 0);
+ QCOMPARE(tableViewPrivate->loadedTable.right(), columnCount - 1);
+ QCOMPARE(tableViewPrivate->loadedTable.top(), rowCount - 1);
+ QCOMPARE(tableViewPrivate->loadedTable.bottom(), rowCount - 1);
+
+ // Flick table out of view left and top at the same time
+ tableView->setContentX(-tableView->width() - outsideMargin);
+ tableView->setContentY(-tableView->height() - outsideMargin);
+ tableView->polish();
+
+ WAIT_UNTIL_POLISHED;
+
+ QCOMPARE(tableViewPrivate->loadedTable.left(), 0);
+ QCOMPARE(tableViewPrivate->loadedTable.right(), 0);
+ QCOMPARE(tableViewPrivate->loadedTable.top(), 0);
+ QCOMPARE(tableViewPrivate->loadedTable.bottom(), 0);
+
+ // Flick table back to origo
+ tableView->setContentX(0);
+ tableView->setContentY(0);
+ tableView->polish();
+
+ WAIT_UNTIL_POLISHED;
+
+ QCOMPARE(tableViewPrivate->loadedTable.left(), 0);
+ QCOMPARE(tableViewPrivate->loadedTable.right(), columnCount - 1);
+ QCOMPARE(tableViewPrivate->loadedTable.top(), 0);
+ QCOMPARE(tableViewPrivate->loadedTable.bottom(), rowCount - 1);
+
+ // Flick table out of view right and bottom at the same time
+ tableView->setContentX(tableWidth + outsideMargin);
+ tableView->setContentY(tableHeight + outsideMargin);
+ tableView->polish();
+
+ WAIT_UNTIL_POLISHED;
+
+ QCOMPARE(tableViewPrivate->loadedTable.left(), columnCount - 1);
+ QCOMPARE(tableViewPrivate->loadedTable.right(), columnCount - 1);
+ QCOMPARE(tableViewPrivate->loadedTable.top(), rowCount - 1);
+ QCOMPARE(tableViewPrivate->loadedTable.bottom(), rowCount - 1);
+
+ // Flick table back to origo
+ tableView->setContentX(0);
+ tableView->setContentY(0);
+ tableView->polish();
+
+ WAIT_UNTIL_POLISHED;
+
+ QCOMPARE(tableViewPrivate->loadedTable.left(), 0);
+ QCOMPARE(tableViewPrivate->loadedTable.right(), columnCount - 1);
+ QCOMPARE(tableViewPrivate->loadedTable.top(), 0);
+ QCOMPARE(tableViewPrivate->loadedTable.bottom(), rowCount - 1);
+}
+
+void tst_QQuickTableView::checkRowColumnCount()
+{
+ // If we flick several columns (rows) at the same time, check that we don't
+ // end up with loading more delegate items into memory than necessary. We
+ // should free up columns as we go before loading new ones.
+ LOAD_TABLEVIEW("countingtableview.qml");
+
+ const char *maxDelegateCountProp = "maxDelegateCount";
+ auto model = TestModelAsVariant(100, 100);
+
+ tableView->setModel(model);
+
+ WAIT_UNTIL_POLISHED;
+
+ const int tableViewCount = tableViewPrivate->loadedItems.count();
+ const int qmlCountAfterInit = view->rootObject()->property(maxDelegateCountProp).toInt();
+ QCOMPARE(tableViewCount, qmlCountAfterInit);
+
+ // Flick a long distance right
+ tableView->setContentX(tableView->width() * 2);
+ tableView->polish();
+
+ WAIT_UNTIL_POLISHED;
+
+ const int qmlCountAfterRightFlick = view->rootObject()->property(maxDelegateCountProp).toInt();
+ QCOMPARE(qmlCountAfterRightFlick, qmlCountAfterInit);
+
+ // Flick a long distance down
+ tableView->setContentX(tableView->height() * 2);
+ tableView->polish();
+
+ WAIT_UNTIL_POLISHED;
+
+ const int qmlCountAfterDownFlick = view->rootObject()->property(maxDelegateCountProp).toInt();
+ QCOMPARE(qmlCountAfterDownFlick, qmlCountAfterInit);
+
+ // Flick a long distance left
+ tableView->setContentX(0);
+ tableView->polish();
+
+ WAIT_UNTIL_POLISHED;
+
+ const int qmlCountAfterLeftFlick = view->rootObject()->property(maxDelegateCountProp).toInt();
+ QCOMPARE(qmlCountAfterLeftFlick, qmlCountAfterInit);
+
+ // Flick a long distance up
+ tableView->setContentY(0);
+ tableView->polish();
+
+ WAIT_UNTIL_POLISHED;
+
+ const int qmlCountAfterUpFlick = view->rootObject()->property(maxDelegateCountProp).toInt();
+ QCOMPARE(qmlCountAfterUpFlick, qmlCountAfterInit);
+}
+
+QTEST_MAIN(tst_QQuickTableView)
+
+#include "tst_qquicktableview.moc"
diff --git a/tests/auto/quick/qquicktext/data/implicitSizeChangeRewrap.qml b/tests/auto/quick/qquicktext/data/implicitSizeChangeRewrap.qml
new file mode 100644
index 0000000000..fb8626a75a
--- /dev/null
+++ b/tests/auto/quick/qquicktext/data/implicitSizeChangeRewrap.qml
@@ -0,0 +1,27 @@
+import QtQuick 2.0
+import QtQuick.Layouts 1.0
+
+Item
+{
+ id : _rootItem
+ width : 200
+ height : 1000
+ ColumnLayout
+ {
+ id : _textContainer
+ anchors.centerIn: parent
+ Layout.maximumWidth: (_rootItem.width - 40) // to have some space left / right
+ Text
+ {
+ id : text
+ objectName: "text"
+ font.italic: true
+ textFormat: Text.RichText
+ horizontalAlignment : Text.AlignHCenter
+ verticalAlignment : Text.AlignVCenter
+ wrapMode: Text.Wrap
+ Layout.maximumWidth: (_rootItem.width - 60)
+ Component.onCompleted: text.text = "This is a too long text for the interface with a stupid path also too long -> /home/long/long/long/to/force/it/to/need/to/wrap This is a too long text for the interface with a stupid path also too long -> /home/long/long/long/to/force/it/to/need/to/wrap This is a too long text for the interface with a stupid path also too long -> /home/long/long/long/to/force/it/to/need/to/wrap This is a too long text for the interface with a stupid path also too long -> /home/long/long/long/to/force/it/to/need/to/wrap"
+ }
+ }
+}
diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
index 89d2590c03..48069ab8c5 100644
--- a/tests/auto/quick/qquicktext/tst_qquicktext.cpp
+++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
@@ -105,6 +105,7 @@ private slots:
void implicitSize_data();
void implicitSize();
+ void implicitSizeChangeRewrap();
void dependentImplicitSizes();
void contentSize();
void implicitSizeBinding_data();
@@ -999,11 +1000,14 @@ static inline QByteArray msgNotLessThan(int n1, int n2)
void tst_qquicktext::hAlignImplicitWidth()
{
+#ifdef Q_OS_MACOS
+ QSKIP("this test currently crashes on MacOS. See QTBUG-68047");
+#endif
QQuickView view(testFileUrl("hAlignImplicitWidth.qml"));
view.setFlags(view.flags() | Qt::WindowStaysOnTopHint); // Prevent being obscured by other windows.
view.show();
view.requestActivate();
- QVERIFY(QTest::qWaitForWindowActive(&view));
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QQuickText *text = view.rootObject()->findChild<QQuickText*>("textItem");
QVERIFY(text != nullptr);
@@ -4369,6 +4373,23 @@ void tst_qquicktext::fontInfo()
QVERIFY(copy->font().pixelSize() < 1000);
}
+void tst_qquicktext::implicitSizeChangeRewrap()
+{
+ QScopedPointer<QQuickView> window(new QQuickView);
+ window->setSource(testFileUrl("implicitSizeChangeRewrap.qml"));
+ QTRY_COMPARE(window->status(), QQuickView::Ready);
+
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
+
+ QObject *root = window->rootObject();
+
+ QQuickText *text = root->findChild<QQuickText *>("text");
+ QVERIFY(text != nullptr);
+
+ QVERIFY(text->contentWidth() < window->width());
+}
+
QTEST_MAIN(tst_qquicktext)
#include "tst_qquicktext.moc"
diff --git a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
index 65c9c9e8ad..ed2d535fda 100644
--- a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
+++ b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
@@ -1990,9 +1990,6 @@ void tst_qquicktextinput::validators()
QCOMPARE(intInput->hasAcceptableInput(), false);
QCOMPARE(intInput->property("acceptable").toBool(), false);
QCOMPARE(intSpy.count(), 0);
- QTest::keyPress(&window, Qt::Key_2);
- QTest::keyRelease(&window, Qt::Key_2, Qt::NoModifier);
- QTRY_COMPARE(intInput->text(), QLatin1String("1"));
QCOMPARE(intInput->hasAcceptableInput(), false);
QCOMPARE(intInput->property("acceptable").toBool(), false);
QCOMPARE(intSpy.count(), 0);
@@ -5989,7 +5986,7 @@ void tst_qquicktextinput::QTBUG_19956_regexp()
{
QUrl url = testFileUrl("qtbug-19956regexp.qml");
- QString warning = url.toString() + ":11:17: Unable to assign [undefined] to QRegExp";
+ QString warning = url.toString() + ":11:9: Unable to assign [undefined] to QRegExp";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
QQuickView window(url);
diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
index 44cd1dd656..381da76fa3 100644
--- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
+++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
@@ -631,9 +631,10 @@ void tst_qquickwindow::touchEvent_basic()
topItem->setSize(QSizeF(150, 150));
QPointF pos(10, 10);
+ QTest::QTouchEventSequence touchSeq = QTest::touchEvent(window, touchDevice, false);
// press single point
- QTest::touchEvent(window, touchDevice).press(0, topItem->mapToScene(pos).toPoint(),window);
+ touchSeq.press(0, topItem->mapToScene(pos).toPoint(),window).commit();
QQuickTouchUtils::flush(window);
QTRY_COMPARE(topItem->lastEvent.touchPoints.count(), 1);
@@ -643,11 +644,11 @@ void tst_qquickwindow::touchEvent_basic()
// would put the decorated window at that position rather than the window itself.
COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchBegin, window, Qt::TouchPointPressed, makeTouchPoint(topItem, pos)));
topItem->reset();
- QTest::touchEvent(window, touchDevice).release(0, topItem->mapToScene(pos).toPoint(), window);
+ touchSeq.release(0, topItem->mapToScene(pos).toPoint(), window).commit();
// press multiple points
- QTest::touchEvent(window, touchDevice).press(0, topItem->mapToScene(pos).toPoint(), window)
- .press(1, bottomItem->mapToScene(pos).toPoint(), window);
+ touchSeq.press(0, topItem->mapToScene(pos).toPoint(), window)
+ .press(1, bottomItem->mapToScene(pos).toPoint(), window).commit();
QQuickTouchUtils::flush(window);
QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
@@ -656,35 +657,35 @@ void tst_qquickwindow::touchEvent_basic()
COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchBegin, window, Qt::TouchPointPressed, makeTouchPoint(bottomItem, pos)));
topItem->reset();
bottomItem->reset();
- QTest::touchEvent(window, touchDevice).release(0, topItem->mapToScene(pos).toPoint(), window).release(1, bottomItem->mapToScene(pos).toPoint(), window);
+ touchSeq.release(0, topItem->mapToScene(pos).toPoint(), window).release(1, bottomItem->mapToScene(pos).toPoint(), window).commit();
// touch point on top item moves to bottom item, but top item should still receive the event
- QTest::touchEvent(window, touchDevice).press(0, topItem->mapToScene(pos).toPoint(), window);
+ touchSeq.press(0, topItem->mapToScene(pos).toPoint(), window).commit();
QQuickTouchUtils::flush(window);
- QTest::touchEvent(window, touchDevice).move(0, bottomItem->mapToScene(pos).toPoint(), window);
+ touchSeq.move(0, bottomItem->mapToScene(pos).toPoint(), window).commit();
QQuickTouchUtils::flush(window);
QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchUpdate, window, Qt::TouchPointMoved,
makeTouchPoint(topItem, topItem->mapFromItem(bottomItem, pos), pos)));
topItem->reset();
- QTest::touchEvent(window, touchDevice).release(0, bottomItem->mapToScene(pos).toPoint(), window);
+ touchSeq.release(0, bottomItem->mapToScene(pos).toPoint(), window).commit();
// touch point on bottom item moves to top item, but bottom item should still receive the event
- QTest::touchEvent(window, touchDevice).press(0, bottomItem->mapToScene(pos).toPoint(), window);
+ touchSeq.press(0, bottomItem->mapToScene(pos).toPoint(), window).commit();
QQuickTouchUtils::flush(window);
- QTest::touchEvent(window, touchDevice).move(0, topItem->mapToScene(pos).toPoint(), window);
+ touchSeq.move(0, topItem->mapToScene(pos).toPoint(), window).commit();
QQuickTouchUtils::flush(window);
QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1);
COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchUpdate, window, Qt::TouchPointMoved,
makeTouchPoint(bottomItem, bottomItem->mapFromItem(topItem, pos), pos)));
bottomItem->reset();
- QTest::touchEvent(window, touchDevice).release(0, bottomItem->mapToScene(pos).toPoint(), window);
+ touchSeq.release(0, bottomItem->mapToScene(pos).toPoint(), window).commit();
// a single stationary press on an item shouldn't cause an event
- QTest::touchEvent(window, touchDevice).press(0, topItem->mapToScene(pos).toPoint(), window);
+ touchSeq.press(0, topItem->mapToScene(pos).toPoint(), window).commit();
QQuickTouchUtils::flush(window);
- QTest::touchEvent(window, touchDevice).stationary(0)
- .press(1, bottomItem->mapToScene(pos).toPoint(), window);
+ touchSeq.stationary(0)
+ .press(1, bottomItem->mapToScene(pos).toPoint(), window).commit();
QQuickTouchUtils::flush(window);
QCOMPARE(topItem->lastEvent.touchPoints.count(), 1); // received press only, not stationary
QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
@@ -696,13 +697,13 @@ void tst_qquickwindow::touchEvent_basic()
// cleanup: what is pressed must be released
// Otherwise you will get an assertion failure:
// ASSERT: "itemForTouchPointId.isEmpty()" in file items/qquickwindow.cpp
- QTest::touchEvent(window, touchDevice).release(0, pos.toPoint(), window).release(1, pos.toPoint(), window);
+ touchSeq.release(0, pos.toPoint(), window).release(1, pos.toPoint(), window).commit();
QQuickTouchUtils::flush(window);
// move touch point from top item to bottom, and release
- QTest::touchEvent(window, touchDevice).press(0, topItem->mapToScene(pos).toPoint(),window);
+ touchSeq.press(0, topItem->mapToScene(pos).toPoint(),window).commit();
QQuickTouchUtils::flush(window);
- QTest::touchEvent(window, touchDevice).release(0, bottomItem->mapToScene(pos).toPoint(),window);
+ touchSeq.release(0, bottomItem->mapToScene(pos).toPoint(),window).commit();
QQuickTouchUtils::flush(window);
QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchEnd, window, Qt::TouchPointReleased,
@@ -710,13 +711,13 @@ void tst_qquickwindow::touchEvent_basic()
topItem->reset();
// release while another point is pressed
- QTest::touchEvent(window, touchDevice).press(0, topItem->mapToScene(pos).toPoint(),window)
- .press(1, bottomItem->mapToScene(pos).toPoint(), window);
+ touchSeq.press(0, topItem->mapToScene(pos).toPoint(),window)
+ .press(1, bottomItem->mapToScene(pos).toPoint(), window).commit();
QQuickTouchUtils::flush(window);
- QTest::touchEvent(window, touchDevice).move(0, bottomItem->mapToScene(pos).toPoint(), window);
+ touchSeq.move(0, bottomItem->mapToScene(pos).toPoint(), window).commit();
QQuickTouchUtils::flush(window);
- QTest::touchEvent(window, touchDevice).release(0, bottomItem->mapToScene(pos).toPoint(), window)
- .stationary(1);
+ touchSeq.release(0, bottomItem->mapToScene(pos).toPoint(), window)
+ .stationary(1).commit();
QQuickTouchUtils::flush(window);
QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
diff --git a/tests/auto/quick/qquickxmllistmodel/tst_qquickxmllistmodel.cpp b/tests/auto/quick/qquickxmllistmodel/tst_qquickxmllistmodel.cpp
index 757cb8f513..bcff0c46fb 100644
--- a/tests/auto/quick/qquickxmllistmodel/tst_qquickxmllistmodel.cpp
+++ b/tests/auto/quick/qquickxmllistmodel/tst_qquickxmllistmodel.cpp
@@ -354,7 +354,7 @@ void tst_qquickxmllistmodel::xml()
QSignalSpy spy(model, SIGNAL(statusChanged(QQuickXmlListModel::Status)));
QVERIFY(errorString(model).isEmpty());
- QCOMPARE(model->property("progress").toDouble(), qreal(0.0));
+ QCOMPARE(model->property("progress").toDouble(), qreal(1.0));
QCOMPARE(qvariant_cast<QQuickXmlListModel::Status>(model->property("status")),
QQuickXmlListModel::Loading);
QTRY_COMPARE(spy.count(), 1); spy.clear();
@@ -410,6 +410,13 @@ void tst_qquickxmllistmodel::headers()
QTRY_COMPARE(qvariant_cast<QQuickXmlListModel::Status>(model->property("status")),
QQuickXmlListModel::Ready);
+ // It doesn't do a network request for a local file
+ QCOMPARE(factory.lastSentHeaders.count(), 0);
+
+ model->setProperty("source", QUrl("http://localhost/filethatdoesnotexist.xml"));
+ QTRY_COMPARE(qvariant_cast<QQuickXmlListModel::Status>(model->property("status")),
+ QQuickXmlListModel::Error);
+
QVariantMap expectedHeaders;
expectedHeaders["Accept"] = "application/xml,*/*";
@@ -433,7 +440,7 @@ void tst_qquickxmllistmodel::source()
QSignalSpy spy(model, SIGNAL(statusChanged(QQuickXmlListModel::Status)));
QVERIFY(errorString(model).isEmpty());
- QCOMPARE(model->property("progress").toDouble(), qreal(0.0));
+ QCOMPARE(model->property("progress").toDouble(), qreal(1.0));
QCOMPARE(qvariant_cast<QQuickXmlListModel::Status>(model->property("status")),
QQuickXmlListModel::Loading);
QTRY_COMPARE(spy.count(), 1); spy.clear();
@@ -447,7 +454,7 @@ void tst_qquickxmllistmodel::source()
if (model->property("source").toString().isEmpty())
QCOMPARE(qvariant_cast<QQuickXmlListModel::Status>(model->property("status")),
QQuickXmlListModel::Null);
- QCOMPARE(model->property("progress").toDouble(), qreal(0.0));
+ QCOMPARE(model->property("progress").toDouble(), qreal(source.isLocalFile() ? 1.0 : 0.0));
QTRY_COMPARE(spy.count(), 1); spy.clear();
QCOMPARE(qvariant_cast<QQuickXmlListModel::Status>(model->property("status")),
QQuickXmlListModel::Loading);
diff --git a/tests/auto/quick/quick.pro b/tests/auto/quick/quick.pro
index a54a707f4a..a4b6076a34 100644
--- a/tests/auto/quick/quick.pro
+++ b/tests/auto/quick/quick.pro
@@ -66,6 +66,7 @@ QUICKTESTS += \
qquickitem2 \
qquickitemlayer \
qquicklistview \
+ qquicktableview \
qquickloader \
qquickmousearea \
qquickmultipointtoucharea \
@@ -93,7 +94,7 @@ QUICKTESTS += \
SUBDIRS += $$PUBLICTESTS
# Following tests are too slow on qemu + software backend
-boot2qt: QUICKTESTS -= qquickgridview qquicklistview qquickpositioners
+boot2qt: QUICKTESTS -= qquickgridview qquicklistview qquicktableview qquickpositioners
!qtConfig(accessibility):QUICKTESTS -= qquickaccessible
diff --git a/tests/auto/quick/shared/viewtestutil.cpp b/tests/auto/quick/shared/viewtestutil.cpp
index dc813b9d59..3bfa23173e 100644
--- a/tests/auto/quick/shared/viewtestutil.cpp
+++ b/tests/auto/quick/shared/viewtestutil.cpp
@@ -153,6 +153,12 @@ int QQuickViewTestUtil::QaimModel::rowCount(const QModelIndex &parent) const
return list.count();
}
+int QQuickViewTestUtil::QaimModel::columnCount(const QModelIndex &parent) const
+{
+ Q_UNUSED(parent);
+ return columns;
+}
+
QHash<int,QByteArray> QQuickViewTestUtil::QaimModel::roleNames() const
{
QHash<int,QByteArray> roles = QAbstractListModel::roleNames();
@@ -174,7 +180,7 @@ QVariant QQuickViewTestUtil::QaimModel::data(const QModelIndex &index, int role)
int QQuickViewTestUtil::QaimModel::count() const
{
- return rowCount();
+ return rowCount() * columnCount();
}
QString QQuickViewTestUtil::QaimModel::name(int index) const
diff --git a/tests/auto/quick/shared/viewtestutil.h b/tests/auto/quick/shared/viewtestutil.h
index b11d5e4859..04e1771ef8 100644
--- a/tests/auto/quick/shared/viewtestutil.h
+++ b/tests/auto/quick/shared/viewtestutil.h
@@ -76,6 +76,7 @@ namespace QQuickViewTestUtil
QaimModel(QObject *parent=0);
int rowCount(const QModelIndex &parent=QModelIndex()) const;
+ int columnCount(const QModelIndex &parent=QModelIndex()) const;
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const;
QHash<int,QByteArray> roleNames() const;
@@ -104,6 +105,8 @@ namespace QQuickViewTestUtil
using QAbstractListModel::dataChanged;
+ int columns = 1;
+
private:
QList<QPair<QString,QString> > list;
};
diff --git a/tests/auto/quick/touchmouse/tst_touchmouse.cpp b/tests/auto/quick/touchmouse/tst_touchmouse.cpp
index a69cd5bc34..2fc56c2ad8 100644
--- a/tests/auto/quick/touchmouse/tst_touchmouse.cpp
+++ b/tests/auto/quick/touchmouse/tst_touchmouse.cpp
@@ -824,6 +824,7 @@ void tst_TouchMouse::buttonOnTouch()
EventItem *eventItem4 = window->rootObject()->findChild<EventItem*>("eventItem4");
QVERIFY(eventItem4);
+ QTest::QTouchEventSequence touchSeq = QTest::touchEvent(window.data(), device, false);
// Test the common case of a mouse area on top of pinch
eventItem1->setAcceptedMouseButtons(Qt::LeftButton);
@@ -835,9 +836,9 @@ void tst_TouchMouse::buttonOnTouch()
// Normal touch click
QPoint p1 = QPoint(10, 110);
- QTest::touchEvent(window.data(), device).press(0, p1, window.data());
+ touchSeq.press(0, p1, window.data()).commit();
QQuickTouchUtils::flush(window.data());
- QTest::touchEvent(window.data(), device).release(0, p1, window.data());
+ touchSeq.release(0, p1, window.data()).commit();
QQuickTouchUtils::flush(window.data());
QCOMPARE(eventItem1->eventList.size(), 5);
QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
@@ -860,9 +861,9 @@ void tst_TouchMouse::buttonOnTouch()
QPoint p2 = QPoint(60, 10);
// Start the events after each other
- QTest::touchEvent(window.data(), device).press(0, p1, window.data());
+ touchSeq.press(0, p1, window.data()).commit();
QQuickTouchUtils::flush(window.data());
- QTest::touchEvent(window.data(), device).stationary(0).press(1, p2, window.data());
+ touchSeq.stationary(0).press(1, p2, window.data()).commit();
QQuickTouchUtils::flush(window.data());
QCOMPARE(button1->scale(), 1.0);
@@ -870,24 +871,24 @@ void tst_TouchMouse::buttonOnTouch()
// This event seems to be discarded, let's ignore it for now until someone digs into pincharea
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
- QTest::touchEvent(window.data(), device).move(0, p1, window.data()).move(1, p2, window.data());
+ touchSeq.move(0, p1, window.data()).move(1, p2, window.data()).commit();
QQuickTouchUtils::flush(window.data());
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
- QTest::touchEvent(window.data(), device).move(0, p1, window.data()).move(1, p2, window.data());
+ touchSeq.move(0, p1, window.data()).move(1, p2, window.data()).commit();
QQuickTouchUtils::flush(window.data());
// QCOMPARE(button1->scale(), 1.5);
qDebug() << "Button scale: " << button1->scale();
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
- QTest::touchEvent(window.data(), device).move(0, p1, window.data()).move(1, p2, window.data());
+ touchSeq.move(0, p1, window.data()).move(1, p2, window.data()).commit();
QQuickTouchUtils::flush(window.data());
// QCOMPARE(button1->scale(), 2.0);
qDebug() << "Button scale: " << button1->scale();
- QTest::touchEvent(window.data(), device).release(0, p1, window.data()).release(1, p2, window.data());
+ touchSeq.release(0, p1, window.data()).release(1, p2, window.data()).commit();
QQuickTouchUtils::flush(window.data());
// QVERIFY(eventItem1->eventList.isEmpty());
// QCOMPARE(button1->scale(), 2.0);
@@ -901,7 +902,7 @@ void tst_TouchMouse::buttonOnTouch()
button1->setScale(1.0);
p1 = QPoint(40, 110);
p2 = QPoint(60, 110);
- QTest::touchEvent(window.data(), device).press(0, p1, window.data()).press(1, p2, window.data());
+ touchSeq.press(0, p1, window.data()).press(1, p2, window.data()).commit();
QQuickTouchUtils::flush(window.data());
QCOMPARE(button1->scale(), 1.0);
QCOMPARE(eventItem1->eventList.count(), 2);
@@ -911,24 +912,24 @@ void tst_TouchMouse::buttonOnTouch()
// This event seems to be discarded, let's ignore it for now until someone digs into pincharea
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
- QTest::touchEvent(window.data(), device).move(0, p1, window.data()).move(1, p2, window.data());
+ touchSeq.move(0, p1, window.data()).move(1, p2, window.data()).commit();
QQuickTouchUtils::flush(window.data());
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
- QTest::touchEvent(window.data(), device).move(0, p1, window.data()).move(1, p2, window.data());
+ touchSeq.move(0, p1, window.data()).move(1, p2, window.data()).commit();
QQuickTouchUtils::flush(window.data());
//QCOMPARE(button1->scale(), 1.5);
qDebug() << button1->scale();
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
- QTest::touchEvent(window.data(), device).move(0, p1, window.data()).move(1, p2, window.data());
+ touchSeq.move(0, p1, window.data()).move(1, p2, window.data()).commit();
QQuickTouchUtils::flush(window.data());
qDebug() << button1->scale();
//QCOMPARE(button1->scale(), 2.0);
- QTest::touchEvent(window.data(), device).release(0, p1, window.data()).release(1, p2, window.data());
+ touchSeq.release(0, p1, window.data()).release(1, p2, window.data()).commit();
QQuickTouchUtils::flush(window.data());
// QCOMPARE(eventItem1->eventList.size(), 99);
qDebug() << button1->scale();
@@ -1334,6 +1335,7 @@ void tst_TouchMouse::touchPointDeliveryOrder()
QPoint pLeftMiddle = QPoint(200, 100);
QPoint pRightMiddle = QPoint(350, 100);
+ QTest::QTouchEventSequence touchSeq = QTest::touchEvent(window.data(), device, false);
QVector<QQuickItem*> events;
EventItem *background = window->rootObject()->findChild<EventItem*>("background");
@@ -1349,7 +1351,7 @@ void tst_TouchMouse::touchPointDeliveryOrder()
connect(middle, &EventItem::onTouchEvent, [&events](QQuickItem* receiver){ events.append(receiver); });
connect(right, &EventItem::onTouchEvent, [&events](QQuickItem* receiver){ events.append(receiver); });
- QTest::touchEvent(window.data(), device).press(0, pLeft, window.data());
+ touchSeq.press(0, pLeft, window.data()).commit();
QQuickTouchUtils::flush(window.data());
// Touch on left, then background
@@ -1359,7 +1361,7 @@ void tst_TouchMouse::touchPointDeliveryOrder()
events.clear();
// New press events are deliverd first, the stationary point was not accepted, thus it doesn't get delivered
- QTest::touchEvent(window.data(), device).stationary(0).press(1, pRightMiddle, window.data());
+ touchSeq.stationary(0).press(1, pRightMiddle, window.data()).commit();
QQuickTouchUtils::flush(window.data());
QCOMPARE(events.size(), 3);
QCOMPARE(events.at(0), middle);
@@ -1367,49 +1369,49 @@ void tst_TouchMouse::touchPointDeliveryOrder()
QCOMPARE(events.at(2), background);
events.clear();
- QTest::touchEvent(window.data(), device).release(0, pLeft, window.data()).release(1, pRightMiddle, window.data());
+ touchSeq.release(0, pLeft, window.data()).release(1, pRightMiddle, window.data()).commit();
QQuickTouchUtils::flush(window.data());
QCOMPARE(events.size(), 0); // no accepted events
// Two presses, the first point should come first
- QTest::touchEvent(window.data(), device).press(0, pLeft, window.data()).press(1, pRight, window.data());
+ touchSeq.press(0, pLeft, window.data()).press(1, pRight, window.data()).commit();
QQuickTouchUtils::flush(window.data());
QCOMPARE(events.size(), 3);
QCOMPARE(events.at(0), left);
QCOMPARE(events.at(1), right);
QCOMPARE(events.at(2), background);
- QTest::touchEvent(window.data(), device).release(0, pLeft, window.data()).release(1, pRight, window.data());
+ touchSeq.release(0, pLeft, window.data()).release(1, pRight, window.data()).commit();
events.clear();
// Again, pressing right first
- QTest::touchEvent(window.data(), device).press(0, pRight, window.data()).press(1, pLeft, window.data());
+ touchSeq.press(0, pRight, window.data()).press(1, pLeft, window.data()).commit();
QQuickTouchUtils::flush(window.data());
QCOMPARE(events.size(), 3);
QCOMPARE(events.at(0), right);
QCOMPARE(events.at(1), left);
QCOMPARE(events.at(2), background);
- QTest::touchEvent(window.data(), device).release(0, pRight, window.data()).release(1, pLeft, window.data());
+ touchSeq.release(0, pRight, window.data()).release(1, pLeft, window.data()).commit();
events.clear();
// Two presses, both hitting the middle item on top, then branching left and right, then bottom
// Each target should be offered the events exactly once, middle first, left must come before right (id 0)
- QTest::touchEvent(window.data(), device).press(0, pLeftMiddle, window.data()).press(1, pRightMiddle, window.data());
+ touchSeq.press(0, pLeftMiddle, window.data()).press(1, pRightMiddle, window.data()).commit();
QCOMPARE(events.size(), 4);
QCOMPARE(events.at(0), middle);
QCOMPARE(events.at(1), left);
QCOMPARE(events.at(2), right);
QCOMPARE(events.at(3), background);
- QTest::touchEvent(window.data(), device).release(0, pLeftMiddle, window.data()).release(1, pRightMiddle, window.data());
+ touchSeq.release(0, pLeftMiddle, window.data()).release(1, pRightMiddle, window.data()).commit();
events.clear();
- QTest::touchEvent(window.data(), device).press(0, pRightMiddle, window.data()).press(1, pLeftMiddle, window.data());
+ touchSeq.press(0, pRightMiddle, window.data()).press(1, pLeftMiddle, window.data()).commit();
qDebug() << events;
QCOMPARE(events.size(), 4);
QCOMPARE(events.at(0), middle);
QCOMPARE(events.at(1), right);
QCOMPARE(events.at(2), left);
QCOMPARE(events.at(3), background);
- QTest::touchEvent(window.data(), device).release(0, pRightMiddle, window.data()).release(1, pLeftMiddle, window.data());
+ touchSeq.release(0, pRightMiddle, window.data()).release(1, pLeftMiddle, window.data()).commit();
}
void tst_TouchMouse::hoverEnabled()