aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/qml
diff options
context:
space:
mode:
authorAndrei Golubev <andrei.golubev@qt.io>2021-12-21 16:49:51 +0100
committerAndrei Golubev <andrei.golubev@qt.io>2021-12-27 08:27:04 +0100
commit39aee682bf388e191a409485cbbe2e01996bc163 (patch)
tree571e078686af4cb789f930d5ba64e2836c94cb0b /tests/auto/qml
parente659b5b23a75676627fb6dfb275c4eede24c086e (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.txt2
-rw-r--r--tests/auto/qml/qmltc/data/ComponentType.qml7
-rw-r--r--tests/auto/qml/qmltc/data/componentTypes.qml25
-rw-r--r--tests/auto/qml/qmltc/tst_qmltc.cpp43
-rw-r--r--tests/auto/qml/qmltc/tst_qmltc.h1
-rw-r--r--tests/auto/qml/qqmlcomponent/data/ComponentType.qml4
-rw-r--r--tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp17
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);
}
}