diff options
author | Tarja Sundqvist <tarja.sundqvist@qt.io> | 2023-10-11 16:01:45 +0300 |
---|---|---|
committer | Tarja Sundqvist <tarja.sundqvist@qt.io> | 2023-10-11 16:01:45 +0300 |
commit | 3f56c6b4bd1e3883581340243b4a7289807fffc9 (patch) | |
tree | bd3c65b5950d0931ba1a826e5f64f250584e2deb | |
parent | e8727aabe55526956295407d27317ec15e12b283 (diff) | |
parent | 29c25449e72ac918b5500f9b9e4cd0b189630498 (diff) |
Merge remote-tracking branch 'origin/tqtc/lts-5.15.12' into tqtc/lts-5.15-opensourcev5.15.12-lts-lgpl
Change-Id: Ic8e3766553bda7745290a39db8ff28e15c0dfe4d
-rw-r--r-- | .qmake.conf | 2 | ||||
-rw-r--r-- | src/scxml/qscxmlstatemachine.cpp | 9 | ||||
-rw-r--r-- | tests/auto/scion/tst_scion.cpp | 54 |
3 files changed, 57 insertions, 8 deletions
diff --git a/.qmake.conf b/.qmake.conf index 098b456..9b73845 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -4,4 +4,4 @@ CONFIG += warning_clean DEFINES += QT_NO_FOREACH QT_NO_JAVA_STYLE_ITERATORS QT_NO_LINKED_LIST -MODULE_VERSION = 5.15.11 +MODULE_VERSION = 5.15.12 diff --git a/src/scxml/qscxmlstatemachine.cpp b/src/scxml/qscxmlstatemachine.cpp index 58832b8..b22c618 100644 --- a/src/scxml/qscxmlstatemachine.cpp +++ b/src/scxml/qscxmlstatemachine.cpp @@ -767,6 +767,9 @@ void QScxmlStateMachinePrivate::attach(QScxmlStateMachineInfo *info) void QScxmlStateMachinePrivate::updateMetaCache() { + // This function creates a mapping from state index/name to their signal indexes. + // The state index may differ from its signal index as we don't generate history + // and invalid states, effectively skipping them m_stateIndexToSignalIndex.clear(); m_stateNameToSignalIndex.clear(); @@ -2366,7 +2369,11 @@ void QScxmlStateMachine::stop() bool QScxmlStateMachine::isActive(int stateIndex) const { Q_D(const QScxmlStateMachine); - return d->m_configuration.contains(stateIndex); + // Here we need to find the actual internal state index that corresponds with the + // index of the compiled metaobject (which is same as its mapped signal index). + // See updateMetaCache() + const int mappedStateIndex = d->m_stateIndexToSignalIndex.key(stateIndex, -1); + return d->m_configuration.contains(mappedStateIndex); } QT_END_NAMESPACE diff --git a/tests/auto/scion/tst_scion.cpp b/tests/auto/scion/tst_scion.cpp index d1e4873..eaa8e4d 100644 --- a/tests/auto/scion/tst_scion.cpp +++ b/tests/auto/scion/tst_scion.cpp @@ -269,16 +269,37 @@ void TestScion::compiled() static bool verifyStates(QScxmlStateMachine *stateMachine, const QJsonObject &stateDescription, const QString &key, int counter) { + const auto errorMessage = [&key, &counter](const QStringList& current, + const QStringList& expected, const QLatin1String& details) { + qWarning("Incorrect %s (%d)!", qPrintable(key), counter); + qWarning() << "Current configuration:" << current; + qWarning() << "Expected configuration:" << expected; + qWarning() << "Failed state read was done with:" << details; + }; + + // Verify that activeStateNames() matches the expectation auto current = stateMachine->activeStateNames(); std::sort(current.begin(), current.end()); auto expected = getStates(stateDescription, key); - if (current == expected) - return true; + if (current != expected) { + errorMessage(current, expected, QLatin1String("activeStateNames()")); + return false; + } - qWarning("Incorrect %s (%d)!", qPrintable(key), counter); - qWarning() << "Current configuration:" << current; - qWarning() << "Expected configuration:" << expected; - return false; + for (const auto& s : expected) { + // Verify that isActive(stateName) matches the expectation + if (!stateMachine->isActive(s)) { + errorMessage(current, expected, QLatin1String("isActive()")); + return false; + } + // Verify that the metaobject matches the expectation + const auto mo = stateMachine->metaObject(); + if (!mo->property(mo->indexOfProperty(s.toLocal8Bit())).read(stateMachine).toBool()) { + errorMessage(current, expected, QLatin1String("metaobject read")); + return false; + } + } + return true; } static bool playEvent(QScxmlStateMachine *stateMachine, const QJsonObject &eventDescription, int counter) @@ -344,11 +365,32 @@ static bool playEvent(QScxmlStateMachine *stateMachine, const QJsonObject &event }); MySignalSpy triggerSpy(&trigger, SIGNAL(timeout())); + // Create a signal spy for each state we expect to be (de)activated in next transition. + const auto expectedActive = getStates(eventDescription, QLatin1String("nextConfiguration")); + std::list<std::unique_ptr<QSignalSpy>> stateSpies; + const auto mo = stateMachine->metaObject(); + + for (const auto& s : stateMachine->stateNames()) { + if (expectedActive.contains(s) == stateMachine->isActive(s)) + continue; + // The state is expected to undergo an activation change, create a signal spy + const auto changedSignal = s + QLatin1String("Changed(bool)"); + auto signalIndex = mo->indexOfSignal(changedSignal.toUtf8().constData()); + stateSpies.push_back(std::unique_ptr<QSignalSpy>( + new QSignalSpy(stateMachine, mo->method(signalIndex)))); + } + stateMachine->submitEvent(e); if (!triggerSpy.fastWait()) { qWarning() << "State machine did not reach a stable state."; } else if (verifyStates(stateMachine, eventDescription, QLatin1String("nextConfiguration"), counter)) { + for (const auto& spy : stateSpies) { + if (spy->size() != 1) { + qWarning() << "Signal error for:" << spy->signal() << ", size:" << spy->size(); + return false; + } + } return true; } |