diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-10-04 01:00:22 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2019-10-04 11:29:16 +0200 |
commit | 9c7121df1579d38c7f4136da6146d7acae8fedcc (patch) | |
tree | 0917e293d83b4c1ce635cf65185e6ad98fe66519 /tests/auto | |
parent | f529d38103a6c1c5c7b76ad92e0e5641719e369e (diff) | |
parent | c211b93bb87308601fe1c808634eb648d1949c40 (diff) |
Merge remote-tracking branch 'origin/5.14' into 5.15
Conflicts:
src/imports/qtquick2/plugins.qmltypes
src/quick/items/qquickitemsmodule.cpp
Change-Id: I841c65c9c131354788b4f3fcfe3d7ed27be316d5
Diffstat (limited to 'tests/auto')
39 files changed, 746 insertions, 167 deletions
diff --git a/tests/auto/qml/qmlcachegen/data/module.mjs b/tests/auto/qml/qmlcachegen/data/module.mjs new file mode 100644 index 0000000000..6838766329 --- /dev/null +++ b/tests/auto/qml/qmlcachegen/data/module.mjs @@ -0,0 +1,6 @@ + +import { helper } from "utils.mjs" + +export function entry() { + return helper() +} diff --git a/tests/auto/qml/qmlcachegen/data/utils.mjs b/tests/auto/qml/qmlcachegen/data/utils.mjs new file mode 100644 index 0000000000..25a1f38709 --- /dev/null +++ b/tests/auto/qml/qmlcachegen/data/utils.mjs @@ -0,0 +1,4 @@ + +export function helper() { + return "ok" +} diff --git a/tests/auto/qml/qmlcachegen/qmlcachegen.pro b/tests/auto/qml/qmlcachegen/qmlcachegen.pro index 18d3abd6bc..1a334b68ce 100644 --- a/tests/auto/qml/qmlcachegen/qmlcachegen.pro +++ b/tests/auto/qml/qmlcachegen/qmlcachegen.pro @@ -15,7 +15,9 @@ RESOURCES += \ data/Enums.qml \ data/componentInItem.qml \ data/jsmoduleimport.qml \ - data/script.mjs + data/script.mjs \ + data/module.mjs \ + data/utils.mjs workerscripts_test.files = \ data/worker.js \ diff --git a/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp b/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp index 7441aed11f..5d87c319f3 100644 --- a/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp +++ b/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp @@ -65,6 +65,7 @@ private slots: void qrcScriptImport(); void fsScriptImport(); void moduleScriptImport(); + void esModulesViaQJSEngine(); void enums(); @@ -601,6 +602,14 @@ void tst_qmlcachegen::moduleScriptImport() } } +void tst_qmlcachegen::esModulesViaQJSEngine() +{ + QJSEngine engine; + QJSValue module = engine.importModule(":/data/module.mjs"); + QJSValue result = module.property("entry").call(); + QCOMPARE(result.toString(), "ok"); +} + void tst_qmlcachegen::enums() { QQmlEngine engine; diff --git a/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp b/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp index b6cc7fd866..2acc62ca28 100644 --- a/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp +++ b/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp @@ -225,12 +225,12 @@ void tst_qqmlcomponent::qmlCreateObjectAutoParent() QVERIFY(window_item); QVERIFY(window_window); - QCOMPARE(qtobject_item->metaObject()->className(), "QQuickItem"); - QCOMPARE(qtobject_window->metaObject()->className(), "QQuickWindow"); - QCOMPARE(item_item->metaObject()->className(), "QQuickItem"); - QCOMPARE(item_window->metaObject()->className(), "QQuickWindow"); - QCOMPARE(window_item->metaObject()->className(), "QQuickItem"); - QCOMPARE(window_window->metaObject()->className(), "QQuickWindow"); + QVERIFY(QByteArray(qtobject_item->metaObject()->className()).startsWith("QQuickItem")); + QVERIFY(QByteArray(qtobject_window->metaObject()->className()).startsWith("QQuickWindow")); + QVERIFY(QByteArray(item_item->metaObject()->className()).startsWith("QQuickItem")); + QVERIFY(QByteArray(item_window->metaObject()->className()).startsWith("QQuickWindow")); + QVERIFY(QByteArray(window_item->metaObject()->className()).startsWith("QQuickItem")); + QVERIFY(QByteArray(window_window->metaObject()->className()).startsWith("QQuickWindow")); QCOMPARE(qtobject_qtobject->parent(), qtobjectParent); QCOMPARE(qtobject_item->parent(), qtobjectParent); diff --git a/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp b/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp index cf0f3c7bb3..07af519a3d 100644 --- a/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp +++ b/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp @@ -470,7 +470,7 @@ void tst_qqmlconnections::noAcceleratedGlobalLookup() QVERIFY(c.isReady()); QScopedPointer<QObject> object(c.create()); const QVariant val = object->property("testEnum"); - QCOMPARE(val.type(), int(QMetaType::Int)); + QCOMPARE(val.type(), QVariant::Int); QCOMPARE(val.toInt(), int(Proxy::EnumValue)); } diff --git a/tests/auto/qml/qqmlcpputils/tst_qqmlcpputils.cpp b/tests/auto/qml/qqmlcpputils/tst_qqmlcpputils.cpp index 99cabb4b09..13e4d4c53b 100644 --- a/tests/auto/qml/qqmlcpputils/tst_qqmlcpputils.cpp +++ b/tests/auto/qml/qqmlcpputils/tst_qqmlcpputils.cpp @@ -71,7 +71,7 @@ void tst_qqmlcpputils::fastConnect() { MyObject obj; - qmlobject_connect(&obj, MyObject, SIGNAL(signal1()), &obj, MyObject, SLOT(slot1())) + qmlobject_connect(&obj, MyObject, SIGNAL(signal1()), &obj, MyObject, SLOT(slot1())); obj.signal1(); QCOMPARE(obj.slotCount, 1); diff --git a/tests/auto/qml/qqmlecmascript/data/signalParameterTypes.qml b/tests/auto/qml/qqmlecmascript/data/signalParameterTypes.qml index 54d29dfc94..9fdb7f92f3 100644 --- a/tests/auto/qml/qqmlecmascript/data/signalParameterTypes.qml +++ b/tests/auto/qml/qqmlecmascript/data/signalParameterTypes.qml @@ -1,4 +1,5 @@ import Qt.test 1.0 +import QtQuick 2.0 // We need the the QtQuick color provider for colorProperty MyQmlObject { diff --git a/tests/auto/qml/qqmlecmascript/testtypes.h b/tests/auto/qml/qqmlecmascript/testtypes.h index 730dc7cab8..3233e7f105 100644 --- a/tests/auto/qml/qqmlecmascript/testtypes.h +++ b/tests/auto/qml/qqmlecmascript/testtypes.h @@ -1098,13 +1098,11 @@ class MyItemUsingRevisionedObject : public QObject Q_PROPERTY(MyRevisionedClass *revisioned READ revisioned) public: - MyItemUsingRevisionedObject() { - m_revisioned = new MyRevisionedClass; - } + MyItemUsingRevisionedObject() : m_revisioned (new MyRevisionedClass) {} - MyRevisionedClass *revisioned() const { return m_revisioned; } + MyRevisionedClass *revisioned() const { return m_revisioned.get(); } private: - MyRevisionedClass *m_revisioned; + QScopedPointer<MyRevisionedClass> m_revisioned; }; QML_DECLARE_TYPE(MyRevisionedBaseClassRegistered) diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index cfdb15304d..160546fc64 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -1693,10 +1693,10 @@ void tst_qqmlecmascript::componentCreation() } QQmlComponent component(&engine, testUrl); - MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create()); + QScopedPointer<MyTypeObject> object(qobject_cast<MyTypeObject*>(component.create())); QVERIFY(object != nullptr); - QMetaObject::invokeMethod(object, method.toUtf8()); + QMetaObject::invokeMethod(object.get(), method.toUtf8()); QQmlComponent *created = object->componentProperty(); if (creationError.isEmpty()) { @@ -1704,7 +1704,7 @@ void tst_qqmlecmascript::componentCreation() QObject *expectedParent = reinterpret_cast<QObject *>(quintptr(-1)); if (createdParent == QLatin1String("obj")) { - expectedParent = object; + expectedParent = object.get(); } else if ((createdParent == QLatin1String("null")) || createdParent.isEmpty()) { expectedParent = nullptr; } @@ -2050,7 +2050,7 @@ void tst_qqmlecmascript::functionErrors() QObject *resource = qobject_cast<ScarceResourceObject*>(QQmlProperty::read(object, "a").value<QObject*>()); warning = url + QLatin1String(":16: TypeError: Property 'scarceResource' of object ScarceResourceObject(0x%1) is not a function"); - warning = warning.arg(QString::number((quintptr)resource, 16)); + warning = warning.arg(QString::number(quintptr(resource), 16)); QTest::ignoreMessage(QtWarningMsg, warning.toLatin1().constData()); // we expect a meaningful warning to be printed. QMetaObject::invokeMethod(object, "retrieveScarceResource"); delete object; @@ -3124,13 +3124,13 @@ void tst_qqmlecmascript::callQtInvokables() void tst_qqmlecmascript::resolveClashingProperties() { - ClashingNames *o = new ClashingNames(); + QScopedPointer<ClashingNames> o(new ClashingNames()); QQmlEngine qmlengine; QV4::ExecutionEngine *engine = qmlengine.handle(); QV4::Scope scope(engine); - QV4::ScopedValue object(scope, QV4::QObjectWrapper::wrap(engine, o)); + QV4::ScopedValue object(scope, QV4::QObjectWrapper::wrap(engine, o.get())); QV4::ObjectIterator it(scope, object->as<QV4::Object>(), QV4::ObjectIterator::EnumerableOnly); QV4::ScopedValue name(scope); QV4::ScopedValue value(scope); @@ -4575,7 +4575,7 @@ void tst_qqmlecmascript::scarceResources_other() eo = qobject_cast<ScarceResourceObject*>(QQmlProperty::read(object, "a").value<QObject*>()); QVERIFY(eo->scarceResourceIsDetached()); // should be no other copies of it at this stage. expectedWarning = varComponentTwelve.url().toString() + QLatin1String(":16: TypeError: Property 'scarceResource' of object ScarceResourceObject(0x%1) is not a function"); - expectedWarning = expectedWarning.arg(QString::number((quintptr)eo, 16)); + expectedWarning = expectedWarning.arg(QString::number(quintptr(eo), 16)); QTest::ignoreMessage(QtWarningMsg, qPrintable(expectedWarning)); // we expect a meaningful warning to be printed. QMetaObject::invokeMethod(object, "retrieveScarceResource"); QVERIFY(!object->property("scarceResourceCopy").isValid()); // due to exception, assignment will NOT have occurred. @@ -4649,7 +4649,7 @@ void tst_qqmlecmascript::scarceResources_other() eo = qobject_cast<ScarceResourceObject*>(QQmlProperty::read(object, "a").value<QObject*>()); QVERIFY(eo->scarceResourceIsDetached()); // should be no other copies of it at this stage. expectedWarning = variantComponentTwelve.url().toString() + QLatin1String(":16: TypeError: Property 'scarceResource' of object ScarceResourceObject(0x%1) is not a function"); - expectedWarning = expectedWarning.arg(QString::number((quintptr)eo, 16)); + expectedWarning = expectedWarning.arg(QString::number(quintptr(eo), 16)); QTest::ignoreMessage(QtWarningMsg, qPrintable(expectedWarning)); // we expect a meaningful warning to be printed. QMetaObject::invokeMethod(object, "retrieveScarceResource"); QVERIFY(!object->property("scarceResourceCopy").isValid()); // due to exception, assignment will NOT have occurred. @@ -6093,7 +6093,7 @@ void tst_qqmlecmascript::variants() QQmlEngine engine; QQmlComponent component(&engine, testFileUrl("variants.qml")); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); QCOMPARE(object->property("undefinedVariant").type(), QVariant::Invalid); @@ -6102,13 +6102,13 @@ void tst_qqmlecmascript::variants() QCOMPARE(object->property("doubleVariant").type(), QVariant::Double); QVariant result; - QMetaObject::invokeMethod(object, "checkNull", Q_RETURN_ARG(QVariant, result)); + QMetaObject::invokeMethod(object.get(), "checkNull", Q_RETURN_ARG(QVariant, result)); QCOMPARE(result.toBool(), true); - QMetaObject::invokeMethod(object, "checkUndefined", Q_RETURN_ARG(QVariant, result)); + QMetaObject::invokeMethod(object.get(), "checkUndefined", Q_RETURN_ARG(QVariant, result)); QCOMPARE(result.toBool(), true); - QMetaObject::invokeMethod(object, "checkNumber", Q_RETURN_ARG(QVariant, result)); + QMetaObject::invokeMethod(object.get(), "checkNumber", Q_RETURN_ARG(QVariant, result)); QCOMPARE(result.toBool(), true); } @@ -7000,12 +7000,12 @@ void tst_qqmlecmascript::realToInt() { QQmlEngine engine; QQmlComponent component(&engine, testFileUrl("realToInt.qml")); - MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create()); + QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject*>(component.create())); QVERIFY(object != nullptr); - QMetaObject::invokeMethod(object, "test1"); + QMetaObject::invokeMethod(object.get(), "test1"); QCOMPARE(object->value(), int(4)); - QMetaObject::invokeMethod(object, "test2"); + QMetaObject::invokeMethod(object.get(), "test2"); QCOMPARE(object->value(), int(7)); } @@ -7014,7 +7014,7 @@ void tst_qqmlecmascript::urlProperty() QQmlEngine engine; { QQmlComponent component(&engine, testFileUrl("urlProperty.1.qml")); - MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create()); + QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject*>(component.create())); QVERIFY(object != nullptr); object->setStringProperty("http://qt-project.org"); QCOMPARE(object->urlProperty(), QUrl("http://qt-project.org/index.html")); @@ -7029,7 +7029,7 @@ void tst_qqmlecmascript::urlPropertyWithEncoding() QQmlEngine engine; { QQmlComponent component(&engine, testFileUrl("urlProperty.2.qml")); - MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create()); + QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject*>(component.create())); QVERIFY(object != nullptr); object->setStringProperty("http://qt-project.org"); const QUrl encoded = QUrl::fromEncoded("http://qt-project.org/?get%3cDATA%3e", QUrl::TolerantMode); @@ -7064,7 +7064,7 @@ void tst_qqmlecmascript::dynamicString() { QQmlEngine engine; QQmlComponent component(&engine, testFileUrl("dynamicString.qml")); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); QCOMPARE(object->property("stringProperty").toString(), QString::fromLatin1("string:Hello World false:0 true:1 uint32:100 int32:-100 double:3.14159 date:2011-02-11 05::30:50!")); @@ -7074,7 +7074,7 @@ void tst_qqmlecmascript::deleteLaterObjectMethodCall() { QQmlEngine engine; QQmlComponent component(&engine, testFileUrl("deleteLaterObjectMethodCall.qml")); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); } @@ -7082,7 +7082,7 @@ void tst_qqmlecmascript::automaticSemicolon() { QQmlEngine engine; QQmlComponent component(&engine, testFileUrl("automaticSemicolon.qml")); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); } @@ -7090,7 +7090,7 @@ void tst_qqmlecmascript::compatibilitySemicolon() { QQmlEngine engine; QQmlComponent component(&engine, testFileUrl("compatibilitySemicolon.qml")); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); } @@ -7098,7 +7098,7 @@ void tst_qqmlecmascript::incrDecrSemicolon1() { QQmlEngine engine; QQmlComponent component(&engine, testFileUrl("incrDecrSemicolon1.qml")); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); } @@ -7106,7 +7106,7 @@ void tst_qqmlecmascript::incrDecrSemicolon2() { QQmlEngine engine; QQmlComponent component(&engine, testFileUrl("incrDecrSemicolon2.qml")); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); } @@ -7122,7 +7122,7 @@ void tst_qqmlecmascript::unaryExpression() { QQmlEngine engine; QQmlComponent component(&engine, testFileUrl("unaryExpression.qml")); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); } @@ -7262,7 +7262,7 @@ void tst_qqmlecmascript::switchStatement() QQmlEngine engine; { QQmlComponent component(&engine, testFileUrl("switchStatement.1.qml")); - MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); + QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject*>(component.create())); QVERIFY(object != nullptr); // `object->value()' is the number of executed statements @@ -7285,7 +7285,7 @@ void tst_qqmlecmascript::switchStatement() { QQmlComponent component(&engine, testFileUrl("switchStatement.2.qml")); - MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); + QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject*>(component.create())); QVERIFY(object != nullptr); // `object->value()' is the number of executed statements @@ -7308,7 +7308,7 @@ void tst_qqmlecmascript::switchStatement() { QQmlComponent component(&engine, testFileUrl("switchStatement.3.qml")); - MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); + QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject*>(component.create())); QVERIFY(object != nullptr); // `object->value()' is the number of executed statements @@ -7335,7 +7335,7 @@ void tst_qqmlecmascript::switchStatement() QString warning = component.url().toString() + ":4:5: Unable to assign [undefined] to int"; QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); - MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); + QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject*>(component.create())); QVERIFY(object != nullptr); // `object->value()' is the number of executed statements @@ -7359,7 +7359,7 @@ void tst_qqmlecmascript::switchStatement() { QQmlComponent component(&engine, testFileUrl("switchStatement.5.qml")); - MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); + QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject*>(component.create())); QVERIFY(object != nullptr); // `object->value()' is the number of executed statements @@ -7382,7 +7382,7 @@ void tst_qqmlecmascript::switchStatement() { QQmlComponent component(&engine, testFileUrl("switchStatement.6.qml")); - MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); + QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject*>(component.create())); QVERIFY(object != nullptr); // `object->value()' is the number of executed statements @@ -7410,7 +7410,7 @@ void tst_qqmlecmascript::withStatement() { QUrl url = testFileUrl("withStatement.1.qml"); QQmlComponent component(&engine, url); - MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); + QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject*>(component.create())); QVERIFY(object != nullptr); QCOMPARE(object->value(), 123); @@ -7422,7 +7422,7 @@ void tst_qqmlecmascript::tryStatement() QQmlEngine engine; { QQmlComponent component(&engine, testFileUrl("tryStatement.1.qml")); - MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); + QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject*>(component.create())); QVERIFY(object != nullptr); QCOMPARE(object->value(), 123); @@ -7430,7 +7430,7 @@ void tst_qqmlecmascript::tryStatement() { QQmlComponent component(&engine, testFileUrl("tryStatement.2.qml")); - MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); + QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject*>(component.create())); QVERIFY(object != nullptr); QCOMPARE(object->value(), 321); @@ -7438,7 +7438,7 @@ void tst_qqmlecmascript::tryStatement() { QQmlComponent component(&engine, testFileUrl("tryStatement.3.qml")); - MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); + QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject*>(component.create())); QVERIFY(object != nullptr); QVERIFY(object->qjsvalue().isUndefined()); @@ -7446,7 +7446,7 @@ void tst_qqmlecmascript::tryStatement() { QQmlComponent component(&engine, testFileUrl("tryStatement.4.qml")); - MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); + QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject*>(component.create())); QVERIFY(object != nullptr); QVERIFY(object->qjsvalue().isUndefined()); @@ -7587,7 +7587,7 @@ void tst_qqmlecmascript::onDestruction() // component instance. This shouldn't crash. QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("onDestruction.qml")); - QObject *obj = c.create(); + QScopedPointer<QObject> obj(c.create()); QVERIFY(obj != nullptr); QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete); } @@ -7928,19 +7928,19 @@ void tst_qqmlecmascript::dateParse() QQmlEngine engine; QQmlComponent component(&engine, testFileUrl("date.qml")); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); if (object == nullptr) qDebug() << component.errorString(); QVERIFY(object != nullptr); QVariant q; - QMetaObject::invokeMethod(object, "test_is_invalid_jsDateTime", Q_RETURN_ARG(QVariant, q)); + QMetaObject::invokeMethod(object.get(), "test_is_invalid_jsDateTime", Q_RETURN_ARG(QVariant, q)); QVERIFY(q.toBool()); - QMetaObject::invokeMethod(object, "test_is_invalid_qtDateTime", Q_RETURN_ARG(QVariant, q)); + QMetaObject::invokeMethod(object.get(), "test_is_invalid_qtDateTime", Q_RETURN_ARG(QVariant, q)); QVERIFY(q.toBool()); - QMetaObject::invokeMethod(object, "test_rfc2822_date", Q_RETURN_ARG(QVariant, q)); + QMetaObject::invokeMethod(object.get(), "test_rfc2822_date", Q_RETURN_ARG(QVariant, q)); QCOMPARE(q.toLongLong(), 1379512851000LL); } @@ -7949,14 +7949,14 @@ void tst_qqmlecmascript::utcDate() QQmlEngine engine; QQmlComponent component(&engine, testFileUrl("utcdate.qml")); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); if (object == nullptr) qDebug() << component.errorString(); QVERIFY(object != nullptr); QVariant q; QVariant val = QString::fromLatin1("2014-07-16T23:30:31"); - QMetaObject::invokeMethod(object, "check_utc", Q_RETURN_ARG(QVariant, q), Q_ARG(QVariant, val)); + QMetaObject::invokeMethod(object.get(), "check_utc", Q_RETURN_ARG(QVariant, q), Q_ARG(QVariant, val)); QVERIFY(q.toBool()); } @@ -7965,20 +7965,20 @@ void tst_qqmlecmascript::negativeYear() QQmlEngine engine; QQmlComponent component(&engine, testFileUrl("negativeyear.qml")); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); if (object == nullptr) qDebug() << component.errorString(); QVERIFY(object != nullptr); QVariant q; - QMetaObject::invokeMethod(object, "check_negative_tostring", Q_RETURN_ARG(QVariant, q)); + QMetaObject::invokeMethod(object.get(), "check_negative_tostring", Q_RETURN_ARG(QVariant, q)); // Only check for the year. We hope that every language writes the year in arabic numerals and // in relation to a specific dude's date of birth. We also hope that no language adds a "-2001" // junk string somewhere in the middle. QVERIFY(q.toString().indexOf(QStringLiteral("-2001")) != -1); - QMetaObject::invokeMethod(object, "check_negative_toisostring", Q_RETURN_ARG(QVariant, q)); + QMetaObject::invokeMethod(object.get(), "check_negative_toisostring", Q_RETURN_ARG(QVariant, q)); QCOMPARE(q.toString().left(16), QStringLiteral("result: -002000-")); } @@ -8021,6 +8021,7 @@ void tst_qqmlecmascript::jsOwnedObjectsDeletedOnEngineDestroy() QCOMPARE(spy1.count(), 1); QCOMPARE(spy2.count(), 1); + deleteObject.deleteNestedObject(); delete object; } @@ -8032,7 +8033,7 @@ void tst_qqmlecmascript::updateCall() QString file("updateCall.qml"); QQmlEngine engine; QQmlComponent component(&engine, testFileUrl(file)); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); } @@ -8043,7 +8044,7 @@ void tst_qqmlecmascript::numberParsing() QString file("numberParsing.%1.qml"); file = file.arg(i); QQmlComponent component(&engine, testFileUrl(file)); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); } for (int i = 1; i < 3; ++i) { @@ -8226,8 +8227,8 @@ void tst_qqmlecmascript::idsAsLValues() QString err = QString(QLatin1String("%1:5: Error: left-hand side of assignment operator is not an lvalue")).arg(testFileUrl("idAsLValue.qml").toString()); QQmlComponent component(&engine, testFileUrl("idAsLValue.qml")); QTest::ignoreMessage(QtWarningMsg, qPrintable(err)); - MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create()); - QVERIFY(!object); + QScopedPointer<QObject> object(component.create()); + QVERIFY(!qobject_cast<MyQmlObject*>(object.get())); } void tst_qqmlecmascript::qtbug_34792() @@ -8442,10 +8443,10 @@ void tst_qqmlecmascript::readUnregisteredQObjectProperty() qmlRegisterType<ObjectContainer>("Test", 1, 0, "ObjectContainer"); QQmlEngine engine; QQmlComponent component(&engine, testFileUrl("accessUnregisteredQObjectProperty.qml")); - QObject *root = component.create(); + QScopedPointer<QObject> root(component.create()); QVERIFY(root); - QMetaObject::invokeMethod(root, "readProperty"); + QMetaObject::invokeMethod(root.get(), "readProperty"); QCOMPARE(root->property("container").value<ObjectContainer*>()->mGetterCalled, true); } @@ -8454,10 +8455,10 @@ void tst_qqmlecmascript::writeUnregisteredQObjectProperty() qmlRegisterType<ObjectContainer>("Test", 1, 0, "ObjectContainer"); QQmlEngine engine; QQmlComponent component(&engine, testFileUrl("accessUnregisteredQObjectProperty.qml")); - QObject *root = component.create(); + QScopedPointer<QObject> root(component.create()); QVERIFY(root); - QMetaObject::invokeMethod(root, "writeProperty"); + QMetaObject::invokeMethod(root.get(), "writeProperty"); QCOMPARE(root->property("container").value<ObjectContainer*>()->mSetterCalled, true); } diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index 4474f504af..ed3f7a5658 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -244,12 +244,11 @@ private slots: void compositeSingletonModuleQualified(); void compositeSingletonInstantiateError(); void compositeSingletonDynamicPropertyError(); - void compositeSingletonDynamicSignal(); + void compositeSingletonDynamicSignalAndJavaScriptPragma(); void compositeSingletonQmlRegisterTypeError(); void compositeSingletonQmldirNoPragmaError(); void compositeSingletonQmlDirError(); void compositeSingletonRemote(); - void compositeSingletonJavaScriptPragma(); void compositeSingletonSelectors(); void compositeSingletonRegistered(); void compositeSingletonCircular(); @@ -2522,7 +2521,15 @@ void tst_qqmllanguage::testType(const QString& qml, const QString& type, const Q VERIFY_ERRORS(0); QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); - QCOMPARE(QString(object->metaObject()->className()), type); + const QMetaObject *meta = object->metaObject(); + for (; meta; meta = meta->superClass()) { + const QString className(meta->className()); + if (!className.contains("_QMLTYPE_") && !className.contains("_QML_")) { + QCOMPARE(className, type); + break; + } + } + QVERIFY(meta != nullptr); } engine.setImportPathList(defaultImportPathList); @@ -4065,10 +4072,12 @@ void tst_qqmllanguage::implicitImportsLast() VERIFY_ERRORS(0); QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); - QVERIFY(QString(object->metaObject()->className()).startsWith(QLatin1String("QQuickMouseArea"))); + QVERIFY(QString(object->metaObject()->superClass()->superClass()->className()) + .startsWith(QLatin1String("QQuickMouseArea"))); QObject* object2 = object->property("item").value<QObject*>(); QVERIFY(object2 != nullptr); - QCOMPARE(QString(object2->metaObject()->className()), QLatin1String("QQuickRectangle")); + QCOMPARE(QString(object2->metaObject()->superClass()->className()), + QLatin1String("QQuickRectangle")); engine.setImportPathList(defaultImportPathList); } @@ -4289,16 +4298,35 @@ void tst_qqmllanguage::compositeSingletonDynamicPropertyError() VERIFY_ERRORS(0); } -// Having a composite singleton type as dynamic signal parameter succeeds -// (like C++ singleton) -void tst_qqmllanguage::compositeSingletonDynamicSignal() +void tst_qqmllanguage::compositeSingletonDynamicSignalAndJavaScriptPragma() { - QQmlComponent component(&engine, testFileUrl("singletonTest11.qml")); - VERIFY_ERRORS(0); - QScopedPointer<QObject> o(component.create()); - QVERIFY(o != nullptr); + { + // Having a composite singleton type as dynamic signal parameter succeeds + // (like C++ singleton) + + QQmlComponent component(&engine, testFileUrl("singletonTest11.qml")); + VERIFY_ERRORS(0); + QScopedPointer<QObject> o(component.create()); + QVERIFY(o != nullptr); + + verifyCompositeSingletonPropertyValues(o.data(), "value1", 99, "value2", -55); + } + { + // Load a composite singleton type and a javascript file that has .pragma library + // in it. This will make sure that the javascript .pragma does not get mixed with + // the pragma Singleton changes. - verifyCompositeSingletonPropertyValues(o.data(), "value1", 99, "value2", -55); + QQmlComponent component(&engine, testFileUrl("singletonTest16.qml")); + VERIFY_ERRORS(0); + QScopedPointer<QObject> o(component.create()); + QVERIFY(o != nullptr); + + // The value1 that is read from the SingletonType was changed from 125 to 99 + // above. As the type is a singleton and + // the engine has not been destroyed, we just retrieve the old instance and + // the value is still 99. + verifyCompositeSingletonPropertyValues(o.data(), "value1", 99, "value2", 333); + } } // Use qmlRegisterType to register a qml composite type with pragma Singleton defined in it. @@ -4350,23 +4378,6 @@ void tst_qqmllanguage::compositeSingletonRemote() verifyCompositeSingletonPropertyValues(o.data(), "value1", 525, "value2", 355); } -// Load a composite singleton type and a javascript file that has .pragma library -// in it. This will make sure that the javascript .pragma does not get mixed with -// the pragma Singleton changes. -void tst_qqmllanguage::compositeSingletonJavaScriptPragma() -{ - QQmlComponent component(&engine, testFileUrl("singletonTest16.qml")); - VERIFY_ERRORS(0); - QScopedPointer<QObject> o(component.create()); - QVERIFY(o != nullptr); - - // The value1 that is read from the SingletonType was changed from 125 to 99 - // in compositeSingletonDynamicSignal() above. As the type is a singleton and - // the engine has not been destroyed, we just retrieve the old instance and - // the value is still 99. - verifyCompositeSingletonPropertyValues(o.data(), "value1", 99, "value2", 333); -} - // Reads values from a Singleton accessed through selectors. void tst_qqmllanguage::compositeSingletonSelectors() { @@ -5052,7 +5063,6 @@ void tst_qqmllanguage::instanceof() if (QTest::currentDataTag() == QLatin1String("customRectangleWithPropInstance instanceof CustomRectangle") || QTest::currentDataTag() == QLatin1String("customRectangleWithPropInstance instanceof CustomImport.CustomRectangle")) - QEXPECT_FAIL("", "QTBUG-58477: QML type rules are a little lax", Continue); QCOMPARE(returnValue, expectedValue.toBool()); } else { QVERIFY(expr.hasError()); @@ -5088,7 +5098,8 @@ void tst_qqmllanguage::accessDeletedObject() { QQmlEngine engine; - engine.rootContext()->setContextProperty("objectCreator", new ObjectCreator); + QScopedPointer<ObjectCreator> creator(new ObjectCreator); + engine.rootContext()->setContextProperty("objectCreator", creator.get()); QQmlComponent component(&engine, testFileUrl("accessDeletedObject.qml")); VERIFY_ERRORS(0); diff --git a/tests/auto/qml/qqmlpromise/data/promisehandlerthrows.qml b/tests/auto/qml/qqmlpromise/data/promisehandlerthrows.qml new file mode 100644 index 0000000000..d23ea43e74 --- /dev/null +++ b/tests/auto/qml/qqmlpromise/data/promisehandlerthrows.qml @@ -0,0 +1,17 @@ +import QtQuick 2.12 + +Item { + id: root + property string errorMessage + Component.onCompleted: () => { + let prom = Promise.reject("Some error") + .then( + o => {console.log("Never reached");}, + err => { + console.log("Rethrowing err"); + throw err; + } + ) + .catch(err => root.errorMessage = err) + } +} diff --git a/tests/auto/qml/qqmlpromise/tst_qqmlpromise.cpp b/tests/auto/qml/qqmlpromise/tst_qqmlpromise.cpp index 41850d0263..b430434526 100644 --- a/tests/auto/qml/qqmlpromise/tst_qqmlpromise.cpp +++ b/tests/auto/qml/qqmlpromise/tst_qqmlpromise.cpp @@ -83,6 +83,7 @@ private slots: void then_reject_non_callable(); void then_resolve_multiple_then(); void promiseChain(); + void promiseHandlerThrows(); private: void execute_test(QString testName); @@ -285,6 +286,17 @@ void tst_qqmlpromise::promiseChain() } +void tst_qqmlpromise::promiseHandlerThrows() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("promisehandlerthrows.qml")); + QVERIFY(component.isReady()); + QTest::ignoreMessage(QtDebugMsg, "Rethrowing err"); + QScopedPointer<QObject> root(component.create()); + QVERIFY(root); + QTRY_VERIFY(root->property("errorMessage") == QLatin1String("Some error")); +} + QTEST_MAIN(tst_qqmlpromise) diff --git a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp index ad901c4eba..f6e3dc0226 100644 --- a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp +++ b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp @@ -35,6 +35,9 @@ #include <private/qqmlboundsignal_p.h> #include <QtCore/qfileinfo.h> #include <QtCore/qdir.h> +#if QT_CONFIG(regularexpression) +#include <QtCore/qregularexpression.h> +#endif #include <QtCore/private/qobject_p.h> #include "../../shared/util.h" @@ -2017,9 +2020,13 @@ void tst_qqmlproperty::warnOnInvalidBinding() expectedWarning = testUrl.toString() + QString::fromLatin1(":7:5: Unable to assign QQuickText to QQuickRectangle"); QTest::ignoreMessage(QtWarningMsg, expectedWarning.toLatin1().constData()); +#if QT_CONFIG(regularexpression) // V8 error message for invalid binding to anchor - expectedWarning = testUrl.toString() + QString::fromLatin1(":14:9: Unable to assign QQuickItem_QML_8 to QQuickAnchorLine"); - QTest::ignoreMessage(QtWarningMsg, expectedWarning.toLatin1().constData()); + const QRegularExpression warning( + "^" + testUrl.toString() + + ":14:9: Unable to assign QQuickItem_QML_\\d+ to QQuickAnchorLine$"); + QTest::ignoreMessage(QtWarningMsg, warning); +#endif QQmlComponent component(&engine, testUrl); QObject *obj = component.create(); diff --git a/tests/auto/qml/qqmlpropertycache/data/SpecialObject1.qml b/tests/auto/qml/qqmlpropertycache/data/SpecialObject1.qml new file mode 100644 index 0000000000..9559bc0b5f --- /dev/null +++ b/tests/auto/qml/qqmlpropertycache/data/SpecialObject1.qml @@ -0,0 +1,5 @@ +import QtQml 2.0 + +QtObject { + readonly property bool fakeProperty: false +} diff --git a/tests/auto/qml/qqmlpropertycache/data/SpecialObject2.qml b/tests/auto/qml/qqmlpropertycache/data/SpecialObject2.qml new file mode 100644 index 0000000000..ed4ad04fef --- /dev/null +++ b/tests/auto/qml/qqmlpropertycache/data/SpecialObject2.qml @@ -0,0 +1,5 @@ +import QtQml 2.0 + +QtObject { + objectName: "special" +} diff --git a/tests/auto/qml/qqmlpropertycache/data/noDuckType.qml b/tests/auto/qml/qqmlpropertycache/data/noDuckType.qml new file mode 100644 index 0000000000..5e1ea233b9 --- /dev/null +++ b/tests/auto/qml/qqmlpropertycache/data/noDuckType.qml @@ -0,0 +1,7 @@ +import QtQml 2.9 + +QtObject { + property SpecialObject1 obj1: SpecialObject1 {} + property SpecialObject2 obj2: SpecialObject2 {} + property string result: (obj1 instanceof SpecialObject2) ? "bad" : "good" +} diff --git a/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp b/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp index 9a1e4667dd..c9e92cd3c9 100644 --- a/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp +++ b/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp @@ -54,6 +54,7 @@ private slots: void metaObjectSize_data(); void metaObjectSize(); void metaObjectChecksum(); + void metaObjectsForRootElements(); private: QQmlEngine engine; @@ -543,4 +544,14 @@ void tst_qqmlpropertycache::metaObjectChecksum() } } +void tst_qqmlpropertycache::metaObjectsForRootElements() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("noDuckType.qml")); + QVERIFY(c.isReady()); + QScopedPointer<QObject> obj(c.create()); + QVERIFY(!obj.isNull()); + QCOMPARE(obj->property("result").toString(), QString::fromLatin1("good")); +} + QTEST_MAIN(tst_qqmlpropertycache) diff --git a/tests/auto/qml/qqmltypeloader/data/Com/Orga/BaseStyle.qml b/tests/auto/qml/qqmltypeloader/data/Com/Orga/BaseStyle.qml new file mode 100644 index 0000000000..28521e3af2 --- /dev/null +++ b/tests/auto/qml/qqmltypeloader/data/Com/Orga/BaseStyle.qml @@ -0,0 +1,5 @@ +import QtQuick 2.6 + +Item { + +} diff --git a/tests/auto/qml/qqmltypeloader/data/Com/Orga/Handlers/Handler.qml b/tests/auto/qml/qqmltypeloader/data/Com/Orga/Handlers/Handler.qml new file mode 100644 index 0000000000..b20a2def11 --- /dev/null +++ b/tests/auto/qml/qqmltypeloader/data/Com/Orga/Handlers/Handler.qml @@ -0,0 +1,7 @@ +import QtQuick 2.6 +import Com.Orga 1.0 + +Rectangle { + color: Style.name + Text {text: "Hello world!"} +} diff --git a/tests/auto/qml/qqmltypeloader/data/Com/Orga/Handlers/qmldir b/tests/auto/qml/qqmltypeloader/data/Com/Orga/Handlers/qmldir new file mode 100644 index 0000000000..368cb65b35 --- /dev/null +++ b/tests/auto/qml/qqmltypeloader/data/Com/Orga/Handlers/qmldir @@ -0,0 +1,2 @@ +module Com.Orga.Handlers +Handler 1.0 Handler.qml diff --git a/tests/auto/qml/qqmltypeloader/data/Com/Orga/Style.qml b/tests/auto/qml/qqmltypeloader/data/Com/Orga/Style.qml new file mode 100644 index 0000000000..7951f5e768 --- /dev/null +++ b/tests/auto/qml/qqmltypeloader/data/Com/Orga/Style.qml @@ -0,0 +1,6 @@ +pragma Singleton +import QtQuick 2.6 + +BaseStyle { + property color name: "black" +} diff --git a/tests/auto/qml/qqmltypeloader/data/Com/Orga/qmldir b/tests/auto/qml/qqmltypeloader/data/Com/Orga/qmldir new file mode 100644 index 0000000000..9c5560b323 --- /dev/null +++ b/tests/auto/qml/qqmltypeloader/data/Com/Orga/qmldir @@ -0,0 +1,2 @@ +singleton Style 1.0 Style.qml +BaseStyle 1.0 BaseStyle.qml diff --git a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp index 2993b4b3c8..9ad53aaa8b 100644 --- a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp +++ b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp @@ -60,6 +60,7 @@ private slots: void implicitComponentModule(); void qrcRootPathUrl(); void implicitImport(); + void compositeSingletonCycle(); }; void tst_QQMLTypeLoader::testLoadComplete() @@ -434,7 +435,7 @@ void tst_QQMLTypeLoader::redirect() component.loadUrl(server.urlString("/Load.qml"), QQmlComponent::Asynchronous); QTRY_VERIFY2(component.isReady(), qPrintable(component.errorString())); - QObject *object = component.create(); + QScopedPointer<QObject> object {component.create()}; QTRY_COMPARE(object->property("xy").toInt(), 323232); } @@ -524,6 +525,23 @@ void tst_QQMLTypeLoader::implicitImport() QVERIFY(!obj.isNull()); } +void tst_QQMLTypeLoader::compositeSingletonCycle() +{ + TestHTTPServer server; + QVERIFY2(server.listen(), qPrintable(server.errorString())); + QVERIFY(server.serveDirectory(dataDirectory())); + + QQmlEngine engine; + QQmlComponent component(&engine); + engine.addImportPath(server.baseUrl().toString()); + component.loadUrl(server.urlString("Com/Orga/Handlers/Handler.qml"), QQmlComponent::Asynchronous); + QTRY_VERIFY2(component.isReady(), qPrintable(component.errorString())); + + QScopedPointer<QObject> object {component.create()}; + QVERIFY(object); + QCOMPARE(qvariant_cast<QColor>(object->property("color")), QColorConstants::Black); +} + QTEST_MAIN(tst_QQMLTypeLoader) #include "tst_qqmltypeloader.moc" diff --git a/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp b/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp index b7600351b7..ae99e35467 100644 --- a/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp +++ b/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp @@ -75,6 +75,7 @@ private slots: void introspectQrc(); void sortCaseSensitive_data(); void sortCaseSensitive(); + void updateProperties(); private: void checkNoErrors(const QQmlComponent& component); QQmlEngine engine; @@ -425,6 +426,47 @@ void tst_qquickfolderlistmodel::sortCaseSensitive() QTRY_COMPARE(flm->data(flm->index(i),FileNameRole).toString(), expectedOrder.at(i)); } +void tst_qquickfolderlistmodel::updateProperties() +{ + QQmlComponent component(&engine, testFileUrl("basic.qml")); + checkNoErrors(component); + + QObject *folderListModel = component.create(); + QVERIFY(folderListModel); + + QVariant caseSensitive = folderListModel->property("caseSensitive"); + QVERIFY(caseSensitive.isValid()); + QCOMPARE(caseSensitive.toBool(), true); + folderListModel->setProperty("caseSensitive", false); + caseSensitive = folderListModel->property("caseSensitive"); + QVERIFY(caseSensitive.isValid()); + QCOMPARE(caseSensitive.toBool(), false); + + QVariant showOnlyReadable = folderListModel->property("showOnlyReadable"); + QVERIFY(showOnlyReadable.isValid()); + QCOMPARE(showOnlyReadable.toBool(), false); + folderListModel->setProperty("showOnlyReadable", true); + showOnlyReadable = folderListModel->property("showOnlyReadable"); + QVERIFY(showOnlyReadable.isValid()); + QCOMPARE(showOnlyReadable.toBool(), true); + + QVariant showDotAndDotDot = folderListModel->property("showDotAndDotDot"); + QVERIFY(showDotAndDotDot.isValid()); + QCOMPARE(showDotAndDotDot.toBool(), false); + folderListModel->setProperty("showDotAndDotDot", true); + showDotAndDotDot = folderListModel->property("showDotAndDotDot"); + QVERIFY(showDotAndDotDot.isValid()); + QCOMPARE(showDotAndDotDot.toBool(), true); + + QVariant showHidden = folderListModel->property("showHidden"); + QVERIFY(showHidden.isValid()); + QCOMPARE(showHidden.toBool(), false); + folderListModel->setProperty("showHidden", true); + showHidden = folderListModel->property("showHidden"); + QVERIFY(showHidden.isValid()); + QCOMPARE(showHidden.toBool(), true); +} + QTEST_MAIN(tst_qquickfolderlistmodel) #include "tst_qquickfolderlistmodel.moc" diff --git a/tests/auto/quick/qquickanimatedimage/data/currentframe.qml b/tests/auto/quick/qquickanimatedimage/data/currentframe.qml new file mode 100644 index 0000000000..b679da2a99 --- /dev/null +++ b/tests/auto/quick/qquickanimatedimage/data/currentframe.qml @@ -0,0 +1,13 @@ +import QtQuick 2.0 + +AnimatedImage { + property int currentFrameChangeCount: 0 + property int frameChangeCount: 0 + source: "stickman.gif" + onCurrentFrameChanged: if (currentFrame > 0) ++currentFrameChangeCount; + onFrameChanged: if (currentFrame > 0) ++frameChangeCount; + function scriptedSetCurrentFrame(frame) { + currentFrame = frame; + } +} + diff --git a/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp b/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp index 8026bafb9e..31c3fb9946 100644 --- a/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp +++ b/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp @@ -27,6 +27,7 @@ ****************************************************************************/ #include <qtest.h> #include <QtQml/qqmlengine.h> +#include <QtQml/qqmlexpression.h> #include <QtQml/qqmlcomponent.h> #include <QtQuick/qquickview.h> #include <QtQuick/private/qquickrectangle_p.h> @@ -40,6 +41,23 @@ Q_DECLARE_METATYPE(QQuickImageBase::Status) +template <typename T> static T evaluate(QObject *scope, const QString &expression) +{ + QQmlExpression expr(qmlContext(scope), scope, expression); + QVariant result = expr.evaluate(); + if (expr.hasError()) + qWarning() << expr.error().toString(); + return result.value<T>(); +} + +template <> void evaluate<void>(QObject *scope, const QString &expression) +{ + QQmlExpression expr(qmlContext(scope), scope, expression); + expr.evaluate(); + if (expr.hasError()) + qWarning() << expr.error().toString(); +} + class tst_qquickanimatedimage : public QQmlDataTest { Q_OBJECT @@ -68,6 +86,7 @@ private slots: void playingAndPausedChanges(); void noCaching(); void sourceChangesOnFrameChanged(); + void currentFrame(); }; void tst_qquickanimatedimage::cleanup() @@ -618,6 +637,33 @@ void tst_qquickanimatedimage::sourceChangesOnFrameChanged() qDeleteAll(images); } +void tst_qquickanimatedimage::currentFrame() +{ + QQuickView window; + window.setSource(testFileUrl("currentframe.qml")); + window.show(); + QVERIFY(QTest::qWaitForWindowExposed(&window)); + + QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(window.rootObject()); + QVERIFY(anim); + QSignalSpy frameChangedSpy(anim, SIGNAL(frameChanged())); + QSignalSpy currentFrameChangedSpy(anim, SIGNAL(currentFrameChanged())); + + anim->setCurrentFrame(1); + QCOMPARE(anim->currentFrame(), 1); + QCOMPARE(frameChangedSpy.count(), 1); + QCOMPARE(currentFrameChangedSpy.count(), 1); + QCOMPARE(anim->property("currentFrameChangeCount"), 1); + QCOMPARE(anim->property("frameChangeCount"), 1); + + evaluate<void>(anim, "scriptedSetCurrentFrame(2)"); + QCOMPARE(anim->currentFrame(), 2); + QCOMPARE(frameChangedSpy.count(), 2); + QCOMPARE(currentFrameChangedSpy.count(), 2); + QCOMPARE(anim->property("currentFrameChangeCount"), 2); + QCOMPARE(anim->property("frameChangeCount"), 2); +} + QTEST_MAIN(tst_qquickanimatedimage) #include "tst_qquickanimatedimage.moc" diff --git a/tests/auto/quick/qquicklayouts/data/tst_gridlayout.qml b/tests/auto/quick/qquicklayouts/data/tst_gridlayout.qml index 6a1c0632ad..49838c4fd5 100644 --- a/tests/auto/quick/qquicklayouts/data/tst_gridlayout.qml +++ b/tests/auto/quick/qquicklayouts/data/tst_gridlayout.qml @@ -60,8 +60,8 @@ Item { id: testCase name: "Tests_GridLayout" when: windowShown - width: 200 - height: 200 + width: parent.width + height: parent.height Component { id: layout_flow_Component @@ -84,7 +84,7 @@ Item { function test_flow() { - var layout = layout_flow_Component.createObject(container); + var layout = createTemporaryObject(layout_flow_Component, container); tryCompare(layout.children[0], "itemRect", [ 0, 0, 10, 10]) tryCompare(layout.children[1], "itemRect", [10, 0, 10, 10]) tryCompare(layout.children[2], "itemRect", [20, 0, 10, 10]) @@ -102,8 +102,6 @@ Item { tryCompare(layout.children[4], "itemRect", [10, 0, 10, 10]) tryCompare(layout.children[5], "itemRect", [10, 10, 10, 10]) - - layout.destroy() } Component { @@ -178,7 +176,7 @@ Item { } function test_flowLeftToRight() { - var layout = layout_flowLeftToRight_Component.createObject(container); + var layout = createTemporaryObject(layout_flowLeftToRight_Component, container); compare(layout.implicitWidth, 80); compare(layout.children[0].x, 0); compare(layout.children[0].y, 0); @@ -208,8 +206,6 @@ Item { compare(layout.children[11].y, 60); compare(layout.children[12].x, 40); compare(layout.children[12].y, 80); - - layout.destroy(); } @@ -259,7 +255,7 @@ Item { function test_flowLeftToRightDefaultPositions() { ignoreWarning("QGridLayoutEngine::addItem: Cell (1, 0) already taken"); - var layout = layout_flowLeftToRightDefaultPositions_Component.createObject(container); + var layout = createTemporaryObject(layout_flowLeftToRightDefaultPositions_Component, container); compare(layout.implicitWidth, 40); compare(layout.children[0].x, 0); compare(layout.children[0].y, 0); @@ -267,7 +263,6 @@ Item { compare(layout.children[1].y, 20); compare(layout.children[2].x, 20); compare(layout.children[2].y, 20); - layout.destroy(); } @@ -342,7 +337,7 @@ Item { } function test_flowTopToBottom() { - var layout = layout_flowTopToBottom_Component.createObject(container); + var layout = createTemporaryObject(layout_flowTopToBottom_Component, container); compare(layout.children[0].x, 0); compare(layout.children[0].y, 0); compare(layout.children[1].x, 20); @@ -371,8 +366,6 @@ Item { compare(layout.children[11].y, 60); compare(layout.children[12].x, 80); compare(layout.children[12].y, 0); - - layout.destroy(); } Component { @@ -432,7 +425,7 @@ Item { } function test_spanAcrossEmptyRows() { - var layout = layout_spanAcrossEmptyRows_Component.createObject(container); + var layout = createTemporaryObject(layout_spanAcrossEmptyRows_Component, container); compare(layout.children[0].x, 0); compare(layout.children[0].y, 0); compare(layout.children[1].x, 20); @@ -442,8 +435,6 @@ Item { compare(layout.implicitWidth, 60); compare(layout.Layout.maximumWidth, 120); - - layout.destroy(); } Component { @@ -463,14 +454,13 @@ Item { } function test_spanIsMoreThanColumns() { - var layout = layout_spanIsMoreThanColumns_Component.createObject(container); + var layout = createTemporaryObject(layout_spanIsMoreThanColumns_Component, container); // item was not added, therefore implicit width is 0 compare(layout.implicitWidth, 0); - layout.destroy(); } function test_sizeHints() { - var layout = layout_spanAcrossEmptyRows_Component.createObject(container); + var layout = createTemporaryObject(layout_spanAcrossEmptyRows_Component, container); compare(layout.visible, true) var minWidth = layout.Layout.minimumWidth @@ -489,8 +479,6 @@ Item { compare(prefHeight, layout.implicitHeight) compare(maxWidth, layout.Layout.maximumWidth) compare(maxHeight, layout.Layout.maximumHeight) - - layout.destroy(); } Component { @@ -567,7 +555,7 @@ Item { function test_alignment() { - var layout = layout_alignment_Component.createObject(container); + var layout = createTemporaryObject(layout_alignment_Component, container); layout.width = 60; layout.height = 100; @@ -596,8 +584,6 @@ Item { layout.children[4].Layout.alignment = Qt.AlignLeft tryCompare(layout.children[4], "x", 0); tryCompare(layout.children[4], "y", 60); - - layout.destroy(); } @@ -648,7 +634,7 @@ Item { function test_rightToLeft() { - var layout = layout_rightToLeft_Component.createObject(container); + var layout = createTemporaryObject(layout_rightToLeft_Component, container); layout.width = 180; layout.height = 50; @@ -674,8 +660,6 @@ Item { layout.LayoutMirroring.enabled = true verifyIsRightToLeft(layout) - - layout.destroy(); } Component { @@ -698,7 +682,7 @@ Item { function test_columnsChanged() { - var layout = layout_columnsOrRowsChanged_Component.createObject(container); + var layout = createTemporaryObject(layout_columnsOrRowsChanged_Component, container); layout.width = 40; layout.height = 20; tryCompare(layout.children[0], "itemRect", [ 0, 5, 10, 10]) @@ -711,13 +695,11 @@ Item { tryCompare(layout.children[1], "itemRect", [20, 0, 10, 10]) tryCompare(layout.children[2], "itemRect", [ 0, 10, 10, 10]) tryCompare(layout.children[3], "itemRect", [20, 10, 10, 10]) - - layout.destroy() } function test_rowsChanged() { - var layout = layout_columnsOrRowsChanged_Component.createObject(container); + var layout = createTemporaryObject(layout_columnsOrRowsChanged_Component, container); layout.flow = GridLayout.TopToBottom layout.width = 20; layout.height = 40; @@ -731,8 +713,6 @@ Item { tryCompare(layout.children[1], "itemRect", [ 0, 25, 10, 10]) tryCompare(layout.children[2], "itemRect", [10, 5, 10, 10]) tryCompare(layout.children[3], "itemRect", [10, 25, 10, 10]) - - layout.destroy() } Component { @@ -767,7 +747,7 @@ Item { function test_columnOrRowChanged() { - var layout = layout_columnOrRowChanged_Component.createObject(container); + var layout = createTemporaryObject(layout_columnOrRowChanged_Component, container); layout.width = layout.implicitWidth layout.height = layout.implicitHeight // c0-c1-c2 @@ -795,8 +775,6 @@ Item { tryCompare(layout.children[0], "itemRect", [10, 10, 10, 10]) tryCompare(layout.children[1], "itemRect", [ 0, 0, 10, 10]) tryCompare(layout.children[2], "itemRect", [20, 0, 10, 10]) - - layout.destroy() } Component { @@ -819,7 +797,7 @@ Item { } function test_baselines() { - var layout = layout_baselines_Component.createObject(container); + var layout = createTemporaryObject(layout_baselines_Component, container); tryCompare(layout.children[0], "itemRect", [ 0, 0, 10, 10]) tryCompare(layout.children[1], "itemRect", [10, 0, 10, 10]) compare(layout.implicitWidth, 20) @@ -832,8 +810,6 @@ Item { tryCompare(layout.children[1], "itemRect", [10, 10, 10, 10]) compare(layout.implicitWidth, 20) compare(layout.implicitHeight, 20) - - layout.destroy(); } Component { @@ -851,30 +827,42 @@ Item { } } - function test_spacings() + function test_spacings_data() + { + let data = [ + { spacing: Number.NaN }, + { spacing: 0 }, + { spacing: 10 }, + { spacing: -5 }, + { spacing: -19 } + ] + for (let i = 0; i < data.length; ++i) { + data[i].tag = data[i].spacing.toString() + } + return data + } + + function test_spacings(data) { - var layout = layout_spacings_Component.createObject(container); + var layout = createTemporaryObject(layout_spacings_Component, container); // breaks down below -19. This is acceptable, since it means that the implicit size of the layout is negative var testSpacings = [Number.NaN, 0, 10, -5, -19] layout.rowSpacing = 0 - for (var i = 0; i < testSpacings.length; ++i) { - var sp = testSpacings[i] - if (isNaN(sp)) { - sp = 5 // Test defaults - } else { - layout.columnSpacing = sp - } - tryCompare(layout.children[0], "itemRect", [ 0, 0, 10, 10]) - tryCompare(layout.children[1], "itemRect", [10 + sp, 0, 10, 10]) - compare(layout.implicitWidth, 20 + sp) + var spacing = data.spacing + if (isNaN(spacing)) { + spacing = 5 // Test defaults + } else { + layout.columnSpacing = spacing } + tryCompare(layout.children[0], "itemRect", [ 0, 0, 10, 10]) + tryCompare(layout.children[1], "itemRect", [10 + spacing, 0, 10, 10]) + compare(layout.implicitWidth, 20 + spacing) // do not crash layout.columnSpacing = -100 waitForRendering(layout) verify(isFinite(layout.implicitWidth)) - layout.destroy(); } Component { @@ -1026,11 +1014,10 @@ Item { function test_invalidateWhileRearranging_QTBUG_44139() { - var layout = layout_invalidateWhileRearranging_Component.createObject(container) + var layout = createTemporaryObject(layout_invalidateWhileRearranging_Component, container) waitForRendering(layout); verify(layout.children[1].visible == false); - layout.destroy() } } } diff --git a/tests/auto/quick/qquickmousearea/BLACKLIST b/tests/auto/quick/qquickmousearea/BLACKLIST new file mode 100644 index 0000000000..f2cb00225b --- /dev/null +++ b/tests/auto/quick/qquickmousearea/BLACKLIST @@ -0,0 +1,4 @@ +# QTBUG-78153 +[nestedStopAtBounds] +opensuse-leap + diff --git a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp index 5844720aa4..17553ee6c4 100644 --- a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp +++ b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp @@ -1359,6 +1359,34 @@ void tst_QQuickMouseArea::hoverVisible() QCOMPARE(enteredSpy.count(), 1); QCOMPARE(QPointF(mouseTracker->mouseX(), mouseTracker->mouseY()), QPointF(11,33)); + + // QTBUG-77983 + mouseTracker->setVisible(false); + mouseTracker->setEnabled(false); + + QCOMPARE(mouseTracker->hovered(), false); + mouseTracker->setVisible(true); + // if the enabled property is false, the containsMouse property shouldn't become true + // when an invisible mousearea become visible + QCOMPARE(mouseTracker->hovered(), false); + + mouseTracker->parentItem()->setEnabled(false); + mouseTracker->setVisible(false); + mouseTracker->setEnabled(true); + + QCOMPARE(mouseTracker->hovered(), false); + mouseTracker->setVisible(true); + // if the parent item is not enabled, the containsMouse property will be false, even if + // the mousearea is enabled + QCOMPARE(mouseTracker->hovered(), false); + + mouseTracker->parentItem()->setEnabled(true); + mouseTracker->setVisible(false); + mouseTracker->setEnabled(true); + + QCOMPARE(mouseTracker->hovered(), false); + mouseTracker->setVisible(true); + QCOMPARE(mouseTracker->hovered(), true); } void tst_QQuickMouseArea::hoverAfterPress() diff --git a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp index cd66fc4ede..e96b892b54 100644 --- a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp +++ b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp @@ -72,6 +72,7 @@ private slots: void mouseGestureStarted_data(); void mouseGestureStarted(); void cancel(); + void stationaryTouchWithChangingPressure(); private: QQuickView *createAndShowView(const QString &file); @@ -1305,6 +1306,42 @@ void tst_QQuickMultiPointTouchArea::cancel() } +void tst_QQuickMultiPointTouchArea::stationaryTouchWithChangingPressure() // QTBUG-77142 +{ + QScopedPointer<QQuickView> window(createAndShowView("basic.qml")); + QVERIFY(window->rootObject() != nullptr); + + QQuickTouchPoint *point1 = window->rootObject()->findChild<QQuickTouchPoint*>("point1"); + QCOMPARE(point1->pressed(), false); + + QPoint p1(20,100); + QTouchEvent::TouchPoint tp1(1); + + tp1.setScreenPos(window->mapToGlobal(p1)); + tp1.setState(Qt::TouchPointPressed); + tp1.setPressure(0.5); + qt_handleTouchEvent(window.data(), device, {tp1}); + QQuickTouchUtils::flush(window.data()); + + QCOMPARE(point1->pressed(), true); + QCOMPARE(point1->pressure(), 0.5); + + tp1.setState(Qt::TouchPointStationary); + tp1.setPressure(0.6); + qt_handleTouchEvent(window.data(), device, {tp1}); + QQuickTouchUtils::flush(window.data()); + + QCOMPARE(point1->pressure(), 0.6); + + tp1.setState(Qt::TouchPointReleased); + tp1.setPressure(0); + qt_handleTouchEvent(window.data(), device, {tp1}); + QQuickTouchUtils::flush(window.data()); + + QCOMPARE(point1->pressed(), false); + QCOMPARE(point1->pressure(), 0); +} + QTEST_MAIN(tst_QQuickMultiPointTouchArea) diff --git a/tests/auto/quick/qquickpathview/data/nestedmousearea2.qml b/tests/auto/quick/qquickpathview/data/nestedmousearea2.qml new file mode 100644 index 0000000000..ff11002552 --- /dev/null +++ b/tests/auto/quick/qquickpathview/data/nestedmousearea2.qml @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +PathView { + id: view + width: 400; height: 240 + highlight: Rectangle { width: 80; height: 80; color: "lightsteelblue" } + preferredHighlightBegin: 0.5 + preferredHighlightEnd: 0.5 + model: ListModel { + id: appModel + ListElement { name: "Music" } + ListElement { name: "Movies" } + ListElement { name: "Camera" } + ListElement { name: "Calendar" } + ListElement { name: "Messaging" } + ListElement { name: "Todo List" } + ListElement { name: "Contacts" } + } + delegate: Rectangle { + width: 100; height: 100 + scale: PathView.iconScale + border.color: "lightgrey" + color: "transparent" + Text { + anchors { horizontalCenter: parent.horizontalCenter } + text: name + smooth: true + color: ma.pressed ? "red" : "black" + } + + MouseArea { + id: ma + anchors.fill: parent + onClicked: view.currentIndex = index + } + } + path: Path { + startX: 10 + startY: 50 + PathAttribute { name: "iconScale"; value: 0.5 } + PathQuad { x: 200; y: 150; controlX: 50; controlY: 200 } + PathAttribute { name: "iconScale"; value: 1.0 } + PathQuad { x: 390; y: 50; controlX: 350; controlY: 200 } + PathAttribute { name: "iconScale"; value: 0.5 } + } + Text { + anchors.horizontalCenter: parent.horizontalCenter + y: 20 + text: view.currentIndex + " @ " + offset.toFixed(2) + } +} diff --git a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp index d2058cc8b3..48d6c257a6 100644 --- a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp +++ b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp @@ -120,6 +120,7 @@ private slots: void undefinedPath(); void mouseDrag(); void nestedMouseAreaDrag(); + void flickNClick(); void treeModel(); void changePreferredHighlight(); void missingPercent(); @@ -1603,6 +1604,32 @@ void tst_QQuickPathView::nestedMouseAreaDrag() QVERIFY(pathview->isMoving()); } +void tst_QQuickPathView::flickNClick() // QTBUG-77173 +{ + QScopedPointer<QQuickView> window(createView()); + QQuickViewTestUtil::moveMouseAway(window.data()); + window->setSource(testFileUrl("nestedmousearea2.qml")); + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window.data())); + QCOMPARE(window.data(), qGuiApp->focusWindow()); + + QQuickPathView *pathview = qobject_cast<QQuickPathView*>(window->rootObject()); + QVERIFY(pathview != nullptr); + + for (int duration = 100; duration > 0; duration -= 20) { + // Dragging the child mouse area should animate the PathView (MA has no drag target) + flick(window.data(), QPoint(200,200), QPoint(400,200), duration); + QVERIFY(pathview->isMoving()); + + // Now while it's still moving, click it. + // The PathView should stop at a position such that offset is a whole number. + QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, QPoint(200, 200)); + QTRY_VERIFY(!pathview->isMoving()); + QVERIFY(qFuzzyIsNull(pathview->offset() - int(pathview->offset()))); + } +} + void tst_QQuickPathView::treeModel() { QScopedPointer<QQuickView> window(createView()); diff --git a/tests/auto/quick/qquicktableview/data/tweakimplicitsize.qml b/tests/auto/quick/qquicktableview/data/tweakimplicitsize.qml new file mode 100644 index 0000000000..ecc79a9368 --- /dev/null +++ b/tests/auto/quick/qquicktableview/data/tweakimplicitsize.qml @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.12 +import QtQuick.Window 2.3 + +Item { + width: 640 + height: 450 + + property alias tableView: tableView + property real delegateSize: 10 + property int hideRow: -1 + + TableView { + id: tableView + width: 600 + height: 400 + anchors.margins: 1 + clip: true + delegate: tableViewDelegate + columnSpacing: 1 + rowSpacing: 1 + columnWidthProvider: function(column) { + return -1 + } + rowHeightProvider: function(row) { + if (row === hideRow) + return 0 + return -1 + } + } + + Component { + id: tableViewDelegate + Rectangle { + objectName: "tableViewDelegate" + implicitWidth: row === 0 ? 10 : delegateSize + implicitHeight: column === 0 ? 10 : delegateSize + color: "lightgray" + border.width: 1 + + Text { + id: textItem + anchors.centerIn: parent + text: model.display + renderType: Text.NativeRendering + } + } + } + +} + diff --git a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp index e3f79995d2..230dcc9446 100644 --- a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp +++ b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp @@ -119,6 +119,7 @@ private slots: void checkRowHeightProviderNegativeReturnValue(); void checkRowHeightProviderNotCallable(); void checkForceLayoutFunction(); + void checkForceLayoutEndUpDoingALayout(); void checkContentWidthAndHeight(); void checkPageFlicking(); void checkExplicitContentWidthAndHeight(); @@ -561,6 +562,32 @@ void tst_QQuickTableView::checkForceLayoutFunction() QCOMPARE(fxItem->item->width(), newColumnWidth); } +void tst_QQuickTableView::checkForceLayoutEndUpDoingALayout() +{ + // QTBUG-77074 + // Check that we change the implicit size of the delegate after + // the initial loading, and at the same time hide some rows or + // columns, and then do a forceLayout(), we end up with a + // complete relayout that respects the new implicit size. + LOAD_TABLEVIEW("tweakimplicitsize.qml"); + + auto model = TestModelAsVariant(10, 10); + + tableView->setModel(model); + + WAIT_UNTIL_POLISHED; + + const qreal newDelegateSize = 20; + view->rootObject()->setProperty("delegateSize", newDelegateSize); + // Hide a row, just to force the following relayout to + // do a complete reload (and not just a relayout) + view->rootObject()->setProperty("hideRow", 1); + tableView->forceLayout(); + + for (auto fxItem : tableViewPrivate->loadedItems) + QCOMPARE(fxItem->item->height(), newDelegateSize); +} + void tst_QQuickTableView::checkContentWidthAndHeight() { // Check that contentWidth/Height reports the correct size of the diff --git a/tests/auto/quick/qquicktext/data/transparentBackground.qml b/tests/auto/quick/qquicktext/data/transparentBackground.qml new file mode 100644 index 0000000000..a10a1779bb --- /dev/null +++ b/tests/auto/quick/qquicktext/data/transparentBackground.qml @@ -0,0 +1,16 @@ +import QtQuick 2.0 + +Rectangle { + width: 200 + height: 200 + color: "white" + Text { + objectName: "text" + textFormat: Text.RichText + anchors.fill: parent + color: "black" + text: "<h1 style=\"background-color:rgba(255,255,255,0.00)\">foo</h1>" + verticalAlignment: Text.AlignTop + horizontalAlignment: Text.AlignLeft + } +} diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp index 97107694bd..e62db81d27 100644 --- a/tests/auto/quick/qquicktext/tst_qquicktext.cpp +++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp @@ -164,6 +164,8 @@ private slots: void verticallyAlignedImageInTable(); + void transparentBackground(); + private: QStringList standard; QStringList richText; @@ -4429,6 +4431,26 @@ void tst_qquicktext::verticallyAlignedImageInTable() // Don't crash } +void tst_qquicktext::transparentBackground() +{ + if ((QGuiApplication::platformName() == QLatin1String("offscreen")) + || (QGuiApplication::platformName() == QLatin1String("minimal"))) + QSKIP("Skipping due to grabToImage not functional on offscreen/minimimal platforms"); + + QScopedPointer<QQuickView> window(new QQuickView); + window->setSource(testFileUrl("transparentBackground.qml")); + QTRY_COMPARE(window->status(), QQuickView::Ready); + + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); + QImage img = window->grabWindow(); + QCOMPARE(img.isNull(), false); + + QColor color = img.pixelColor(0, 0); + QCOMPARE(color.red(), 255); + QCOMPARE(color.blue(), 255); + QCOMPARE(color.green(), 255); +} QTEST_MAIN(tst_qquicktext) #include "tst_qquicktext.moc" diff --git a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp index 33a6b829bc..facd63027e 100644 --- a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp +++ b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp @@ -2106,30 +2106,31 @@ void tst_qquicktextedit::mouseSelection() textEditObject->setFocus(focus); textEditObject->setFocusOnPress(focusOnPress); + // Avoid that the last click from the previous test data and the first click in the + // current test data happens so close in time that they are interpreted as a double click. + static const int moreThanDoubleClickInterval = QGuiApplication::styleHints()->mouseDoubleClickInterval() + 1; + // press-and-drag-and-release from x1 to x2 QPoint p1 = textEditObject->positionToRectangle(from).center().toPoint(); QPoint p2 = textEditObject->positionToRectangle(to).center().toPoint(); if (clicks == 2) - QTest::mouseClick(&window, Qt::LeftButton, Qt::NoModifier, p1); + QTest::mouseClick(&window, Qt::LeftButton, Qt::NoModifier, p1, moreThanDoubleClickInterval); else if (clicks == 3) - QTest::mouseDClick(&window, Qt::LeftButton, Qt::NoModifier, p1); + QTest::mouseDClick(&window, Qt::LeftButton, Qt::NoModifier, p1, moreThanDoubleClickInterval); + // cancel the 500ms delta QTestLib adds in order to properly synthesize a triple click within the required interval + QTest::lastMouseTimestamp -= QTest::mouseDoubleClickInterval; QTest::mousePress(&window, Qt::LeftButton, Qt::NoModifier, p1); - if (clicks == 2) { - // QTBUG-50022: Since qtbase commit beef975, QTestLib avoids generating - // double click events by adding 500ms delta to release event timestamps. - // Send a double click event by hand to ensure the correct sequence: - // press, release, press, _dbl click_, move, release. - QMouseEvent dblClickEvent(QEvent::MouseButtonDblClick, p1, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); - QGuiApplication::sendEvent(textEditObject, &dblClickEvent); - } QTest::mouseMove(&window, p2); QTest::mouseRelease(&window, Qt::LeftButton, Qt::NoModifier, p2); QTRY_COMPARE(textEditObject->selectedText(), selectedText); // Clicking and shift to clicking between the same points should select the same text. textEditObject->setCursorPosition(0); - if (clicks > 1) + if (clicks > 1) { QTest::mouseDClick(&window, Qt::LeftButton, Qt::NoModifier, p1); + // cancel the 500ms delta QTestLib adds in order to properly synthesize a triple click within the required interval + QTest::lastMouseTimestamp -= QTest::mouseDoubleClickInterval; + } if (clicks != 2) QTest::mouseClick(&window, Qt::LeftButton, Qt::NoModifier, p1); QTest::mouseClick(&window, Qt::LeftButton, Qt::ShiftModifier, p2); diff --git a/tests/auto/quick/qquicktextinput/BLACKLIST b/tests/auto/quick/qquicktextinput/BLACKLIST new file mode 100644 index 0000000000..ada7c57c75 --- /dev/null +++ b/tests/auto/quick/qquicktextinput/BLACKLIST @@ -0,0 +1,3 @@ +# QTBUG-78162 +[mouseSelectionMode] +opensuse-leap |