aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2020-09-22 10:48:23 +0200
committerFabian Kosmale <fabian.kosmale@qt.io>2020-10-12 17:50:07 +0200
commita243f1eeeb9eda237ea2f6dad403984ab14aa375 (patch)
tree3ded380bfe0f1293263403d2676a3e3db0709160 /tests
parent7750609d8850f6b36317b6243db77b3fe98fd841 (diff)
Fix QProperty property interaction with aliases
With this change, an alias of a bindable property is also bindable, and shares its bindable interface with the target. Moreover, the logic in QQmlTypeCompiler is adjusted so that a change handler of an alias uses the bindable interface if possible, instead of connecting to the alias' change signal. That would never be emitted if the target is a QProperty without a notify signal. Alias properties still have a change signal, but those never get emitted. Change-Id: I857dfdbe51048a2b604ad632982e7f4adac6b907 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/qml/qqmlecmascript/data/aliasOfQProperty.qml7
-rw-r--r--tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp37
2 files changed, 44 insertions, 0 deletions
diff --git a/tests/auto/qml/qqmlecmascript/data/aliasOfQProperty.qml b/tests/auto/qml/qqmlecmascript/data/aliasOfQProperty.qml
new file mode 100644
index 0000000000..6c37a33f39
--- /dev/null
+++ b/tests/auto/qml/qqmlecmascript/data/aliasOfQProperty.qml
@@ -0,0 +1,7 @@
+import Qt.test 1.0
+ClassWithQProperty {
+ id: root
+ property alias myAlias: root.value
+ property int changeCounter: 0
+ onMyAliasChanged: ++changeCounter
+}
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
index ef2eb5ad03..e3396a430f 100644
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
@@ -382,6 +382,7 @@ private slots:
void semicolonAfterProperty();
void hugeStack();
void bindingOnQProperty();
+ void aliasOfQProperty();
void bindingOnQPropertyContextProperty();
void bindingContainingQProperty();
void urlConstruction();
@@ -9177,6 +9178,42 @@ void tst_qqmlecmascript::bindingOnQProperty()
QVERIFY(qprop.hasBinding());
}
+void tst_qqmlecmascript::aliasOfQProperty() {
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("aliasOfQProperty.qml"));
+ QVERIFY2(component.isReady(), qPrintable(component.errorString()));
+ QScopedPointer<QObject> root(component.create());
+ QProperty<float> &qprop = static_cast<ClassWithQProperty*>(root.data())->value;
+ QProperty<float> otherProperty;
+
+
+ qprop.setBinding([&](){return otherProperty.value();});
+ // changing the target properties value triggers the alias property's change handler exactly
+ // once, and doesn't require reading the value (binding is no longer lazy)
+ otherProperty.setValue(42.0);
+ QCOMPARE(root->property("changeCounter").toInt(), 1);
+ // reading the value afterwards doesn't trigger the observer again
+ QCOMPARE(root->property("myAlias").toFloat(), 42.0);
+ QCOMPARE(root->property("changeCounter").toInt(), 1);
+
+ // writing to the alias breaks the binding
+ root->setProperty("myAlias", 12.0);
+ QCOMPARE(qprop.value(), 12.0);
+ QVERIFY(!qprop.hasBinding());
+
+ // it is possible to obtain the bindable interface of the target from the bindable property
+ QUntypedBindable bindable;
+ void *argv[] = { &bindable };
+ int myaliasPropertyIndex = root->metaObject()->indexOfProperty("myAlias");
+ root->metaObject()->metacall(root.get(), QMetaObject::BindableProperty, myaliasPropertyIndex, argv);
+ QVERIFY(bindable.isValid());
+
+ bool ok = bindable.setBinding(Qt::makePropertyBinding([&]() -> float {return 13.0; } ));
+ QVERIFY(ok);
+ QVERIFY(qprop.hasBinding());
+ QCOMPARE(qprop.value(), 13.0);
+}
+
void tst_qqmlecmascript::bindingOnQPropertyContextProperty()
{
QSKIP("Test needs to be adjusted");