diff options
| author | Ulf Hermann <ulf.hermann@qt.io> | 2023-02-16 10:54:34 +0100 |
|---|---|---|
| committer | Ulf Hermann <ulf.hermann@qt.io> | 2023-03-03 12:02:00 +0100 |
| commit | 05f56d7c78754855c643470ad4e8dfd35c96f927 (patch) | |
| tree | fe23c5afec83efd75f06046bc0fdb7b7da465999 /tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp | |
| parent | e625e39845ccecda871659a8ff39ac081f4aee82 (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.cpp | 45 |
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" |
