aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/particles/qquickimageparticle/tst_qquickimageparticle.cpp80
-rw-r--r--tests/auto/qml/debugger/qv4debugger/CMakeLists.txt1
-rw-r--r--tests/auto/qml/ecmascripttests/qjstest/test262runner.cpp4
-rw-r--r--tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp108
-rw-r--r--tests/auto/qml/qmlformat/data/ecmaScriptClassInQml.formatted.qml37
-rw-r--r--tests/auto/qml/qmlformat/data/ecmaScriptClassInQml.qml45
-rw-r--r--tests/auto/qml/qmlformat/tst_qmlformat.cpp3
-rw-r--r--tests/auto/qml/qmltyperegistrar/CMakeLists.txt1
-rw-r--r--tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp7
-rw-r--r--tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h12
-rw-r--r--tests/auto/qml/qqmlconnections/data/invalidTarget.qml31
-rw-r--r--tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp20
-rw-r--r--tests/auto/qml/qqmlecmascript/data/methodTypeMismatch.qml25
-rw-r--r--tests/auto/qml/qqmlecmascript/data/readOnlyBindable.qml7
-rw-r--r--tests/auto/qml/qqmlecmascript/testtypes.cpp1
-rw-r--r--tests/auto/qml/qqmlecmascript/testtypes.h45
-rw-r--r--tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp95
-rw-r--r--tests/auto/qml/qqmlfileselector/data/qmldirtest/main.qml13
-rw-r--r--tests/auto/qml/qqmlfileselector/data/qmldirtest/qml/+linux/MyButton.qml7
-rw-r--r--tests/auto/qml/qqmlfileselector/data/qmldirtest/qml/+macos/MyButton.qml7
-rw-r--r--tests/auto/qml/qqmlfileselector/data/qmldirtest/qml/MyButton.qml7
-rw-r--r--tests/auto/qml/qqmlfileselector/data/qmldirtest/qmldir5
-rw-r--r--tests/auto/qml/qqmlfileselector/tst_qqmlfileselector.cpp19
-rw-r--r--tests/auto/qml/qqmllanguage/data/MyRectangle.qml10
-rw-r--r--tests/auto/qml/qqmllanguage/data/alias.19.qml11
-rw-r--r--tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp10
-rw-r--r--tests/auto/qml/qqmllistmodel/data/protectQObjectFromGC.qml21
-rw-r--r--tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp22
-rw-r--r--tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp20
-rw-r--r--tests/auto/quick/pointerhandlers/qquicktaphandler/BLACKLIST4
-rw-r--r--tests/auto/quick/qquickcanvasitem/data/tst_arc.qml22
-rw-r--r--tests/auto/quick/qquickcanvasitem/data/tst_arcto.qml9
-rw-r--r--tests/auto/quick/qquickcanvasitem/data/tst_composite.qml7
-rw-r--r--tests/auto/quick/qquickcanvasitem/data/tst_fillStyle.qml8
-rw-r--r--tests/auto/quick/qquickcanvasitem/data/tst_fillrect.qml1
-rw-r--r--tests/auto/quick/qquickcanvasitem/data/tst_gradient.qml6
-rw-r--r--tests/auto/quick/qquickcanvasitem/data/tst_image.qml25
-rw-r--r--tests/auto/quick/qquickcanvasitem/data/tst_imagedata.qml1
-rw-r--r--tests/auto/quick/qquickcanvasitem/data/tst_line.qml9
-rw-r--r--tests/auto/quick/qquickcanvasitem/data/tst_path.qml16
-rw-r--r--tests/auto/quick/qquickcanvasitem/data/tst_pattern.qml6
-rw-r--r--tests/auto/quick/qquickcanvasitem/data/tst_pixel.qml5
-rw-r--r--tests/auto/quick/qquickcanvasitem/data/tst_shadow.qml11
-rw-r--r--tests/auto/quick/qquickcanvasitem/data/tst_state.qml16
-rw-r--r--tests/auto/quick/qquickcanvasitem/data/tst_strokeStyle.qml5
-rw-r--r--tests/auto/quick/qquickcanvasitem/data/tst_svgpath.qml1
-rw-r--r--tests/auto/quick/qquickcanvasitem/data/tst_text.qml6
-rw-r--r--tests/auto/quick/qquickcanvasitem/data/tst_transform.qml6
-rw-r--r--tests/auto/quick/qquickflickable/tst_qquickflickable.cpp8
-rw-r--r--tests/auto/quick/qquickflipable/data/flip-y-axis-flipable.qml32
-rw-r--r--tests/auto/quick/qquickflipable/tst_qquickflipable.cpp28
-rw-r--r--tests/auto/quick/qquicklistview2/data/qtbug86744.qml25
-rw-r--r--tests/auto/quick/qquicklistview2/data/qtbug98315.qml98
-rw-r--r--tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp41
-rw-r--r--tests/auto/quick/qquickloader/tst_qquickloader.cpp21
-rw-r--r--tests/auto/quickcontrols2/controls/data/tst_splitview.qml22
-rw-r--r--tests/auto/quickcontrols2/qquickdrawer/data/itemPartialOverlayModal.qml13
-rw-r--r--tests/auto/quickcontrols2/qquickdrawer/tst_qquickdrawer.cpp41
-rw-r--r--tests/auto/quickcontrols2/qquickpopup/data/mirroredCombobox.qml26
-rw-r--r--tests/auto/quickcontrols2/qquickpopup/data/rotatedCombobox.qml26
-rw-r--r--tests/auto/quickcontrols2/qquickpopup/tst_qquickpopup.cpp151
-rw-r--r--tests/auto/quickwidgets/qquickwidget/CMakeLists.txt1
-rw-r--r--tests/auto/quickwidgets/qquickwidget/data/button.qml27
-rw-r--r--tests/auto/quickwidgets/qquickwidget/data/mouse.qml2
-rw-r--r--tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp98
65 files changed, 1446 insertions, 52 deletions
diff --git a/tests/auto/particles/qquickimageparticle/tst_qquickimageparticle.cpp b/tests/auto/particles/qquickimageparticle/tst_qquickimageparticle.cpp
index 6f48cb85bd..06c0e898d3 100644
--- a/tests/auto/particles/qquickimageparticle/tst_qquickimageparticle.cpp
+++ b/tests/auto/particles/qquickimageparticle/tst_qquickimageparticle.cpp
@@ -243,46 +243,50 @@ void tst_qquickimageparticle::test_deformed()
void tst_qquickimageparticle::test_tabled()
{
- QQuickView* view = createView(testFileUrl("tabled.qml"), 600);
- QQuickParticleSystem* system = view->rootObject()->findChild<QQuickParticleSystem*>("system");
- ensureAnimTime(600, system->m_animation);
+ #if defined(Q_OS_LINUX)
+ QSKIP("Crashing on Ubuntu 22.04: QTBUG-107707");
+ #else
+ QQuickView* view = createView(testFileUrl("tabled.qml"), 600);
+ QQuickParticleSystem* system = view->rootObject()->findChild<QQuickParticleSystem*>("system");
+ ensureAnimTime(600, system->m_animation);
- QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
- for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
- if (d->t == -1)
- continue; //Particle data unused
+ QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
+ if (d->t == -1)
+ continue; //Particle data unused
- QCOMPARE(d->x, 0.f);
- QCOMPARE(d->y, 0.f);
- QCOMPARE(d->vx, 0.f);
- QCOMPARE(d->vy, 0.f);
- QCOMPARE(d->ax, 0.f);
- QCOMPARE(d->ay, 0.f);
- QCOMPARE(d->lifeSpan, 0.5f);
- QCOMPARE(d->size, 32.f);
- QCOMPARE(d->endSize, 32.f);
- QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
- QCOMPARE(d->color.r, (uchar)255);
- QCOMPARE(d->color.g, (uchar)255);
- QCOMPARE(d->color.b, (uchar)255);
- QCOMPARE(d->color.a, (uchar)255);
- QCOMPARE(d->xx, 1.0f);
- QCOMPARE(d->xy, 0.0f);
- QCOMPARE(d->yy, 1.0f);
- QCOMPARE(d->yx, 0.0f);
- QCOMPARE(d->rotation, 0.0f);
- QCOMPARE(d->rotationVelocity, 0.0f);
- QCOMPARE(d->autoRotate, (uchar)0);
- QCOMPARE(d->animX, 0.0f);
- QCOMPARE(d->animY, 0.0f);
- QCOMPARE(d->animWidth, 1.0f);
- QCOMPARE(d->animHeight, 1.0f);
- QCOMPARE(d->frameDuration, 1.0f);
- QCOMPARE(d->frameCount, 1.0f);
- QCOMPARE(d->animT, -1.0f);
- //TODO: This performance level doesn't alter particleData, but goes straight to shaders. Find something to test
- }
- delete view;
+ QCOMPARE(d->x, 0.f);
+ QCOMPARE(d->y, 0.f);
+ QCOMPARE(d->vx, 0.f);
+ QCOMPARE(d->vy, 0.f);
+ QCOMPARE(d->ax, 0.f);
+ QCOMPARE(d->ay, 0.f);
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
+ QCOMPARE(d->color.r, (uchar)255);
+ QCOMPARE(d->color.g, (uchar)255);
+ QCOMPARE(d->color.b, (uchar)255);
+ QCOMPARE(d->color.a, (uchar)255);
+ QCOMPARE(d->xx, 1.0f);
+ QCOMPARE(d->xy, 0.0f);
+ QCOMPARE(d->yy, 1.0f);
+ QCOMPARE(d->yx, 0.0f);
+ QCOMPARE(d->rotation, 0.0f);
+ QCOMPARE(d->rotationVelocity, 0.0f);
+ QCOMPARE(d->autoRotate, (uchar)0);
+ QCOMPARE(d->animX, 0.0f);
+ QCOMPARE(d->animY, 0.0f);
+ QCOMPARE(d->animWidth, 1.0f);
+ QCOMPARE(d->animHeight, 1.0f);
+ QCOMPARE(d->frameDuration, 1.0f);
+ QCOMPARE(d->frameCount, 1.0f);
+ QCOMPARE(d->animT, -1.0f);
+ //TODO: This performance level doesn't alter particleData, but goes straight to shaders. Find something to test
+ }
+ delete view;
+ #endif
}
diff --git a/tests/auto/qml/debugger/qv4debugger/CMakeLists.txt b/tests/auto/qml/debugger/qv4debugger/CMakeLists.txt
index e8fe26cb5a..92565f55c1 100644
--- a/tests/auto/qml/debugger/qv4debugger/CMakeLists.txt
+++ b/tests/auto/qml/debugger/qv4debugger/CMakeLists.txt
@@ -20,6 +20,7 @@ qt6_add_qml_module(testCppTypes
SOURCES
commontypes.h
)
+qt_autogen_tools_initial_setup(testCppTypesplugin)
qt_internal_add_test(tst_qv4debugger
SOURCES
diff --git a/tests/auto/qml/ecmascripttests/qjstest/test262runner.cpp b/tests/auto/qml/ecmascripttests/qjstest/test262runner.cpp
index 24633d9c6d..9037ed0c92 100644
--- a/tests/auto/qml/ecmascripttests/qjstest/test262runner.cpp
+++ b/tests/auto/qml/ecmascripttests/qjstest/test262runner.cpp
@@ -393,9 +393,7 @@ void Test262Runner::loadTestExpectations()
return;
}
- int line = 0;
while (!file.atEnd()) {
- ++line;
QByteArray line = file.readLine().trimmed();
if (line.startsWith('#') || line.isEmpty())
continue;
@@ -440,9 +438,7 @@ void Test262Runner::updateTestExpectations()
QTemporaryFile updatedExpectations;
updatedExpectations.open();
- int line = 0;
while (!file.atEnd()) {
- ++line;
QByteArray originalLine = file.readLine();
QByteArray line = originalLine.trimmed();
if (line.startsWith('#') || line.isEmpty()) {
diff --git a/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp
index 3f429fec22..d84aaaeba3 100644
--- a/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp
+++ b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp
@@ -65,6 +65,7 @@ private slots:
void cppRegisteredSingletonDependency();
void cacheModuleScripts();
void reuseStaticMappings();
+ void invalidateSaveLoadCache();
private:
QDir m_qmlCacheDirectory;
@@ -550,6 +551,7 @@ void tst_qmldiskcache::recompileAfterChange()
CleanlyLoadingComponent component(&engine, testCompiler.testFilePath);
QScopedPointer<TypeVersion2> obj(qobject_cast<TypeVersion2*>(component.create()));
QVERIFY(!obj.isNull());
+ qDebug() << obj->property("x");
QVERIFY(QFileInfo(testCompiler.cacheFilePath).lastModified() > initialCacheTimeStamp);
}
}
@@ -1030,6 +1032,112 @@ void tst_qmldiskcache::reuseStaticMappings()
QCOMPARE(testCompiler.unitData(), data1);
}
+class AParent : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int x MEMBER x)
+public:
+ AParent(QObject *parent = nullptr) : QObject(parent) {}
+ int x = 25;
+};
+
+class BParent : public QObject
+{
+ Q_OBJECT
+
+ // Insert y before x, to change the property index of x
+ Q_PROPERTY(int y MEMBER y)
+
+ Q_PROPERTY(int x MEMBER x)
+public:
+ BParent(QObject *parent = nullptr) : QObject(parent) {}
+ int y = 13;
+ int x = 25;
+};
+
+static QString writeTempFile(
+ const QTemporaryDir &tempDir, const QString &fileName, const char *contents) {
+ QFile f(tempDir.path() + '/' + fileName);
+ const bool ok = f.open(QIODevice::WriteOnly | QIODevice::Truncate);
+ Q_ASSERT(ok);
+ f.write(contents);
+ return f.fileName();
+};
+
+void tst_qmldiskcache::invalidateSaveLoadCache()
+{
+ qmlRegisterType<AParent>("Base", 1, 0, "Parent");
+ QQmlEngine e;
+
+ // If you store a CU to a .qmlc file at run time, the .qmlc file will contain
+ // alias entries with the encodedMetaPropertyIndex pre-resolved. That's in
+ // contrast to .qmlc files generated ahead of time. Exploit that to cause
+ // a need to recompile the file.
+
+ QTemporaryDir tempDir;
+ const QString fileName = writeTempFile(
+ tempDir, QLatin1String("a.qml"),
+ "import Base\nParent { id: self; property alias z: self.x }");
+ const QUrl url = QUrl::fromLocalFile(fileName);
+ waitForFileSystem();
+
+ {
+ QQmlComponent a(&e, url);
+ QVERIFY2(a.isReady(), qPrintable(a.errorString()));
+ QScopedPointer<QObject> ao(a.create());
+ QVERIFY(!ao.isNull());
+ AParent *ap = qobject_cast<AParent *>(ao.data());
+ QCOMPARE(ap->property("z").toInt(), ap->x);
+ }
+
+ QString errorString;
+ QQmlRefPointer<QV4::ExecutableCompilationUnit> oldUnit
+ = QV4::ExecutableCompilationUnit::create();
+ QVERIFY2(oldUnit->loadFromDisk(url, QFileInfo(fileName).lastModified(), &errorString), qPrintable(errorString));
+
+ // Produce a checksum mismatch.
+ e.clearComponentCache();
+ qmlClearTypeRegistrations();
+ qmlRegisterType<BParent>("Base", 1, 0, "Parent");
+
+ {
+ QQmlComponent b(&e, url);
+ QVERIFY2(b.isReady(), qPrintable(b.errorString()));
+ QScopedPointer<QObject> bo(b.create());
+ QVERIFY(!bo.isNull());
+ BParent *bp = qobject_cast<BParent *>(bo.data());
+ QCOMPARE(bp->property("z").toInt(), bp->x);
+ }
+
+ // Make it recompile again.
+ e.clearComponentCache();
+ {
+ QFile file(fileName);
+ file.open(QIODevice::WriteOnly | QIODevice::Append);
+ file.write(" ");
+ }
+ waitForFileSystem();
+
+ {
+ QQmlComponent b(&e, url);
+ QVERIFY2(b.isReady(), qPrintable(b.errorString()));
+ QScopedPointer<QObject> bo(b.create());
+ QVERIFY(!bo.isNull());
+ BParent *bp = qobject_cast<BParent *>(bo.data());
+ QCOMPARE(bp->property("z").toInt(), bp->x);
+ }
+
+ // Verify that the mapped unit data is actually different now.
+ // The cache should have been invalidated after all.
+ // So, now we should be able to load a freshly written CU.
+
+ QQmlRefPointer<QV4::ExecutableCompilationUnit> unit
+ = QV4::ExecutableCompilationUnit::create();
+ QVERIFY2(unit->loadFromDisk(url, QFileInfo(fileName).lastModified(), &errorString), qPrintable(errorString));
+
+ QVERIFY(unit->unitData() != oldUnit->unitData());
+}
+
QTEST_MAIN(tst_qmldiskcache)
#include "tst_qmldiskcache.moc"
diff --git a/tests/auto/qml/qmlformat/data/ecmaScriptClassInQml.formatted.qml b/tests/auto/qml/qmlformat/data/ecmaScriptClassInQml.formatted.qml
new file mode 100644
index 0000000000..edbb12c6e6
--- /dev/null
+++ b/tests/auto/qml/qmlformat/data/ecmaScriptClassInQml.formatted.qml
@@ -0,0 +1,37 @@
+import QtQuick
+
+Item {
+
+ function f() {
+ var count = 0;
+ class Person {
+ constructor(name){
+ this._name = name;
+ }
+ }
+ class Employee extends Person {
+ constructor(name, age){
+ super(name);
+ this._name = name;
+ this._age = age;
+ ++count;
+ }
+
+ doWork(){}
+
+ /* do we get the comment? */ get name(){
+ return this._name.toUpperCase();
+ }
+
+ set name(newName){
+ if (newName) {
+ this._name = newName;
+ }
+ }
+
+ static get count(){
+ return count;
+ }
+ }
+ }
+}
diff --git a/tests/auto/qml/qmlformat/data/ecmaScriptClassInQml.qml b/tests/auto/qml/qmlformat/data/ecmaScriptClassInQml.qml
new file mode 100644
index 0000000000..268859d3cc
--- /dev/null
+++ b/tests/auto/qml/qmlformat/data/ecmaScriptClassInQml.qml
@@ -0,0 +1,45 @@
+import QtQuick
+
+Item {
+
+function f() {
+
+var count = 0;
+
+class Person {
+ constructor(name) {
+ this._name = name
+ }
+}
+
+class Employee extends Person{
+
+
+ constructor(name, age) {
+ super(name);
+ this._name = name;
+ this._age = age;
+ ++count;
+ }
+
+ doWork() {
+
+ }
+
+ get /* do we get the comment? */ name() {
+ return this._name.toUpperCase();
+ }
+
+ set name(newName){
+ if(newName){
+ this._name = newName;
+ }
+ }
+
+ static get count() { return count;}
+}
+
+
+}
+
+} \ No newline at end of file
diff --git a/tests/auto/qml/qmlformat/tst_qmlformat.cpp b/tests/auto/qml/qmlformat/tst_qmlformat.cpp
index 65b423b919..843c078f8c 100644
--- a/tests/auto/qml/qmlformat/tst_qmlformat.cpp
+++ b/tests/auto/qml/qmlformat/tst_qmlformat.cpp
@@ -252,6 +252,9 @@ void TestQmlformat::testFormat_data()
<< "emptyObject.formatted.qml" << QStringList {};
QTest::newRow("arrow functions") << "arrowFunctions.qml"
<< "arrowFunctions.formatted.qml" << QStringList {};
+ QTest::newRow("ecmaScriptClassInQml")
+ << "ecmaScriptClassInQml.qml"
+ << "ecmaScriptClassInQml.formatted.qml" << QStringList {};
}
void TestQmlformat::testFormat()
diff --git a/tests/auto/qml/qmltyperegistrar/CMakeLists.txt b/tests/auto/qml/qmltyperegistrar/CMakeLists.txt
index 9ab6c69b9c..02a0347ac2 100644
--- a/tests/auto/qml/qmltyperegistrar/CMakeLists.txt
+++ b/tests/auto/qml/qmltyperegistrar/CMakeLists.txt
@@ -67,3 +67,4 @@ qt_add_qml_module(tst-qmltyperegistrar-with-dashes
SOURCES
foo.cpp foo.h
)
+qt_autogen_tools_initial_setup(tst-qmltyperegistrar-with-dashesplugin)
diff --git a/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp b/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp
index aeb46a8274..27f83ca22f 100644
--- a/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp
+++ b/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp
@@ -300,4 +300,11 @@ void tst_qmltyperegistrar::methodReturnType()
QVERIFY(qmltypesData.contains("type: \"QQmlComponent\""));
}
+void tst_qmltyperegistrar::omitInvisible()
+{
+ // If it cannot resolve the type a QML_FOREIGN refers to, it should not generate anything.
+ QVERIFY(qmltypesData.contains(
+ R"(Component { file: "tst_qmltyperegistrar.h"; name: "Invisible"; accessSemantics: "none" })"));
+}
+
QTEST_MAIN(tst_qmltyperegistrar)
diff --git a/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h b/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h
index 7cfce1c2be..1372c32d02 100644
--- a/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h
+++ b/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h
@@ -398,6 +398,17 @@ public:
Q_INVOKABLE QQmlComponent *createAThing(int) { return nullptr; }
};
+class Invisible : public QObject
+{
+};
+
+struct InvisibleForeign
+{
+ Q_GADGET
+ QML_FOREIGN(Invisible)
+ QML_NAMED_ELEMENT(Invisible)
+};
+
class tst_qmltyperegistrar : public QObject
{
Q_OBJECT
@@ -429,6 +440,7 @@ private slots:
void namespacesAndValueTypes();
void derivedFromForeignPrivate();
void methodReturnType();
+ void omitInvisible();
private:
QByteArray qmltypesData;
diff --git a/tests/auto/qml/qqmlconnections/data/invalidTarget.qml b/tests/auto/qml/qqmlconnections/data/invalidTarget.qml
new file mode 100644
index 0000000000..23599649ec
--- /dev/null
+++ b/tests/auto/qml/qqmlconnections/data/invalidTarget.qml
@@ -0,0 +1,31 @@
+import QtQml
+
+QtObject {
+ id: root
+ objectName: button.objectName
+
+ property QtObject b: QtObject {
+ objectName: "button"
+ id: button
+ signal clicked
+ }
+
+ property Connections c: Connections {
+ id: connections
+ target: null
+ function onClicked() { button.destroy(); }
+ }
+
+ property Timer t: Timer {
+ interval: 10
+ running: true
+ onTriggered: {
+ root.objectName = connections.target.objectName
+ }
+ }
+
+ Component.onCompleted: {
+ connections.target = button;
+ button.clicked()
+ }
+}
diff --git a/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp b/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp
index 1cdf458c0d..a28a8dd9dd 100644
--- a/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp
+++ b/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp
@@ -78,6 +78,7 @@ private slots:
void noAcceleratedGlobalLookup();
void bindToPropertyWithUnderscoreChangeHandler();
+ void invalidTarget();
private:
QQmlEngine engine;
@@ -490,6 +491,25 @@ void tst_qqmlconnections::bindToPropertyWithUnderscoreChangeHandler()
QVERIFY(root->property("success").toBool());
}
+void tst_qqmlconnections::invalidTarget()
+{
+ QQmlEngine engine;
+ const QUrl url = testFileUrl("invalidTarget.qml");
+ QQmlComponent component(&engine, url);
+ QVERIFY2(component.isReady(), qPrintable(component.errorString()));
+
+ QScopedPointer<QObject> root {component.create()};
+ QVERIFY(root);
+ QCOMPARE(root->objectName(), QStringLiteral("button"));
+
+ QTest::ignoreMessage(
+ QtWarningMsg,
+ qPrintable(
+ url.toString()
+ + QLatin1String(":5:5: TypeError: Cannot read property 'objectName' of null")));
+ QTRY_VERIFY(root->objectName().isEmpty());
+}
+
QTEST_MAIN(tst_qqmlconnections)
#include "tst_qqmlconnections.moc"
diff --git a/tests/auto/qml/qqmlecmascript/data/methodTypeMismatch.qml b/tests/auto/qml/qqmlecmascript/data/methodTypeMismatch.qml
new file mode 100644
index 0000000000..fdf5f4ea11
--- /dev/null
+++ b/tests/auto/qml/qqmlecmascript/data/methodTypeMismatch.qml
@@ -0,0 +1,25 @@
+import QtQuick 2.0
+
+Item {
+ id: self
+ property font myFont
+ property int notMyFont
+
+ property var object
+
+ function callWithFont() {
+ object.method_gadget(myFont) // should be fine
+ }
+ function callWithInt() {
+ object.method_gadget(123)
+ }
+ function callWithInt2() {
+ object.method_gadget(notMyFont)
+ }
+ function callWithNull() {
+ object.method_gadget(null)
+ }
+ function callWithAllowedNull() {
+ object.method_qobject(null)
+ }
+}
diff --git a/tests/auto/qml/qqmlecmascript/data/readOnlyBindable.qml b/tests/auto/qml/qqmlecmascript/data/readOnlyBindable.qml
new file mode 100644
index 0000000000..116036c9ff
--- /dev/null
+++ b/tests/auto/qml/qqmlecmascript/data/readOnlyBindable.qml
@@ -0,0 +1,7 @@
+import Qt.test
+import QtQuick
+
+ReadOnlyBindable {
+ property int v: 12
+ x: v
+}
diff --git a/tests/auto/qml/qqmlecmascript/testtypes.cpp b/tests/auto/qml/qqmlecmascript/testtypes.cpp
index 87d8ed0c1f..cd83702d3a 100644
--- a/tests/auto/qml/qqmlecmascript/testtypes.cpp
+++ b/tests/auto/qml/qqmlecmascript/testtypes.cpp
@@ -560,6 +560,7 @@ void registerTypes()
qmlRegisterType<Receiver>("Qt.test", 1,0, "Receiver");
qmlRegisterType<Sender>("Qt.test", 1,0, "Sender");
+ qmlRegisterTypesAndRevisions<ReadOnlyBindable>("Qt.test", 1);
}
#include "testtypes.moc"
diff --git a/tests/auto/qml/qqmlecmascript/testtypes.h b/tests/auto/qml/qqmlecmascript/testtypes.h
index acc066fddd..a3df73972e 100644
--- a/tests/auto/qml/qqmlecmascript/testtypes.h
+++ b/tests/auto/qml/qqmlecmascript/testtypes.h
@@ -833,12 +833,38 @@ public:
Q_INVOKABLE void method_unknown(NonRegisteredType) { invoke(28); }
+ Q_PROPERTY(QFont someFont READ someFont WRITE setSomeFont NOTIFY someFontChanged);
+ QFont someFont() { return m_someFont; }
+ void setSomeFont(const QFont &f)
+ {
+ if (f == m_someFont)
+ return;
+ m_someFont = f;
+ emit someFontChanged();
+ }
+ Q_INVOKABLE void method_gadget(QFont f)
+ {
+ invoke(40);
+ m_actuals << f;
+ }
+ Q_INVOKABLE void method_qobject(QObject *o)
+ {
+ invoke(41);
+ m_actuals << QVariant::fromValue(o);
+ }
+
private:
friend class MyInvokableBaseObject;
void invoke(int idx) { if (m_invoked != -1) m_invokedError = true; m_invoked = idx;}
int m_invoked;
bool m_invokedError;
QVariantList m_actuals;
+
+ QFont m_someFont;
+
+public:
+Q_SIGNALS:
+ void someFontChanged();
};
MyInvokableBaseObject::~MyInvokableBaseObject() {}
@@ -1847,6 +1873,25 @@ public slots:
int slot1(int i, int j, int k) {return i+j+k;}
};
+class ReadOnlyBindable : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+ Q_PROPERTY(int x READ x WRITE setX BINDABLE bindableX)
+ Q_OBJECT_BINDABLE_PROPERTY(ReadOnlyBindable, int, _xProp)
+
+public:
+ ReadOnlyBindable(QObject *parent = nullptr)
+ : QObject(parent)
+ {
+ setX(7);
+ }
+
+ int x() const { return _xProp.value(); }
+ void setX(int x) { _xProp.setValue(x); }
+ QBindable<int> bindableX() const { return &_xProp; }
+};
+
void registerTypes();
#endif // TESTTYPES_H
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
index 2d38bf0524..f47c7132a2 100644
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
@@ -428,6 +428,9 @@ private slots:
void functionAsDefaultArgument();
void internalClassParentGc();
+ void methodTypeMismatch();
+
+ void doNotCrashOnReadOnlyBindable();
private:
// static void propertyVarWeakRefCallback(v8::Persistent<v8::Value> object, void* parameter);
@@ -3331,6 +3334,19 @@ void tst_qqmlecmascript::callQtInvokables()
QJSValue callback = qvariant_cast<QJSValue>(o->actuals().at(1));
QVERIFY(!callback.isNull());
QVERIFY(callback.isCallable());
+
+ o->reset();
+ QVERIFY(EVALUATE_VALUE("object.method_gadget(object.someFont)",
+ QV4::Primitive::undefinedValue()));
+ QCOMPARE(o->error(), false);
+ QCOMPARE(o->invoked(), 40);
+ QCOMPARE(o->actuals(), QVariantList() << QVariant(o->someFont()));
+
+ o->reset();
+ QVERIFY(EVALUATE_ERROR("object.method_gadget(123)"));
+ QCOMPARE(o->error(), false);
+ QCOMPARE(o->invoked(), -1);
+ QCOMPARE(o->actuals(), QVariantList());
}
void tst_qqmlecmascript::resolveClashingProperties()
@@ -9978,6 +9994,85 @@ void tst_qqmlecmascript::internalClassParentGc()
QCOMPARE(root->objectName(), "3");
}
+void tst_qqmlecmascript::methodTypeMismatch()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("methodTypeMismatch.qml"));
+
+ QScopedPointer<MyInvokableObject> object(new MyInvokableObject());
+
+ QScopedPointer<QObject> o(component.create());
+ QVERIFY2(o, qPrintable(component.errorString()));
+ o->setProperty("object", QVariant::fromValue(object.get()));
+
+ auto mo = o->metaObject();
+ QVERIFY(mo);
+
+ auto method = mo->method(mo->indexOfMethod("callWithFont()"));
+ QVERIFY(method.isValid());
+ QVERIFY(method.invoke(o.get()));
+ QCOMPARE(object->actuals(), QVariantList() << QVariant(object->someFont()));
+
+ QRegularExpression argumentConversionErrorMatcher("Could not convert argument 0");
+ QRegularExpression argumentConversionErrorMatcher2(".*/methodTypeMismatch.qml");
+ QRegularExpression typeErrorMatcher(
+ ".*/methodTypeMismatch\\.qml:..: TypeError: Passing incompatible arguments to C\\+\\+ "
+ "functions from JavaScript is not allowed.");
+
+ QTest::ignoreMessage(QtWarningMsg, argumentConversionErrorMatcher);
+ QTest::ignoreMessage(QtWarningMsg, argumentConversionErrorMatcher2);
+ QTest::ignoreMessage(QtWarningMsg, typeErrorMatcher);
+ object->reset();
+ method = mo->method(mo->indexOfMethod("callWithInt()"));
+ QVERIFY(method.isValid());
+ QVERIFY(method.invoke(o.get()));
+ QCOMPARE(object->actuals().size(),
+ 0); // actuals() should not contain reinterpret_cast<QFont>(123) !!!
+
+ QTest::ignoreMessage(QtWarningMsg, argumentConversionErrorMatcher);
+ QTest::ignoreMessage(QtWarningMsg, argumentConversionErrorMatcher2);
+ QTest::ignoreMessage(QtWarningMsg, typeErrorMatcher);
+ object->reset();
+ method = mo->method(mo->indexOfMethod("callWithInt2()"));
+ QVERIFY(method.isValid());
+ QVERIFY(method.invoke(o.get()));
+ QCOMPARE(object->actuals().size(),
+ 0); // actuals() should not contain reinterpret_cast<QFont>(0) !!!
+
+ QTest::ignoreMessage(QtWarningMsg, argumentConversionErrorMatcher);
+ QTest::ignoreMessage(QtWarningMsg, argumentConversionErrorMatcher2);
+ QTest::ignoreMessage(QtWarningMsg, typeErrorMatcher);
+ object->reset();
+ method = mo->method(mo->indexOfMethod("callWithNull()"));
+ QVERIFY(method.isValid());
+ QVERIFY(method.invoke(o.get()));
+ QCOMPARE(object->actuals().size(),
+ 0); // actuals() should not contain reinterpret_cast<QFont>(nullptr) !!!
+
+ // make sure that null is still accepted by functions accepting, e.g., a QObject*!
+ object->reset();
+ method = mo->method(mo->indexOfMethod("callWithAllowedNull()"));
+ QVERIFY(method.isValid());
+ QVERIFY(method.invoke(o.get()));
+ QCOMPARE(object->actuals(), QVariantList() << QVariant::fromValue((QObject *)nullptr));
+}
+
+void tst_qqmlecmascript::doNotCrashOnReadOnlyBindable()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("readOnlyBindable.qml"));
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+#ifndef QT_NO_DEBUG
+ QTest::ignoreMessage(
+ QtWarningMsg,
+ "setBinding: Could not set binding via bindable interface. "
+ "The QBindable is read-only.");
+#endif
+ QScopedPointer<QObject> o(c.create());
+ QVERIFY(o);
+ QCOMPARE(o->property("x").toInt(), 7);
+}
+
QTEST_MAIN(tst_qqmlecmascript)
#include "tst_qqmlecmascript.moc"
diff --git a/tests/auto/qml/qqmlfileselector/data/qmldirtest/main.qml b/tests/auto/qml/qqmlfileselector/data/qmldirtest/main.qml
new file mode 100644
index 0000000000..d6dd2c9b90
--- /dev/null
+++ b/tests/auto/qml/qqmlfileselector/data/qmldirtest/main.qml
@@ -0,0 +1,13 @@
+import QtQuick
+import qmldirtest
+
+Window {
+ width: 640
+ height: 480
+ visible: true
+ property color color: mybutton.color
+
+ MyButton {
+ id: mybutton
+ }
+}
diff --git a/tests/auto/qml/qqmlfileselector/data/qmldirtest/qml/+linux/MyButton.qml b/tests/auto/qml/qqmlfileselector/data/qmldirtest/qml/+linux/MyButton.qml
new file mode 100644
index 0000000000..cc6eb967da
--- /dev/null
+++ b/tests/auto/qml/qqmlfileselector/data/qmldirtest/qml/+linux/MyButton.qml
@@ -0,0 +1,7 @@
+import QtQuick
+
+Rectangle {
+ width: 300
+ height: 50
+ color: "blue"
+}
diff --git a/tests/auto/qml/qqmlfileselector/data/qmldirtest/qml/+macos/MyButton.qml b/tests/auto/qml/qqmlfileselector/data/qmldirtest/qml/+macos/MyButton.qml
new file mode 100644
index 0000000000..5bf632c48d
--- /dev/null
+++ b/tests/auto/qml/qqmlfileselector/data/qmldirtest/qml/+macos/MyButton.qml
@@ -0,0 +1,7 @@
+import QtQuick
+
+Rectangle {
+ width: 300
+ height: 50
+ color: "yellow"
+}
diff --git a/tests/auto/qml/qqmlfileselector/data/qmldirtest/qml/MyButton.qml b/tests/auto/qml/qqmlfileselector/data/qmldirtest/qml/MyButton.qml
new file mode 100644
index 0000000000..32db428c4f
--- /dev/null
+++ b/tests/auto/qml/qqmlfileselector/data/qmldirtest/qml/MyButton.qml
@@ -0,0 +1,7 @@
+import QtQuick
+
+Rectangle {
+ width: 300
+ height: 50
+ color: "green"
+}
diff --git a/tests/auto/qml/qqmlfileselector/data/qmldirtest/qmldir b/tests/auto/qml/qqmlfileselector/data/qmldirtest/qmldir
new file mode 100644
index 0000000000..ac68d9097d
--- /dev/null
+++ b/tests/auto/qml/qqmlfileselector/data/qmldirtest/qmldir
@@ -0,0 +1,5 @@
+module qmldirtest
+MyButton 1.0 qml/MyButton.qml
+MyButton 1.0 qml/+linux/MyButton.qml
+MyButton 1.0 qml/+macos/MyButton.qml
+
diff --git a/tests/auto/qml/qqmlfileselector/tst_qqmlfileselector.cpp b/tests/auto/qml/qqmlfileselector/tst_qqmlfileselector.cpp
index 4c99bcf9c8..fe55d8b056 100644
--- a/tests/auto/qml/qqmlfileselector/tst_qqmlfileselector.cpp
+++ b/tests/auto/qml/qqmlfileselector/tst_qqmlfileselector.cpp
@@ -47,7 +47,7 @@ private slots:
void basicTest();
void basicTestCached();
void applicationEngineTest();
-
+ void qmldirCompatibility();
};
void tst_qqmlfileselector::basicTest()
@@ -95,6 +95,23 @@ void tst_qqmlfileselector::applicationEngineTest()
QCOMPARE(object->property("value").toString(), QString("selected"));
}
+void tst_qqmlfileselector::qmldirCompatibility()
+{
+ QQmlApplicationEngine engine;
+ engine.addImportPath(dataDirectory());
+ engine.load(testFileUrl("qmldirtest/main.qml"));
+ QVERIFY(!engine.rootObjects().isEmpty());
+ QObject *object = engine.rootObjects().at(0);
+ auto color = object->property("color").value<QColor>();
+#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)
+ QCOMPARE(color, QColorConstants::Svg::blue);
+#elif defined(Q_OS_DARWIN)
+ QCOMPARE(color, QColorConstants::Svg::yellow);
+#else
+ QCOMPARE(color, QColorConstants::Svg::green);
+#endif
+}
+
QTEST_MAIN(tst_qqmlfileselector)
#include "tst_qqmlfileselector.moc"
diff --git a/tests/auto/qml/qqmllanguage/data/MyRectangle.qml b/tests/auto/qml/qqmllanguage/data/MyRectangle.qml
new file mode 100644
index 0000000000..4d5e7c6c8d
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/MyRectangle.qml
@@ -0,0 +1,10 @@
+import QtQuick
+
+Item {
+ property alias rectangle1AnchorsleftMargin: rectangle1.anchors.leftMargin
+
+ Rectangle {
+ id: rectangle1
+ anchors.leftMargin: 250
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/alias.19.qml b/tests/auto/qml/qqmllanguage/data/alias.19.qml
new file mode 100644
index 0000000000..a96c0c694d
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/alias.19.qml
@@ -0,0 +1,11 @@
+import QtQuick
+
+Item {
+ id: myThing
+ width: 1920
+
+ MyRectangle {
+ rectangle1AnchorsleftMargin: myThing.width / 2
+ Component.onCompleted: myThing.height = rectangle1AnchorsleftMargin
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
index 06b2738c9e..047df2f6d0 100644
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
@@ -2257,6 +2257,16 @@ void tst_qqmllanguage::aliasProperties()
QQmlComponent component(&engine, testFileUrl("alias.18.qml"));
VERIFY_ERRORS("alias.18.errors.txt");
}
+
+ // Binding on deep alias
+ {
+ QQmlComponent component(&engine, testFileUrl("alias.19.qml"));
+ VERIFY_ERRORS(0);
+
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(!object.isNull());
+ QCOMPARE(object->property("height").toInt(), 960);
+ }
}
// QTBUG-13374 Test that alias properties and signals can coexist
diff --git a/tests/auto/qml/qqmllistmodel/data/protectQObjectFromGC.qml b/tests/auto/qml/qqmllistmodel/data/protectQObjectFromGC.qml
new file mode 100644
index 0000000000..43b375b681
--- /dev/null
+++ b/tests/auto/qml/qqmllistmodel/data/protectQObjectFromGC.qml
@@ -0,0 +1,21 @@
+import QtQml
+import QtQml.Models
+
+ListModel {
+ id: filesModel
+ property Component testComponent: Component {
+ id: testComponent
+ QtObject {
+ required property string name
+ }
+ }
+ Component.onCompleted: {
+ filesModel.clear()
+ for(let i = 0; i < 10; i++) {
+ filesModel.append({
+ path: testComponent.createObject(null, { name: "" + i })
+ })
+ }
+ gc()
+ }
+}
diff --git a/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp b/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
index 37b0f6f1fe..fbdf6d90f3 100644
--- a/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
+++ b/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
@@ -139,6 +139,7 @@ private slots:
void listElementWithTemplateString();
void destroyComponentObject();
void objectOwnershipFlip();
+ void protectQObjectFromGC();
};
bool tst_qqmllistmodel::compareVariantList(const QVariantList &testList, QVariant object)
@@ -1882,7 +1883,7 @@ void tst_qqmllistmodel::destroyComponentObject()
Q_RETURN_ARG(QVariant, retVal));
QVERIFY(retVal.toBool());
QTRY_VERIFY(created.isNull());
- QTRY_VERIFY(list->get(0).property("obj").isUndefined());
+ QTRY_VERIFY(list->get(0).property("obj").isNull());
QCOMPARE(list->count(), 1);
}
@@ -1920,6 +1921,25 @@ void tst_qqmllistmodel::objectOwnershipFlip()
QCOMPARE(QJSEngine::objectOwnership(item.data()), QJSEngine::CppOwnership);
}
+void tst_qqmllistmodel::protectQObjectFromGC()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("protectQObjectFromGC.qml"));
+ QVERIFY2(component.isReady(), qPrintable(component.errorString()));
+ QScopedPointer<QObject> root(component.create());
+ QVERIFY(!root.isNull());
+
+ QQmlListModel *listModel = qobject_cast<QQmlListModel *>(root.data());
+ QVERIFY(listModel);
+ QCOMPARE(listModel->count(), 10);
+
+ for (int i = 0; i < 10; ++i) {
+ QObject *element = qjsvalue_cast<QObject *>(listModel->get(i).property("path"));
+ QVERIFY(element);
+ QCOMPARE(element->property("name").toString(), QString::number(i));
+ }
+}
+
QTEST_MAIN(tst_qqmllistmodel)
#include "tst_qqmllistmodel.moc"
diff --git a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp
index be493484ee..f726855727 100644
--- a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp
+++ b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp
@@ -72,6 +72,8 @@ private slots:
void enumsInRecursiveImport_data();
void enumsInRecursiveImport();
+
+ void clearPropertyCaches();
};
class TestType : public QObject
@@ -734,6 +736,24 @@ void tst_qqmlmetatype::enumsInRecursiveImport()
QTRY_COMPARE(obj->property("color").toString(), QString("green"));
}
+void tst_qqmlmetatype::clearPropertyCaches()
+{
+ qmlClearTypeRegistrations();
+ qmlRegisterType<TestType>("ClearPropertyCaches", 1, 0, "A");
+
+ QQmlRefPointer<QQmlPropertyCache> oldCache(
+ QQmlMetaType::propertyCache(&TestType::staticMetaObject));
+ QVERIFY(oldCache);
+
+ qmlClearTypeRegistrations();
+ qmlRegisterType<TestType>("ClearPropertyCaches", 1, 0, "B");
+ QQmlRefPointer<QQmlPropertyCache> newCache(
+ QQmlMetaType::propertyCache(&TestType::staticMetaObject));
+ QVERIFY(newCache);
+
+ QVERIFY(oldCache.data() != newCache.data());
+}
+
QTEST_MAIN(tst_qqmlmetatype)
#include "tst_qqmlmetatype.moc"
diff --git a/tests/auto/quick/pointerhandlers/qquicktaphandler/BLACKLIST b/tests/auto/quick/pointerhandlers/qquicktaphandler/BLACKLIST
deleted file mode 100644
index 9cc6783375..0000000000
--- a/tests/auto/quick/pointerhandlers/qquicktaphandler/BLACKLIST
+++ /dev/null
@@ -1,4 +0,0 @@
-# QTBUG-103072
-[gesturePolicyDragWithinBounds]
-android
-
diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_arc.qml b/tests/auto/quick/qquickcanvasitem/data/tst_arc.qml
index 33fffd4cb1..00d13f31f4 100644
--- a/tests/auto/quick/qquickcanvasitem/data/tst_arc.qml
+++ b/tests/auto/quick/qquickcanvasitem/data/tst_arc.qml
@@ -6,6 +6,7 @@ CanvasTestCase {
function init_data() { return testData("2d"); }
function test_angle_1(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -21,6 +22,7 @@ CanvasTestCase {
}
function test_angle_2(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -36,6 +38,7 @@ CanvasTestCase {
}
function test_angle_3(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.fillStyle = '#0f0';
@@ -53,6 +56,7 @@ CanvasTestCase {
}
function test_angle_4(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -71,6 +75,7 @@ CanvasTestCase {
}
function test_angle_5(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -90,6 +95,7 @@ CanvasTestCase {
function test_angle_6(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -110,6 +116,7 @@ CanvasTestCase {
function test_empty(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -125,6 +132,7 @@ CanvasTestCase {
}
function test_nonempty(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -141,6 +149,7 @@ CanvasTestCase {
}
function test_nonfinite(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -199,6 +208,7 @@ CanvasTestCase {
}
function test_end(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -216,6 +226,7 @@ CanvasTestCase {
}
function test_negative(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -234,6 +245,7 @@ CanvasTestCase {
function test_scale_1(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -270,6 +282,7 @@ CanvasTestCase {
function test_scale_2(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -296,6 +309,7 @@ CanvasTestCase {
function test_selfintersect_1(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -316,6 +330,7 @@ CanvasTestCase {
function test_selfintersect_2(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -340,6 +355,7 @@ CanvasTestCase {
function test_shape_1(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -361,6 +377,7 @@ CanvasTestCase {
function test_shape_2(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -381,6 +398,7 @@ CanvasTestCase {
}
function test_shape_3(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -401,6 +419,7 @@ CanvasTestCase {
function test_shape_4(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -421,6 +440,7 @@ CanvasTestCase {
function test_shape_5(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -441,6 +461,7 @@ CanvasTestCase {
function test_twopie(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -488,6 +509,7 @@ CanvasTestCase {
function test_zero(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_arcto.qml b/tests/auto/quick/qquickcanvasitem/data/tst_arcto.qml
index ef1b7a7b2a..81412d98c9 100644
--- a/tests/auto/quick/qquickcanvasitem/data/tst_arcto.qml
+++ b/tests/auto/quick/qquickcanvasitem/data/tst_arcto.qml
@@ -7,6 +7,7 @@ CanvasTestCase {
function test_coincide(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.fillStyle = '#f00';
@@ -44,6 +45,7 @@ CanvasTestCase {
}
function test_collinear(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -109,6 +111,7 @@ CanvasTestCase {
}
function test_subpath(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -135,6 +138,7 @@ CanvasTestCase {
function test_negative(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -152,6 +156,7 @@ CanvasTestCase {
function test_nonfinite(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -208,6 +213,7 @@ CanvasTestCase {
}
function test_scale(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -237,6 +243,7 @@ CanvasTestCase {
function test_shape(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -348,6 +355,7 @@ CanvasTestCase {
function test_transform(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -374,6 +382,7 @@ CanvasTestCase {
}
function test_zero(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_composite.qml b/tests/auto/quick/qquickcanvasitem/data/tst_composite.qml
index 8a5a52cf1e..4ee24ad437 100644
--- a/tests/auto/quick/qquickcanvasitem/data/tst_composite.qml
+++ b/tests/auto/quick/qquickcanvasitem/data/tst_composite.qml
@@ -6,6 +6,7 @@ CanvasTestCase {
function init_data() { return testData("2d"); }
function test_clearRect(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.fillStyle = '#f00';
@@ -17,6 +18,7 @@ CanvasTestCase {
function test_clip(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
var composites = [ {compsite:"copy"},
{compsite:"destination-atop"},
@@ -47,6 +49,7 @@ CanvasTestCase {
function test_globalAlpha(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
compare(ctx.globalAlpha, 1.0);
@@ -83,6 +86,7 @@ CanvasTestCase {
function test_operation(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.globalCompositeOperation = 'xor';
@@ -137,6 +141,7 @@ CanvasTestCase {
function test_solid(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.fillStyle = Qt.rgba(0, 1, 1, 1.0);
@@ -233,6 +238,7 @@ CanvasTestCase {
}
function test_transparent(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
@@ -330,6 +336,7 @@ CanvasTestCase {
function test_uncovered(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_fillStyle.qml b/tests/auto/quick/qquickcanvasitem/data/tst_fillStyle.qml
index 58ea6d7f59..9e8c0785c3 100644
--- a/tests/auto/quick/qquickcanvasitem/data/tst_fillStyle.qml
+++ b/tests/auto/quick/qquickcanvasitem/data/tst_fillStyle.qml
@@ -6,6 +6,7 @@ CanvasTestCase {
function init_data() { return testData("2d"); }
function test_default(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
verify(ctx.fillStyle, "#000000");
@@ -14,6 +15,7 @@ CanvasTestCase {
}
function test_get(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.fillStyle = '#fa0';
@@ -23,6 +25,7 @@ CanvasTestCase {
}
function test_hex(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.fillStyle = '#f00';
@@ -37,6 +40,7 @@ CanvasTestCase {
}
function test_invalid(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.fillStyle = '#fa0';
@@ -60,6 +64,7 @@ CanvasTestCase {
}
function test_saverestore(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
var old = ctx.fillStyle;
ctx.save();
@@ -75,6 +80,7 @@ CanvasTestCase {
}
function test_namedColor(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.fillStyle = "red";
@@ -91,6 +97,7 @@ CanvasTestCase {
}
function test_rgba(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.fillStyle = "rgb(-100, 300, 255)";
@@ -108,6 +115,7 @@ CanvasTestCase {
function test_hsla(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.fillStyle = "hsla(120, 100%, 50%, 0.499)";
diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_fillrect.qml b/tests/auto/quick/qquickcanvasitem/data/tst_fillrect.qml
index ce1c27c6bc..213abdd622 100644
--- a/tests/auto/quick/qquickcanvasitem/data/tst_fillrect.qml
+++ b/tests/auto/quick/qquickcanvasitem/data/tst_fillrect.qml
@@ -6,6 +6,7 @@ CanvasTestCase {
function init_data() { return testData("2d"); }
function test_fillRect(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.fillStyle = "red";
ctx.fillRect(0, 0, canvas.width, canvas.height);
diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_gradient.qml b/tests/auto/quick/qquickcanvasitem/data/tst_gradient.qml
index 7c87d896fb..70e77c8760 100644
--- a/tests/auto/quick/qquickcanvasitem/data/tst_gradient.qml
+++ b/tests/auto/quick/qquickcanvasitem/data/tst_gradient.qml
@@ -6,6 +6,7 @@ CanvasTestCase {
function init_data() { return testData("2d"); }
function test_basic(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.fillStyle = '#0f0';
@@ -18,6 +19,7 @@ CanvasTestCase {
function test_interpolate(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -166,6 +168,7 @@ CanvasTestCase {
}
function test_radial(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.fillStyle = '#0f0';
@@ -788,6 +791,7 @@ CanvasTestCase {
}
function test_linear(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
try { var err = false;
@@ -907,6 +911,7 @@ CanvasTestCase {
}
function test_object(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
var g1 = ctx.createLinearGradient(0, 0, 100, 0);
@@ -978,6 +983,7 @@ CanvasTestCase {
function test_conical(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
var g = ctx.createConicalGradient(10, 10, 50);
diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_image.qml b/tests/auto/quick/qquickcanvasitem/data/tst_image.qml
index 1f695d7080..a1eb272cd0 100644
--- a/tests/auto/quick/qquickcanvasitem/data/tst_image.qml
+++ b/tests/auto/quick/qquickcanvasitem/data/tst_image.qml
@@ -11,12 +11,12 @@ CanvasTestCase {
canvas.loadImage('rgrg-256x256.png');
canvas.loadImage('ggrr-256x256.png');
canvas.loadImage('broken.png');
- while (!canvas.isImageLoaded('green.png'))
- wait(200);
+ tryVerify(function() { return canvas.isImageLoaded('green.png'); })
}
function test_3args(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
loadImages(canvas);
ctx.reset();
@@ -35,6 +35,7 @@ CanvasTestCase {
}
function test_5args(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
loadImages(canvas);
@@ -54,6 +55,7 @@ CanvasTestCase {
}
function test_9args(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
loadImages(canvas);
@@ -118,6 +120,7 @@ CanvasTestCase {
}
function test_animated(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
loadImages(canvas);
@@ -125,6 +128,7 @@ CanvasTestCase {
}
function test_clip(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
loadImages(canvas);
@@ -139,6 +143,7 @@ CanvasTestCase {
}
function test_self(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
loadImages(canvas);
@@ -170,6 +175,7 @@ CanvasTestCase {
function test_outsidesource(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
loadImages(canvas);
@@ -207,6 +213,7 @@ CanvasTestCase {
function test_null(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
loadImages(canvas);
@@ -220,15 +227,18 @@ CanvasTestCase {
function test_url(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
canvas.loadImage(testCase.green);
+ tryVerify(function() { return canvas.isImageLoaded(testCase.green); })
ctx.drawImage(testCase.green, 0, 0);
comparePixel(ctx, 0,0, 0,255,0,255,2);
}
function test_composite(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
loadImages(canvas);
@@ -241,12 +251,14 @@ CanvasTestCase {
}
function test_path(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
loadImages(canvas);
}
function test_transform(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
loadImages(canvas);
@@ -260,6 +272,7 @@ CanvasTestCase {
function test_imageitem(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
loadImages(canvas);
@@ -268,6 +281,7 @@ CanvasTestCase {
function test_imageData(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
loadImages(canvas);
@@ -276,6 +290,7 @@ CanvasTestCase {
function test_wrongtype(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
loadImages(canvas);
@@ -293,6 +308,7 @@ CanvasTestCase {
function test_nonfinite(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
loadImages(canvas);
@@ -606,6 +622,7 @@ CanvasTestCase {
function test_negative(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
loadImages(canvas);
@@ -661,6 +678,7 @@ CanvasTestCase {
function test_canvas(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
loadImages(canvas);
@@ -684,6 +702,7 @@ CanvasTestCase {
function test_broken(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
loadImages(canvas);
@@ -694,6 +713,7 @@ CanvasTestCase {
function test_alpha(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
loadImages(canvas);
@@ -706,6 +726,7 @@ CanvasTestCase {
}
function test_multiple_painting(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
loadImages(canvas);
diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_imagedata.qml b/tests/auto/quick/qquickcanvasitem/data/tst_imagedata.qml
index 76b99a765e..aab7a95589 100644
--- a/tests/auto/quick/qquickcanvasitem/data/tst_imagedata.qml
+++ b/tests/auto/quick/qquickcanvasitem/data/tst_imagedata.qml
@@ -11,6 +11,7 @@ CanvasTestCase {
skip("ctx.getImageData crashes on offscreen/minimal platforms");
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
var size = 17
ctx.reset();
diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_line.qml b/tests/auto/quick/qquickcanvasitem/data/tst_line.qml
index ba7ff09728..e5d03e5db7 100644
--- a/tests/auto/quick/qquickcanvasitem/data/tst_line.qml
+++ b/tests/auto/quick/qquickcanvasitem/data/tst_line.qml
@@ -6,6 +6,7 @@ CanvasTestCase {
function init_data() { return testData("2d"); }
function test_default(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
compare(ctx.lineWidth, 1);
@@ -16,6 +17,7 @@ CanvasTestCase {
function test_cross(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.fillStyle = '#0f0';
@@ -43,6 +45,7 @@ CanvasTestCase {
function test_join(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -306,6 +309,7 @@ CanvasTestCase {
}
function test_miter(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.fillStyle = '#f00';
@@ -481,6 +485,7 @@ CanvasTestCase {
}
function test_width(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.fillStyle = '#0f0';
@@ -625,6 +630,7 @@ CanvasTestCase {
skip("line::test_cap crashes on Android, QTBUG-103257")
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -841,6 +847,7 @@ CanvasTestCase {
function test_lineDash(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.strokeStyle = "#fff";
@@ -899,6 +906,7 @@ CanvasTestCase {
function test_lineDashReset(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.strokeStyle = "#ff0000";
@@ -930,6 +938,7 @@ CanvasTestCase {
function test_lineDashOffset(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.strokeStyle = "#fff";
diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_path.qml b/tests/auto/quick/qquickcanvasitem/data/tst_path.qml
index 60c782c8fa..ae08b58519 100644
--- a/tests/auto/quick/qquickcanvasitem/data/tst_path.qml
+++ b/tests/auto/quick/qquickcanvasitem/data/tst_path.qml
@@ -6,6 +6,7 @@ CanvasTestCase {
function init_data() { return testData("2d"); }
function test_basic(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.fillStyle = '#0f0';
@@ -36,6 +37,7 @@ CanvasTestCase {
}
function test_beginPath(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.fillStyle = '#0f0';
ctx.fillRect(0, 0, 100, 50);
@@ -48,6 +50,7 @@ CanvasTestCase {
}
function test_closePath(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.fillStyle = '#0f0';
@@ -86,6 +89,7 @@ CanvasTestCase {
function test_isPointInPath(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.arc(50, 25, 10, 0, Math.PI, false);
@@ -256,6 +260,7 @@ CanvasTestCase {
function test_fill(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.fillStyle = '#f00';
@@ -378,6 +383,7 @@ CanvasTestCase {
}
function test_stroke(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.fillStyle = '#0f0';
@@ -662,6 +668,7 @@ CanvasTestCase {
}
function test_clip(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.fillStyle = '#f00';
@@ -784,6 +791,7 @@ CanvasTestCase {
function test_moveTo(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.fillStyle = '#f00';
@@ -839,6 +847,7 @@ CanvasTestCase {
}
function test_lineTo(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.fillStyle = '#f00';
@@ -904,6 +913,7 @@ CanvasTestCase {
}
function test_bezierCurveTo(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.fillStyle = '#f00';
@@ -1072,6 +1082,7 @@ CanvasTestCase {
}
function test_quadraticCurveTo(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.fillStyle = '#f00';
@@ -1173,6 +1184,7 @@ CanvasTestCase {
}
function test_rect(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -1371,6 +1383,7 @@ CanvasTestCase {
function test_clearRect(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.fillStyle = '#0f0';
@@ -1383,6 +1396,7 @@ CanvasTestCase {
}
function test_fillRect(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.beginPath();
@@ -1397,6 +1411,7 @@ CanvasTestCase {
function test_strokeRect(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.beginPath();
@@ -1412,6 +1427,7 @@ CanvasTestCase {
}
function test_transform(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.fillStyle = '#f00';
diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_pattern.qml b/tests/auto/quick/qquickcanvasitem/data/tst_pattern.qml
index 1d7fd2c12f..e0a4d7ad23 100644
--- a/tests/auto/quick/qquickcanvasitem/data/tst_pattern.qml
+++ b/tests/auto/quick/qquickcanvasitem/data/tst_pattern.qml
@@ -6,36 +6,42 @@ CanvasTestCase {
function init_data() { return testData("2d"); }
function test_basic(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
canvas.destroy()
}
function test_animated(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
canvas.destroy()
}
function test_image(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
canvas.destroy()
}
function test_modified(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
canvas.destroy()
}
function test_paint(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
canvas.destroy()
}
function test_repeat(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
canvas.destroy()
diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_pixel.qml b/tests/auto/quick/qquickcanvasitem/data/tst_pixel.qml
index 281264ba92..ef908db92a 100644
--- a/tests/auto/quick/qquickcanvasitem/data/tst_pixel.qml
+++ b/tests/auto/quick/qquickcanvasitem/data/tst_pixel.qml
@@ -7,6 +7,7 @@ CanvasTestCase {
function init_data() { return testData("2d"); }
function test_createImageData(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
var imageData = ctx.createImageData(1, 1);
var imageDataValues = imageData.data;
@@ -20,24 +21,28 @@ CanvasTestCase {
}
function test_getImageData(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
canvas.destroy()
}
function test_object(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
canvas.destroy()
}
function test_putImageData(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
canvas.destroy()
}
function test_filters(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
canvas.destroy()
diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_shadow.qml b/tests/auto/quick/qquickcanvasitem/data/tst_shadow.qml
index 2baaa072d0..14318b3f56 100644
--- a/tests/auto/quick/qquickcanvasitem/data/tst_shadow.qml
+++ b/tests/auto/quick/qquickcanvasitem/data/tst_shadow.qml
@@ -6,12 +6,14 @@ CanvasTestCase {
function init_data() { return testData("2d"); }
function test_basic(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
canvas.destroy()
}
function test_blur(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
canvas.destroy()
@@ -19,6 +21,7 @@ CanvasTestCase {
function test_clip(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
canvas.destroy()
@@ -26,6 +29,7 @@ CanvasTestCase {
function test_composite(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
canvas.destroy()
@@ -33,6 +37,7 @@ CanvasTestCase {
function test_enable(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
canvas.destroy()
@@ -40,36 +45,42 @@ CanvasTestCase {
function test_gradient(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
canvas.destroy()
}
function test_image(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
canvas.destroy()
}
function test_offset(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
canvas.destroy()
}
function test_pattern(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
canvas.destroy()
}
function test_stroke(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
canvas.destroy()
}
function test_tranform(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
canvas.destroy()
diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_state.qml b/tests/auto/quick/qquickcanvasitem/data/tst_state.qml
index 18464def7c..ce02f9d7f7 100644
--- a/tests/auto/quick/qquickcanvasitem/data/tst_state.qml
+++ b/tests/auto/quick/qquickcanvasitem/data/tst_state.qml
@@ -6,6 +6,7 @@ CanvasTestCase {
function init_data() { return testData("2d"); }
function test_bitmap(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.fillStyle = '#f00';
@@ -19,6 +20,7 @@ CanvasTestCase {
}
function test_clip(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -35,6 +37,7 @@ CanvasTestCase {
}
function test_fillStyle(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
// Test that restore() undoes any modifications
@@ -56,6 +59,7 @@ CanvasTestCase {
}
function test_font(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -78,6 +82,7 @@ CanvasTestCase {
}
function test_globalAlpha(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -100,6 +105,7 @@ CanvasTestCase {
}
function test_globalCompositeOperation(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -122,6 +128,7 @@ CanvasTestCase {
}
function test_lineCap(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -144,6 +151,7 @@ CanvasTestCase {
}
function test_lineJoin(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -166,6 +174,7 @@ CanvasTestCase {
}
function test_lineWidth(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -188,6 +197,7 @@ CanvasTestCase {
}
function test_miterLimit(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -210,6 +220,7 @@ CanvasTestCase {
}
function test_path(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -225,6 +236,7 @@ CanvasTestCase {
}
function test_shadow(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -295,6 +307,7 @@ CanvasTestCase {
}
function test_stack(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -330,6 +343,7 @@ CanvasTestCase {
}
function test_strokeStyle(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -353,6 +367,7 @@ CanvasTestCase {
function test_text(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -392,6 +407,7 @@ CanvasTestCase {
function test_transform(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_strokeStyle.qml b/tests/auto/quick/qquickcanvasitem/data/tst_strokeStyle.qml
index a3f1ab0a9b..0dc39b8b4c 100644
--- a/tests/auto/quick/qquickcanvasitem/data/tst_strokeStyle.qml
+++ b/tests/auto/quick/qquickcanvasitem/data/tst_strokeStyle.qml
@@ -8,6 +8,7 @@ CanvasTestCase {
function init_data() { return testData("2d"); }
function test_default(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
compare(ctx.strokeStyle, "#000000")
@@ -17,6 +18,7 @@ CanvasTestCase {
}
function test_saverestore(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
var old = ctx.strokeStyle;
ctx.save();
@@ -33,6 +35,7 @@ CanvasTestCase {
}
function test_namedColor(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.strokeStyle = "red";
@@ -50,6 +53,7 @@ CanvasTestCase {
}
function test_colorFromObjectToString(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -68,6 +72,7 @@ CanvasTestCase {
}
function test_withInvalidColor(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_svgpath.qml b/tests/auto/quick/qquickcanvasitem/data/tst_svgpath.qml
index 2b39357bed..011fbd497b 100644
--- a/tests/auto/quick/qquickcanvasitem/data/tst_svgpath.qml
+++ b/tests/auto/quick/qquickcanvasitem/data/tst_svgpath.qml
@@ -6,6 +6,7 @@ CanvasTestCase {
function init_data() { return testData("2d"); }
function test_svgpath(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
var svgs = [
// Absolute coordinates, explicit commands.
diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_text.qml b/tests/auto/quick/qquickcanvasitem/data/tst_text.qml
index bfc4067040..f7cd66890b 100644
--- a/tests/auto/quick/qquickcanvasitem/data/tst_text.qml
+++ b/tests/auto/quick/qquickcanvasitem/data/tst_text.qml
@@ -6,36 +6,42 @@ CanvasTestCase {
function init_data() { return testData("2d"); }
function test_baseLine(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
canvas.destroy()
}
function test_align(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
canvas.destroy()
}
function test_stroke(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
canvas.destroy()
}
function test_fill(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
canvas.destroy()
}
function test_font(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
canvas.destroy()
}
function test_measure(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
canvas.destroy()
diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_transform.qml b/tests/auto/quick/qquickcanvasitem/data/tst_transform.qml
index b2f5b51fa5..bbfec6a106 100644
--- a/tests/auto/quick/qquickcanvasitem/data/tst_transform.qml
+++ b/tests/auto/quick/qquickcanvasitem/data/tst_transform.qml
@@ -6,6 +6,7 @@ CanvasTestCase {
function init_data() { return testData("2d"); }
function test_order(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.fillStyle = '#f00';
@@ -20,6 +21,7 @@ CanvasTestCase {
}
function test_rotate(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.fillStyle = '#f00';
@@ -90,6 +92,7 @@ CanvasTestCase {
}
function test_scale(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
@@ -182,6 +185,7 @@ CanvasTestCase {
}
function test_setTransform(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.fillStyle = '#f00';
@@ -325,6 +329,7 @@ CanvasTestCase {
}
function test_transform(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.fillStyle = '#f00';
@@ -460,6 +465,7 @@ CanvasTestCase {
}
function test_translate(row) {
var canvas = createCanvasObject(row);
+ tryVerify(function() { return canvas.available; });
var ctx = canvas.getContext('2d');
ctx.reset();
ctx.fillStyle = '#f00';
diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
index a6fb0fcb59..51020672b7 100644
--- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
+++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
@@ -3117,7 +3117,12 @@ void tst_qquickflickable::setContentPositionWhileDragging() // QTBUG-104966
} else if (newExtent >= 0) {
// ...or reduce the content size be be less than current (contentX, contentY) position
// This forces the content item to move.
- expectedContentPos = moveDelta;
+ // contentY: 150
+ // 320 - 150 = 170 pixels down to bottom
+ // Now reduce contentHeight to 200
+ // since we are at the bottom, and the flickable is 100 pixels tall, contentY must land
+ // at newExtent - 100.
+
if (isHorizontal) {
flickable->setContentWidth(newExtent);
} else {
@@ -3127,6 +3132,7 @@ void tst_qquickflickable::setContentPositionWhileDragging() // QTBUG-104966
// We therefore cannot scroll/flick it further down. Drag it up towards the top instead
// (by moving mouse down).
pos += moveDelta;
+ expectedContentPos = unitDelta * (newExtent - (isHorizontal ? flickable->width() : flickable->height()));
}
QTest::mouseMove(&window, pos);
diff --git a/tests/auto/quick/qquickflipable/data/flip-y-axis-flipable.qml b/tests/auto/quick/qquickflipable/data/flip-y-axis-flipable.qml
new file mode 100644
index 0000000000..1b6a3f5018
--- /dev/null
+++ b/tests/auto/quick/qquickflipable/data/flip-y-axis-flipable.qml
@@ -0,0 +1,32 @@
+// Copyright (C) 2023 UnionTech Software Technology Co., Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick
+
+Flipable {
+ id: flipable
+
+ property real angle: 0
+ width: 3840 // wider than 1024 * 2: part of it goes behind the camera while flipping
+ height: 2160
+
+ front: Rectangle {
+ width: parent.width
+ height: parent.height
+ color: "red"
+ anchors.centerIn: parent
+ }
+ back: Rectangle {
+ color: "yellow"
+ anchors.centerIn: parent
+ width: parent.width
+ height: parent.height
+ }
+ transform: Rotation {
+ id: rotation
+ origin.x: flipable.width / 2
+ origin.y: flipable.height / 2
+ axis.x: 0; axis.y: 1; axis.z: 0
+ angle: flipable.angle
+ }
+}
diff --git a/tests/auto/quick/qquickflipable/tst_qquickflipable.cpp b/tests/auto/quick/qquickflipable/tst_qquickflipable.cpp
index 7106041eda..55747a7cdd 100644
--- a/tests/auto/quick/qquickflipable/tst_qquickflipable.cpp
+++ b/tests/auto/quick/qquickflipable/tst_qquickflipable.cpp
@@ -52,6 +52,9 @@ private slots:
void QTBUG_9161_crash();
void QTBUG_8474_qgv_abort();
+ void flipRotationAngle_data();
+ void flipRotationAngle();
+
private:
QQmlEngine engine;
};
@@ -137,6 +140,31 @@ void tst_qquickflipable::QTBUG_8474_qgv_abort()
delete window;
}
+void tst_qquickflipable::flipRotationAngle_data()
+{
+ QTest::addColumn<int>("angle");
+ QTest::addColumn<QQuickFlipable::Side>("side");
+
+ QTest::newRow("89") << 89 << QQuickFlipable::Front;
+ QTest::newRow("91") << 91 << QQuickFlipable::Back;
+ QTest::newRow("-89") << -89 << QQuickFlipable::Front;
+ QTest::newRow("-91") << -91 << QQuickFlipable::Back;
+}
+
+void tst_qquickflipable::flipRotationAngle() // QTBUG-75954
+{
+ QFETCH(int, angle);
+ QFETCH(QQuickFlipable::Side, side);
+
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("flip-y-axis-flipable.qml"));
+ QQuickFlipable *obj = qobject_cast<QQuickFlipable*>(c.create());
+ QVERIFY(obj != nullptr);
+ obj->setProperty("angle", angle);
+ QCOMPARE(obj->side(), side);
+ delete obj;
+}
+
QTEST_MAIN(tst_qquickflipable)
#include "tst_qquickflipable.moc"
diff --git a/tests/auto/quick/qquicklistview2/data/qtbug86744.qml b/tests/auto/quick/qquicklistview2/data/qtbug86744.qml
new file mode 100644
index 0000000000..c69a4f7ec6
--- /dev/null
+++ b/tests/auto/quick/qquicklistview2/data/qtbug86744.qml
@@ -0,0 +1,25 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQml.Models
+
+Item {
+ height: 200
+ width: 100
+ DelegateModel {
+ id: dm
+ model: 2
+ delegate: Item {
+ width: 100
+ height: 20
+ property bool isCurrent: ListView.isCurrentItem
+ }
+ }
+ ListView {
+ objectName: "listView"
+ model: dm
+ currentIndex: 1
+ anchors.fill: parent
+ }
+}
diff --git a/tests/auto/quick/qquicklistview2/data/qtbug98315.qml b/tests/auto/quick/qquicklistview2/data/qtbug98315.qml
new file mode 100644
index 0000000000..bf2ed857b1
--- /dev/null
+++ b/tests/auto/quick/qquicklistview2/data/qtbug98315.qml
@@ -0,0 +1,98 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQml.Models
+
+Item {
+ width: 500
+ height: 200
+
+ property list<QtObject> myModel: [
+ QtObject {
+ objectName: "Item 0"
+ property bool selected: true
+ },
+ QtObject {
+ objectName: "Item 1"
+ property bool selected: false
+ },
+ QtObject {
+ objectName: "Item 2"
+ property bool selected: false
+ },
+ QtObject {
+ objectName: "Item 3"
+ property bool selected: true
+ },
+ QtObject {
+ objectName: "Item 4"
+ property bool selected: true
+ },
+ QtObject {
+ objectName: "Item 5"
+ property bool selected: true
+ },
+ QtObject {
+ objectName: "Item 6"
+ property bool selected: false
+ }
+ ]
+
+ ListView {
+ objectName: "listView"
+ id: listview
+ width: 500
+ height: 200
+
+ focus: true
+ clip: true
+ spacing: 2
+ orientation: ListView.Horizontal
+ highlightMoveDuration: 300
+ highlightMoveVelocity: -1
+ preferredHighlightBegin: (500 - 100) / 2
+ preferredHighlightEnd: (500 + 100) / 2
+ highlightRangeMode: ListView.StrictlyEnforceRange
+ cacheBuffer: 500
+ currentIndex: 1
+
+ model: DelegateModel {
+ id: delegateModel
+ filterOnGroup: "visible"
+ model: myModel
+ groups: [
+ DelegateModelGroup {
+ name: "visible"
+ includeByDefault: true
+ }
+ ]
+ delegate: Rectangle {
+ id: tile
+ objectName: model.modelData.objectName
+
+ width: 100
+ height: 100
+ border.width: 0
+ anchors.verticalCenter: parent.verticalCenter
+
+ visible: model.modelData.selected
+ Component.onCompleted: {
+ DelegateModel.inPersistedItems = true
+ DelegateModel.inVisible = Qt.binding(function () {
+ return model.modelData.selected
+ })
+ }
+
+ property bool isCurrent: ListView.isCurrentItem
+ color: isCurrent ? "red" : "green"
+
+ Text {
+ id: valueText
+ anchors.centerIn: parent
+ text: model.modelData.objectName
+ }
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp b/tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp
index 2c701bd5dc..4c6f9c70e2 100644
--- a/tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp
+++ b/tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp
@@ -63,6 +63,8 @@ private slots:
void tapDelegateDuringFlicking();
void flickDuringFlicking_data();
void flickDuringFlicking();
+ void isCurrentItem_DelegateModel();
+ void isCurrentItem_NoRegressionWithDelegateModelGroups();
private:
void flickWithTouch(QQuickWindow *window, const QPoint &from, const QPoint &to);
@@ -423,6 +425,45 @@ void tst_QQuickListView2::delegateModelRefresh()
QTRY_VERIFY(engine.rootObjects().first()->property("done").toBool());
}
+void tst_QQuickListView2::isCurrentItem_DelegateModel()
+{
+ QScopedPointer<QQuickView> window(createView());
+ window->setSource(testFileUrl("qtbug86744.qml"));
+ window->resize(640, 480);
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
+ QQuickListView* listView = window->rootObject()->findChild<QQuickListView*>("listView");
+ QVERIFY(listView);
+ QVariant value = listView->itemAtIndex(1)->property("isCurrent");
+ QVERIFY(value.toBool() == true);
+}
+
+void tst_QQuickListView2::isCurrentItem_NoRegressionWithDelegateModelGroups()
+{
+ QScopedPointer<QQuickView> window(createView());
+ window->setSource(testFileUrl("qtbug98315.qml"));
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
+ QQuickListView* listView = window->rootObject()->findChild<QQuickListView*>("listView");
+ QVERIFY(listView);
+
+ QQuickItem *item3 = listView->itemAtIndex(1);
+ QVERIFY(item3);
+ QCOMPARE(item3->property("isCurrent").toBool(), true);
+
+ QObject *item0 = listView->itemAtIndex(0);
+ QVERIFY(item0);
+ QCOMPARE(item0->property("isCurrent").toBool(), false);
+
+ // Press left arrow key -> Item 1 should become current, Item 3 should not
+ // be current anymore. After a previous fix of QTBUG-86744 it was working
+ // incorrectly - see QTBUG-98315
+ QTest::keyPress(window.get(), Qt::Key_Left);
+
+ QTRY_COMPARE(item0->property("isCurrent").toBool(), true);
+ QCOMPARE(item3->property("isCurrent").toBool(), false);
+}
+
QTEST_MAIN(tst_QQuickListView2)
#include "tst_qquicklistview2.moc"
diff --git a/tests/auto/quick/qquickloader/tst_qquickloader.cpp b/tests/auto/quick/qquickloader/tst_qquickloader.cpp
index 620ada57db..067fa759d8 100644
--- a/tests/auto/quick/qquickloader/tst_qquickloader.cpp
+++ b/tests/auto/quick/qquickloader/tst_qquickloader.cpp
@@ -133,6 +133,7 @@ private slots:
void statusChangeOnlyEmittedOnce();
void setSourceAndCheckStatus();
+ void loadComponentWithStates();
void asyncLoaderRace();
void noEngine();
@@ -1518,6 +1519,26 @@ void tst_QQuickLoader::setSourceAndCheckStatus()
QCOMPARE(loader->status(), QQuickLoader::Null);
}
+void tst_QQuickLoader::loadComponentWithStates()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData(QByteArray("import QtQuick\n"
+ "Loader {\n"
+ "id: loader\n"
+ "property int createdObjCount: 0\n"
+ "states: [ State { when: true; PropertyChanges { target: loader; sourceComponent: myComp } } ]\n"
+ "Component { id: myComp; Item { Component.onCompleted: { ++createdObjCount } } }\n"
+ "}" )
+ , dataDirectoryUrl());
+ QScopedPointer<QQuickLoader> loader(qobject_cast<QQuickLoader*>(component.create()));
+ QTest::qWait(200);
+ QTRY_VERIFY(loader != nullptr);
+ QVERIFY(loader->item());
+ QCOMPARE(static_cast<QQuickItem*>(loader.data())->childItems().size(), 1);
+ QCOMPARE(loader->property("createdObjCount").toInt(), 1);
+}
+
void tst_QQuickLoader::asyncLoaderRace()
{
QQmlApplicationEngine engine;
diff --git a/tests/auto/quickcontrols2/controls/data/tst_splitview.qml b/tests/auto/quickcontrols2/controls/data/tst_splitview.qml
index 6004f9eb44..76174a3c8e 100644
--- a/tests/auto/quickcontrols2/controls/data/tst_splitview.qml
+++ b/tests/auto/quickcontrols2/controls/data/tst_splitview.qml
@@ -2575,4 +2575,26 @@ TestCase {
mouseMove(control, control.width - 100, control.height / 2)
verify(!targetHandle.SplitHandle.hovered)
}
+
+ function test_touch() {
+ let control = createTemporaryObject(threeSizedItemsComponent, testCase)
+ verify(control)
+
+ let touch = touchEvent(control)
+
+ let handles = findHandles(control)
+ let firstHandle = handles[0]
+ let handleCenter = control.mapFromItem(firstHandle, firstHandle.width / 2, firstHandle.height / 2)
+ touch.press(0, control, handleCenter.x, handleCenter.y).commit()
+ verify(firstHandle.SplitHandle.pressed)
+
+ touch.move(0, control, handleCenter.x + 100, handleCenter.y).commit()
+ verify(firstHandle.SplitHandle.pressed)
+ let firstItem = control.itemAt(0)
+ compare(firstItem.width, 125)
+
+ touch.release(0, control, handleCenter.x + 100, handleCenter.y).commit()
+ verify(!firstHandle.SplitHandle.pressed)
+ compare(firstItem.width, 125)
+ }
}
diff --git a/tests/auto/quickcontrols2/qquickdrawer/data/itemPartialOverlayModal.qml b/tests/auto/quickcontrols2/qquickdrawer/data/itemPartialOverlayModal.qml
new file mode 100644
index 0000000000..23aa4ca3c2
--- /dev/null
+++ b/tests/auto/quickcontrols2/qquickdrawer/data/itemPartialOverlayModal.qml
@@ -0,0 +1,13 @@
+import QtQuick 2.15
+import QtQuick.Controls 2.15
+
+Item {
+ width: 400; height: 400
+
+ Drawer {
+ edge: Qt.LeftEdge
+ height: 200
+ width: 200
+ modal: true
+ }
+}
diff --git a/tests/auto/quickcontrols2/qquickdrawer/tst_qquickdrawer.cpp b/tests/auto/quickcontrols2/qquickdrawer/tst_qquickdrawer.cpp
index 6b6713bdde..2c6d50a591 100644
--- a/tests/auto/quickcontrols2/qquickdrawer/tst_qquickdrawer.cpp
+++ b/tests/auto/quickcontrols2/qquickdrawer/tst_qquickdrawer.cpp
@@ -46,14 +46,16 @@
#include <QtGui/private/qguiapplication_p.h>
#include <QtQuick/private/qquickwindow_p.h>
#include <QtQuick/private/qquickflickable_p.h>
+#include <QtQuick/qquickview.h>
#include <QtQuickTestUtils/private/qmlutils_p.h>
#include <QtQuickTestUtils/private/visualtestutils_p.h>
#include <QtQuickTemplates2/private/qquickapplicationwindow_p.h>
-#include <QtQuickTemplates2/private/qquickoverlay_p.h>
+#include <QtQuickTemplates2/private/qquickoverlay_p_p.h>
#include <QtQuickTemplates2/private/qquickpopup_p_p.h>
#include <QtQuickTemplates2/private/qquickdrawer_p.h>
#include <QtQuickTemplates2/private/qquickbutton_p.h>
#include <QtQuickTemplates2/private/qquickslider_p.h>
+#include <QtQuickTestUtils/private/viewtestutils_p.h>
#include <QtQuickControlsTestUtils/private/controlstestutils_p.h>
#include <QtQuickControlsTestUtils/private/qtest_quickcontrols_p.h>
@@ -121,6 +123,8 @@ private slots:
void topEdgeScreenEdge();
+ void touchOutsideOverlay();
+
private:
QScopedPointer<QPointingDevice> touchDevice;
};
@@ -1393,6 +1397,41 @@ void tst_QQuickDrawer::topEdgeScreenEdge()
QTRY_COMPARE(drawer->position(), 1.0);
}
+void tst_QQuickDrawer::touchOutsideOverlay() // QTBUG-103811
+{
+ QQuickView window;
+ QVERIFY(QQuickTest::showView(window, testFileUrl("itemPartialOverlayModal.qml")));
+ auto *drawer = window.rootObject()->findChild<QQuickDrawer*>();
+ QVERIFY(drawer);
+ QSignalSpy openedSpy(drawer, &QQuickDrawer::opened);
+ QSignalSpy closedSpy(drawer, &QQuickDrawer::closed);
+
+ drawer->open();
+ QVERIFY(openedSpy.size() == 1 || openedSpy.wait());
+ QVERIFY(drawer->isOpened());
+
+ // tap-dance in bottom area beyond the overlay
+ QPoint p1(100, 250);
+ QPoint p2(300, 250);
+ QTest::touchEvent(&window, touchDevice.data()).press(1, p1);
+ p1 -= QPoint(1, 0);
+ QTest::touchEvent(&window, touchDevice.data()).move(1, p1).press(2, p2);
+ p2 -= QPoint(1, 0);
+ QTest::touchEvent(&window, touchDevice.data()).release(1, p1).move(2, p2);
+ QTest::touchEvent(&window, touchDevice.data()).press(1, p1).stationary(2);
+ QTest::touchEvent(&window, touchDevice.data()).release(1, p1).release(2, p2);
+ QQuickTouchUtils::flush(&window);
+
+ // tap the overlay to try to close the drawer
+ QVERIFY(drawer->closePolicy().testFlag(QQuickPopup::CloseOnReleaseOutside));
+ const QPoint p3(300, 100);
+ QTest::touchEvent(&window, touchDevice.data()).press(3, p3);
+ QTest::touchEvent(&window, touchDevice.data()).release(3, p3);
+ QQuickTouchUtils::flush(&window);
+ QVERIFY(closedSpy.size() == 1 || closedSpy.wait());
+ QCOMPARE(drawer->isOpened(), false);
+}
+
QTEST_QUICKCONTROLS_MAIN(tst_QQuickDrawer)
#include "tst_qquickdrawer.moc"
diff --git a/tests/auto/quickcontrols2/qquickpopup/data/mirroredCombobox.qml b/tests/auto/quickcontrols2/qquickpopup/data/mirroredCombobox.qml
new file mode 100644
index 0000000000..ed48179bce
--- /dev/null
+++ b/tests/auto/quickcontrols2/qquickpopup/data/mirroredCombobox.qml
@@ -0,0 +1,26 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Controls
+
+Window {
+ width: 400
+ height: 400
+
+ contentItem.rotation: 180
+
+ ComboBox {
+ objectName: "first"
+ x: 100
+ y: 300 // is missing space, needs to unroll in the "mirrored" direction
+ model: ["First", "Second", "Third", "Fourth", "Fifth"]
+ }
+
+ ComboBox {
+ objectName: "second"
+ x: 200
+ y: 100 // has enough space to unroll
+ model: ["A", "B", "C"]
+ }
+}
diff --git a/tests/auto/quickcontrols2/qquickpopup/data/rotatedCombobox.qml b/tests/auto/quickcontrols2/qquickpopup/data/rotatedCombobox.qml
new file mode 100644
index 0000000000..df217be4b7
--- /dev/null
+++ b/tests/auto/quickcontrols2/qquickpopup/data/rotatedCombobox.qml
@@ -0,0 +1,26 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Controls
+
+Window {
+ width: 400
+ height: 400
+
+ contentItem.rotation: 90
+
+ ComboBox {
+ objectName: "first"
+ x: 100
+ y: 320 // is missing space, needs to unroll in the "mirrored" direction
+ model: ["First", "Second", "Third", "Fourth", "Fifth"]
+ }
+
+ ComboBox {
+ objectName: "second"
+ x: 200
+ y: 100 // has enough space to unroll
+ model: ["A", "B", "C"]
+ }
+}
diff --git a/tests/auto/quickcontrols2/qquickpopup/tst_qquickpopup.cpp b/tests/auto/quickcontrols2/qquickpopup/tst_qquickpopup.cpp
index 75d66335f1..d2cfda9375 100644
--- a/tests/auto/quickcontrols2/qquickpopup/tst_qquickpopup.cpp
+++ b/tests/auto/quickcontrols2/qquickpopup/tst_qquickpopup.cpp
@@ -118,6 +118,8 @@ private slots:
void dimmerContainmentMask();
void shrinkPopupThatWasLargerThanWindow_data();
void shrinkPopupThatWasLargerThanWindow();
+ void mirroredCombobox();
+ void rotatedCombobox();
private:
static bool hasWindowActivation();
@@ -1878,6 +1880,155 @@ void tst_QQuickPopup::shrinkPopupThatWasLargerThanWindow()
.arg(popup->height()).arg(window->height())));
}
+void tst_QQuickPopup::mirroredCombobox()
+{
+#ifdef Q_OS_ANDROID
+ // Android screens might be pretty small, such that additional
+ // repositioning (apart from the mirroring) will happen to the
+ // popups and mess up the expected positions below.
+ QSKIP("Skipping test for Android.");
+#endif
+ QStringList nativeStyles;
+ nativeStyles.append("macOS");
+ nativeStyles.append("iOS");
+ nativeStyles.append("Windows");
+ if (nativeStyles.contains(QQuickStyle::name()))
+ QSKIP("Skipping test for native styles: they might rearrange their combobox the way they "
+ "want.");
+
+ QQuickControlsApplicationHelper helper(this, "mirroredCombobox.qml");
+ QVERIFY2(helper.ready, helper.failureMessage());
+
+ QQuickWindow *window = helper.window;
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
+
+ {
+ QQuickComboBox *comboBox = window->findChild<QQuickComboBox *>("first");
+ QVERIFY(comboBox);
+ QQuickPopup *popup = comboBox->popup();
+ QVERIFY(popup);
+ popup->open();
+ QTRY_COMPARE(popup->isVisible(), true);
+ const QPointF popupPos(popup->contentItem()->mapToItem(comboBox->parentItem(),
+ popup->contentItem()->position()));
+ const QSizeF popupSize(popup->contentItem()->size());
+
+ // ignore popup.{top,bottom}Padding() as not included in popup->contentItem()->size()
+ // some styles prefer to draw the popup "over" (in z-axis direction) the combobox to hide
+ // the combobox
+ const bool styleDrawsPopupOverCombobox =
+ comboBox->position().y() - popupSize.height() + comboBox->size().height()
+ == popupPos.y();
+ // some styles prefer to draw the popup below (in y-axis direction) the combobox
+ const bool styleDrawsPopupBelowCombobox =
+ comboBox->position().y() - popupSize.height() + comboBox->topPadding()
+ == popupPos.y();
+
+ QVERIFY(styleDrawsPopupOverCombobox || styleDrawsPopupBelowCombobox);
+
+ popup->close();
+ }
+
+ {
+ QQuickComboBox *comboBox = window->findChild<QQuickComboBox *>("second");
+ QVERIFY(comboBox);
+ QQuickPopup *popup = comboBox->popup();
+ QVERIFY(popup);
+ popup->open();
+ QTRY_COMPARE(popup->isVisible(), true);
+ const QPointF popupPos(popup->contentItem()->mapToItem(comboBox->parentItem(),
+ popup->contentItem()->position()));
+
+ // some styles prefer to draw the popup "over" (in z-axis direction) the combobox to hide
+ // the combobox
+ const bool styleDrawsPopupOverCombobox = comboBox->position().y() + comboBox->topPadding()
+ + popup->topPadding() + popup->bottomPadding()
+ == popupPos.y();
+ // some styles prefer to draw the popup above (in y-axis direction) the combobox
+ const bool styleDrawsPopupAboveCombobox =
+ comboBox->position().y() + comboBox->height() - comboBox->topPadding()
+ == popupPos.y();
+
+ QVERIFY(styleDrawsPopupOverCombobox || styleDrawsPopupAboveCombobox);
+
+ popup->close();
+ }
+}
+
+void tst_QQuickPopup::rotatedCombobox()
+{
+#ifdef Q_OS_ANDROID
+ // Android screens might be pretty small, such that additional
+ // repositioning (apart from the rotating) will happen to the
+ // popups and mess up the expected positions below.
+ QSKIP("Skipping test for Android.");
+#endif
+ QStringList nativeStyles;
+ nativeStyles.append("macOS");
+ nativeStyles.append("iOS");
+ nativeStyles.append("Windows");
+ if (nativeStyles.contains(QQuickStyle::name()))
+ QSKIP("Skipping test for native styles: they might rearrange their combobox the way they "
+ "want.");
+
+ QQuickControlsApplicationHelper helper(this, "rotatedCombobox.qml");
+ QVERIFY2(helper.ready, helper.failureMessage());
+
+ QQuickWindow *window = helper.window;
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
+
+ {
+ QQuickComboBox *comboBox = window->findChild<QQuickComboBox *>("first");
+ QVERIFY(comboBox);
+ QQuickPopup *popup = comboBox->popup();
+ QVERIFY(popup);
+ popup->open();
+ QTRY_COMPARE(popup->isVisible(), true);
+ const QPointF popupPos(popup->contentItem()->mapToItem(comboBox->parentItem(),
+ popup->contentItem()->position()));
+ const QSizeF popupSize(popup->contentItem()->size());
+
+ // ignore popup.{left,right}Padding() as not included in popup->contentItem()->size()
+ // some styles prefer to draw the popup "over" (in z-axis direction) the combobox to hide
+ // the combobox
+ const bool styleDrawsPopupOverCombobox =
+ comboBox->position().x() - popupSize.width() + comboBox->width() == popupPos.x();
+ // some styles prefer to draw the popup right (in x-axis direction) of the combobox
+ const bool styleDrawsPopupBelowCombobox =
+ comboBox->position().x() - popupSize.width() - comboBox->leftPadding()
+ == popupPos.x();
+
+ QVERIFY(styleDrawsPopupOverCombobox || styleDrawsPopupBelowCombobox);
+ }
+
+ {
+ QQuickComboBox *comboBox = window->findChild<QQuickComboBox *>("second");
+ QVERIFY(comboBox);
+ QQuickPopup *popup = comboBox->popup();
+ QVERIFY(popup);
+ popup->open();
+ QTRY_COMPARE(popup->isVisible(), true);
+ const QPointF popupPos(popup->contentItem()->mapToItem(comboBox->parentItem(),
+ popup->contentItem()->position()));
+
+ // some styles prefer to draw the popup "over" (in z-axis direction) the combobox to hide
+ // the combobox
+ const bool styleDrawsPopupOverCombobox = comboBox->position().x() + comboBox->leftPadding()
+ + popup->leftPadding() + popup->rightPadding()
+ == popupPos.x();
+ // some styles prefer to draw the popup left (in y-axis direction) of the combobox
+ const bool styleDrawsPopupAboveCombobox =
+ comboBox->position().x() + comboBox->width() - comboBox->leftPadding()
+ == popupPos.x();
+
+ QVERIFY(styleDrawsPopupOverCombobox || styleDrawsPopupAboveCombobox);
+
+ popup->close();
+ }
+}
+
QTEST_QUICKCONTROLS_MAIN(tst_QQuickPopup)
#include "tst_qquickpopup.moc"
diff --git a/tests/auto/quickwidgets/qquickwidget/CMakeLists.txt b/tests/auto/quickwidgets/qquickwidget/CMakeLists.txt
index 24da087db5..5ce5cf3125 100644
--- a/tests/auto/quickwidgets/qquickwidget/CMakeLists.txt
+++ b/tests/auto/quickwidgets/qquickwidget/CMakeLists.txt
@@ -19,6 +19,7 @@ qt_internal_add_test(tst_qquickwidget
Qt::GuiPrivate
Qt::QmlPrivate
Qt::QuickPrivate
+ Qt::QuickTemplates2Private
Qt::QuickWidgets
Qt::QuickWidgetsPrivate
Qt::WidgetsPrivate
diff --git a/tests/auto/quickwidgets/qquickwidget/data/button.qml b/tests/auto/quickwidgets/qquickwidget/data/button.qml
new file mode 100644
index 0000000000..30698908d7
--- /dev/null
+++ b/tests/auto/quickwidgets/qquickwidget/data/button.qml
@@ -0,0 +1,27 @@
+import QtQuick
+import QtQuick.Controls.Basic
+
+Item {
+ width: 100
+ height: 100
+ visible: true
+
+ property bool wasPressed: false
+ property bool wasReleased: false
+ property bool wasClicked: false
+
+ Popup {
+ closePolicy: Popup.NoAutoClose
+ visible: true
+
+ Button {
+ objectName: "button"
+ text: "TAP ME"
+ anchors.fill: parent
+
+ onPressed: wasPressed = true
+ onReleased: wasReleased = true
+ onClicked: wasClicked = true
+ }
+ }
+}
diff --git a/tests/auto/quickwidgets/qquickwidget/data/mouse.qml b/tests/auto/quickwidgets/qquickwidget/data/mouse.qml
index 5d1c6e8443..25a7329a08 100644
--- a/tests/auto/quickwidgets/qquickwidget/data/mouse.qml
+++ b/tests/auto/quickwidgets/qquickwidget/data/mouse.qml
@@ -7,8 +7,10 @@ Rectangle {
property bool wasClicked: false
property bool wasDoubleClicked: false
property bool wasMoved: false
+ color: ma.pressed ? "wheat" : "lightsteelblue"
MouseArea {
+ id: ma
anchors.fill: parent
hoverEnabled: true
onClicked: wasClicked = true
diff --git a/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp b/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp
index 1ef70e6515..54673b70ce 100644
--- a/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp
+++ b/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp
@@ -35,6 +35,8 @@
#include <QtQuick/qquickview.h>
#include <QtQuick/qquickitem.h>
#include <QtQuick/private/qquickitem_p.h>
+#include <QtQuick/private/qquickmousearea_p.h>
+#include <QtQuickTemplates2/private/qquickbutton_p.h>
#include <QtQuickTestUtils/private/qmlutils_p.h>
#include <QtGui/QWindow>
#include <QtGui/QScreen>
@@ -148,6 +150,9 @@ private slots:
void mouseEventWindowPos();
void synthMouseFromTouch_data();
void synthMouseFromTouch();
+ void touchTapMouseArea();
+ void touchTapButton();
+ void touchMultipleWidgets();
void tabKey();
void resizeOverlay();
void controls();
@@ -641,6 +646,7 @@ void tst_qquickwidget::synthMouseFromTouch()
QTest::touchEvent(&window, device).move(0, p2, &window);
QTest::touchEvent(&window, device).release(0, p2, &window);
+ qCDebug(lcTests) << item->m_touchEvents << item->m_mouseEvents;
QCOMPARE(item->m_touchEvents.count(), synthMouse ? 0 : (acceptTouch ? 3 : 1));
QCOMPARE(item->m_mouseEvents.count(), synthMouse ? 3 : 0);
QCOMPARE(childView->m_mouseEvents.count(), 0);
@@ -648,6 +654,98 @@ void tst_qquickwidget::synthMouseFromTouch()
QCOMPARE(ev, Qt::MouseEventSynthesizedByQt);
}
+void tst_qquickwidget::touchTapMouseArea()
+{
+ QWidget window;
+ window.resize(100, 100);
+ window.setObjectName("window widget");
+ window.setAttribute(Qt::WA_AcceptTouchEvents);
+ QVERIFY(QCoreApplication::testAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents));
+ QQuickWidget *quick = new QQuickWidget(&window);
+ quick->setSource(testFileUrl("mouse.qml"));
+ quick->move(50, 50);
+ quick->setObjectName("quick widget");
+ window.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&window));
+ QQuickItem *rootItem = quick->rootObject();
+ QVERIFY(rootItem);
+ QQuickMouseArea *ma = rootItem->findChild<QQuickMouseArea *>();
+ QVERIFY(ma);
+
+ QPoint p1 = QPoint(70, 70);
+ QTest::touchEvent(&window, device).press(0, p1, &window);
+ QTRY_COMPARE(ma->pressed(), true);
+ QTest::touchEvent(&window, device).move(0, p1, &window);
+ QTest::touchEvent(&window, device).release(0, p1, &window);
+ QTRY_COMPARE(ma->pressed(), false);
+ QVERIFY(rootItem->property("wasClicked").toBool());
+}
+
+void tst_qquickwidget::touchTapButton()
+{
+ QWidget window;
+ QQuickWidget *quick = new QQuickWidget;
+ quick->setSource(testFileUrl("button.qml"));
+
+ QHBoxLayout hbox;
+ hbox.addWidget(quick);
+ window.setLayout(&hbox);
+ window.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&window));
+
+ QQuickItem *rootItem = quick->rootObject();
+ QVERIFY(rootItem);
+ QQuickButton *button = rootItem->findChild<QQuickButton *>("button");
+ QVERIFY(button);
+
+ const QPoint point = quick->mapTo(&window, button->mapToScene(button->boundingRect().center()).toPoint());
+ QTest::touchEvent(&window, device).press(0, point, &window).commit();
+ QTRY_VERIFY(rootItem->property("wasPressed").toBool());
+ QTest::touchEvent(&window, device).release(0, point, &window).commit();
+ QTRY_VERIFY(rootItem->property("wasReleased").toBool());
+ QTRY_VERIFY(rootItem->property("wasClicked").toBool());
+}
+
+void tst_qquickwidget::touchMultipleWidgets()
+{
+ QWidget window;
+ QQuickWidget *leftQuick = new QQuickWidget;
+ leftQuick->setSource(testFileUrl("button.qml"));
+ QQuickWidget *rightQuick = new QQuickWidget;
+ rightQuick->setSource(testFileUrl("button.qml"));
+
+ QHBoxLayout hbox;
+ hbox.addWidget(leftQuick);
+ hbox.addWidget(rightQuick);
+ window.setLayout(&hbox);
+ window.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&window));
+
+ QQuickItem *leftRootItem = leftQuick->rootObject();
+ QQuickItem *rightRootItem = rightQuick->rootObject();
+ QVERIFY(leftRootItem);
+ QVERIFY(rightRootItem);
+ QQuickButton *leftButton = leftRootItem->findChild<QQuickButton *>("button");
+ QQuickButton *rightButton = rightRootItem->findChild<QQuickButton *>("button");
+ QVERIFY(leftButton);
+ QVERIFY(rightButton);
+
+ const QPoint leftPoint = leftQuick->mapTo(&window, leftButton->mapToScene(
+ leftButton->boundingRect().center()).toPoint());
+ const QPoint rightPoint = rightQuick->mapTo(&window, rightButton->mapToScene(
+ rightButton->boundingRect().center()).toPoint());
+ QTest::touchEvent(&window, device).press(0, leftPoint, &window).commit();
+ QTRY_VERIFY(leftRootItem->property("wasPressed").toBool());
+ QTest::touchEvent(&window, device).press(1, rightPoint, &window).commit();
+ QTRY_VERIFY(rightRootItem->property("wasPressed").toBool());
+ QTest::touchEvent(&window, device).release(1, rightPoint, &window).commit();
+ QTRY_VERIFY(rightRootItem->property("wasReleased").toBool());
+ QVERIFY(rightRootItem->property("wasClicked").toBool());
+ QTest::touchEvent(&window, device).release(0, leftPoint, &window).commit();
+ QTRY_VERIFY(leftRootItem->property("wasReleased").toBool());
+ QVERIFY(leftRootItem->property("wasClicked").toBool());
+}
+
void tst_qquickwidget::tabKey()
{
if (QGuiApplication::styleHints()->tabFocusBehavior() != Qt::TabFocusAllControls)