aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto
diff options
context:
space:
mode:
authorTarja Sundqvist <[email protected]>2024-11-22 10:46:11 +0200
committerTarja Sundqvist <[email protected]>2024-11-22 10:46:11 +0200
commit64364dbe06b46e5f355c3b2a6684a3eae4f54a7a (patch)
treeb501b88601bbda604da2adac9307c47b6d3733b2 /tests/auto
parent6b64e58767c6dd32a29a261e3327fa88b5613621 (diff)
parent4d94cd012575956a7633fc19d87059f7a8e0dda2 (diff)
Merge tag 'v6.2.11-lts' into tqtc/lts-6.2-opensource
Qt 6.2.11-lts release Conflicts solved: dependencies.yaml Change-Id: I088fe99748b323fbdf49c3766c262eb2a05131d9
Diffstat (limited to 'tests/auto')
-rw-r--r--tests/auto/qml/debugger/qv4debugger/data/breakPointInJSModule.qml4
-rw-r--r--tests/auto/qml/debugger/qv4debugger/data/module1.js5
-rw-r--r--tests/auto/qml/debugger/qv4debugger/data/module2.mjs7
-rw-r--r--tests/auto/qml/debugger/qv4debugger/data/module3.mjs0
-rw-r--r--tests/auto/qml/debugger/qv4debugger/data/module4.mjs0
-rw-r--r--tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp45
-rw-r--r--tests/auto/qml/qjsengine/tst_qjsengine.cpp8
-rw-r--r--tests/auto/qml/qmlcachegen/data/truncateTest.qml764
-rw-r--r--tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp19
-rw-r--r--tests/auto/qml/qqmlecmascript/data/methodCallOnDerivedSingleton.qml6
-rw-r--r--tests/auto/qml/qqmlecmascript/testtypes.cpp2
-rw-r--r--tests/auto/qml/qqmlecmascript/testtypes.h36
-rw-r--r--tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp16
-rw-r--r--tests/auto/qml/qqmlengine/data/bindingInstallUseAfterFree.qml19
-rw-r--r--tests/auto/qml/qqmlengine/tst_qqmlengine.cpp10
-rw-r--r--tests/auto/qml/qqmllanguage/data/DeepAliasOnIC.qml28
-rw-r--r--tests/auto/qml/qqmllanguage/data/TypeAnnotationCycle1.qml15
-rw-r--r--tests/auto/qml/qqmllanguage/data/TypeAnnotationCycle2.qml6
-rw-r--r--tests/auto/qml/qqmllanguage/data/deepAliasOnICUser.qml9
-rw-r--r--tests/auto/qml/qqmllanguage/data/deepAliasOnReadonly.qml5
-rw-r--r--tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp42
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/data/pinchOnFlickableWithParentTapHandler.qml24
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp118
-rw-r--r--tests/auto/quick/qquickmultipointtoucharea/data/nestedPinchArea.qml44
-rw-r--r--tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp44
-rw-r--r--tests/auto/quick/qquicktableview/data/deletedDelegate.qml25
-rw-r--r--tests/auto/quick/qquicktableview/data/resetJsModelData.qml19
-rw-r--r--tests/auto/quick/qquicktableview/tst_qquicktableview.cpp54
-rw-r--r--tests/auto/quickcontrols2/qquickmenu/data/scrollableWithFixedHeight.qml27
-rw-r--r--tests/auto/quickcontrols2/qquickmenu/tst_qquickmenu.cpp1
-rw-r--r--tests/auto/quickcontrols2/sanity/tst_sanity.cpp24
31 files changed, 1394 insertions, 32 deletions
diff --git a/tests/auto/qml/debugger/qv4debugger/data/breakPointInJSModule.qml b/tests/auto/qml/debugger/qv4debugger/data/breakPointInJSModule.qml
new file mode 100644
index 0000000000..2582a23ec5
--- /dev/null
+++ b/tests/auto/qml/debugger/qv4debugger/data/breakPointInJSModule.qml
@@ -0,0 +1,4 @@
+import QtQml 2.15
+import "module1.js" as Module1
+
+QtObject {}
diff --git a/tests/auto/qml/debugger/qv4debugger/data/module1.js b/tests/auto/qml/debugger/qv4debugger/data/module1.js
new file mode 100644
index 0000000000..9ce1f1e6b1
--- /dev/null
+++ b/tests/auto/qml/debugger/qv4debugger/data/module1.js
@@ -0,0 +1,5 @@
+.pragma library
+
+.import "module2.mjs" as Module2
+
+Module2.crashMe();
diff --git a/tests/auto/qml/debugger/qv4debugger/data/module2.mjs b/tests/auto/qml/debugger/qv4debugger/data/module2.mjs
new file mode 100644
index 0000000000..80f82af953
--- /dev/null
+++ b/tests/auto/qml/debugger/qv4debugger/data/module2.mjs
@@ -0,0 +1,7 @@
+import * as Module3 from "module3.mjs"
+import * as Module4 from "module4.mjs"
+
+export function crashMe()
+{
+ console.log("Hello world!");
+}
diff --git a/tests/auto/qml/debugger/qv4debugger/data/module3.mjs b/tests/auto/qml/debugger/qv4debugger/data/module3.mjs
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/qml/debugger/qv4debugger/data/module3.mjs
diff --git a/tests/auto/qml/debugger/qv4debugger/data/module4.mjs b/tests/auto/qml/debugger/qv4debugger/data/module4.mjs
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/qml/debugger/qv4debugger/data/module4.mjs
diff --git a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp
index b9b2fd6b69..331d978dd7 100644
--- a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp
+++ b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp
@@ -241,10 +241,14 @@ public:
QJsonArray scopes = frameObj.value(QLatin1String("scopes")).toArray();
int nscopes = scopes.size();
int s = 0;
- for (s = 0; s < nscopes; ++s) {
- QJsonObject o = scopes.at(s).toObject();
- if (o.value(QLatin1String("type")).toInt(-2) == 1) // CallContext
- break;
+ if (m_targetScope != -1) {
+ s = m_targetScope;
+ } else {
+ for (s = 0; s < nscopes; ++s) {
+ QJsonObject o = scopes.at(s).toObject();
+ if (o.value(QLatin1String("type")).toInt(-2) == 1) // CallContext
+ break;
+ }
}
if (s == nscopes)
return;
@@ -274,6 +278,7 @@ public:
bool m_wasPaused;
QV4Debugger::PauseReason m_pauseReason;
bool m_captureContextInfo;
+ int m_targetScope = -1;
QList<QV4Debugger::ExecutionState> m_statesWhenPaused;
QList<TestBreakPoint> m_breakPointsToAddWhenPaused;
QVector<QV4::StackFrame> m_stackTrace;
@@ -347,6 +352,9 @@ private slots:
void readThis();
void signalParameters();
void debuggerNoCrash();
+
+ void breakPointInJSModule();
+
private:
QV4Debugger *debugger() const
{
@@ -992,6 +1000,35 @@ void tst_qv4debugger::debuggerNoCrash()
debugThread->wait();
}
+void tst_qv4debugger::breakPointInJSModule()
+{
+ QQmlEngine engine;
+ QV4::ExecutionEngine *v4 = engine.handle();
+ QPointer<QV4Debugger> v4Debugger = new QV4Debugger(v4);
+ v4->setDebugger(v4Debugger.data());
+
+ QScopedPointer<QThread> debugThread(new QThread);
+ debugThread->start();
+ QScopedPointer<TestAgent> debuggerAgent(new TestAgent(v4));
+ debuggerAgent->addDebugger(v4Debugger);
+ debuggerAgent->moveToThread(debugThread.data());
+
+ QQmlComponent component(&engine, testFileUrl("breakPointInJSModule.qml"));
+ QVERIFY2(component.isReady(), qPrintable(component.errorString()));
+
+ debuggerAgent->m_captureContextInfo = true;
+ debuggerAgent->m_targetScope = 1;
+ v4Debugger->addBreakPoint("module2.mjs", 6);
+
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+
+ QVERIFY(!debuggerAgent->m_capturedScope.isEmpty());
+
+ debugThread->quit();
+ debugThread->wait();
+}
+
tst_qv4debugger::tst_qv4debugger() : QQmlDataTest(QT_QMLTEST_DATADIR) { }
QTEST_MAIN(tst_qv4debugger)
diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
index 81ac086294..7883ca721d 100644
--- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp
+++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
@@ -43,6 +43,7 @@
#include <QScopeGuard>
#include <QUrl>
#include <QModelIndex>
+#include <QtQml/qqmllist.h>
#ifdef Q_CC_MSVC
#define NO_INLINE __declspec(noinline)
@@ -1658,6 +1659,13 @@ void tst_QJSEngine::valueConversion_basic()
QCOMPARE(eng.fromScriptValue<QChar>(eng.toScriptValue(c)), c);
}
+ {
+ QList<QObject *> list = {this};
+ QQmlListProperty<QObject> prop(this, &list);
+ QJSValue jsVal = eng.toScriptValue(prop);
+ QCOMPARE(eng.fromScriptValue<QQmlListProperty<QObject>>(jsVal), prop);
+ }
+
QVERIFY(eng.toScriptValue(static_cast<void *>(nullptr)).isNull());
}
diff --git a/tests/auto/qml/qmlcachegen/data/truncateTest.qml b/tests/auto/qml/qmlcachegen/data/truncateTest.qml
new file mode 100644
index 0000000000..fee768cf77
--- /dev/null
+++ b/tests/auto/qml/qmlcachegen/data/truncateTest.qml
@@ -0,0 +1,764 @@
+import QtQuick 2.15
+import QtQuick.Layouts 2.15
+
+Item {
+ width: 400
+ height: 400
+
+ component Button : Item {
+ property string text
+ property Item background
+ }
+
+ ColumnLayout {
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ Button {
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: "red"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+
+ }
+}
diff --git a/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp b/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp
index a2639bc532..f235bbe557 100644
--- a/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp
+++ b/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp
@@ -86,6 +86,8 @@ private slots:
void inlineComponent();
void posthocRequired();
+ void gracefullyHandleTruncatedCacheFile();
+
void scriptStringCachegenInteraction();
void saveableUnitPointer();
};
@@ -782,6 +784,23 @@ void tst_qmlcachegen::posthocRequired()
QVERIFY(component.errorString().contains(QStringLiteral("Required property x was not initialized")));
}
+void tst_qmlcachegen::gracefullyHandleTruncatedCacheFile()
+{
+#if defined(QTEST_CROSS_COMPILED)
+ QSKIP("Cannot call qmlcachegen on cross-compiled target.");
+#endif
+
+ bool ok = generateCache(testFile("truncateTest.qml"));
+ QVERIFY(ok);
+ const QString qmlcFile = testFile("truncateTest.qmlc");
+ QVERIFY(QFile::exists(qmlcFile));
+ QFile::resize(qmlcFile, QFileInfo(qmlcFile).size() / 2);
+ QQmlEngine engine;
+ CleanlyLoadingComponent component(&engine, testFileUrl("truncateTest.qml"));
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+}
+
void tst_qmlcachegen::scriptStringCachegenInteraction()
{
#if defined(QTEST_CROSS_COMPILED)
diff --git a/tests/auto/qml/qqmlecmascript/data/methodCallOnDerivedSingleton.qml b/tests/auto/qml/qqmlecmascript/data/methodCallOnDerivedSingleton.qml
new file mode 100644
index 0000000000..9d2ee433fd
--- /dev/null
+++ b/tests/auto/qml/qqmlecmascript/data/methodCallOnDerivedSingleton.qml
@@ -0,0 +1,6 @@
+import Qt.test
+import QtQml
+
+QtObject {
+ Component.onCompleted: SingletonInheritanceTest.trackPage("test", {x: 42})
+}
diff --git a/tests/auto/qml/qqmlecmascript/testtypes.cpp b/tests/auto/qml/qqmlecmascript/testtypes.cpp
index cd83702d3a..803e09a2e9 100644
--- a/tests/auto/qml/qqmlecmascript/testtypes.cpp
+++ b/tests/auto/qml/qqmlecmascript/testtypes.cpp
@@ -561,6 +561,8 @@ void registerTypes()
qmlRegisterType<Receiver>("Qt.test", 1,0, "Receiver");
qmlRegisterType<Sender>("Qt.test", 1,0, "Sender");
qmlRegisterTypesAndRevisions<ReadOnlyBindable>("Qt.test", 1);
+
+ qmlRegisterTypesAndRevisions<SingletonRegistrationWrapper>("Qt.test", 1);
}
#include "testtypes.moc"
diff --git a/tests/auto/qml/qqmlecmascript/testtypes.h b/tests/auto/qml/qqmlecmascript/testtypes.h
index a3df73972e..622d7c44c8 100644
--- a/tests/auto/qml/qqmlecmascript/testtypes.h
+++ b/tests/auto/qml/qqmlecmascript/testtypes.h
@@ -1892,6 +1892,42 @@ public:
QBindable<int> bindableX() const { return &_xProp; }
};
+class SingletonBase : public QObject {
+ Q_OBJECT
+
+public:
+ Q_INVOKABLE virtual void trackPage(const QString&) {}
+ Q_INVOKABLE virtual void trackPage(const QString&, const QVariantMap&) {}
+
+ bool m_okay = false;
+};
+
+class SingletonImpl : public SingletonBase {
+ Q_OBJECT
+
+public:
+ Q_INVOKABLE virtual void trackPage(const QString&) override {}
+ Q_INVOKABLE virtual void trackPage(const QString&, const QVariantMap&) override
+ {
+ m_okay = true;
+ }
+};
+
+class SingletonRegistrationWrapper {
+ Q_GADGET
+ QML_FOREIGN(SingletonBase)
+ QML_NAMED_ELEMENT(SingletonInheritanceTest)
+ QML_SINGLETON
+
+public:
+ static SingletonBase* create(QQmlEngine*, QJSEngine*) {
+ return new SingletonImpl();
+ }
+
+private:
+ SingletonRegistrationWrapper() = default;
+};
+
void registerTypes();
#endif // TESTTYPES_H
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
index e976ec46a3..c30c4de825 100644
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
@@ -437,6 +437,8 @@ private slots:
void doNotCrashOnReadOnlyBindable();
+
+ void methodCallOnDerivedSingleton();
private:
// static void propertyVarWeakRefCallback(v8::Persistent<v8::Value> object, void* parameter);
static void verifyContextLifetime(const QQmlRefPointer<QQmlContextData> &ctxt);
@@ -10146,6 +10148,20 @@ void tst_qqmlecmascript::doNotCrashOnReadOnlyBindable()
QCOMPARE(o->property("x").toInt(), 7);
}
+
+void tst_qqmlecmascript::methodCallOnDerivedSingleton()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFile("methodCallOnDerivedSingleton.qml"));
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+ QScopedPointer<QObject> o(c.create());
+ QVERIFY(o);
+ int singletonTypeId = qmlTypeId("Qt.test", 1, 0, "SingletonInheritanceTest");
+ auto singleton = engine.singletonInstance<SingletonBase *>(singletonTypeId);
+ QVERIFY(singleton);
+ QVERIFY(singleton->m_okay);
+}
+
QTEST_MAIN(tst_qqmlecmascript)
#include "tst_qqmlecmascript.moc"
diff --git a/tests/auto/qml/qqmlengine/data/bindingInstallUseAfterFree.qml b/tests/auto/qml/qqmlengine/data/bindingInstallUseAfterFree.qml
new file mode 100644
index 0000000000..596ab10ee7
--- /dev/null
+++ b/tests/auto/qml/qqmlengine/data/bindingInstallUseAfterFree.qml
@@ -0,0 +1,19 @@
+import QtQuick
+
+Item {
+ visible: false
+
+ property int test: 1
+
+ Component {
+ id: comp
+ Item {
+ width: { width = test * 100 }
+ }
+ }
+
+ Loader {
+ sourceComponent: comp
+ width: 100
+ }
+}
diff --git a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
index d2ec48ffb4..953bce9603 100644
--- a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
+++ b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
@@ -92,6 +92,7 @@ private slots:
void attachedObjectAsObject();
void listPropertyAsQJSValue();
void stringToColor();
+ void bindingInstallUseAfterFree();
public slots:
QObject *createAQObjectForOwnershipTest ()
@@ -1436,6 +1437,15 @@ void tst_qqmlengine::stringToColor()
QCOMPARE(color, variant);
}
+void tst_qqmlengine::bindingInstallUseAfterFree()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("bindingInstallUseAfterFree.qml"));
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+ std::unique_ptr<QObject> o{ c.create() };
+ QVERIFY(o);
+}
+
QTEST_MAIN(tst_qqmlengine)
#include "tst_qqmlengine.moc"
diff --git a/tests/auto/qml/qqmllanguage/data/DeepAliasOnIC.qml b/tests/auto/qml/qqmllanguage/data/DeepAliasOnIC.qml
new file mode 100644
index 0000000000..bde2ad9813
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/DeepAliasOnIC.qml
@@ -0,0 +1,28 @@
+import QtQml
+
+QtObject {
+ id: root
+ objectName: "theRoot"
+
+ component ObjectWithColor: QtObject {
+ property string color
+ property var varvar
+ }
+
+ property ObjectWithColor border: ObjectWithColor {
+ id: border
+ objectName: root.objectName
+ color: root.trueBorderColor
+ varvar: root.trueBorderVarvar
+ }
+
+ readonly property rect readonlyRect: Qt.rect(12, 13, 14, 15)
+
+ property alias borderObjectName: border.objectName
+ property alias borderColor: border.color
+ property alias borderVarvar: border.varvar
+ property alias readonlyRectX: root.readonlyRect.x
+
+ property string trueBorderColor: "green"
+ property var trueBorderVarvar: 1234
+}
diff --git a/tests/auto/qml/qqmllanguage/data/TypeAnnotationCycle1.qml b/tests/auto/qml/qqmllanguage/data/TypeAnnotationCycle1.qml
new file mode 100644
index 0000000000..6186faa00b
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/TypeAnnotationCycle1.qml
@@ -0,0 +1,15 @@
+import QtQml
+
+QtObject {
+ id: self
+ property QtObject b
+ property Component c
+ function a() : TypeAnnotationCycle2 { return c.createObject() as TypeAnnotationCycle2 }
+
+ Component.onCompleted: {
+ c = Qt.createComponent("TypeAnnotationCycle2.qml");
+ let v = a();
+ v.addTypeAnnotationCycle1(self as TypeAnnotationCycle1);
+ b = v.b;
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/TypeAnnotationCycle2.qml b/tests/auto/qml/qqmllanguage/data/TypeAnnotationCycle2.qml
new file mode 100644
index 0000000000..9e3ffa86d2
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/TypeAnnotationCycle2.qml
@@ -0,0 +1,6 @@
+import QtQml
+
+QtObject {
+ property QtObject b
+ function addTypeAnnotationCycle1(c: TypeAnnotationCycle1) { b = c; }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/deepAliasOnICUser.qml b/tests/auto/qml/qqmllanguage/data/deepAliasOnICUser.qml
new file mode 100644
index 0000000000..50eaa7c3e2
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/deepAliasOnICUser.qml
@@ -0,0 +1,9 @@
+import QtQml
+
+DeepAliasOnIC {
+ borderObjectName: "theLeaf"
+ borderColor: "black"
+ borderVarvar: "mauve"
+}
+
+
diff --git a/tests/auto/qml/qqmllanguage/data/deepAliasOnReadonly.qml b/tests/auto/qml/qqmllanguage/data/deepAliasOnReadonly.qml
new file mode 100644
index 0000000000..f5ae62406b
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/deepAliasOnReadonly.qml
@@ -0,0 +1,5 @@
+import QtQml
+
+DeepAliasOnIC {
+ readonlyRectX: 55
+}
diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
index 0d26772c6c..41fb24a76c 100644
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
@@ -390,6 +390,9 @@ private slots:
void callMethodOfAttachedDerived();
+ void typeAnnotationCycle();
+ void deepAliasOnICOrReadonly();
+
private:
QQmlEngine engine;
QStringList defaultImportPathList;
@@ -6692,6 +6695,45 @@ void tst_qqmllanguage::callMethodOfAttachedDerived()
QCOMPARE(o->property("v").toInt(), 99);
}
+void tst_qqmllanguage::typeAnnotationCycle()
+{
+ QQmlEngine engine;
+
+ const QUrl url = testFileUrl("TypeAnnotationCycle1.qml");
+ const QUrl url2 = testFileUrl("TypeAnnotationCycle2.qml");
+
+ QTest::ignoreMessage(
+ QtWarningMsg,
+ qPrintable(
+ QLatin1String("Cyclic dependency detected between \"%1\" and \"%2\"")
+ .arg(url.toString(), url2.toString())));
+
+ QQmlComponent c(&engine, url);
+ QVERIFY(!c.isReady());
+}
+
+void tst_qqmllanguage::deepAliasOnICOrReadonly()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("deepAliasOnICUser.qml"));
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+ QScopedPointer<QObject> o(c.create());
+ QVERIFY(!o.isNull());
+
+ QCOMPARE(o->property("borderColor").toString(), QLatin1String("black"));
+ QCOMPARE(o->property("borderObjectName").toString(), QLatin1String("theLeaf"));
+
+ const QVariant var = o->property("borderVarvar");
+ QCOMPARE(var.metaType(), QMetaType::fromType<QString>());
+ QCOMPARE(var.toString(), QLatin1String("mauve"));
+
+ QQmlComponent c2(&engine, testFileUrl("deepAliasOnReadonly.qml"));
+ QVERIFY(c2.isError());
+ QVERIFY(c2.errorString().contains(
+ QLatin1String(
+ "Invalid property assignment: \"readonlyRectX\" is a read-only property")));
+}
+
QTEST_MAIN(tst_qqmllanguage)
#include "tst_qqmllanguage.moc"
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/pinchOnFlickableWithParentTapHandler.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/pinchOnFlickableWithParentTapHandler.qml
new file mode 100644
index 0000000000..2660952f16
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/pinchOnFlickableWithParentTapHandler.qml
@@ -0,0 +1,24 @@
+import QtQuick
+
+Rectangle {
+ width: 320
+ height: 320
+
+ TapHandler {
+ onTapped: color = "tomato"
+ }
+
+ Flickable {
+ anchors.fill: parent
+ contentWidth: content.width
+ contentHeight: content.height
+ Rectangle {
+ id: content
+ objectName: "pinchable"
+ width: 150
+ height: 150
+ color: "wheat"
+ PinchHandler {}
+ }
+ }
+}
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp b/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp
index 0bf6b3fdcc..b7f49834d1 100644
--- a/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp
@@ -36,6 +36,7 @@
#include <QtQuick/private/qquickitemview_p.h>
#include <QtQuick/private/qquickpointerhandler_p.h>
#include <QtQuick/private/qquickdraghandler_p.h>
+#include <QtQuick/private/qquickpinchhandler_p.h>
#include <QtQuick/private/qquicktaphandler_p.h>
#include <QtQuick/private/qquicktableview_p.h>
#include <qpa/qwindowsysteminterface.h>
@@ -81,10 +82,14 @@ private slots:
void touchAndDragHandlerOnFlickable_data();
void touchAndDragHandlerOnFlickable();
void pinchHandlerOnFlickable();
+ void nativeGesturePinchOnFlickableWithParentTapHandler_data();
+ void nativeGesturePinchOnFlickableWithParentTapHandler();
private:
void createView(QScopedPointer<QQuickView> &window, const char *fileName);
QPointingDevice *touchDevice;
+ QScopedPointer<QPointingDevice> touchpad = QScopedPointer<QPointingDevice>(
+ QTest::createTouchDevice(QInputDevice::DeviceType::TouchPad));
};
void tst_FlickableInterop::createView(QScopedPointer<QQuickView> &window, const char *fileName)
@@ -879,6 +884,119 @@ void tst_FlickableInterop::pinchHandlerOnFlickable()
QCOMPARE(flickMoveSpy.count(), 0); // Flickable never moved
}
+void tst_FlickableInterop::nativeGesturePinchOnFlickableWithParentTapHandler_data()
+{
+ QTest::addColumn<const QPointingDevice*>("device");
+ QTest::addColumn<Qt::MouseButton>("button");
+ QTest::addColumn<Qt::NativeGestureType>("gesture");
+ QTest::addColumn<qreal>("value");
+ QTest::addColumn<qreal>("expectedPropertyValue");
+
+ const QPointingDevice *constTouchPad = touchpad.data();
+
+ // expectedPropertyValue is 10 in newer Qt versions, but in 6.2 QQuickPinchHandler::onActiveChanged() resets the first rotation
+ QTest::newRow("touchpad: left and rotate") << constTouchPad << Qt::LeftButton << Qt::RotateNativeGesture << 5.0 << 5.0;
+ QTest::newRow("touchpad: right and rotate") << constTouchPad << Qt::RightButton << Qt::RotateNativeGesture << 5.0 << 5.0;
+
+ // whereas zoom is cumulative as expected
+ QTest::newRow("touchpad: left and scale") << constTouchPad << Qt::LeftButton << Qt::ZoomNativeGesture << 0.1 << 1.21;
+ QTest::newRow("touchpad: right and scale") << constTouchPad << Qt::RightButton << Qt::ZoomNativeGesture << 0.1 << 1.21;
+
+ const auto *mouse = QPointingDevice::primaryPointingDevice();
+ if (mouse->type() == QInputDevice::DeviceType::Mouse) {
+ QTest::newRow("mouse: left and rotate") << mouse << Qt::LeftButton << Qt::RotateNativeGesture << 5.0 << 10.0;
+ QTest::newRow("mouse: right and rotate") << mouse << Qt::RightButton << Qt::RotateNativeGesture << 5.0 << 10.0;
+ QTest::newRow("mouse: left and scale") << mouse << Qt::LeftButton << Qt::ZoomNativeGesture << 0.1 << 1.21;
+ QTest::newRow("mouse: right and scale") << mouse << Qt::RightButton << Qt::ZoomNativeGesture << 0.1 << 1.21;
+ } else {
+ qCWarning(lcPointerTests) << "skipping mouse tests: primary device is not a mouse" << mouse;
+ }
+}
+
+void tst_FlickableInterop::nativeGesturePinchOnFlickableWithParentTapHandler()
+{
+ QFETCH(const QPointingDevice*, device);
+ QFETCH(Qt::MouseButton, button);
+ QFETCH(Qt::NativeGestureType, gesture);
+ QFETCH(qreal, value);
+ QFETCH(qreal, expectedPropertyValue);
+
+ QQuickView window;
+ QVERIFY(QQuickTest::showView(window, testFileUrl("pinchOnFlickableWithParentTapHandler.qml")));
+ QQuickFlickable *flickable = window.rootObject()->findChild<QQuickFlickable*>();
+ QVERIFY(flickable);
+ QQuickPointerHandler *pinchHandler = flickable->findChild<QQuickPinchHandler*>();
+ QVERIFY(pinchHandler);
+ QQuickItem *pinchable = pinchHandler->target();
+ QVERIFY(pinchable);
+ QQuickTapHandler *tapHandler = window.rootObject()->findChild<QQuickTapHandler*>();
+ QVERIFY(tapHandler);
+ const bool expectTap = button & tapHandler->acceptedButtons();
+
+ QSignalSpy flickMoveSpy(flickable, &QQuickFlickable::movementStarted);
+ QSignalSpy grabChangedSpy(touchDevice, &QPointingDevice::grabChanged);
+ QSignalSpy tapActiveSpy(tapHandler, &QQuickTapHandler::activeChanged);
+ QSignalSpy tapSpy(tapHandler, &QQuickTapHandler::tapped);
+
+ QObject *grabber = nullptr;
+ connect(device, &QPointingDevice::grabChanged,
+ [&grabber](QObject *g, QPointingDevice::GrabTransition transition, const QPointerEvent *, const QEventPoint &) {
+ if (transition == QPointingDevice::GrabTransition::GrabExclusive)
+ grabber = g;
+ });
+
+ const QPoint pinchPos(75, 75);
+ const QPoint outsidePos(200, 200);
+
+ // move to position
+ QTest::mouseMove(&window, pinchPos);
+
+ // pinch via native gesture
+ ulong ts = 502; // after the mouse move, which is at time 501 in practice
+ QWindowSystemInterface::handleGestureEvent(&window, ts++, touchpad.get(),
+ Qt::BeginNativeGesture, pinchPos, pinchPos);
+ if (lcPointerTests().isDebugEnabled()) QTest::qWait(500);
+ for (int i = 0; i < 2; ++i) {
+ QWindowSystemInterface::handleGestureEventWithRealValue(&window, ts++, touchpad.get(),
+ gesture, value, pinchPos, pinchPos);
+ }
+ if (gesture == Qt::RotateNativeGesture)
+ QTRY_COMPARE(pinchHandler->parentItem()->rotation(), expectedPropertyValue);
+ else if (gesture == Qt::ZoomNativeGesture)
+ QTRY_COMPARE(pinchHandler->parentItem()->scale(), expectedPropertyValue);
+ QVERIFY(pinchHandler->active());
+ QCOMPARE(grabChangedSpy.count(), 0);
+ QCOMPARE(grabber, nullptr);
+ if (lcPointerTests().isDebugEnabled()) QTest::qWait(500);
+ QWindowSystemInterface::handleGestureEvent(&window, ts++, touchpad.get(),
+ Qt::EndNativeGesture, pinchPos, pinchPos);
+
+ // tap in square: TapHandler detects tap iff acceptedButtons permits
+ // TODO delay; unfortunately this also begins at timestamp 502 because we don't have testlib
+ // functions to send gesture events, and QQuickTest::pointerPress() doesn't take a delay value
+ QQuickTest::pointerPress(device, &window, 0, pinchPos, button);
+ QCOMPARE(tapHandler->point().id(), expectTap ? 0 : -1);
+ QQuickTest::pointerRelease(device, &window, 0, pinchPos, button);
+ if (lcPointerTests().isDebugEnabled()) QTest::qWait(500);
+ QCOMPARE(tapSpy.size(), expectTap);
+ QCOMPARE(tapActiveSpy.size(), 0);
+ QCOMPARE(tapHandler->point().id(), -1); // does not keep tracking after release
+
+ // move outside: nothing should happen;
+ // but QTBUG-108896 happened because TapHandler was setting pointInfo to track this moving point
+ QQuickTest::pointerMove(device, &window, 0, outsidePos);
+ QCOMPARE(tapHandler->point().id(), -1); // does not track after mouse move
+
+ // tap outside: nothing happens
+ tapSpy.clear();
+ tapActiveSpy.clear();
+ QQuickTest::pointerPress(device, &window, 0, outsidePos, button);
+ QQuickTest::pointerRelease(device, &window, 0, outsidePos, button);
+ if (lcPointerTests().isDebugEnabled()) QTest::qWait(500);
+ QCOMPARE(tapSpy.size(), 0);
+ QCOMPARE(tapActiveSpy.size(), 0);
+}
+
QTEST_MAIN(tst_FlickableInterop)
#include "tst_flickableinterop.moc"
diff --git a/tests/auto/quick/qquickmultipointtoucharea/data/nestedPinchArea.qml b/tests/auto/quick/qquickmultipointtoucharea/data/nestedPinchArea.qml
new file mode 100644
index 0000000000..0e51804b30
--- /dev/null
+++ b/tests/auto/quick/qquickmultipointtoucharea/data/nestedPinchArea.qml
@@ -0,0 +1,44 @@
+import QtQuick 2.15
+
+MultiPointTouchArea {
+ width: 240
+ height: 320
+ mouseEnabled: true
+ property int pressedCount: 0
+ property int updatedCount: 0
+ property int releasedCount: 0
+
+ onPressed: (points) => { pressedCount = points.length }
+ onUpdated: (points) => { updatedCount = points.length }
+ onReleased: (points) => { releasedCount = points.length }
+
+ touchPoints: [
+ TouchPoint {
+ id: point1
+ objectName: "point1"
+ },
+ TouchPoint {
+ id: point2
+ objectName: "point2"
+ }
+ ]
+
+ PinchArea {
+ anchors.fill: parent
+ }
+
+ Rectangle {
+ width: 30; height: 30
+ color: "green"
+ x: point1.x
+ y: point1.y
+ }
+
+ Rectangle {
+ id: rectangle
+ width: 30; height: 30
+ color: "yellow"
+ x: point2.x
+ y: point2.y
+ }
+}
diff --git a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp
index 3e6a7fce16..f85fba45d6 100644
--- a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp
+++ b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp
@@ -74,6 +74,7 @@ private slots:
void cancel();
void stationaryTouchWithChangingPressure();
void touchFiltering();
+ void nestedPinchAreaMouse();
private:
QQuickView *createAndShowView(const QString &file);
@@ -1385,6 +1386,49 @@ void tst_QQuickMultiPointTouchArea::touchFiltering() // QTBUG-74028
QCOMPARE(mptaSpy.count(), 1);
}
+void tst_QQuickMultiPointTouchArea::nestedPinchAreaMouse() // QTBUG-83662
+{
+ QScopedPointer<QQuickView> window(createAndShowView("nestedPinchArea.qml"));
+ QQuickMultiPointTouchArea *mpta = qobject_cast<QQuickMultiPointTouchArea *>(window->rootObject());
+ QVERIFY(mpta);
+ QQuickTouchPoint *point1 = mpta->findChild<QQuickTouchPoint*>("point1");
+ QCOMPARE(point1->pressed(), false);
+ QQuickTouchPoint *point2 = mpta->findChild<QQuickTouchPoint*>("point2");
+ QCOMPARE(point2->pressed(), false);
+ QSignalSpy pressedSpy(mpta, &QQuickMultiPointTouchArea::pressed);
+ QSignalSpy updatedSpy(mpta, &QQuickMultiPointTouchArea::updated);
+ QSignalSpy releasedSpy(mpta, &QQuickMultiPointTouchArea::released);
+ QPoint p1(20, 20);
+ QTest::mousePress(window.data(), Qt::LeftButton, Qt::NoModifier, p1);
+ QCOMPARE(point1->pressed(), true);
+ QCOMPARE(point2->pressed(), false);
+ QCOMPARE(pressedSpy.count(), 1);
+ QCOMPARE(mpta->property("pressedCount").toInt(), 1);
+ QCOMPARE(updatedSpy.count(), 0);
+ QCOMPARE(mpta->property("updatedCount").toInt(), 0);
+ QCOMPARE(releasedSpy.count(), 0);
+ QCOMPARE(mpta->property("releasedCount").toInt(), 0);
+ p1 += QPoint(0, 15);
+ QTest::mouseMove(window.data(), p1);
+ QCOMPARE(point1->pressed(), true);
+ QCOMPARE(point2->pressed(), false);
+ QCOMPARE(pressedSpy.count(), 1);
+ QCOMPARE(mpta->property("pressedCount").toInt(), 1);
+ QCOMPARE(updatedSpy.count(), 1);
+ QCOMPARE(mpta->property("updatedCount").toInt(), 1);
+ QCOMPARE(releasedSpy.count(), 0);
+ QCOMPARE(mpta->property("releasedCount").toInt(), 0);
+ QTest::mouseRelease(window.data(), Qt::LeftButton, Qt::NoModifier, p1);
+ QCOMPARE(point1->pressed(), false);
+ QCOMPARE(point2->pressed(), false);
+ QCOMPARE(pressedSpy.count(), 1);
+ QCOMPARE(mpta->property("pressedCount").toInt(), 1);
+ QCOMPARE(updatedSpy.count(), 1);
+ QCOMPARE(mpta->property("updatedCount").toInt(), 1);
+ QCOMPARE(releasedSpy.count(), 1);
+ QCOMPARE(mpta->property("releasedCount").toInt(), 1);
+}
+
QTEST_MAIN(tst_QQuickMultiPointTouchArea)
#include "tst_qquickmultipointtoucharea.moc"
diff --git a/tests/auto/quick/qquicktableview/data/deletedDelegate.qml b/tests/auto/quick/qquicktableview/data/deletedDelegate.qml
new file mode 100644
index 0000000000..ec3161bbac
--- /dev/null
+++ b/tests/auto/quick/qquicktableview/data/deletedDelegate.qml
@@ -0,0 +1,25 @@
+import QtQuick 2.15
+
+Item {
+ width: 800
+ height: 600
+
+ Component {
+ id: dyn
+ Item {
+ property Component comp: Item {}
+ }
+ }
+
+ TableView {
+ id: tv
+ anchors.fill: parent
+ objectName: "tableview"
+ }
+
+ Component.onCompleted: {
+ let o = dyn.createObject();
+ tv.delegate = o.comp;
+ o.destroy();
+ }
+}
diff --git a/tests/auto/quick/qquicktableview/data/resetJsModelData.qml b/tests/auto/quick/qquicktableview/data/resetJsModelData.qml
new file mode 100644
index 0000000000..def5346147
--- /dev/null
+++ b/tests/auto/quick/qquicktableview/data/resetJsModelData.qml
@@ -0,0 +1,19 @@
+import QtQuick
+
+Item {
+ width: 100
+ height: 300
+
+ property alias tableView: tableView
+
+ TableView {
+ id: tableView
+ anchors.fill: parent
+ property int modelUpdated: 0
+ onModelChanged: { ++modelUpdated }
+ delegate: Item {
+ implicitHeight: 10
+ implicitWidth: 10
+ }
+ }
+}
diff --git a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
index 97dae95fce..ec568a21e4 100644
--- a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
+++ b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
@@ -122,7 +122,7 @@ private slots:
void isColumnLoadedAndIsRowLoaded();
void checkForceLayoutFunction();
void checkForceLayoutEndUpDoingALayout();
- void checkForceLayoutDuringModelChange();
+ void checkForceLayoutInbetweenAddingRowsToModel();
void checkForceLayoutWhenAllItemsAreHidden();
void checkContentWidthAndHeight();
void checkContentWidthAndHeightForSmallTables();
@@ -213,6 +213,8 @@ private slots:
void testSelectableStartPosEndPosOutsideView();
void testSelectableScrollTowardsPos();
void resettingRolesRespected();
+ void deletedDelegate();
+ void checkRebuildJsModel();
};
tst_QQuickTableView::tst_QQuickTableView()
@@ -681,10 +683,11 @@ void tst_QQuickTableView::checkForceLayoutEndUpDoingALayout()
QCOMPARE(tableView->contentHeight(), (9 * (newDelegateSize + rowSpacing)) - rowSpacing);
}
-void tst_QQuickTableView::checkForceLayoutDuringModelChange()
+void tst_QQuickTableView::checkForceLayoutInbetweenAddingRowsToModel()
{
- // Check that TableView doesn't assert if we call
- // forceLayout() in the middle of a model change.
+ // Check that TableView doesn't assert if we call forceLayout() while waiting
+ // for a callback from the model that the row count has changed. Also make sure
+ // that we don't move the contentItem while doing so.
LOAD_TABLEVIEW("plaintableview.qml");
const int initialRowCount = 10;
@@ -699,9 +702,13 @@ void tst_QQuickTableView::checkForceLayoutDuringModelChange()
WAIT_UNTIL_POLISHED;
+ const int contentY = 10;
+ tableView->setContentY(contentY);
QCOMPARE(tableView->rows(), initialRowCount);
+ QCOMPARE(tableView->contentY(), contentY);
model.addRow(0);
QCOMPARE(tableView->rows(), initialRowCount + 1);
+ QCOMPARE(tableView->contentY(), contentY);
}
void tst_QQuickTableView::checkForceLayoutWhenAllItemsAreHidden()
@@ -3989,6 +3996,45 @@ void tst_QQuickTableView::resettingRolesRespected()
QTRY_VERIFY(tableView->property("success").toBool());
}
+void tst_QQuickTableView::deletedDelegate()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("deletedDelegate.qml"));
+ std::unique_ptr<QObject> root(component.create());
+ QVERIFY(root);
+ auto tv = root->findChild<QQuickTableView *>("tableview");
+ QVERIFY(tv);
+ // we need one event loop iteration for the deferred delete to trigger
+ // thus the QTRY_VERIFY
+ QTRY_COMPARE(tv->delegate(), nullptr);
+}
+
+void tst_QQuickTableView::checkRebuildJsModel()
+{
+ LOAD_TABLEVIEW("resetJsModelData.qml"); // gives us 'tableView' variable
+
+ // Generate javascript model
+ const int size = 5;
+ const char* modelUpdated = "modelUpdated";
+
+ QJSEngine jsEngine;
+ QJSValue jsArray;
+ jsArray = jsEngine.newArray(size);
+ for (int i = 0; i < size; ++i)
+ jsArray.setProperty(i, QRandomGenerator::global()->generate());
+
+ QVariant jsModel = QVariant::fromValue(jsArray);
+ tableView->setModel(jsModel);
+ WAIT_UNTIL_POLISHED;
+
+ // Model change would be triggered for the first time
+ QCOMPARE(tableView->property(modelUpdated).toInt(), 1);
+
+ // Set the same model once again and check if model changes
+ tableView->setModel(jsModel);
+ QCOMPARE(tableView->property(modelUpdated).toInt(), 1);
+}
+
QTEST_MAIN(tst_QQuickTableView)
#include "tst_qquicktableview.moc"
diff --git a/tests/auto/quickcontrols2/qquickmenu/data/scrollableWithFixedHeight.qml b/tests/auto/quickcontrols2/qquickmenu/data/scrollableWithFixedHeight.qml
new file mode 100644
index 0000000000..1156d30aef
--- /dev/null
+++ b/tests/auto/quickcontrols2/qquickmenu/data/scrollableWithFixedHeight.qml
@@ -0,0 +1,27 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Window
+
+Window {
+ width: 300
+ height: 300
+
+ property alias menu: menu
+
+ Menu {
+ id: menu
+ anchors.centerIn: parent
+ height: 100
+ visible: true
+ Repeater {
+ model: 10
+ delegate: MenuItem {
+ objectName: text
+ text: (index + 1)
+ }
+ }
+ }
+}
diff --git a/tests/auto/quickcontrols2/qquickmenu/tst_qquickmenu.cpp b/tests/auto/quickcontrols2/qquickmenu/tst_qquickmenu.cpp
index 0176c2db35..4b1628038d 100644
--- a/tests/auto/quickcontrols2/qquickmenu/tst_qquickmenu.cpp
+++ b/tests/auto/quickcontrols2/qquickmenu/tst_qquickmenu.cpp
@@ -1778,6 +1778,7 @@ void tst_QQuickMenu::scrollable_data()
QTest::addRow("Window") << QString::fromLatin1("windowScrollable.qml");
QTest::addRow("ApplicationWindow") << QString::fromLatin1("applicationWindowScrollable.qml");
QTest::addRow("WithPadding") << QString::fromLatin1("scrollableWithPadding.qml");
+ QTest::addRow("FixedHeight") << QString::fromLatin1("scrollableWithFixedHeight.qml");
}
void tst_QQuickMenu::scrollable()
diff --git a/tests/auto/quickcontrols2/sanity/tst_sanity.cpp b/tests/auto/quickcontrols2/sanity/tst_sanity.cpp
index c29a191cd9..dc1a4b3836 100644
--- a/tests/auto/quickcontrols2/sanity/tst_sanity.cpp
+++ b/tests/auto/quickcontrols2/sanity/tst_sanity.cpp
@@ -458,11 +458,6 @@ void tst_Sanity::attachedObjects_data()
QTest::newRow("Basic/HorizontalHeaderView.qml") << ignoredNames << StringPairSet {};
QTest::newRow("Basic/ItemDelegate.qml") << ignoredNames << StringPairSet {};
QTest::newRow("Basic/Label.qml") << ignoredNames << StringPairSet {};
- QTest::newRow("Basic/Menu.qml") << ignoredNames << StringPairSet {
- { "QQuickOverlayAttached", "Menu_QMLTYPE" },
- { "QQuickScrollIndicatorAttached", "QQuickListView" },
- { "QQuickWindowAttached", "QQuickListView" }
- };
QTest::newRow("Basic/MenuBar.qml") << ignoredNames << StringPairSet {};
QTest::newRow("Basic/MenuBarItem.qml") << ignoredNames << StringPairSet {};
QTest::newRow("Basic/MenuItem.qml") << ignoredNames << StringPairSet {};
@@ -513,11 +508,6 @@ void tst_Sanity::attachedObjects_data()
QTest::newRow("Fusion/HorizontalHeaderView.qml") << ignoredNames << StringPairSet {};
QTest::newRow("Fusion/ItemDelegate.qml") << ignoredNames << StringPairSet {};
QTest::newRow("Fusion/Label.qml") << ignoredNames << StringPairSet {};
- QTest::newRow("Fusion/Menu.qml") << ignoredNames << StringPairSet {
- { "QQuickOverlayAttached", "Menu_QMLTYPE" },
- { "QQuickScrollIndicatorAttached", "QQuickListView" },
- { "QQuickWindowAttached", "QQuickListView" }
- };
QTest::newRow("Fusion/MenuBar.qml") << ignoredNames << StringPairSet {};
QTest::newRow("Fusion/MenuBarItem.qml") << ignoredNames << StringPairSet {};
QTest::newRow("Fusion/MenuItem.qml") << ignoredNames << StringPairSet {};
@@ -573,13 +563,6 @@ void tst_Sanity::attachedObjects_data()
QTest::newRow("Material/HorizontalHeaderView.qml") << ignoredNames << StringPairSet {};
QTest::newRow("Material/ItemDelegate.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "ItemDelegate_QMLTYPE" }};
QTest::newRow("Material/Label.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "Label_QMLTYPE" }};
- QTest::newRow("Material/Menu.qml") << ignoredNames << StringPairSet {
- { "QQuickOverlayAttached", "Menu_QMLTYPE" },
- { "QQuickMaterialStyle", "Menu_QMLTYPE" },
- { "QQuickScrollIndicatorAttached", "QQuickListView" },
- { "QQuickWindowAttached", "QQuickListView" },
- { "QQuickMaterialStyle", "ScrollIndicator_QMLTYPE" }
- };
QTest::newRow("Material/MenuBar.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "MenuBar_QMLTYPE" }};
QTest::newRow("Material/MenuBarItem.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "MenuBarItem_QMLTYPE" }};
QTest::newRow("Material/MenuItem.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "MenuItem_QMLTYPE" }};
@@ -646,13 +629,6 @@ void tst_Sanity::attachedObjects_data()
QTest::newRow("Universal/HorizontalHeaderView.qml") << ignoredNames << StringPairSet {};
QTest::newRow("Universal/ItemDelegate.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "ItemDelegate_QMLTYPE" }};
QTest::newRow("Universal/Label.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "Label_QMLTYPE" }};
- QTest::newRow("Universal/Menu.qml") << ignoredNames << StringPairSet {
- { "QQuickOverlayAttached", "Menu_QMLTYPE" },
- { "QQuickUniversalStyle", "Menu_QMLTYPE" },
- { "QQuickScrollIndicatorAttached", "QQuickListView" },
- { "QQuickWindowAttached", "QQuickListView" },
- { "QQuickUniversalStyle", "ScrollIndicator_QMLTYPE" }
- };
QTest::newRow("Universal/MenuBar.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "MenuBar_QMLTYPE" }};
QTest::newRow("Universal/MenuBarItem.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "MenuBarItem_QMLTYPE" }};
QTest::newRow("Universal/MenuItem.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "MenuItem_QMLTYPE" }};