From 04641454beb27f667062dbf79116729f159b0041 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 28 Sep 2020 10:32:00 +0200 Subject: Disable moving of QProperty The semantics are not very intuitive, and it opens a can of worms with regards to what should happen with observers that observe that property. Change-Id: I6fb00b7693904b968224cc87d098bbd0ea776ba3 Reviewed-by: Ulf Hermann --- .../corelib/kernel/qproperty/tst_qproperty.cpp | 132 ++++++--------------- 1 file changed, 33 insertions(+), 99 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp b/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp index d71053ff04..565916b781 100644 --- a/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp +++ b/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp @@ -45,13 +45,9 @@ private slots: void bindingAfterUse(); void switchBinding(); void avoidDependencyAllocationAfterFirstEval(); - void propertyArrays(); void boolProperty(); void takeBinding(); void replaceBinding(); - void swap(); - void moveNotifies(); - void moveCtor(); void changeHandler(); void propertyChangeHandlerApi(); void subscribe(); @@ -238,27 +234,6 @@ void tst_QProperty::avoidDependencyAllocationAfterFirstEval() QCOMPARE(QPropertyBindingDataPointer::get(propWithBinding).bindingPtr()->dependencyObserverCount, 2u); } -void tst_QProperty::propertyArrays() -{ - std::vector> properties; - - int expectedSum = 0; - for (int i = 0; i < 10; ++i) { - properties.emplace_back(i); - expectedSum += i; - } - - QProperty sum([&]() { - return std::accumulate(properties.begin(), properties.end(), 0); - }); - - QCOMPARE(sum.value(), expectedSum); - - properties[4] = properties[4] + 42; - expectedSum += 42; - QCOMPARE(sum.value(), expectedSum); -} - void tst_QProperty::boolProperty() { QProperty first(true); @@ -311,74 +286,6 @@ void tst_QProperty::replaceBinding() QCOMPARE(second.value(), 100); } -void tst_QProperty::swap() -{ - QProperty firstDependency(1); - QProperty secondDependency(2); - - QProperty first(Qt::makePropertyBinding(firstDependency)); - QProperty second(Qt::makePropertyBinding(secondDependency)); - - QCOMPARE(first.value(), 1); - QCOMPARE(second.value(), 2); - - std::swap(first, second); - - QCOMPARE(first.value(), 2); - QCOMPARE(second.value(), 1); - - secondDependency = 20; - QCOMPARE(first.value(), 20); - QCOMPARE(second.value(), 1); - - firstDependency = 100; - QCOMPARE(first.value(), 20); - QCOMPARE(second.value(), 100); -} - -void tst_QProperty::moveNotifies() -{ - QProperty first(1); - QProperty second(2); - - QProperty propertyInTheMiddle(Qt::makePropertyBinding(first)); - - QProperty finalProp1(Qt::makePropertyBinding(propertyInTheMiddle)); - QProperty finalProp2(Qt::makePropertyBinding(propertyInTheMiddle)); - - QCOMPARE(finalProp1.value(), 1); - QCOMPARE(finalProp2.value(), 1); - - QCOMPARE(QPropertyBindingDataPointer::get(propertyInTheMiddle).observerCount(), 2); - - QProperty other(Qt::makePropertyBinding(second)); - QCOMPARE(other.value(), 2); - - QProperty otherDep(Qt::makePropertyBinding(other)); - QCOMPARE(otherDep.value(), 2); - QCOMPARE(QPropertyBindingDataPointer::get(other).observerCount(), 1); - - propertyInTheMiddle = std::move(other); - - QCOMPARE(QPropertyBindingDataPointer::get(other).observerCount(), 0); - - QCOMPARE(finalProp1.value(), 2); - QCOMPARE(finalProp2.value(), 2); -} - -void tst_QProperty::moveCtor() -{ - QProperty first(1); - - QProperty intermediate(Qt::makePropertyBinding(first)); - QCOMPARE(intermediate.value(), 1); - QCOMPARE(QPropertyBindingDataPointer::get(first).observerCount(), 1); - - QProperty targetProp(std::move(first)); - - QCOMPARE(QPropertyBindingDataPointer::get(targetProp).observerCount(), 0); -} - void tst_QProperty::changeHandler() { QProperty testProperty(0); @@ -570,6 +477,11 @@ void tst_QProperty::bindingLoop() class ReallocTester : public QObject { + /* + * This class and the realloc test rely on the fact that the internal property hashmap has an + * initial capacity of 8 and a load factor of 0.5. Thus, it is necessary to cause actions which + * allocate 5 different QPropertyBindingData + * */ Q_OBJECT Q_PROPERTY(int prop1 READ prop1 WRITE setProp1 BINDABLE bindableProp1) Q_PROPERTY(int prop2 READ prop2 WRITE setProp2 BINDABLE bindableProp2) @@ -595,12 +507,34 @@ public: void tst_QProperty::realloc() { - ReallocTester tester; - tester.bindableProp1().setBinding([&](){return tester.prop5();}); - tester.bindableProp2().setBinding([&](){return tester.prop5();}); - tester.bindableProp3().setBinding([&](){return tester.prop5();}); - tester.bindableProp4().setBinding([&](){return tester.prop5();}); - tester.bindableProp5().setBinding([&]() -> int{return 42;}); + { + // Triggering a reallocation does not crash + ReallocTester tester; + tester.bindableProp1().setBinding([&](){return tester.prop5();}); + tester.bindableProp2().setBinding([&](){return tester.prop5();}); + tester.bindableProp3().setBinding([&](){return tester.prop5();}); + tester.bindableProp4().setBinding([&](){return tester.prop5();}); + tester.bindableProp5().setBinding([&]() -> int{return 42;}); + QCOMPARE(tester.prop1(), 42); + } + { + // After a reallocation, property observers still work + ReallocTester tester; + int modificationCount = 0; + QPropertyChangeHandler observer {[&](){ ++modificationCount; }}; + tester.bindableProp1().observe(&observer); + tester.setProp1(12); + QCOMPARE(modificationCount, 1); + QCOMPARE(tester.prop1(), 12); + + tester.bindableProp1().setBinding([&](){return tester.prop5();}); + tester.bindableProp2().setBinding([&](){return tester.prop5();}); + tester.bindableProp3().setBinding([&](){return tester.prop5();}); + tester.bindableProp4().setBinding([&](){return tester.prop5();}); + tester.bindableProp5().setBinding([&]() -> int{return 42;}); + QEXPECT_FAIL("", "ChangeHandler bug with eager properties", Continue); + QCOMPARE(modificationCount, 2); + } }; void tst_QProperty::changePropertyFromWithinChangeHandler() -- cgit v1.2.3