From 0292acf06df4444086586b951dd1567506e07fa0 Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Tue, 8 Dec 2020 16:03:36 +0100 Subject: QProperty: Handle eager binding calling setBinding When an eager binding triggers a setBinding call, we end up with a special kind of binding loop: setBinding() -> evaluate -> notifyObserver ^ | | / ---------------------------- We now catch set condition, and set the binding status to BindingLoop (with a distinct description). Task-number: QTBUG-87153 Task-number: QTBUG-87733 Change-Id: I9f9915797d82eab820fc279baceaf89d7e5a3f4a Reviewed-by: Ulf Hermann (cherry picked from commit ddc585b7c773786045f3658d7da5425ed2f2f786) Reviewed-by: Qt Cherry-pick Bot --- .../auto/corelib/kernel/qproperty/tst_qproperty.cpp | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'tests/auto/corelib') diff --git a/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp b/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp index 5ae92e8981..ca2de478cf 100644 --- a/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp +++ b/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp @@ -462,6 +462,7 @@ class BindingLoopTester : public QObject eagerData2.setBinding(Qt::makePropertyBinding([&](){ return eagerData.value() + 1; } ) ); i->setValue(42); } + BindingLoopTester() {} int eagerProp() {return eagerData.value();} void setEagerProp(int i) { eagerData = i; } @@ -495,11 +496,21 @@ void tst_QProperty::bindingLoop() QCOMPARE(secondProp.binding().error().type(), QPropertyBindingError::BindingLoop); - QProperty i; - BindingLoopTester tester(&i); - QCOMPARE(tester.bindableEagerProp().binding().error().type(), QPropertyBindingError::BindingLoop); - QEXPECT_FAIL("", "Only the first property in a dependency cycle is set to the error state", Continue); - QCOMPARE(tester.bindableEagerProp2().binding().error().type(), QPropertyBindingError::BindingLoop); + { + QProperty i; + BindingLoopTester tester(&i); + QCOMPARE(tester.bindableEagerProp().binding().error().type(), QPropertyBindingError::BindingLoop); + QCOMPARE(tester.bindableEagerProp2().binding().error().type(), QPropertyBindingError::BindingLoop); + } + { + BindingLoopTester tester; + auto handler = tester.bindableEagerProp().onValueChanged([&]() { + tester.bindableEagerProp().setBinding([](){return 42;}); + }); + tester.bindableEagerProp().setBinding([]() {return 42;}); + QCOMPARE(tester.bindableEagerProp().binding().error().type(), QPropertyBindingError::BindingLoop); + QCOMPARE(tester.bindableEagerProp().binding().error().description(), "Binding set during binding evaluation!"); + } } class ReallocTester : public QObject -- cgit v1.2.3