diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2021-04-21 15:13:11 +0200 |
---|---|---|
committer | Fabian Kosmale <fabian.kosmale@qt.io> | 2021-04-22 08:44:32 +0200 |
commit | 297a3479c6b7c5220deccb1baf8806c2c15be9ed (patch) | |
tree | c9f928799780221df956495b501a1751545c2b65 | |
parent | 54cfca2eca7168e35d14d00197ae669fc75073b0 (diff) |
QQmlPropertyBinding: Call RESET every time binding evaluates to undefined
To be in line with the behavior of the old bindings, we have to call
reset, even when the binding was undefined before.
Add a test which checks this behavior for both new and old types of
properties. Amends d64e7c9c6cd172e426b9bb2c5e45fda5e6a5bfb2.
Task-number: QTBUG-91001
Pick-to: 6.1
Change-Id: I1067a2fd56d5b7587281a9262e9bd389c825e587
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
5 files changed, 70 insertions, 5 deletions
diff --git a/src/qml/qml/qqmlpropertybinding.cpp b/src/qml/qml/qqmlpropertybinding.cpp index 9624c15ee7..e00bf08a16 100644 --- a/src/qml/qml/qqmlpropertybinding.cpp +++ b/src/qml/qml/qqmlpropertybinding.cpp @@ -335,10 +335,6 @@ void QQmlPropertyBinding::handleUndefinedAssignment(QQmlEnginePrivate *ep, void metaType.destruct(dataPtr); metaType.construct(dataPtr, currentValue.constData()); }; - if (isUndefined()) { - // if we are already detached, there is no reason to call reset again (?) - return; - } if (prop.isResettable()) { // Normally a reset would remove any existing binding; but now we need to keep the binding alive // to handle the case where this binding becomes defined again diff --git a/tests/auto/qml/qqmlecmascript/data/undefinedResetsProperty.3.qml b/tests/auto/qml/qqmlecmascript/data/undefinedResetsProperty.3.qml new file mode 100644 index 0000000000..51831bf9f5 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/undefinedResetsProperty.3.qml @@ -0,0 +1,12 @@ +import Qt.test 1.0 + +MyQmlObject { + id: root + property int counter: 0 + + resettableProperty: root.counter == 0 ? 19 : undefined + + function incrementCount() { + root.counter = (root.counter + 1) % 3 + } +} diff --git a/tests/auto/qml/qqmlecmascript/data/undefinedResetsProperty.4.qml b/tests/auto/qml/qqmlecmascript/data/undefinedResetsProperty.4.qml new file mode 100644 index 0000000000..5418a1d229 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/undefinedResetsProperty.4.qml @@ -0,0 +1,12 @@ +import Qt.test 1.0 + +MyQmlObject { + id: root + property int counter: 0 + + resettableProperty2: root.counter == 0 ? 19 : undefined + + function incrementCount() { + root.counter = (root.counter + 1) % 3 + } +} diff --git a/tests/auto/qml/qqmlecmascript/testtypes.h b/tests/auto/qml/qqmlecmascript/testtypes.h index 34f612e276..acc066fddd 100644 --- a/tests/auto/qml/qqmlecmascript/testtypes.h +++ b/tests/auto/qml/qqmlecmascript/testtypes.h @@ -104,6 +104,7 @@ class MyQmlObject : public QObject Q_PROPERTY(QObject *objectProperty READ objectProperty WRITE setObjectProperty NOTIFY objectChanged) Q_PROPERTY(QQmlListProperty<QObject> objectListProperty READ objectListProperty CONSTANT) Q_PROPERTY(int resettableProperty READ resettableProperty WRITE setResettableProperty RESET resetProperty) + Q_PROPERTY(int resettableProperty2 READ resettableProperty2 WRITE setResettableProperty2 RESET resetProperty2 BINDABLE bindableResetProperty2) Q_PROPERTY(QRegularExpression regularExpression READ regularExpression WRITE setRegularExpression) Q_PROPERTY(int nonscriptable READ nonscriptable WRITE setNonscriptable SCRIPTABLE false) Q_PROPERTY(int intProperty READ intProperty WRITE setIntProperty NOTIFY intChanged) @@ -169,7 +170,12 @@ public: int resettableProperty() const { return m_resetProperty; } void setResettableProperty(int v) { m_resetProperty = v; } - void resetProperty() { m_resetProperty = 13; } + void resetProperty() { m_resetProperty = 13; ++m_resetCount; } + + int resettableProperty2() const { return m_resetProperty2; } + void setResettableProperty2(int i) { m_resetProperty2 = i; } + void resetProperty2(){ m_resetProperty2 = 13; ++ m_resetCount; } + QBindable<int> bindableResetProperty2() { return &m_resetProperty2; } QRegularExpression regularExpression() { return m_regularExpression; } void setRegularExpression(const QRegularExpression ®ularExpression) @@ -264,6 +270,7 @@ public slots: void v8function(QQmlV4Function*); void registeredFlagMethod(Qt::MouseButtons v) { m_buttons = v; } QString slotWithReturnValue(const QString &arg) { return arg; } + int resetCount() { return m_resetCount; } private: friend class tst_qqmlecmascript; @@ -275,7 +282,9 @@ private: QUrl m_url; QList<QObject *> m_objectQList; int m_value; + Q_OBJECT_BINDABLE_PROPERTY(MyQmlObject, int, m_resetProperty2) int m_resetProperty; + int m_resetCount = 0; QRegularExpression m_regularExpression; QVariant m_variant; QJSValue m_qjsvalue; diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index ea47b0384d..89e0246623 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -145,6 +145,8 @@ private slots: void compositePropertyType(); void jsObject(); void undefinedResetsProperty(); + void undefinedResetsEveryTime_data(); + void undefinedResetsEveryTime(); void listToVariant(); void listAssignment(); void multiEngineObject(); @@ -2514,6 +2516,40 @@ void tst_qqmlecmascript::undefinedResetsProperty() } } +void tst_qqmlecmascript::undefinedResetsEveryTime_data() +{ + QTest::addColumn<QString>("file"); + QTest::addColumn<QByteArray>("property"); + + QTest::newRow("old property") << QString::fromUtf8("undefinedResetsProperty.3.qml") << QByteArray("resettableProperty"); + QTest::newRow("new property") << QString::fromUtf8("undefinedResetsProperty.4.qml") << QByteArray("resettableProperty2"); +} + +void tst_qqmlecmascript::undefinedResetsEveryTime() +{ + QFETCH(QString, file); + QFETCH(QByteArray, property); + + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl(file)); + QScopedPointer<QObject> object(component.create()); + QVERIFY(object != nullptr); + auto qmlObject = qobject_cast<MyQmlObject *>(object.get()); + QVERIFY(qmlObject); + + QCOMPARE(qmlObject->resetCount(), 0); + QCOMPARE(object->property(property).toInt(), 19); + + bool ok = QMetaObject::invokeMethod(object.get(), "incrementCount"); + QVERIFY(ok); + QCOMPARE(qmlObject->resetCount(), 1); + ok = QMetaObject::invokeMethod(object.get(), "incrementCount"); + QVERIFY(ok); + QCOMPARE(qmlObject->resetCount(), 2); + + QCOMPARE(object->property(property).toInt(), 13); +} + // Aliases to variant properties should work void tst_qqmlecmascript::qtbug_22464() { |