diff options
author | Andrei Golubev <andrei.golubev@qt.io> | 2021-12-21 16:49:51 +0100 |
---|---|---|
committer | Andrei Golubev <andrei.golubev@qt.io> | 2021-12-27 08:27:04 +0100 |
commit | 39aee682bf388e191a409485cbbe2e01996bc163 (patch) | |
tree | 571e078686af4cb789f930d5ba64e2836c94cb0b /tests/auto/qml | |
parent | e659b5b23a75676627fb6dfb275c4eede24c086e (diff) |
qmltc: Support Component roots
It is a very special case that doesn't undergo a normal compilation but
instead just uses QQmlObjectCreator::createComponent() logic.
As QQmlObjectCreator::createComponent() returns a new QQmlComponent,
we can't use it within the qmltc-generated type's ctor. Instead, just
fake the same flow by incorporating the code into the qmltc type
setting
As a drive-by, fix the code to work correctly with Component roots.
This should now pretty much cover all the mystical logic of
QQmlComponentAndAliasResolver and, with tests, we can safely simplify
the qmltc code generator bits later without introducing bugs
Enhance tst_qqmlcomponent::componentTypes test to highlight that
property Component p: ComponentDerivedType {} is not marked with
QV4::CompiledData::Object::IsComponent flag at all and thus considered
to be an ordinary object binding, unlike
property Component p: NotComponentDerivedType {}
Pick-to: 6.3
Change-Id: I4ec41952d15f9659d316e44dab4050aa4908327c
Reviewed-by: Fawzi Mohamed <fawzi.mohamed@qt.io>
Diffstat (limited to 'tests/auto/qml')
-rw-r--r-- | tests/auto/qml/qmltc/CMakeLists.txt | 2 | ||||
-rw-r--r-- | tests/auto/qml/qmltc/data/ComponentType.qml | 7 | ||||
-rw-r--r-- | tests/auto/qml/qmltc/data/componentTypes.qml | 25 | ||||
-rw-r--r-- | tests/auto/qml/qmltc/tst_qmltc.cpp | 43 | ||||
-rw-r--r-- | tests/auto/qml/qmltc/tst_qmltc.h | 1 | ||||
-rw-r--r-- | tests/auto/qml/qqmlcomponent/data/ComponentType.qml | 4 | ||||
-rw-r--r-- | tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp | 17 |
7 files changed, 98 insertions, 1 deletions
diff --git a/tests/auto/qml/qmltc/CMakeLists.txt b/tests/auto/qml/qmltc/CMakeLists.txt index 17a9442f70..e6982ab1e3 100644 --- a/tests/auto/qml/qmltc/CMakeLists.txt +++ b/tests/auto/qml/qmltc/CMakeLists.txt @@ -24,6 +24,8 @@ set(qml_sources data/ObjectWithId.qml data/documentWithIds.qml data/importNamespace.qml + data/ComponentType.qml + data/componentTypes.qml data/signalHandlers.qml data/javaScriptFunctions.qml diff --git a/tests/auto/qml/qmltc/data/ComponentType.qml b/tests/auto/qml/qmltc/data/ComponentType.qml new file mode 100644 index 0000000000..55fe4249a6 --- /dev/null +++ b/tests/auto/qml/qmltc/data/ComponentType.qml @@ -0,0 +1,7 @@ +import QtQml +Component { + id: componentRoot + QtObject { + objectName: "enclosed" + } +} diff --git a/tests/auto/qml/qmltc/data/componentTypes.qml b/tests/auto/qml/qmltc/data/componentTypes.qml new file mode 100644 index 0000000000..48b68e9112 --- /dev/null +++ b/tests/auto/qml/qmltc/data/componentTypes.qml @@ -0,0 +1,25 @@ +import QtQuick +Item { + ComponentType { // normal type here + id: normal + property string text: "indirect component" + } + + Component { + id: accessibleNormal + ComponentType { + id: inaccessibleNormal + } + } + + property Component p2: ComponentType { id: accessible; property string text: "foo" } + property Component p3: Rectangle { id: inaccessible; property string text: "bar" } + + TableView { + delegate: Rectangle { id: inaccessibleDelegate } + } + + TableView { + delegate: ComponentType { id: accessibleDelegate } + } +} diff --git a/tests/auto/qml/qmltc/tst_qmltc.cpp b/tests/auto/qml/qmltc/tst_qmltc.cpp index 1fdaddbcde..d097e62a67 100644 --- a/tests/auto/qml/qmltc/tst_qmltc.cpp +++ b/tests/auto/qml/qmltc/tst_qmltc.cpp @@ -38,6 +38,8 @@ #include "objectwithid.h" #include "documentwithids.h" #include "importnamespace.h" +#include "componenttype.h" +#include "componenttypes.h" #include "signalhandlers.h" #include "javascriptfunctions.h" @@ -542,6 +544,47 @@ void tst_qmltc::importNamespace() QCOMPARE(created.text(), u"hello, world"_qs); } +void tst_qmltc::componentTypes() +{ + { + QQmlEngine e; + PREPEND_NAMESPACE(ComponentType) created(&e); + QQmlContext *ctx = e.contextForObject(&created); + QCOMPARE(ctx->objectForName("componentRoot"), &created); + + QScopedPointer<QObject> enclosed(created.create()); + QVERIFY(enclosed); + QCOMPARE(enclosed->objectName(), u"enclosed"_qs); + } + + { + QQmlEngine e; + PREPEND_NAMESPACE(componentTypes) created(&e); + QQmlContext *ctx = e.contextForObject(&created); + + QObject *normal = ctx->objectForName(u"normal"_qs); + QVERIFY(normal); + QCOMPARE(normal->property("text").toString(), u"indirect component"_qs); + + QVERIFY(ctx->objectForName(u"accessibleNormal"_qs)); + QVERIFY(!ctx->objectForName(u"inaccessibleNormal"_qs)); + QVERIFY(ctx->objectForName(u"accessible"_qs)); + QVERIFY(!ctx->objectForName(u"inaccessible"_qs)); + QVERIFY(ctx->objectForName(u"accessibleDelegate"_qs)); + QVERIFY(!ctx->objectForName(u"inaccessibleDelegate"_qs)); + + QCOMPARE(created.p2()->property("text").toString(), u"foo"_qs); + QVERIFY(created.p3()->property("text").toString().isEmpty()); + + // ComponentType still subclasses QQmlComponent, so create() works: + QQmlComponent *normalComponent = qobject_cast<QQmlComponent *>(normal); + QVERIFY(normalComponent); + QScopedPointer<QObject> enclosed(normalComponent->create()); + QVERIFY(enclosed); + QCOMPARE(enclosed->objectName(), u"enclosed"_qs); + } +} + void tst_qmltc::signalHandlers() { QQmlEngine e; diff --git a/tests/auto/qml/qmltc/tst_qmltc.h b/tests/auto/qml/qmltc/tst_qmltc.h index be5ab2850e..ffffc6d9b7 100644 --- a/tests/auto/qml/qmltc/tst_qmltc.h +++ b/tests/auto/qml/qmltc/tst_qmltc.h @@ -52,6 +52,7 @@ private slots: void properties(); void ids(); void importNamespace(); + void componentTypes(); void signalHandlers(); void jsFunctions(); diff --git a/tests/auto/qml/qqmlcomponent/data/ComponentType.qml b/tests/auto/qml/qqmlcomponent/data/ComponentType.qml index 1e6fa88216..dbad44b511 100644 --- a/tests/auto/qml/qqmlcomponent/data/ComponentType.qml +++ b/tests/auto/qml/qqmlcomponent/data/ComponentType.qml @@ -1,4 +1,6 @@ import QtQml Component { - QtObject {} // this is required + QtObject { // having a type inside Component is required + objectName: "enclosed" + } } diff --git a/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp b/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp index 4f52661767..30be024217 100644 --- a/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp +++ b/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp @@ -1136,6 +1136,11 @@ void tst_qqmlcomponent::componentTypes() component.loadUrl(testFileUrl("ComponentType.qml")); QScopedPointer<QObject> o(component.create()); QVERIFY2(!o.isNull(), qPrintable(component.errorString())); + QQmlComponent *oComponent = qobject_cast<QQmlComponent *>(o.get()); + QVERIFY(oComponent); + QScopedPointer<QObject> enclosed(oComponent->create()); + QVERIFY(!enclosed.isNull()); + QCOMPARE(enclosed->objectName(), u"enclosed"_qs); } { @@ -1158,6 +1163,18 @@ void tst_qqmlcomponent::componentTypes() QVERIFY(!ctx->objectForName(u"inaccessible"_qs)); QVERIFY(ctx->objectForName(u"accessibleDelegate"_qs)); QVERIFY(!ctx->objectForName(u"inaccessibleDelegate"_qs)); + + QCOMPARE(qvariant_cast<QObject *>(o->property("p2"))->property("text").toString(), + u"foo"_qs); + auto p3Object = qvariant_cast<QObject *>(o->property("p3")); + QVERIFY(p3Object); + QVERIFY(p3Object->property("text").toString().isEmpty()); + + QQmlComponent *normalComponent = qobject_cast<QQmlComponent *>(normal); + QVERIFY(normalComponent); + QScopedPointer<QObject> enclosed(normalComponent->create()); + QVERIFY(enclosed); + QCOMPARE(enclosed->objectName(), u"enclosed"_qs); } } |