aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2023-02-16 10:54:34 +0100
committerUlf Hermann <ulf.hermann@qt.io>2023-03-03 12:02:00 +0100
commit05f56d7c78754855c643470ad4e8dfd35c96f927 (patch)
treefe23c5afec83efd75f06046bc0fdb7b7da465999 /tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp
parente625e39845ccecda871659a8ff39ac081f4aee82 (diff)
QML: Allow as-casting to value types
If the "Addressable" option to ValueTypeBehavior is set, you can use the "as" operator to cast a previously unknown type into either undefined or the given type. We can use this in qmlcachegen to generate efficient code for further operations on the same type. In the generated C++ it in fact only works for GetLookup because: a, We generally don't do SetLookup on value types, yet. b, We generally don't call methods on value types, yet. c, We cannot store a union of undefined and a sequence type, yet. However, getting properties of value types is the most important application of the new casts so this is well worth it. As a side effect we can also look up things in potentially undefined results of other operations now. For example list lookups. Task-number: QTBUG-94807 Change-Id: Ifdf34f1f3f67b7a0a8953b9ed0e947b74638a28c Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp')
-rw-r--r--tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp45
1 files changed, 45 insertions, 0 deletions
diff --git a/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp b/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp
index f19e33017c..131724c5ec 100644
--- a/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp
+++ b/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp
@@ -171,6 +171,7 @@ private slots:
void variantMapLookup();
void mathMinMax();
void enumFromBadSingleton();
+ void objectLookupOnListElement();
};
void tst_QmlCppCodegen::initTestCase()
@@ -533,6 +534,7 @@ void tst_QmlCppCodegen::math()
QVERIFY(!object.isNull());
QCOMPARE(object->property("a").toInt(), 9);
QCOMPARE(object->property("b").toDouble(), 50.0 / 22.0);
+ QCOMPARE(object->property("c").toDouble(), std::atan(1.0) * 8.0);
}
void tst_QmlCppCodegen::unknownParameter()
@@ -3222,6 +3224,22 @@ void tst_QmlCppCodegen::valueTypeBehavior()
QVERIFY(!o2.isNull());
QVERIFY(qIsNaN(o2->property("e").toDouble()));
QCOMPARE(o2->property("f").toDouble(), 5.0);
+
+ const QUrl cast(u"qrc:/qt/qml/TestTypes/valueTypeCast.qml"_s);
+ QQmlComponent c3(&engine, cast);
+ QVERIFY2(c3.isReady(), qPrintable(c3.errorString()));
+ QScopedPointer o3(c3.create());
+ QVERIFY(!o3.isNull());
+ QCOMPARE(o3->property("x"), 10);
+
+ QTest::ignoreMessage(
+ QtWarningMsg,
+ qPrintable(cast.toString()
+ + u":8: TypeError: Cannot read property 'x' of undefined"_s));
+ o3->setProperty("v", QLatin1String("not a rect"));
+
+ // If the binding throws an exception, the value doesn't change.
+ QCOMPARE(o3->property("x"), 10);
}
void tst_QmlCppCodegen::invisibleSingleton()
@@ -3380,6 +3398,33 @@ void tst_QmlCppCodegen::enumFromBadSingleton()
QVERIFY(o->objectName().isEmpty());
}
+void tst_QmlCppCodegen::objectLookupOnListElement()
+{
+ QQmlEngine engine;
+
+ const QUrl url(u"qrc:/qt/qml/TestTypes/objectLookupOnListElement.qml"_s);
+ QQmlComponent c1(&engine, url);
+ QVERIFY2(c1.isReady(), qPrintable(c1.errorString()));
+
+ QScopedPointer<QObject> object(c1.create());
+ QVERIFY(!object.isNull());
+
+ QList<int> zOrders;
+ QMetaObject::invokeMethod(object.data(), "zOrders", Q_RETURN_ARG(QList<int>, zOrders));
+ QCOMPARE(zOrders, (QList<int>{1, 0, 0}));
+ object->setProperty("current", 1);
+ QMetaObject::invokeMethod(object.data(), "zOrders", Q_RETURN_ARG(QList<int>, zOrders));
+ QCOMPARE(zOrders, (QList<int>{0, 1, 0}));
+
+ QMetaObject::invokeMethod(object.data(), "clearChildren");
+ QTest::ignoreMessage(
+ QtWarningMsg,
+ qPrintable(url.toString()
+ + u":21: TypeError: Cannot read property 'z' of undefined"_s));
+ QMetaObject::invokeMethod(object.data(), "zOrders", Q_RETURN_ARG(QList<int>, zOrders));
+ QCOMPARE(zOrders, (QList<int>()));
+}
+
QTEST_MAIN(tst_QmlCppCodegen)
#include "tst_qmlcppcodegen.moc"