diff options
author | Juha Vuolle <juha.vuolle@insta.fi> | 2021-04-26 08:20:38 +0300 |
---|---|---|
committer | Juha Vuolle <juha.vuolle@insta.fi> | 2021-05-03 13:52:26 +0300 |
commit | 8c4ce171b22d2513733f6a5ebb94b0fd95e7440f (patch) | |
tree | 79d003a4860e25273f0b7591da20449752d873a4 | |
parent | 5f2290b9affcbc5025d0be5892cd95ea80817a9c (diff) |
Convert autotests to use QTestPrivate bindable helpers
Also add the missing fail-checks after the helper calls.
Task-number: QTBUG-91375
Task-number: QTBUG-89895
Change-Id: I889657fed7488508c5e4157c7527f54f4232a2f5
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
-rw-r--r-- | tests/auto/qml/qqmlstatemachine/CMakeLists.txt | 1 | ||||
-rw-r--r-- | tests/auto/qml/qqmlstatemachine/tst_qqmlstatemachine.cpp | 24 | ||||
-rw-r--r-- | tests/auto/qml/scxmlqmlcpp/CMakeLists.txt | 1 | ||||
-rw-r--r-- | tests/auto/qml/scxmlqmlcpp/tst_scxmlqmlcpp.cpp | 132 | ||||
-rw-r--r-- | tests/auto/qstatemachine/qstatemachine/CMakeLists.txt | 5 | ||||
-rw-r--r-- | tests/auto/qstatemachine/qstatemachine/tst_qstatemachine.cpp | 112 | ||||
-rw-r--r-- | tests/auto/shared/bindableutils.h | 165 | ||||
-rw-r--r-- | tests/auto/statemachine/CMakeLists.txt | 4 | ||||
-rw-r--r-- | tests/auto/statemachine/tst_statemachine.cpp | 69 |
9 files changed, 240 insertions, 273 deletions
diff --git a/tests/auto/qml/qqmlstatemachine/CMakeLists.txt b/tests/auto/qml/qqmlstatemachine/CMakeLists.txt index fd14ad7..bf77991 100644 --- a/tests/auto/qml/qqmlstatemachine/CMakeLists.txt +++ b/tests/auto/qml/qqmlstatemachine/CMakeLists.txt @@ -15,6 +15,7 @@ qt_internal_add_test(tst_qqmlstatemachine Qt::GuiPrivate Qt::QmlPrivate Qt::StateMachineQmlPrivate + Qt::TestPrivate ) ## Scopes: diff --git a/tests/auto/qml/qqmlstatemachine/tst_qqmlstatemachine.cpp b/tests/auto/qml/qqmlstatemachine/tst_qqmlstatemachine.cpp index d0b9445..938821a 100644 --- a/tests/auto/qml/qqmlstatemachine/tst_qqmlstatemachine.cpp +++ b/tests/auto/qml/qqmlstatemachine/tst_qqmlstatemachine.cpp @@ -37,8 +37,8 @@ #include <QtQml/qqmlscriptstring.h> #include <QTest> +#include <QtTest/private/qpropertytesthelper_p.h> #include "../../shared/util.h" -#include "../../shared/bindableutils.h" #include "../../shared/bindableqmlutils.h" class tst_qqmlstatemachine : public QQmlDataTest @@ -117,19 +117,23 @@ void tst_qqmlstatemachine::tst_cppObjectSignal() void tst_qqmlstatemachine::tst_bindings() { - // -- SignalTransition::guard SignalTransition signalTransition; // Generating QQmlScriptString requires proper qml context setup, and here we // use same the element that we are testing to create the testing material QQmlEngine engine; QQmlComponent component(&engine, QUrl(QLatin1String("qrc:///data/signaltransition.qml"))); - std::unique_ptr<QObject> obj(component.create()); SignalTransition *st1 = qobject_cast<SignalTransition*>(obj->findChild<QObject*>("st1")); SignalTransition *st2 = qobject_cast<SignalTransition*>(obj->findChild<QObject*>("st2")); QVERIFY(st1 && st2 && (st1->guard() != st2->guard())); - testWritableBindableBasics<SignalTransition, QQmlScriptString>( + + // -- SignalTransition::guard + QTestPrivate::testReadWritePropertyBasics<SignalTransition, QQmlScriptString>( signalTransition, st1->guard(), st2->guard(), "guard"); + if (QTest::currentTestFailed()) { + qWarning() << "SignalTransition::guard bindable test failed."; + return; + } // -- SignalTransition::signal // We use QML to create the test material (QJSValues that contain valid methods) @@ -138,17 +142,25 @@ void tst_qqmlstatemachine::tst_bindings() QMetaObject::invokeMethod(obj.get(), "getSignal1", Q_RETURN_ARG(QVariant, signal1)); QMetaObject::invokeMethod(obj.get(), "getSignal2", Q_RETURN_ARG(QVariant, signal2)); // QJSValue does not implement operator== so we supply own comparator - testWritableBindableBasics<SignalTransition, QJSValue>( + QTestPrivate::testReadWritePropertyBasics<SignalTransition, QJSValue>( *st1, signal1.value<QJSValue>(), signal2.value<QJSValue>(), "signal", [](QJSValue d1, QJSValue d2) { return d1.strictlyEquals(d2); }); + if (QTest::currentTestFailed()) { + qWarning() << "SignalTransition::signal bindable test failed."; + return; + } // -- TimeoutTransition::timeout TimeoutTransition timeoutTransition; QCOMPARE(timeoutTransition.timeout(), 1000); // the initialvalue int timeout1{100}; int timeout2{200}; - testWritableBindableBasics<TimeoutTransition, int>( + QTestPrivate::testReadWritePropertyBasics<TimeoutTransition, int>( timeoutTransition, timeout1, timeout2, "timeout"); + if (QTest::currentTestFailed()) { + qWarning() << "TimeoutTransition::timeout bindable test failed."; + return; + } // -- FinalState::children FinalState finalState; diff --git a/tests/auto/qml/scxmlqmlcpp/CMakeLists.txt b/tests/auto/qml/scxmlqmlcpp/CMakeLists.txt index 67268d5..62e9f10 100644 --- a/tests/auto/qml/scxmlqmlcpp/CMakeLists.txt +++ b/tests/auto/qml/scxmlqmlcpp/CMakeLists.txt @@ -5,6 +5,7 @@ qt_internal_add_test(tst_scxmlqmlcpp Qt::Scxml Qt::ScxmlQmlPrivate Qt::CorePrivate + Qt::TestPrivate ) qt_internal_add_resource(tst_scxmlqmlcpp "tst_compiled" diff --git a/tests/auto/qml/scxmlqmlcpp/tst_scxmlqmlcpp.cpp b/tests/auto/qml/scxmlqmlcpp/tst_scxmlqmlcpp.cpp index 73d4a8e..3e13621 100644 --- a/tests/auto/qml/scxmlqmlcpp/tst_scxmlqmlcpp.cpp +++ b/tests/auto/qml/scxmlqmlcpp/tst_scxmlqmlcpp.cpp @@ -27,7 +27,7 @@ ****************************************************************************/ #include <QtTest> -#include <QObject> +#include <QtTest/private/qpropertytesthelper_p.h> #include <QtScxml/QScxmlStateMachine> #include <QtScxml/QScxmlNullDataModel> #include <QtScxmlQml/private/eventconnection_p.h> @@ -38,106 +38,143 @@ #include <QtQml/QQmlEngine> #include <QtQml/QQmlComponent> #include <memory> -#include "../../shared/bindableutils.h" - -#include <QDebug> class tst_scxmlqmlcpp: public QObject { Q_OBJECT + private slots: - void bindings(); + void initTestCase(); + + void eventConnectionStateMachineBinding(); + void eventConnectionEventsBinding(); + + void invokedServicesStateMachineBinding(); + void invokedServicesChildrenBinding(); + + void stateMachineLoaderInitialValuesBinding(); + void stateMachineLoaderSourceStateMachineBinding(); + void stateMachineLoaderDatamodelBinding(); + +private: + QScxmlEventConnection m_eventConnection; + QScxmlInvokedServices m_invokedServices; + QScxmlStateMachineLoader m_stateMachineLoader; + std::unique_ptr<QScxmlStateMachine> m_stateMachine1; + std::unique_ptr<QScxmlStateMachine> m_stateMachine2; }; -void tst_scxmlqmlcpp::bindings() { +void tst_scxmlqmlcpp::initTestCase() +{ + m_stateMachine1.reset(QScxmlStateMachine::fromFile("no_real_file_needed")); + m_stateMachine2.reset(QScxmlStateMachine::fromFile("no_real_file_needed")); +} - // -- test eventconnection::stateMachine - QScxmlEventConnection eventConnection; - std::unique_ptr<QScxmlStateMachine> sm1(QScxmlStateMachine::fromFile("no_real_file_needed")); - std::unique_ptr<QScxmlStateMachine> sm2(QScxmlStateMachine::fromFile("no_real_file_needed")); - testWritableBindableBasics<QScxmlEventConnection, QScxmlStateMachine*>( - eventConnection, sm1.get(), sm2.get(), "stateMachine"); +void tst_scxmlqmlcpp::eventConnectionStateMachineBinding() +{ + QCOMPARE(m_eventConnection.bindableStateMachine().value(), nullptr); + QTestPrivate::testReadWritePropertyBasics<QScxmlEventConnection, QScxmlStateMachine*>( + m_eventConnection, m_stateMachine1.get(), m_stateMachine2.get(), "stateMachine"); + m_eventConnection.setStateMachine(nullptr); // tidy up +} - // -- test eventconnection::events +void tst_scxmlqmlcpp::eventConnectionEventsBinding() +{ QStringList eventList1{{"event1"},{"event2"}}; QStringList eventList2{{"event3"},{"event4"}}; - testWritableBindableBasics<QScxmlEventConnection, QStringList>( - eventConnection, eventList1, eventList2, "events"); + QCOMPARE(m_eventConnection.events(), QStringList()); + QTestPrivate::testReadWritePropertyBasics<QScxmlEventConnection, QStringList>( + m_eventConnection, eventList1, eventList2, "events"); + m_eventConnection.setEvents(QStringList()); // tidy up +} - // -- test invokedservices::statemachine - QScxmlInvokedServices invokedServices; - testWritableBindableBasics<QScxmlInvokedServices, QScxmlStateMachine*>( - invokedServices, sm1.get(), sm2.get(), "stateMachine"); +void tst_scxmlqmlcpp::invokedServicesStateMachineBinding() +{ + QCOMPARE(m_invokedServices.stateMachine(), nullptr); + QTestPrivate::testReadWritePropertyBasics<QScxmlInvokedServices, QScxmlStateMachine*>( + m_invokedServices, m_stateMachine1.get(), m_stateMachine2.get(), "stateMachine"); + m_invokedServices.setStateMachine(nullptr); // tidy up +} - // -- test invokedservices::children +void tst_scxmlqmlcpp::invokedServicesChildrenBinding() +{ TopMachine topSm; + QScxmlInvokedServices invokedServices; invokedServices.setStateMachine(&topSm); QCOMPARE(invokedServices.children().count(), 0); QCOMPARE(topSm.invokedServices().count(), 0); - // at some point during the topSm execution there are 3 invoked services // of the same name ('3' filters out as '1' at QML binding) topSm.start(); QTRY_COMPARE(topSm.invokedServices().count(), 3); QCOMPARE(invokedServices.children().count(), 1); - // after completion invoked services drop back to 0 QTRY_COMPARE(topSm.invokedServices().count(), 0); QCOMPARE(invokedServices.children().count(), 0); - // bind *to* the invokedservices property and check that we observe same changes // during the topSm execution QProperty<qsizetype> serviceCounter; serviceCounter.setBinding([&](){ return invokedServices.children().count(); }); - QCOMPARE(serviceCounter, 0); topSm.start(); QTRY_COMPARE(serviceCounter, 1); QCOMPARE(topSm.invokedServices().count(), 3); +} - // -- test statemachineloader::initialValues - QScxmlStateMachineLoader stateMachineLoader; +void tst_scxmlqmlcpp::stateMachineLoaderInitialValuesBinding() +{ QVariantMap values1{{"key1","value1"}, {"key2","value2"}}; QVariantMap values2{{"key3","value3"}, {"key4","value4"}}; - testWritableBindableBasics<QScxmlStateMachineLoader, QVariantMap>( - stateMachineLoader, values1, values2, "initialValues"); + QTestPrivate::testReadWritePropertyBasics<QScxmlStateMachineLoader, QVariantMap>( + m_stateMachineLoader, values1, values2, "initialValues"); + m_stateMachineLoader.setInitialValues(QVariantMap()); // tidy up +} + +void tst_scxmlqmlcpp::stateMachineLoaderSourceStateMachineBinding() +{ + // Test source and stateMachine together as they interact with each other - // -- test statemachineloader::source QUrl source1(QStringLiteral("qrc:///statemachine.scxml")); QUrl source2(QStringLiteral("qrc:///topmachine.scxml")); - // The 'setSource' assumes a valid qml context, so we need to create a bit differently + // The 'setSource' of the statemachineloader assumes a valid qml context QQmlEngine engine; QQmlComponent component(&engine); - component.setData("import QtQuick\n; import QtScxml\n; Item { StateMachineLoader { objectName: \'sml\'; } }", QUrl()); + component.setData( + "import QtQuick;\n" + "import QtScxml;\n" + "Item { StateMachineLoader { objectName: \'sml\'; } }", + QUrl()); std::unique_ptr<QObject> root(component.create()); - QScxmlStateMachineLoader *sml = qobject_cast<QScxmlStateMachineLoader*>(root->findChild<QObject*>("sml")); + QScxmlStateMachineLoader *sml = + qobject_cast<QScxmlStateMachineLoader*>(root->findChild<QObject*>("sml")); QVERIFY(sml != nullptr); - testWritableBindableBasics<QScxmlStateMachineLoader, QUrl>(*sml, source1, source2, "source"); - // -- test statemachineloader::datamodel - QScxmlNullDataModel model1; - QScxmlNullDataModel model2; - testWritableBindableBasics<QScxmlStateMachineLoader,QScxmlDataModel*> - (stateMachineLoader, &model1, &model2, "dataModel"); + // -- StateMachineLoader::source + QTestPrivate::testReadWritePropertyBasics<QScxmlStateMachineLoader, QUrl>( + *sml, source1, source2, "source"); + if (QTest::currentTestFailed()) { + qWarning() << "QScxmlStateMachineLoader::source property testing failed"; + return; + } - // -- test statemachineloader::statemachine - // The statemachine can be indirectly set by setting the source + // -- StateMachineLoader::stateMachine + // The statemachine can be set indirectly by setting the 'source' QSignalSpy smSpy(sml, &QScxmlStateMachineLoader::stateMachineChanged); QUrl sourceNonexistent(QStringLiteral("qrc:///file_doesnt_exist.scxml")); QUrl sourceBroken(QStringLiteral("qrc:///brokenstatemachine.scxml")); QVERIFY(sml->stateMachine() != nullptr); QTest::ignoreMessage(QtWarningMsg, - "<Unknown File>:3:11: QML StateMachineLoader: Cannot open 'qrc:///file_doesnt_exist.scxml' for reading."); + "<Unknown File>:3:8: QML StateMachineLoader: Cannot open 'qrc:///file_doesnt_exist.scxml' for reading."); sml->setSource(sourceNonexistent); QVERIFY(sml->stateMachine() == nullptr); QCOMPARE(smSpy.count(), 1); QTest::ignoreMessage(QtWarningMsg, - "<Unknown File>:3:11: QML StateMachineLoader: :/brokenstatemachine.scxml:59:1: error: initial state 'working' not found for <scxml> element"); + "<Unknown File>:3:8: QML StateMachineLoader: :/brokenstatemachine.scxml:59:1: error: initial state 'working' not found for <scxml> element"); QTest::ignoreMessage(QtWarningMsg, "SCXML document has errors"); QTest::ignoreMessage(QtWarningMsg, - "<Unknown File>:3:11: QML StateMachineLoader: Something went wrong while parsing 'qrc:///brokenstatemachine.scxml':\n"); + "<Unknown File>:3:8: QML StateMachineLoader: Something went wrong while parsing 'qrc:///brokenstatemachine.scxml':\n"); sml->setSource(sourceBroken); QVERIFY(sml->stateMachine() == nullptr); QCOMPARE(smSpy.count(), 1); @@ -149,5 +186,14 @@ void tst_scxmlqmlcpp::bindings() { QVERIFY(hasStateMachine == true); } +void tst_scxmlqmlcpp::stateMachineLoaderDatamodelBinding() +{ + QScxmlNullDataModel model1; + QScxmlNullDataModel model2; + QTestPrivate::testReadWritePropertyBasics<QScxmlStateMachineLoader,QScxmlDataModel*> + (m_stateMachineLoader, &model1, &model2, "dataModel"); + m_stateMachineLoader.setDataModel(nullptr); // tidy up +} + QTEST_MAIN(tst_scxmlqmlcpp) #include "tst_scxmlqmlcpp.moc" diff --git a/tests/auto/qstatemachine/qstatemachine/CMakeLists.txt b/tests/auto/qstatemachine/qstatemachine/CMakeLists.txt index 1d0c13b..13cd6c2 100644 --- a/tests/auto/qstatemachine/qstatemachine/CMakeLists.txt +++ b/tests/auto/qstatemachine/qstatemachine/CMakeLists.txt @@ -6,15 +6,16 @@ qt_internal_add_test(tst_qstatemachine SOURCES tst_qstatemachine.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::StateMachine Qt::StateMachinePrivate + Qt::TestPrivate ) ## Scopes: ##################################################################### qt_internal_extend_target(tst_qstatemachine CONDITION TARGET Qt::Widgets - PUBLIC_LIBRARIES + LIBRARIES Qt::Widgets ) diff --git a/tests/auto/qstatemachine/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/qstatemachine/tst_qstatemachine.cpp index 50d264d..3be1615 100644 --- a/tests/auto/qstatemachine/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/qstatemachine/qstatemachine/tst_qstatemachine.cpp @@ -27,6 +27,7 @@ ****************************************************************************/ #include <QtTest/QtTest> +#include <QtTest/private/qpropertytesthelper_p.h> #include <QtCore/QCoreApplication> #ifndef QT_NO_WIDGETS #include <QtWidgets/QPushButton> @@ -48,8 +49,6 @@ #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 @@ -6870,32 +6869,52 @@ void tst_QStateMachine::bindings() // -- QHistoryState::defaultTransition QHistoryState *historyState = new QHistoryState(&machine); - testWritableBindableBasics<QHistoryState, QAbstractTransition*>( + QTestPrivate::testReadWritePropertyBasics<QHistoryState, QAbstractTransition*>( *historyState, transition1, transition2, "defaultTransition"); + if (QTest::currentTestFailed()) { + qWarning() << "QHistoryState::defaultTransition bindable test failed."; + return; + } // -- QHistoryState::historyType QHistoryState::HistoryType type1 = QHistoryState::HistoryType::DeepHistory; QHistoryState::HistoryType type2 = QHistoryState::HistoryType::ShallowHistory; - testWritableBindableBasics<QHistoryState, QHistoryState::HistoryType>( + QTestPrivate::testReadWritePropertyBasics<QHistoryState, QHistoryState::HistoryType>( *historyState, type1, type2, "historyType"); + if (QTest::currentTestFailed()) { + qWarning() << "QHistoryState::historyType bindable test failed."; + return; + } // -- QState::initialState QAbstractState *is1 = new QState(state1); QAbstractState *is2 = new QState(state1); - testWritableBindableBasics<QState, QAbstractState*>( + QTestPrivate::testReadWritePropertyBasics<QState, QAbstractState*>( *state1, is1, is2, "initialState"); + if (QTest::currentTestFailed()) { + qWarning() << "QState::initialState bindable test failed."; + return; + } // -- QState::errorState - testWritableBindableBasics<QState, QAbstractState*>( + QTestPrivate::testReadWritePropertyBasics<QState, QAbstractState*>( *state1, is1, is2, "errorState"); + if (QTest::currentTestFailed()) { + qWarning() << "QState::errorState bindable test failed."; + return; + } // -- 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>( + QTestPrivate::testReadWritePropertyBasics<QState, QState::ChildMode>( *state2, mode1, mode2, "childMode"); + if (QTest::currentTestFailed()) { + qWarning() << "QState::childMode bindable test failed."; + return; + } // -- QAbstractState::active QState *startState = new QState(&machine); @@ -6920,20 +6939,32 @@ void tst_QStateMachine::bindings() QSignalTransition signalTransition; QObject sender1; QObject sender2; - testWritableBindableBasics<QSignalTransition, const QObject*>( + QTestPrivate::testReadWritePropertyBasics<QSignalTransition, const QObject*>( signalTransition, &sender1, &sender2, "senderObject"); + if (QTest::currentTestFailed()) { + qWarning() << "QSignalTransition::senderObject bindable test failed."; + return; + } // -- QSignalTransition::signal QByteArray arr1("arr1"); QByteArray arr2("arr2"); - testWritableBindableBasics<QSignalTransition, QByteArray>( + QTestPrivate::testReadWritePropertyBasics<QSignalTransition, QByteArray>( signalTransition, arr1, arr2, "signal"); + if (QTest::currentTestFailed()) { + qWarning() << "QSignalTransition::signal bindable test failed."; + return; + } // -- QAbstractTransition::transitionType auto transitionType1 = QAbstractTransition::InternalTransition; auto transitionType2 = QAbstractTransition::ExternalTransition; - testWritableBindableBasics<QAbstractTransition, QAbstractTransition::TransitionType>( + QTestPrivate::testReadWritePropertyBasics<QAbstractTransition, QAbstractTransition::TransitionType>( signalTransition, transitionType1, transitionType2, "transitionType"); + if (QTest::currentTestFailed()) { + qWarning() << "QAbstractTransition::transitionType bindable test failed."; + return; + } // -- QStateMachine::errorString QStateMachine brokenMachine; @@ -6941,67 +6972,106 @@ void tst_QStateMachine::bindings() QState* brokenState = new QState(&brokenMachine); brokenMachine.setInitialState(brokenState); new QState(brokenState); // make broken state a compound state that lacks the initial state - testReadableBindableBasics<QStateMachine, QString>( + QTestPrivate::testReadOnlyPropertyBasics<QStateMachine, QString>( brokenMachine, QString(), QStringLiteral("Missing initial state in compound state ''"), "errorString", [&](){ brokenMachine.start(); QTRY_VERIFY(brokenMachine.isRunning()); }); + if (QTest::currentTestFailed()) { + qWarning() << "QStateMachine::errorString bindable test failed for (non-empty case)."; + return; + } // test also clearing of the error above - testReadableBindableBasics<QStateMachine, QString>( + QTestPrivate::testReadOnlyPropertyBasics<QStateMachine, QString>( brokenMachine, QStringLiteral("Missing initial state in compound state ''"), QString(), "errorString", [&](){ brokenMachine.clearError(); }); + if (QTest::currentTestFailed()) { + qWarning() << "QStateMachine::errorString bindable test failed (empty case)."; + return; + } // -- QStateMachine::globalRestorePolicy - testWritableBindableBasics<QStateMachine, QState::RestorePolicy>( + QTestPrivate::testReadWritePropertyBasics<QStateMachine, QState::RestorePolicy>( machine, QState::RestorePolicy::RestoreProperties, QState::RestorePolicy::DontRestoreProperties, "globalRestorePolicy"); + if (QTest::currentTestFailed()) { + qWarning() << "QStateMachine::globalRestorePolicy bindable test failed."; + return; + } #if QT_CONFIG(animation) // -- QStateMachine::animated - testWritableBindableBasics<QStateMachine, bool>( + QTestPrivate::testReadWritePropertyBasics<QStateMachine, bool>( machine, false, true, "animated"); + if (QTest::currentTestFailed()) { + qWarning() << "QStateMachine::animated bindable test failed."; + return; + } #endif // -- QEventTransition::eventSource QEventTransition eventTransition; QObject source1; QObject source2; - testWritableBindableBasics<QEventTransition, QObject*>( + QTestPrivate::testReadWritePropertyBasics<QEventTransition, QObject*>( eventTransition, &source1, &source2, "eventSource"); + if (QTest::currentTestFailed()) { + qWarning() << "QEventTransition::eventSource bindable test failed."; + return; + } // -- QEventTransition::eventType auto eventType1 = QEvent::Enter; auto eventType2 = QEvent::Leave; - testWritableBindableBasics<QEventTransition, QEvent::Type>( + QTestPrivate::testReadWritePropertyBasics<QEventTransition, QEvent::Type>( eventTransition, eventType1, eventType2, "eventType"); + if (QTest::currentTestFailed()) { + qWarning() << "QEventTransition::eventType bindable test failed."; + return; + } // -- QKeyEventTransition::key QKeyEventTransition keyEventTransition; int key1{1}; int key2{2}; - testWritableBindableBasics<QKeyEventTransition, int>( + QTestPrivate::testReadWritePropertyBasics<QKeyEventTransition, int>( keyEventTransition, key1, key2, "key"); + if (QTest::currentTestFailed()) { + qWarning() << "QKeyEventTransition::key bindable test failed."; + return; + } // -- QKeyEventTransition::modifierMask Qt::KeyboardModifiers mod1 = Qt::KeyboardModifier::ShiftModifier; Qt::KeyboardModifiers mod2 = Qt::KeyboardModifier::ControlModifier; - testWritableBindableBasics<QKeyEventTransition>( + QTestPrivate::testReadWritePropertyBasics<QKeyEventTransition>( keyEventTransition, mod1, mod2, "modifierMask"); + if (QTest::currentTestFailed()) { + qWarning() << "QKeyEventTransition::modifierMask bindable test failed."; + return; + } // -- QMouseEventTransition::button QMouseEventTransition mouseEventTransition; Qt::MouseButton button1 = Qt::MouseButton::LeftButton; Qt::MouseButton button2 = Qt::MouseButton::RightButton; - testWritableBindableBasics<QMouseEventTransition>( + QTestPrivate::testReadWritePropertyBasics<QMouseEventTransition>( mouseEventTransition, button1, button2, "button"); + if (QTest::currentTestFailed()) { + qWarning() << "QMouseEventTransition::button bindable test failed."; + return; + } // -- QMouseEventTransition::modifierMask - testWritableBindableBasics<QMouseEventTransition>( + QTestPrivate::testReadWritePropertyBasics<QMouseEventTransition>( mouseEventTransition, mod1, mod2, "modifierMask"); - + if (QTest::currentTestFailed()) { + qWarning() << "QMouseEventTransition::modifierMask bindable test failed."; + return; + } } QTEST_MAIN(tst_QStateMachine) diff --git a/tests/auto/shared/bindableutils.h b/tests/auto/shared/bindableutils.h deleted file mode 100644 index 7c4f03f..0000000 --- a/tests/auto/shared/bindableutils.h +++ /dev/null @@ -1,165 +0,0 @@ -/**************************************************************************** -** -** 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> -#include <memory> - -#define DEFINE_CHANGE_SPY \ - std::unique_ptr<QSignalSpy> changeSpy(metaProperty.hasNotifySignal() ? new QSignalSpy(&testedClass, metaProperty.notifySignal()) : nullptr); - -#define VERIFY_CHANGE_COUNT(expected_count) \ - if (changeSpy) \ - QVERIFY2(changeSpy.get()->count() == expected_count, qPrintable(id + ", actual: " + QString::number(changeSpy.get()->count()))); - -// This is a helper function to test basics of typical bindable -// properties that are read-only (but can change) 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 -// "data0" is the initial datavalue -// "data1" is an instance of the propertydata and must differ from data0 -// "propertyName" is the name of the property we are interested in testing -// "modifierFunction" that does whatever is needed to change the underlying property -// A custom "dataComparator" can be provided for cases that the data doesn't have operator== -template<typename TestedClass, typename TestedData> -void testReadableBindableBasics(TestedClass& testedClass, TestedData data0, TestedData data1, - const char* propertyName, - std::function<void()> modifierFunction = [](){ qWarning() << "Error, data modifier function must be provided"; }, - std::function<bool(TestedData,TestedData)> dataComparator = [](TestedData d1, TestedData d2) { return d1 == d2; }) -{ - // 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(), qPrintable(id)); - QVERIFY2(modifierFunction, qPrintable(id)); - // Create a signal spy for the property changed -signal (if the property has such signal) - DEFINE_CHANGE_SPY - QUntypedBindable bindable = metaProperty.bindable(&testedClass); - - // Verify initial data is as expected - QVERIFY2(dataComparator(testedClass.property(propertyName).template value<TestedData>(), data0), qPrintable(id)); - // Use the property as the source in a binding - QProperty<bool> data1Used([&](){ - return dataComparator(testedClass.property(propertyName).template value<TestedData>(), data1); - }); - // Verify binding's initial state - QVERIFY2(data1Used == false, qPrintable(id)); - // Call the supplied modifier function and verify that the value and binding both change - modifierFunction(); - QVERIFY2(data1Used == true, qPrintable(id)); - QVERIFY2(dataComparator(testedClass.property(propertyName).template value<TestedData>(), data1), qPrintable(id)); - VERIFY_CHANGE_COUNT(1) -} - - -// 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 -// A custom "dataComparator" can be provided for cases that the data doesn't have operator== -template<typename TestedClass, typename TestedData> -void testWritableBindableBasics(TestedClass& testedClass, TestedData data1, - TestedData data2, const char* propertyName, - std::function<bool(TestedData,TestedData)> dataComparator = [](TestedData d1, TestedData d2) { return d1 == d2; }) -{ - // 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(), qPrintable(id)); - // Create a signal change for the property changed -signal (if the property has such signal) - DEFINE_CHANGE_SPY - QUntypedBindable bindable = metaProperty.bindable(&testedClass); - - // Test basic property read and write - testedClass.setProperty(propertyName, QVariant::fromValue(data1)); - - QVERIFY2(dataComparator(testedClass.property(propertyName).template value<TestedData>(), data1), qPrintable(id)); - VERIFY_CHANGE_COUNT(1) - - // 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(dataComparator(testedClass.property(propertyName).template value<TestedData>(), data2), qPrintable(id)); - VERIFY_CHANGE_COUNT(2) - // 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(dataComparator(testedClass.property(propertyName).template value<TestedData>(), data1), qPrintable(id)); - VERIFY_CHANGE_COUNT(3) - - // Remove binding by setting a value directly - QVERIFY2(bindable.hasBinding(), qPrintable(id)); - testedClass.setProperty(propertyName, QVariant::fromValue(data2)); - QVERIFY2(dataComparator(testedClass.property(propertyName).template value<TestedData>(), data2), qPrintable(id)); - QVERIFY2(!bindable.hasBinding(), qPrintable(id)); - VERIFY_CHANGE_COUNT(4) - - // Test using the property as the source in a binding - QProperty<bool> data1Used([&](){ - return dataComparator(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 diff --git a/tests/auto/statemachine/CMakeLists.txt b/tests/auto/statemachine/CMakeLists.txt index d23dc7f..475ac42 100644 --- a/tests/auto/statemachine/CMakeLists.txt +++ b/tests/auto/statemachine/CMakeLists.txt @@ -6,13 +6,13 @@ qt_internal_add_test(tst_statemachine SOURCES tst_statemachine.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::Gui Qt::Qml Qt::Scxml - LIBRARIES Qt::CorePrivate Qt::ScxmlPrivate + Qt::TestPrivate ) # Resources: diff --git a/tests/auto/statemachine/tst_statemachine.cpp b/tests/auto/statemachine/tst_statemachine.cpp index 404243d..a84bf4b 100644 --- a/tests/auto/statemachine/tst_statemachine.cpp +++ b/tests/auto/statemachine/tst_statemachine.cpp @@ -27,6 +27,7 @@ ****************************************************************************/ #include <QtTest> +#include <QtTest/private/qpropertytesthelper_p.h> #include <QObject> #include <QXmlStreamReader> #include <QtScxml/qscxmlcompiler.h> @@ -36,7 +37,6 @@ #include <QtScxml/QScxmlNullDataModel> #include "topmachine.h" -#include "../shared/bindableutils.h" enum { SpyWaitTime = 8000 }; @@ -467,14 +467,22 @@ void tst_StateMachine::bindings() std::unique_ptr<QScxmlStateMachine> stateMachine1( QScxmlStateMachine::fromFile(QString(":/tst_statemachine/invoke.scxml"))); QVERIFY(stateMachine1.get()); - testReadableBindableBasics<QScxmlStateMachine, bool>( + QTestPrivate::testReadOnlyPropertyBasics<QScxmlStateMachine, bool>( *stateMachine1, false, true, "initialized", [&](){ stateMachine1.get()->start(); }); + if (QTest::currentTestFailed()) { + qWarning() << "QScxmlStateMachine::initialized bindable test failed."; + return; + } // -- QScxmlStateMachine::initialValues QVariantMap map1{{"map", 1}}; QVariantMap map2{{"map", 2}}; - testWritableBindableBasics<QScxmlStateMachine, QVariantMap>( + QTestPrivate::testReadWritePropertyBasics<QScxmlStateMachine, QVariantMap>( *stateMachine1, map1, map2, "initialValues"); + if (QTest::currentTestFailed()) { + qWarning() << "QScxmlStateMachine::initialValues bindable test failed."; + return; + } // -- QScxmlStateMachine::loader class MockLoader: public QScxmlCompiler::Loader @@ -484,8 +492,12 @@ void tst_StateMachine::bindings() }; MockLoader loader1; MockLoader loader2; - testWritableBindableBasics<QScxmlStateMachine, QScxmlCompiler::Loader*>( + QTestPrivate::testReadWritePropertyBasics<QScxmlStateMachine, QScxmlCompiler::Loader*>( *stateMachine1, &loader1, &loader2, "loader"); + if (QTest::currentTestFailed()) { + qWarning() << "QScxmlStateMachine::loader bindable test failed."; + return; + } // -- QScxmlStateMachine::dataModel // Use non-existent file below, as valid file would initialize the model @@ -494,26 +506,24 @@ void tst_StateMachine::bindings() std::unique_ptr<QScxmlStateMachine> stateMachine3( QScxmlStateMachine::fromFile(QString("not_a_real_file"))); QScxmlNullDataModel model1; - QScxmlNullDataModel model2; - // Use the "readable" test helper as the data can only change once - testReadableBindableBasics<QScxmlStateMachine, QScxmlDataModel*>( - *stateMachine2, nullptr, &model1, "dataModel", - [&](){ stateMachine2->setDataModel(&model1); }); - // verify that setting the model twice will not break the binding (setting is ignored) - QProperty<QScxmlDataModel*> modelProperty(&model1); - stateMachine3.get()->bindableDataModel().setBinding(Qt::makePropertyBinding(modelProperty)); - QVERIFY(stateMachine3.get()->bindableDataModel().hasBinding()); - QVERIFY(stateMachine3.get()->dataModel() == &model1); - stateMachine3.get()->setDataModel(&model2); // should be ignored - QVERIFY(stateMachine3.get()->dataModel() == &model1); - QVERIFY(stateMachine3.get()->bindableDataModel().hasBinding()); + // data can only change once + QTestPrivate::testWriteOncePropertyBasics<QScxmlStateMachine, QScxmlDataModel*>( + *stateMachine2, nullptr, &model1, "dataModel"); + if (QTest::currentTestFailed()) { + qWarning() << "QScxmlStateMachine::dataModel bindable test failed."; + return; + } // -- QScxmlStateMachine::tableData // Use the statemachine to generate the tabledDatas for testing std::unique_ptr<QScxmlStateMachine> stateMachine4( QScxmlStateMachine::fromFile(QString(":/tst_statemachine/invoke.scxml"))); - testWritableBindableBasics<QScxmlStateMachine, QScxmlTableData*>( + QTestPrivate::testReadWritePropertyBasics<QScxmlStateMachine, QScxmlTableData*>( *stateMachine2, stateMachine1.get()->tableData(), stateMachine4.get()->tableData(), "tableData"); + if (QTest::currentTestFailed()) { + qWarning() << "QScxmlStateMachine::tableData bindable test failed."; + return; + } // -- QScxmlStateMachine::invokedServices // Test executes statemachine and observes as the invoked services change @@ -540,24 +550,15 @@ void tst_StateMachine::bindings() // -- QScxmlDataModel::stateMachine QScxmlNullDataModel dataModel1; - QScxmlNullDataModel dataModel2; std::unique_ptr<QScxmlStateMachine> stateMachine5( QScxmlStateMachine::fromFile(QString("not_a_real_file"))); - std::unique_ptr<QScxmlStateMachine> stateMachine6( - QScxmlStateMachine::fromFile(QString("not_a_real_file"))); - // Use the "readable" test helper as the data can only change once - testReadableBindableBasics<QScxmlDataModel, QScxmlStateMachine*>( - dataModel1, nullptr, stateMachine5.get(), "stateMachine", - [&](){ dataModel1.setStateMachine(stateMachine5.get()); }); - // verify that setting the model twice will not break the binding (setting is ignored) - QProperty<QScxmlStateMachine*> stateMachineProperty(stateMachine6.get()); - dataModel2.bindableStateMachine().setBinding(Qt::makePropertyBinding(stateMachineProperty)); - QVERIFY(dataModel2.bindableStateMachine().hasBinding()); - QVERIFY(dataModel2.stateMachine() == stateMachine6.get()); - dataModel2.setStateMachine(stateMachine5.get()); // should be ignored - QVERIFY(dataModel2.stateMachine() == stateMachine6.get()); - QVERIFY(dataModel2.bindableStateMachine().hasBinding()); - + // data can only change once + QTestPrivate::testWriteOncePropertyBasics<QScxmlDataModel, QScxmlStateMachine*>( + dataModel1, nullptr, stateMachine5.get(), "stateMachine"); + if (QTest::currentTestFailed()) { + qWarning() << "QScxmlDataModel::stateMachine bindable test failed."; + return; + } } QTEST_MAIN(tst_StateMachine) |