summaryrefslogtreecommitdiffstats
path: root/tests/auto
diff options
context:
space:
mode:
authorJuha Vuolle <juha.vuolle@insta.fi>2021-02-23 15:33:34 +0200
committerJuha Vuolle <juha.vuolle@insta.fi>2021-05-03 13:51:54 +0300
commit00f3ec2b5c11aa399d72f8daaf0a45150905123e (patch)
treee91db0d8ed1fc227fe71ea4dbd94f27a77214e2e /tests/auto
parentf87d6ad8eabc03be67bc23136ec0bae488d8ee28 (diff)
QtStateMachine QML-facing properties' bindable support part 1
This commit covers these QML-facing classes: QHistoryState QState QAbstractState Task-number: QTBUG-91375 Change-Id: Ic66977c4f25198c19052f48754a956042caa3632 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'tests/auto')
-rw-r--r--tests/auto/qml/scxmlqmlcpp/tst_scxmlqmlcpp.cpp69
-rw-r--r--tests/auto/qstatemachine/qstatemachine/tst_qstatemachine.cpp59
-rw-r--r--tests/auto/shared/bindableutils.h104
3 files changed, 164 insertions, 68 deletions
diff --git a/tests/auto/qml/scxmlqmlcpp/tst_scxmlqmlcpp.cpp b/tests/auto/qml/scxmlqmlcpp/tst_scxmlqmlcpp.cpp
index 408530e..73d4a8e 100644
--- a/tests/auto/qml/scxmlqmlcpp/tst_scxmlqmlcpp.cpp
+++ b/tests/auto/qml/scxmlqmlcpp/tst_scxmlqmlcpp.cpp
@@ -38,6 +38,7 @@
#include <QtQml/QQmlEngine>
#include <QtQml/QQmlComponent>
#include <memory>
+#include "../../shared/bindableutils.h"
#include <QDebug>
@@ -46,74 +47,6 @@ class tst_scxmlqmlcpp: public QObject
Q_OBJECT
private slots:
void bindings();
-private:
-
- // This is a helper function to test basics of typical bindable
- // properties that are writable. Primarily ensure:
- // - properties work as before bindings
- // - added bindable aspects work
- //
- // "TestedClass" is the class type we are testing
- // "TestedData" is the data type of the property we are testing
- // "testedClass" is an instance of the class we are interested testing
- // "data1" and "data2" are two different instances of property data to set and get
- // "propertyName" is the name of the property we are interested in testing
- template<typename TestedClass, typename TestedData>
- void testWritableBindableBasics(TestedClass& testedClass, TestedData data1,
- TestedData data2, const char* propertyName)
- {
- // Get the property we are testing
- const QMetaObject *metaObject = testedClass.metaObject();
- QMetaProperty metaProperty = metaObject->property(metaObject->indexOfProperty(propertyName));
-
- // Generate a string to help identify failures (as this is a generic template)
- QString id(metaObject->className());
- id.append(QStringLiteral("::"));
- id.append(metaProperty.name());
-
- // Fail gracefully if preconditions to use this helper function are not met:
- QVERIFY2(metaProperty.isBindable() && metaProperty.isWritable()
- && metaProperty.hasNotifySignal(), qPrintable(id));
- // Create a signal spy for the property changed -signal
- QSignalSpy spy(&testedClass, metaProperty.notifySignal());
- QUntypedBindable bindable = metaProperty.bindable(&testedClass);
-
- // Test basic property read and write
- testedClass.setProperty(propertyName, QVariant::fromValue(data1));
- QVERIFY2(testedClass.property(propertyName).template value<TestedData>() == data1, qPrintable(id));
- QVERIFY2(spy.count() == 1, qPrintable(id + ", actual: " + QString::number(spy.count())));
-
- // Test setting a binding as a source for the property
- QProperty<TestedData> property1(data1);
- QProperty<TestedData> property2(data2);
- QVERIFY2(!bindable.hasBinding(), qPrintable(id));
- bindable.setBinding(Qt::makePropertyBinding(property2));
- QVERIFY2(bindable.hasBinding(), qPrintable(id));
- // Check that the value also changed
- QVERIFY2(testedClass.property(propertyName).template value<TestedData>() == data2, qPrintable(id));
- QVERIFY2(spy.count() == 2, qPrintable(id + ", actual: " + QString::number(spy.count())));
- // Same test but with a lambda binding (cast to be able to set the lambda directly)
- QBindable<TestedData> *typedBindable = static_cast<QBindable<TestedData>*>(&bindable);
- typedBindable->setBinding([&](){ return property1.value(); });
- QVERIFY2(typedBindable->hasBinding(), qPrintable(id));
- QVERIFY2(testedClass.property(propertyName).template value<TestedData>() == data1, qPrintable(id));
- QVERIFY2(spy.count() == 3, qPrintable(id + ", actual: " + QString::number(spy.count())));
-
- // Remove binding by setting a value directly
- QVERIFY2(bindable.hasBinding(), qPrintable(id));
- testedClass.setProperty(propertyName, QVariant::fromValue(data2));
- QVERIFY2(testedClass.property(propertyName).template value<TestedData>() == data2, qPrintable(id));
- QVERIFY2(!bindable.hasBinding(), qPrintable(id));
- QVERIFY2(spy.count() == 4, qPrintable(id + ", actual: " + QString::number(spy.count())));
-
- // Test using the property as the source in a binding
- QProperty<bool> data1Used([&](){
- return testedClass.property(propertyName).template value<TestedData>() == data1;
- });
- QVERIFY2(data1Used == false, qPrintable(id));
- testedClass.setProperty(propertyName, QVariant::fromValue(data1));
- QVERIFY2(data1Used == true, qPrintable(id));
- }
};
void tst_scxmlqmlcpp::bindings() {
diff --git a/tests/auto/qstatemachine/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/qstatemachine/tst_qstatemachine.cpp
index de132df..4aecf8f 100644
--- a/tests/auto/qstatemachine/qstatemachine/tst_qstatemachine.cpp
+++ b/tests/auto/qstatemachine/qstatemachine/tst_qstatemachine.cpp
@@ -48,6 +48,8 @@
#include "private/qstate_p.h"
#include "private/qstatemachine_p.h"
+#include "../../shared/bindableutils.h"
+
static int globalTick;
// Run exec for a maximum of TIMEOUT msecs
@@ -260,6 +262,7 @@ private slots:
void cancelDelayedEventWithChrono();
void postDelayedEventWithChronoAndStop();
void postDelayedEventWithChronoFromThread();
+ void bindings();
};
class TestState : public QState
@@ -6858,5 +6861,61 @@ void tst_QStateMachine::postDelayedEventWithChronoFromThread()
#endif
}
+void tst_QStateMachine::bindings()
+{
+ QStateMachine machine;
+ TestState *state1 = new TestState(&machine);
+ TestTransition *transition1 = new TestTransition(state1);
+ TestTransition *transition2 = new TestTransition(state1);
+
+ // -- QHistoryState::defaultTransition
+ QHistoryState *historyState = new QHistoryState(&machine);
+ testWritableBindableBasics<QHistoryState, QAbstractTransition*>(
+ *historyState, transition1, transition2, "defaultTransition");
+
+ // -- QHistoryState::historyType
+ QHistoryState::HistoryType type1 = QHistoryState::HistoryType::DeepHistory;
+ QHistoryState::HistoryType type2 = QHistoryState::HistoryType::ShallowHistory;
+ testWritableBindableBasics<QHistoryState, QHistoryState::HistoryType>(
+ *historyState, type1, type2, "historyType");
+
+ // -- QState::initialState
+ QAbstractState *is1 = new QState(state1);
+ QAbstractState *is2 = new QState(state1);
+ testWritableBindableBasics<QState, QAbstractState*>(
+ *state1, is1, is2, "initialState");
+
+ // -- QState::errorState
+ testWritableBindableBasics<QState, QAbstractState*>(
+ *state1, is1, is2, "errorState");
+
+ // -- QState::childMode
+ // Make a new state as re-use of state1 would yield irrelevant warnings
+ TestState *state2 = new TestState(&machine);
+ QState::ChildMode mode1 = QState::ChildMode::ParallelStates;
+ QState::ChildMode mode2 = QState::ChildMode::ExclusiveStates;
+ testWritableBindableBasics<QState, QState::ChildMode>(
+ *state2, mode1, mode2, "childMode");
+
+ // -- QAbstractState::active
+ QState *startState = new QState(&machine);
+ QFinalState *endState = new QFinalState(&machine);
+ DEFINE_ACTIVE_SPY(startState);
+ DEFINE_ACTIVE_SPY(endState);
+ machine.setInitialState(startState);
+ startState->addTransition(endState);
+
+ // Create a binding to the "active" property
+ QProperty<bool> active([&](){ return endState->active(); });
+ QVERIFY(!active);
+ machine.start();
+ // startState should get "enter/active == true" + "exit/active == false"
+ QTRY_COMPARE(startState_activeSpy.count(), 2);
+ // endState should get "enter/active == true"
+ QTRY_COMPARE(endState_activeSpy.count(), 1);
+ // Verify that the "active" value changed via binding
+ QVERIFY(active);
+}
+
QTEST_MAIN(tst_QStateMachine)
#include "tst_qstatemachine.moc"
diff --git a/tests/auto/shared/bindableutils.h b/tests/auto/shared/bindableutils.h
new file mode 100644
index 0000000..3e93752
--- /dev/null
+++ b/tests/auto/shared/bindableutils.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtScxml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef BINDABLEUTILS_H
+#define BINDABLEUTILS_H
+
+#include <QtTest>
+#include <QObject>
+
+// This is a helper function to test basics of typical bindable
+// properties that are writable. Primarily ensure:
+// - properties work as before bindings
+// - added bindable aspects work
+//
+// "TestedClass" is the class type we are testing
+// "TestedData" is the data type of the property we are testing
+// "testedClass" is an instance of the class we are interested testing
+// "data1" and "data2" are two different instances of property data to set and get
+// The "data1" and "data2" must differ from one another, and
+// the "data1" must differ from instance property's initial state
+// "propertyName" is the name of the property we are interested in testing
+template<typename TestedClass, typename TestedData>
+void testWritableBindableBasics(TestedClass& testedClass, TestedData data1,
+ TestedData data2, const char* propertyName)
+{
+ // Get the property we are testing
+ const QMetaObject *metaObject = testedClass.metaObject();
+ QMetaProperty metaProperty = metaObject->property(metaObject->indexOfProperty(propertyName));
+
+ // Generate a string to help identify failures (as this is a generic template)
+ QString id(metaObject->className());
+ id.append(QStringLiteral("::"));
+ id.append(propertyName);
+
+ // Fail gracefully if preconditions to use this helper function are not met:
+ QVERIFY2(metaProperty.isBindable() && metaProperty.isWritable()
+ && metaProperty.hasNotifySignal(), qPrintable(id));
+ // Create a signal spy for the property changed -signal
+ QSignalSpy spy(&testedClass, metaProperty.notifySignal());
+ QUntypedBindable bindable = metaProperty.bindable(&testedClass);
+
+ // Test basic property read and write
+ testedClass.setProperty(propertyName, QVariant::fromValue(data1));
+ QVERIFY2(testedClass.property(propertyName).template value<TestedData>() == data1, qPrintable(id));
+ QVERIFY2(spy.count() == 1, qPrintable(id + ", actual: " + QString::number(spy.count())));
+
+ // Test setting a binding as a source for the property
+ QProperty<TestedData> property1(data1);
+ QProperty<TestedData> property2(data2);
+ QVERIFY2(!bindable.hasBinding(), qPrintable(id));
+ bindable.setBinding(Qt::makePropertyBinding(property2));
+ QVERIFY2(bindable.hasBinding(), qPrintable(id));
+ // Check that the value also changed
+ QVERIFY2(testedClass.property(propertyName).template value<TestedData>() == data2, qPrintable(id));
+ QVERIFY2(spy.count() == 2, qPrintable(id + ", actual: " + QString::number(spy.count())));
+ // Same test but with a lambda binding (cast to be able to set the lambda directly)
+ QBindable<TestedData> *typedBindable = static_cast<QBindable<TestedData>*>(&bindable);
+ typedBindable->setBinding([&](){ return property1.value(); });
+ QVERIFY2(typedBindable->hasBinding(), qPrintable(id));
+ QVERIFY2(testedClass.property(propertyName).template value<TestedData>() == data1, qPrintable(id));
+ QVERIFY2(spy.count() == 3, qPrintable(id + ", actual: " + QString::number(spy.count())));
+
+ // Remove binding by setting a value directly
+ QVERIFY2(bindable.hasBinding(), qPrintable(id));
+ testedClass.setProperty(propertyName, QVariant::fromValue(data2));
+ QVERIFY2(testedClass.property(propertyName).template value<TestedData>() == data2, qPrintable(id));
+ QVERIFY2(!bindable.hasBinding(), qPrintable(id));
+ QVERIFY2(spy.count() == 4, qPrintable(id + ", actual: " + QString::number(spy.count())));
+
+ // Test using the property as the source in a binding
+ QProperty<bool> data1Used([&](){
+ return testedClass.property(propertyName).template value<TestedData>() == data1;
+ });
+ QVERIFY2(data1Used == false, qPrintable(id));
+ testedClass.setProperty(propertyName, QVariant::fromValue(data1));
+ QVERIFY2(data1Used == true, qPrintable(id));
+}
+
+#endif // BINDABLEUTILS_H