diff options
Diffstat (limited to 'tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp')
-rw-r--r-- | tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp | 1366 |
1 files changed, 1250 insertions, 116 deletions
diff --git a/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp b/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp index cfae5cdb2c..20401c864f 100644 --- a/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp @@ -1,40 +1,32 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:LGPL21$ ** 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 Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information ** use the contact form at http://qt.digia.com/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception +** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** ** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -71,6 +63,43 @@ static int globalTick; QCoreApplication::exec(); \ } +#define TEST_RUNNING_CHANGED(RUNNING) \ +{ \ + QTRY_COMPARE(runningSpy.count(), 1); \ + QList<QVariant> runningArgs = runningSpy.takeFirst(); \ + QVERIFY(runningArgs.at(0).type() == QVariant::Bool); \ + QVERIFY(runningArgs.at(0).toBool() == RUNNING); \ + QCOMPARE(machine.isRunning(), runningArgs.at(0).toBool()); \ +} + +#define TEST_RUNNING_CHANGED_STARTED_STOPPED \ +{ \ + QTRY_COMPARE(runningSpy.count(), 2); \ + QList<QVariant> runningArgs = runningSpy.takeFirst(); \ + QVERIFY(runningArgs.at(0).type() == QVariant::Bool); \ + QVERIFY(runningArgs.at(0).toBool() == true); \ + runningArgs = runningSpy.takeFirst(); \ + QVERIFY(runningArgs.at(0).type() == QVariant::Bool); \ + QVERIFY(runningArgs.at(0).toBool() == false); \ + QCOMPARE(machine.isRunning(), runningArgs.at(0).toBool()); \ +} + +#define DEFINE_ACTIVE_SPY(VAR) \ + QSignalSpy VAR##_activeSpy(VAR, &QState::activeChanged); \ + QVERIFY(VAR##_activeSpy.isValid()); + +#define TEST_ACTIVE_CHANGED(VAR, COUNT) \ +{ \ + QTRY_COMPARE(VAR##_activeSpy.count(), COUNT); \ + bool active = true; \ + foreach (const QList<QVariant> &activeArgs, static_cast<QList<QList<QVariant> > >(VAR##_activeSpy)) { \ + QVERIFY(activeArgs.at(0).type() == QVariant::Bool); \ + QVERIFY(activeArgs.at(0).toBool() == active); \ + active = !active; \ + } \ + QCOMPARE(VAR->active(), !active); \ +} + class SignalEmitter : public QObject { Q_OBJECT @@ -120,6 +149,7 @@ private slots: #endif void historyStates(); void startAndStop(); + void setRunning(); void targetStateWithNoParent(); void targetStateDeleted(); void transitionToRootState(); @@ -277,6 +307,7 @@ void tst_QStateMachine::transitionToRootState() machine.setObjectName("machine"); QState *initialState = new QState(); + DEFINE_ACTIVE_SPY(initialState); initialState->setObjectName("initial"); machine.addState(initialState); machine.setInitialState(initialState); @@ -291,12 +322,14 @@ void tst_QStateMachine::transitionToRootState() QCOMPARE(machine.configuration().count(), 1); QVERIFY(machine.configuration().contains(initialState)); + TEST_ACTIVE_CHANGED(initialState, 1); machine.postEvent(new QEvent(QEvent::User)); QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: No common ancestor for targets and source of transition from state 'initial'"); QCoreApplication::processEvents(); QVERIFY(machine.configuration().isEmpty()); QVERIFY(!machine.isRunning()); + TEST_ACTIVE_CHANGED(initialState, 2); } void tst_QStateMachine::transitionFromRootState() @@ -916,10 +949,13 @@ void tst_QStateMachine::historyStateAfterRestart() s2->addTransition(new EventTransition(QEvent::User, s1)); for (int x = 0; x < 2; ++x) { - QSignalSpy startedSpy(&machine, SIGNAL(started())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy startedSpy(&machine, &QStateMachine::started); QVERIFY(startedSpy.isValid()); machine.start(); QTRY_COMPARE(startedSpy.count(), 1); + TEST_RUNNING_CHANGED(true); QCOMPARE(machine.configuration().count(), 1); QVERIFY(machine.configuration().contains(s1)); @@ -952,10 +988,11 @@ void tst_QStateMachine::historyStateAfterRestart() QVERIFY(machine.configuration().contains(s2)); QVERIFY(machine.configuration().contains(s22)); - QSignalSpy stoppedSpy(&machine, SIGNAL(stopped())); + QSignalSpy stoppedSpy(&machine, &QStateMachine::stopped); QVERIFY(stoppedSpy.isValid()); machine.stop(); QTRY_COMPARE(stoppedSpy.count(), 1); + TEST_RUNNING_CHANGED(false); } } @@ -1094,11 +1131,15 @@ void tst_QStateMachine::rootState() QCOMPARE(machine.machine(), (QStateMachine*)0); QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); QCOMPARE(s1->parentState(), static_cast<QState*>(&machine)); QState *s2 = new QState(); + DEFINE_ACTIVE_SPY(s2); s2->setParent(&machine); QCOMPARE(s2->parentState(), static_cast<QState*>(&machine)); + TEST_ACTIVE_CHANGED(s1, 0); + TEST_ACTIVE_CHANGED(s2, 0); } void tst_QStateMachine::machineWithParent() @@ -1232,13 +1273,15 @@ void tst_QStateMachine::stateEntryAndExit() QCOMPARE(trans->sourceState(), (QState*)s2); } - QSignalSpy startedSpy(&machine, SIGNAL(started())); - QSignalSpy stoppedSpy(&machine, SIGNAL(stopped())); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy startedSpy(&machine, &QStateMachine::started); + QSignalSpy stoppedSpy(&machine, &QStateMachine::stopped); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); QVERIFY(startedSpy.isValid()); QVERIFY(stoppedSpy.isValid()); QVERIFY(finishedSpy.isValid()); + QVERIFY(runningSpy.isValid()); machine.setInitialState(s1); QCOMPARE(machine.initialState(), (QAbstractState*)s1); @@ -1252,11 +1295,11 @@ void tst_QStateMachine::stateEntryAndExit() QVERIFY(machine.configuration().isEmpty()); globalTick = 0; QVERIFY(!machine.isRunning()); - QSignalSpy s1EnteredSpy(s1, SIGNAL(entered())); - QSignalSpy s1ExitedSpy(s1, SIGNAL(exited())); - QSignalSpy tTriggeredSpy(t, SIGNAL(triggered())); - QSignalSpy s2EnteredSpy(s2, SIGNAL(entered())); - QSignalSpy s2ExitedSpy(s2, SIGNAL(exited())); + QSignalSpy s1EnteredSpy(s1, &TestState::entered); + QSignalSpy s1ExitedSpy(s1, &TestState::exited); + QSignalSpy tTriggeredSpy(t, &TestTransition::triggered); + QSignalSpy s2EnteredSpy(s2, &TestState::entered); + QSignalSpy s2ExitedSpy(s2, &TestState::exited); QVERIFY(s1EnteredSpy.isValid()); QVERIFY(s1ExitedSpy.isValid()); @@ -1269,6 +1312,7 @@ void tst_QStateMachine::stateEntryAndExit() QTRY_COMPARE(startedSpy.count(), 1); QTRY_COMPARE(finishedSpy.count(), 1); QTRY_COMPARE(stoppedSpy.count(), 0); + TEST_RUNNING_CHANGED_STARTED_STOPPED; QCOMPARE(machine.configuration().count(), 1); QVERIFY(machine.configuration().contains(s3)); @@ -1312,16 +1356,19 @@ void tst_QStateMachine::stateEntryAndExit() s12->addTransition(t2); s2->addTransition(s3); - QSignalSpy startedSpy(&machine, SIGNAL(started())); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy startedSpy(&machine, &QStateMachine::started); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); QVERIFY(startedSpy.isValid()); QVERIFY(finishedSpy.isValid()); + QVERIFY(runningSpy.isValid()); machine.setInitialState(s1); globalTick = 0; machine.start(); QTRY_COMPARE(startedSpy.count(), 1); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; QCOMPARE(machine.configuration().count(), 1); QVERIFY(machine.configuration().contains(s3)); @@ -1366,6 +1413,7 @@ void tst_QStateMachine::assignProperty() { QStateMachine machine; QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); QTest::ignoreMessage(QtWarningMsg, "QState::assignProperty: cannot assign property 'foo' of null object"); s1->assignProperty(0, "foo", QVariant()); @@ -1376,32 +1424,39 @@ void tst_QStateMachine::assignProperty() machine.setInitialState(s1); machine.start(); QTRY_COMPARE(s1->objectName(), QString::fromLatin1("s1")); + TEST_ACTIVE_CHANGED(s1, 2); s1->assignProperty(s1, "objectName", "foo"); machine.start(); QTRY_COMPARE(s1->objectName(), QString::fromLatin1("foo")); + TEST_ACTIVE_CHANGED(s1, 4); s1->assignProperty(s1, "noSuchProperty", 123); machine.start(); QTRY_COMPARE(s1->dynamicPropertyNames().size(), 1); QCOMPARE(s1->dynamicPropertyNames().at(0), QByteArray("noSuchProperty")); QCOMPARE(s1->objectName(), QString::fromLatin1("foo")); + TEST_ACTIVE_CHANGED(s1, 6); { - QSignalSpy propertiesAssignedSpy(s1, SIGNAL(propertiesAssigned())); + QSignalSpy propertiesAssignedSpy(s1, &QState::propertiesAssigned); QVERIFY(propertiesAssignedSpy.isValid()); machine.start(); QTRY_COMPARE(propertiesAssignedSpy.count(), 1); + TEST_ACTIVE_CHANGED(s1, 8); } // nested states { QState *s11 = new QState(s1); + DEFINE_ACTIVE_SPY(s11); QString str = QString::fromLatin1("set by nested state"); s11->assignProperty(s11, "objectName", str); s1->setInitialState(s11); machine.start(); QTRY_COMPARE(s11->objectName(), str); + TEST_ACTIVE_CHANGED(s1, 10); + TEST_ACTIVE_CHANGED(s11, 2); } } @@ -1419,8 +1474,10 @@ void tst_QStateMachine::assignPropertyWithAnimation() obj.setProperty("foo", 321); obj.setProperty("bar", 654); QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); s1->assignProperty(&obj, "foo", 123); QState *s2 = new QState(&machine); + DEFINE_ACTIVE_SPY(s2); s2->assignProperty(&obj, "foo", 456); s2->assignProperty(&obj, "bar", 789); QAbstractTransition *trans = s1->addTransition(s2); @@ -1444,12 +1501,17 @@ void tst_QStateMachine::assignPropertyWithAnimation() s2->addTransition(s2, SIGNAL(propertiesAssigned()), s3); machine.setInitialState(s1); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.start(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; QCOMPARE(obj.property("foo").toInt(), 456); QCOMPARE(obj.property("bar").toInt(), 789); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 2); } // Two animations { @@ -1458,8 +1520,10 @@ void tst_QStateMachine::assignPropertyWithAnimation() obj.setProperty("foo", 321); obj.setProperty("bar", 654); QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); s1->assignProperty(&obj, "foo", 123); QState *s2 = new QState(&machine); + DEFINE_ACTIVE_SPY(s2); s2->assignProperty(&obj, "foo", 456); s2->assignProperty(&obj, "bar", 789); QAbstractTransition *trans = s1->addTransition(s2); @@ -1473,12 +1537,17 @@ void tst_QStateMachine::assignPropertyWithAnimation() s2->addTransition(s2, SIGNAL(propertiesAssigned()), s3); machine.setInitialState(s1); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); QVERIFY(finishedSpy.isValid()); + QVERIFY(runningSpy.isValid()); machine.start(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; QCOMPARE(obj.property("foo").toInt(), 456); QCOMPARE(obj.property("bar").toInt(), 789); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 2); } // Animation group { @@ -1487,9 +1556,11 @@ void tst_QStateMachine::assignPropertyWithAnimation() obj.setProperty("foo", 321); obj.setProperty("bar", 654); QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); s1->assignProperty(&obj, "foo", 123); s1->assignProperty(&obj, "bar", 321); QState *s2 = new QState(&machine); + DEFINE_ACTIVE_SPY(s2); s2->assignProperty(&obj, "foo", 456); s2->assignProperty(&obj, "bar", 654); s2->assignProperty(&obj, "baz", 789); @@ -1502,13 +1573,18 @@ void tst_QStateMachine::assignPropertyWithAnimation() s2->addTransition(s2, SIGNAL(propertiesAssigned()), s3); machine.setInitialState(s1); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); QVERIFY(finishedSpy.isValid()); + QVERIFY(runningSpy.isValid()); machine.start(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; QCOMPARE(obj.property("foo").toInt(), 456); QCOMPARE(obj.property("bar").toInt(), 654); QCOMPARE(obj.property("baz").toInt(), 789); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 2); } // Nested states { @@ -1517,6 +1593,7 @@ void tst_QStateMachine::assignPropertyWithAnimation() obj.setProperty("foo", 321); obj.setProperty("bar", 654); QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); QCOMPARE(s1->childMode(), QState::ExclusiveStates); s1->setChildMode(QState::ParallelStates); QCOMPARE(s1->childMode(), QState::ParallelStates); @@ -1527,12 +1604,15 @@ void tst_QStateMachine::assignPropertyWithAnimation() s1->assignProperty(&obj, "foo", 123); s1->assignProperty(&obj, "bar", 456); QState *s2 = new QState(&machine); + DEFINE_ACTIVE_SPY(s2); s2->setObjectName("s2"); s2->assignProperty(&obj, "foo", 321); QState *s21 = new QState(s2); + DEFINE_ACTIVE_SPY(s21); s21->setObjectName("s21"); s21->assignProperty(&obj, "bar", 654); QState *s22 = new QState(s2); + DEFINE_ACTIVE_SPY(s22); s22->setObjectName("s22"); s22->assignProperty(&obj, "bar", 789); s2->setInitialState(s21); @@ -1552,12 +1632,19 @@ void tst_QStateMachine::assignPropertyWithAnimation() s22->addTransition(s2, SIGNAL(propertiesAssigned()), s3); machine.setInitialState(s1); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); QVERIFY(finishedSpy.isValid()); + QVERIFY(runningSpy.isValid()); machine.start(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; QCOMPARE(obj.property("foo").toInt(), 321); QCOMPARE(obj.property("bar").toInt(), 789); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 2); + TEST_ACTIVE_CHANGED(s21, 2); + TEST_ACTIVE_CHANGED(s22, 2); } // Aborted animation { @@ -1568,9 +1655,11 @@ void tst_QStateMachine::assignPropertyWithAnimation() obj.setProperty("bar", 654); QState *group = new QState(&machine); QState *s1 = new QState(group); + DEFINE_ACTIVE_SPY(s1); group->setInitialState(s1); s1->assignProperty(&obj, "foo", 123); QState *s2 = new QState(group); + DEFINE_ACTIVE_SPY(s2); s2->assignProperty(&obj, "foo", 456); s2->assignProperty(&obj, "bar", 789); QAbstractTransition *trans = s1->addTransition(&emitter, SIGNAL(signalWithNoArg()), s2); @@ -1581,13 +1670,14 @@ void tst_QStateMachine::assignPropertyWithAnimation() anim2.setDuration(8000); trans->addAnimation(&anim2); QState *s3 = new QState(group); + DEFINE_ACTIVE_SPY(s3); s3->assignProperty(&obj, "foo", 911); s2->addTransition(&emitter, SIGNAL(signalWithNoArg()), s3); machine.setInitialState(group); machine.start(); QTRY_COMPARE(machine.configuration().contains(s1), true); - QSignalSpy propertiesAssignedSpy(s2, SIGNAL(propertiesAssigned())); + QSignalSpy propertiesAssignedSpy(s2, &QState::propertiesAssigned); QVERIFY(propertiesAssignedSpy.isValid()); emitter.emitSignalWithNoArg(); QTRY_COMPARE(machine.configuration().contains(s2), true); @@ -1597,6 +1687,10 @@ void tst_QStateMachine::assignPropertyWithAnimation() QVERIFY(propertiesAssignedSpy.isEmpty()); QCOMPARE(obj.property("foo").toInt(), 911); QCOMPARE(obj.property("bar").toInt(), 789); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 2); + TEST_ACTIVE_CHANGED(s3, 1); + QVERIFY(machine.isRunning()); } } @@ -1668,6 +1762,7 @@ void tst_QStateMachine::postEvent() machine.postEvent(&e); } StringEventPoster *s1 = new StringEventPoster("a"); + DEFINE_ACTIVE_SPY(s1); if (x == 1) s1->setDelay(100); QFinalState *s2 = new QFinalState; @@ -1675,12 +1770,16 @@ void tst_QStateMachine::postEvent() machine.addState(s1); machine.addState(s2); machine.setInitialState(s1); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); QVERIFY(finishedSpy.isValid()); + QVERIFY(runningSpy.isValid()); machine.start(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s2)); + TEST_ACTIVE_CHANGED(s1, 2); s1->setString("b"); QFinalState *s3 = new QFinalState(); @@ -1691,6 +1790,7 @@ void tst_QStateMachine::postEvent() QTRY_COMPARE(finishedSpy.count(), 1); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s3)); + TEST_ACTIVE_CHANGED(s1, 4); } } @@ -1701,17 +1801,21 @@ void tst_QStateMachine::cancelDelayedEvent() QVERIFY(!machine.cancelDelayedEvent(-1)); QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); QFinalState *s2 = new QFinalState(&machine); s1->addTransition(new StringTransition("a", s2)); machine.setInitialState(s1); - QSignalSpy startedSpy(&machine, SIGNAL(started())); + QSignalSpy startedSpy(&machine, &QStateMachine::started); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); QVERIFY(startedSpy.isValid()); + QVERIFY(runningSpy.isValid()); machine.start(); QTRY_COMPARE(startedSpy.count(), 1); + TEST_RUNNING_CHANGED(true); + TEST_ACTIVE_CHANGED(s1, 1); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s1)); - int id1 = machine.postDelayedEvent(new StringEvent("c"), 50000); QVERIFY(id1 != -1); int id2 = machine.postDelayedEvent(new StringEvent("b"), 25000); @@ -1725,9 +1829,11 @@ void tst_QStateMachine::cancelDelayedEvent() QVERIFY(machine.cancelDelayedEvent(id2)); QVERIFY(!machine.cancelDelayedEvent(id2)); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED(false); + TEST_ACTIVE_CHANGED(s1, 2); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s2)); } @@ -1736,28 +1842,37 @@ void tst_QStateMachine::postDelayedEventAndStop() { QStateMachine machine; QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); QFinalState *s2 = new QFinalState(&machine); s1->addTransition(new StringTransition("a", s2)); machine.setInitialState(s1); - QSignalSpy startedSpy(&machine, SIGNAL(started())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy startedSpy(&machine, &QStateMachine::started); QVERIFY(startedSpy.isValid()); machine.start(); QTRY_COMPARE(startedSpy.count(), 1); + TEST_RUNNING_CHANGED(true); + TEST_ACTIVE_CHANGED(s1, 1); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s1)); int id1 = machine.postDelayedEvent(new StringEvent("a"), 0); QVERIFY(id1 != -1); - QSignalSpy stoppedSpy(&machine, SIGNAL(stopped())); + QSignalSpy stoppedSpy(&machine, &QStateMachine::stopped); QVERIFY(stoppedSpy.isValid()); machine.stop(); QTRY_COMPARE(stoppedSpy.count(), 1); + TEST_RUNNING_CHANGED(false); + TEST_ACTIVE_CHANGED(s1, 1); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s1)); machine.start(); QTRY_COMPARE(startedSpy.count(), 2); + TEST_RUNNING_CHANGED(true); + TEST_ACTIVE_CHANGED(s1, 3); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s1)); @@ -1765,11 +1880,16 @@ void tst_QStateMachine::postDelayedEventAndStop() QVERIFY(id2 != -1); machine.stop(); QTRY_COMPARE(stoppedSpy.count(), 2); + TEST_RUNNING_CHANGED(false); + TEST_ACTIVE_CHANGED(s1, 3); machine.start(); QTRY_COMPARE(startedSpy.count(), 3); + TEST_RUNNING_CHANGED(true); QTestEventLoop::instance().enterLoop(2); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s1)); + TEST_ACTIVE_CHANGED(s1, 5); + QVERIFY(machine.isRunning()); } class DelayedEventPosterThread : public QThread @@ -1806,6 +1926,7 @@ void tst_QStateMachine::postDelayedEventFromThread() { QStateMachine machine; QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); QFinalState *f = new QFinalState(&machine); s1->addTransition(new EventTransition(QEvent::User, f)); machine.setInitialState(s1); @@ -1813,11 +1934,14 @@ void tst_QStateMachine::postDelayedEventFromThread() DelayedEventPosterThread poster(&machine); poster.start(); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.start(); QTRY_COMPARE(finishedSpy.count(), 1); - + TEST_RUNNING_CHANGED_STARTED_STOPPED; + TEST_ACTIVE_CHANGED(s1, 2); QVERIFY(poster.firstEventWasCancelled); } @@ -1825,17 +1949,24 @@ void tst_QStateMachine::stopAndPostEvent() { QStateMachine machine; QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); machine.setInitialState(s1); - QSignalSpy startedSpy(&machine, SIGNAL(started())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy startedSpy(&machine, &QStateMachine::started); QVERIFY(startedSpy.isValid()); machine.start(); QTRY_COMPARE(startedSpy.count(), 1); - QSignalSpy stoppedSpy(&machine, SIGNAL(stopped())); + TEST_RUNNING_CHANGED(true); + TEST_ACTIVE_CHANGED(s1, 1); + QSignalSpy stoppedSpy(&machine, &QStateMachine::stopped); QVERIFY(stoppedSpy.isValid()); machine.stop(); QCOMPARE(stoppedSpy.count(), 0); machine.postEvent(new QEvent(QEvent::User)); QTRY_COMPARE(stoppedSpy.count(), 1); + TEST_RUNNING_CHANGED(false); + TEST_ACTIVE_CHANGED(s1, 1); QCoreApplication::processEvents(); } @@ -1843,17 +1974,24 @@ void tst_QStateMachine::stateFinished() { QStateMachine machine; QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); QState *s1_1 = new QState(s1); + DEFINE_ACTIVE_SPY(s1_1); QFinalState *s1_2 = new QFinalState(s1); s1_1->addTransition(s1_2); s1->setInitialState(s1_1); QFinalState *s2 = new QFinalState(&machine); s1->addTransition(s1, SIGNAL(finished()), s2); machine.setInitialState(s1); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.start(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s1_1, 2); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s2)); } @@ -1888,11 +2026,14 @@ void tst_QStateMachine::parallelStates() s1->addTransition(s1, SIGNAL(finished()), s2); machine.setInitialState(s1); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); globalTick = 0; machine.start(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s2)); @@ -1927,15 +2068,19 @@ void tst_QStateMachine::parallelRootState() QCOMPARE(root->childMode(), QState::ParallelStates); QState *s1 = new QState(root); + DEFINE_ACTIVE_SPY(s1); QFinalState *s1_f = new QFinalState(s1); s1->setInitialState(s1_f); QState *s2 = new QState(root); + DEFINE_ACTIVE_SPY(s2); QFinalState *s2_f = new QFinalState(s2); s2->setInitialState(s2_f); - QSignalSpy startedSpy(&machine, SIGNAL(started())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy startedSpy(&machine, &QStateMachine::started); QVERIFY(startedSpy.isValid()); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.start(); QTRY_COMPARE(startedSpy.count(), 1); @@ -1945,22 +2090,32 @@ void tst_QStateMachine::parallelRootState() QVERIFY(machine.configuration().contains(s2)); QVERIFY(machine.configuration().contains(s2_f)); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s2, 1); + QVERIFY(!machine.isRunning()); } void tst_QStateMachine::allSourceToTargetConfigurations() { QStateMachine machine; QState *s0 = new QState(&machine); + DEFINE_ACTIVE_SPY(s0); s0->setObjectName("s0"); QState *s1 = new QState(s0); + DEFINE_ACTIVE_SPY(s1); s1->setObjectName("s1"); QState *s11 = new QState(s1); + DEFINE_ACTIVE_SPY(s11); s11->setObjectName("s11"); QState *s2 = new QState(s0); + DEFINE_ACTIVE_SPY(s2); s2->setObjectName("s2"); QState *s21 = new QState(s2); + DEFINE_ACTIVE_SPY(s21); s21->setObjectName("s21"); QState *s211 = new QState(s21); + DEFINE_ACTIVE_SPY(s211); s211->setObjectName("s211"); QFinalState *f = new QFinalState(&machine); f->setObjectName("f"); @@ -1984,30 +2139,94 @@ void tst_QStateMachine::allSourceToTargetConfigurations() s2->addTransition(new StringTransition("f", s11)); s0->addTransition(new StringTransition("e", s211)); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.setInitialState(s0); machine.start(); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s0, 1); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s11, 1); + TEST_ACTIVE_CHANGED(s2, 0); + TEST_ACTIVE_CHANGED(s21, 0); + TEST_ACTIVE_CHANGED(s211, 0); machine.postEvent(new StringEvent("a")); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s0, 1); + TEST_ACTIVE_CHANGED(s1, 3); + TEST_ACTIVE_CHANGED(s11, 3); + TEST_ACTIVE_CHANGED(s2, 0); + TEST_ACTIVE_CHANGED(s21, 0); + TEST_ACTIVE_CHANGED(s211, 0); + machine.postEvent(new StringEvent("b")); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s0, 1); + TEST_ACTIVE_CHANGED(s1, 5); + TEST_ACTIVE_CHANGED(s11, 5); + TEST_ACTIVE_CHANGED(s2, 0); + TEST_ACTIVE_CHANGED(s21, 0); + TEST_ACTIVE_CHANGED(s211, 0); + machine.postEvent(new StringEvent("c")); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s0, 1); + TEST_ACTIVE_CHANGED(s1, 6); + TEST_ACTIVE_CHANGED(s11, 6); + TEST_ACTIVE_CHANGED(s2, 1); + TEST_ACTIVE_CHANGED(s21, 1); + TEST_ACTIVE_CHANGED(s211, 1); + machine.postEvent(new StringEvent("d")); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s0, 1); + TEST_ACTIVE_CHANGED(s1, 6); + TEST_ACTIVE_CHANGED(s11, 6); + TEST_ACTIVE_CHANGED(s2, 1); + TEST_ACTIVE_CHANGED(s21, 3); + TEST_ACTIVE_CHANGED(s211, 3); + machine.postEvent(new StringEvent("e")); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s0, 3); + TEST_ACTIVE_CHANGED(s1, 6); + TEST_ACTIVE_CHANGED(s11, 6); + TEST_ACTIVE_CHANGED(s2, 3); + TEST_ACTIVE_CHANGED(s21, 5); + TEST_ACTIVE_CHANGED(s211, 5); + machine.postEvent(new StringEvent("f")); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s0, 3); + TEST_ACTIVE_CHANGED(s1, 7); + TEST_ACTIVE_CHANGED(s11, 7); + TEST_ACTIVE_CHANGED(s2, 4); + TEST_ACTIVE_CHANGED(s21, 6); + TEST_ACTIVE_CHANGED(s211, 6); + machine.postEvent(new StringEvent("g")); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s0, 3); + TEST_ACTIVE_CHANGED(s1, 8); + TEST_ACTIVE_CHANGED(s11, 8); + TEST_ACTIVE_CHANGED(s2, 5); + TEST_ACTIVE_CHANGED(s21, 7); + TEST_ACTIVE_CHANGED(s211, 7); + machine.postEvent(new StringEvent("h")); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s0, 4); + TEST_ACTIVE_CHANGED(s1, 8); + TEST_ACTIVE_CHANGED(s11, 8); + TEST_ACTIVE_CHANGED(s2, 6); + TEST_ACTIVE_CHANGED(s21, 8); + TEST_ACTIVE_CHANGED(s211, 8); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; } class TestSignalTransition : public QSignalTransition @@ -2073,6 +2292,7 @@ void tst_QStateMachine::signalTransitions() { QStateMachine machine; QState *s0 = new QState(&machine); + DEFINE_ACTIVE_SPY(s0); QTest::ignoreMessage(QtWarningMsg, "QState::addTransition: sender cannot be null"); QCOMPARE(s0->addTransition(0, SIGNAL(noSuchSignal()), 0), (QSignalTransition*)0); @@ -2094,7 +2314,9 @@ void tst_QStateMachine::signalTransitions() QCOMPARE(trans->senderObject(), (QObject*)&emitter); QCOMPARE(trans->signal(), QByteArray(SIGNAL(signalWithNoArg()))); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.setInitialState(s0); machine.start(); @@ -2103,7 +2325,8 @@ void tst_QStateMachine::signalTransitions() emitter.emitSignalWithNoArg(); QTRY_COMPARE(finishedSpy.count(), 1); - + TEST_RUNNING_CHANGED_STARTED_STOPPED; + TEST_ACTIVE_CHANGED(s0, 2); emitter.emitSignalWithNoArg(); trans->setSignal(SIGNAL(signalWithIntArg(int))); @@ -2112,6 +2335,8 @@ void tst_QStateMachine::signalTransitions() QCoreApplication::processEvents(); emitter.emitSignalWithIntArg(123); QTRY_COMPARE(finishedSpy.count(), 2); + TEST_RUNNING_CHANGED_STARTED_STOPPED; + TEST_ACTIVE_CHANGED(s0, 4); machine.start(); QCoreApplication::processEvents(); @@ -2119,6 +2344,8 @@ void tst_QStateMachine::signalTransitions() QCOMPARE(trans->signal(), QByteArray(SIGNAL(signalWithNoArg()))); emitter.emitSignalWithNoArg(); QTRY_COMPARE(finishedSpy.count(), 3); + TEST_RUNNING_CHANGED_STARTED_STOPPED; + TEST_ACTIVE_CHANGED(s0, 6); SignalEmitter emitter2; machine.start(); @@ -2126,16 +2353,22 @@ void tst_QStateMachine::signalTransitions() trans->setSenderObject(&emitter2); emitter2.emitSignalWithNoArg(); QTRY_COMPARE(finishedSpy.count(), 4); + TEST_RUNNING_CHANGED_STARTED_STOPPED; + TEST_ACTIVE_CHANGED(s0, 8); machine.start(); QCoreApplication::processEvents(); QTest::ignoreMessage(QtWarningMsg, "QSignalTransition: no such signal: SignalEmitter::noSuchSignal()"); trans->setSignal(SIGNAL(noSuchSignal())); QCOMPARE(trans->signal(), QByteArray(SIGNAL(noSuchSignal()))); + TEST_RUNNING_CHANGED(true); + TEST_ACTIVE_CHANGED(s0, 9); + QVERIFY(machine.isRunning()); } { QStateMachine machine; QState *s0 = new QState(&machine); + DEFINE_ACTIVE_SPY(s0); QFinalState *s1 = new QFinalState(&machine); SignalEmitter emitter; QSignalTransition *trans = s0->addTransition(&emitter, "signalWithNoArg()", s1); @@ -2145,40 +2378,52 @@ void tst_QStateMachine::signalTransitions() QCOMPARE(trans->senderObject(), (QObject*)&emitter); QCOMPARE(trans->signal(), QByteArray("signalWithNoArg()")); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.setInitialState(s0); machine.start(); QCoreApplication::processEvents(); - + TEST_ACTIVE_CHANGED(s0, 1); emitter.emitSignalWithNoArg(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; + TEST_ACTIVE_CHANGED(s0, 2); trans->setSignal("signalWithIntArg(int)"); QCOMPARE(trans->signal(), QByteArray("signalWithIntArg(int)")); machine.start(); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s0, 3); emitter.emitSignalWithIntArg(123); QTRY_COMPARE(finishedSpy.count(), 2); + TEST_RUNNING_CHANGED_STARTED_STOPPED; + TEST_ACTIVE_CHANGED(s0, 4); } { QStateMachine machine; QState *s0 = new QState(&machine); + DEFINE_ACTIVE_SPY(s0); QFinalState *s1 = new QFinalState(&machine); SignalEmitter emitter; TestSignalTransition *trans = new TestSignalTransition(&emitter, SIGNAL(signalWithIntArg(int)), s1); s0->addTransition(trans); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.setInitialState(s0); machine.start(); QCoreApplication::processEvents(); - + TEST_ACTIVE_CHANGED(s0, 1); emitter.emitSignalWithIntArg(123); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; + TEST_ACTIVE_CHANGED(s0, 2); QCOMPARE(trans->eventTestSenderReceived(), (QObject*)&emitter); QCOMPARE(trans->eventTestSignalIndexReceived(), emitter.metaObject()->indexOfSignal("signalWithIntArg(int)")); QCOMPARE(trans->eventTestArgumentsReceived().size(), 1); @@ -2191,21 +2436,27 @@ void tst_QStateMachine::signalTransitions() { QStateMachine machine; QState *s0 = new QState(&machine); + DEFINE_ACTIVE_SPY(s0); QFinalState *s1 = new QFinalState(&machine); SignalEmitter emitter; TestSignalTransition *trans = new TestSignalTransition(&emitter, SIGNAL(signalWithStringArg(QString)), s1); s0->addTransition(trans); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.setInitialState(s0); machine.start(); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s0, 1); QString testString = QString::fromLatin1("hello"); emitter.emitSignalWithStringArg(testString); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; + TEST_ACTIVE_CHANGED(s0, 2); QCOMPARE(trans->eventTestSenderReceived(), (QObject*)&emitter); QCOMPARE(trans->eventTestSignalIndexReceived(), emitter.metaObject()->indexOfSignal("signalWithStringArg(QString)")); QCOMPARE(trans->eventTestArgumentsReceived().size(), 1); @@ -2218,6 +2469,7 @@ void tst_QStateMachine::signalTransitions() { QStateMachine machine; QState *s0 = new QState(&machine); + DEFINE_ACTIVE_SPY(s0); QFinalState *s1 = new QFinalState(&machine); TestSignalTransition *trans = new TestSignalTransition(); @@ -2232,52 +2484,69 @@ void tst_QStateMachine::signalTransitions() trans->setTargetState(s1); s0->addTransition(trans); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.setInitialState(s0); machine.start(); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s0, 1); emitter.emitSignalWithNoArg(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; + TEST_ACTIVE_CHANGED(s0, 2); } // Multiple transitions for same (object,signal) { QStateMachine machine; SignalEmitter emitter; QState *s0 = new QState(&machine); + DEFINE_ACTIVE_SPY(s0); QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); QSignalTransition *t0 = s0->addTransition(&emitter, SIGNAL(signalWithNoArg()), s1); QSignalTransition *t1 = s1->addTransition(&emitter, SIGNAL(signalWithNoArg()), s0); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.setInitialState(s0); machine.start(); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s0, 1); + TEST_ACTIVE_CHANGED(s1, 0); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s0)); emitter.emitSignalWithNoArg(); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s0, 2); + TEST_ACTIVE_CHANGED(s1, 1); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s1)); s0->removeTransition(t0); emitter.emitSignalWithNoArg(); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s0, 3); + TEST_ACTIVE_CHANGED(s1, 2); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s0)); emitter.emitSignalWithNoArg(); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s0, 3); + TEST_ACTIVE_CHANGED(s1, 2); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s0)); s1->removeTransition(t1); emitter.emitSignalWithNoArg(); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s0, 3); + TEST_ACTIVE_CHANGED(s1, 2); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s0)); @@ -2285,6 +2554,9 @@ void tst_QStateMachine::signalTransitions() s1->addTransition(t1); emitter.emitSignalWithNoArg(); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s0, 4); + TEST_ACTIVE_CHANGED(s1, 3); + QVERIFY(machine.isRunning()); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s1)); } @@ -2293,6 +2565,7 @@ void tst_QStateMachine::signalTransitions() QStateMachine machine; SignalEmitter emitter; QState *s0 = new QState(&machine); + DEFINE_ACTIVE_SPY(s0); QFinalState *s1 = new QFinalState(&machine); s0->addTransition(&emitter, SIGNAL(signalWithNoArg()), s1); QFinalState *s2 = new QFinalState(&machine); @@ -2300,30 +2573,45 @@ void tst_QStateMachine::signalTransitions() QFinalState *s3 = new QFinalState(&machine); s0->addTransition(&emitter, SIGNAL(signalWithStringArg(QString)), s3); - QSignalSpy startedSpy(&machine, SIGNAL(started())); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy startedSpy(&machine, &QStateMachine::started); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); QVERIFY(startedSpy.isValid()); QVERIFY(finishedSpy.isValid()); + QVERIFY(runningSpy.isValid()); machine.setInitialState(s0); machine.start(); + TEST_ACTIVE_CHANGED(s0, 1); QTRY_COMPARE(startedSpy.count(), 1); + TEST_RUNNING_CHANGED(true); emitter.emitSignalWithNoArg(); + TEST_ACTIVE_CHANGED(s0, 2); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED(false); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s1)); machine.start(); + TEST_ACTIVE_CHANGED(s0, 3); QTRY_COMPARE(startedSpy.count(), 2); + TEST_RUNNING_CHANGED(true); emitter.emitSignalWithIntArg(123); + TEST_ACTIVE_CHANGED(s0, 4); QTRY_COMPARE(finishedSpy.count(), 2); + TEST_RUNNING_CHANGED(false); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s2)); machine.start(); + QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s0, 5); QTRY_COMPARE(startedSpy.count(), 3); + TEST_RUNNING_CHANGED(true); emitter.emitSignalWithStringArg("hello"); + TEST_ACTIVE_CHANGED(s0, 6); QTRY_COMPARE(finishedSpy.count(), 3); + TEST_RUNNING_CHANGED(false); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s3)); } @@ -2332,6 +2620,7 @@ void tst_QStateMachine::signalTransitions() QStateMachine machine; SignalEmitter emitter; QState *s0 = new QState(&machine); + DEFINE_ACTIVE_SPY(s0); QFinalState *s1 = new QFinalState(&machine); QSignalTransition *t0 = s0->addTransition(&emitter, SIGNAL(signalWithNoArg()), s1); QVERIFY(t0 != 0); @@ -2341,18 +2630,25 @@ void tst_QStateMachine::signalTransitions() QVERIFY(t1 != 0); QCOMPARE(t1->signal(), QByteArray(SIGNAL(signalWithStringArg(QString)))); - QSignalSpy startedSpy(&machine, SIGNAL(started())); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy startedSpy(&machine, &QStateMachine::started); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); QVERIFY(startedSpy.isValid()); QVERIFY(finishedSpy.isValid()); + QVERIFY(runningSpy.isValid()); machine.setInitialState(s0); machine.start(); + QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s0, 1); QTRY_COMPARE(startedSpy.count(), 1); QCOMPARE(finishedSpy.count(), 0); + TEST_RUNNING_CHANGED(true); emitter.emitSignalWithNoArg(); + TEST_ACTIVE_CHANGED(s0, 2); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED(false); } } @@ -2406,7 +2702,9 @@ void tst_QStateMachine::eventTransitions() QCOMPARE(trans->targetState(), (QAbstractState*)s1); s0->addTransition(trans); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.setInitialState(s0); machine.start(); @@ -2414,6 +2712,7 @@ void tst_QStateMachine::eventTransitions() QTest::mousePress(&button, Qt::LeftButton); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; QTest::mousePress(&button, Qt::LeftButton); @@ -2423,12 +2722,14 @@ void tst_QStateMachine::eventTransitions() QCoreApplication::processEvents(); QTest::mouseRelease(&button, Qt::LeftButton); QTRY_COMPARE(finishedSpy.count(), 2); + TEST_RUNNING_CHANGED_STARTED_STOPPED; machine.start(); QCoreApplication::processEvents(); trans->setEventType(QEvent::MouseButtonPress); QTest::mousePress(&button, Qt::LeftButton); QTRY_COMPARE(finishedSpy.count(), 3); + TEST_RUNNING_CHANGED_STARTED_STOPPED; QPushButton button2; machine.start(); @@ -2436,6 +2737,7 @@ void tst_QStateMachine::eventTransitions() trans->setEventSource(&button2); QTest::mousePress(&button2, Qt::LeftButton); QTRY_COMPARE(finishedSpy.count(), 4); + TEST_RUNNING_CHANGED_STARTED_STOPPED; } for (int x = 0; x < 2; ++x) { QStateMachine machine; @@ -2459,7 +2761,9 @@ void tst_QStateMachine::eventTransitions() QCOMPARE(trans->targetState(), (QAbstractState*)s1); s0->addTransition(trans); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.setInitialState(s0); machine.start(); @@ -2469,6 +2773,7 @@ void tst_QStateMachine::eventTransitions() QCoreApplication::processEvents(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; } { QStateMachine machine; @@ -2485,16 +2790,19 @@ void tst_QStateMachine::eventTransitions() trans->setTargetState(s1); s0->addTransition(trans); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.setInitialState(s0); machine.start(); QCoreApplication::processEvents(); - + TEST_RUNNING_CHANGED(true); QTest::mousePress(&button, Qt::LeftButton); QCoreApplication::processEvents(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED(false); } { @@ -2508,16 +2816,20 @@ void tst_QStateMachine::eventTransitions() trans->setTargetState(s1); s0->addTransition(trans); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.setInitialState(s0); machine.start(); QCoreApplication::processEvents(); + TEST_RUNNING_CHANGED(true); QTest::keyPress(&button, Qt::Key_A); QCoreApplication::processEvents(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED(false); } { QStateMachine machine; @@ -2534,16 +2846,20 @@ void tst_QStateMachine::eventTransitions() trans->setTargetState(s1); s0->addTransition(trans); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.setInitialState(s0); machine.start(); QCoreApplication::processEvents(); + TEST_RUNNING_CHANGED(true); QTest::keyPress(&button, Qt::Key_A); QCoreApplication::processEvents(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED(false); } // Multiple transitions for same (object,event) { @@ -2557,7 +2873,7 @@ void tst_QStateMachine::eventTransitions() t1->setTargetState(s0); s1->addTransition(t1); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.setInitialState(s0); machine.start(); @@ -2607,23 +2923,29 @@ void tst_QStateMachine::eventTransitions() t1->setTargetState(s2); s0->addTransition(t1); - QSignalSpy startedSpy(&machine, SIGNAL(started())); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy startedSpy(&machine, &QStateMachine::started); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); QVERIFY(startedSpy.isValid()); QVERIFY(finishedSpy.isValid()); + QVERIFY(runningSpy.isValid()); machine.setInitialState(s0); machine.start(); QTRY_COMPARE(startedSpy.count(), 1); + TEST_RUNNING_CHANGED(true); QTest::mousePress(&button, Qt::LeftButton); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED(false); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s1)); machine.start(); QTRY_COMPARE(startedSpy.count(), 2); + TEST_RUNNING_CHANGED(true); QTest::mouseRelease(&button, Qt::LeftButton); QTRY_COMPARE(finishedSpy.count(), 2); + TEST_RUNNING_CHANGED(false); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s2)); } @@ -2637,12 +2959,15 @@ void tst_QStateMachine::eventTransitions() trans->setTargetState(s1); s0->addTransition(trans); - QSignalSpy startedSpy(&machine, SIGNAL(started())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy startedSpy(&machine, &QStateMachine::started); QVERIFY(startedSpy.isValid()); machine.setInitialState(s0); machine.start(); QTest::ignoreMessage(QtWarningMsg, "QObject event transitions are not supported for custom types"); QTRY_COMPARE(startedSpy.count(), 1); + TEST_RUNNING_CHANGED(true); } // custom transition { @@ -2655,16 +2980,20 @@ void tst_QStateMachine::eventTransitions() QCOMPARE(trans->eventSourceReceived(), (QObject*)0); QCOMPARE(trans->eventTypeReceived(), QEvent::None); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.setInitialState(s0); machine.start(); QCoreApplication::processEvents(); + TEST_RUNNING_CHANGED(true); QTest::mousePress(&button, Qt::LeftButton); QCoreApplication::processEvents(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED(false); QCOMPARE(trans->eventSourceReceived(), (QObject*)&button); QCOMPARE(trans->eventTypeReceived(), QEvent::MouseButtonPress); @@ -2684,16 +3013,20 @@ void tst_QStateMachine::graphicsSceneEventTransitions() s1->addTransition(t); machine.setInitialState(s1); - QSignalSpy startedSpy(&machine, SIGNAL(started())); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy startedSpy(&machine, &QStateMachine::started); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); QVERIFY(startedSpy.isValid()); QVERIFY(finishedSpy.isValid()); + QVERIFY(runningSpy.isValid()); machine.start(); QTRY_COMPARE(startedSpy.count(), 1); QVERIFY(finishedSpy.count() == 0); + TEST_RUNNING_CHANGED(true); QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseMove); scene.sendEvent(textItem, &mouseEvent); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED(false); } #endif @@ -2703,8 +3036,11 @@ void tst_QStateMachine::historyStates() QStateMachine machine; QState *root = &machine; QState *s0 = new QState(root); + DEFINE_ACTIVE_SPY(s0); QState *s00 = new QState(s0); + DEFINE_ACTIVE_SPY(s00); QState *s01 = new QState(s0); + DEFINE_ACTIVE_SPY(s01); QHistoryState *s0h; if (x == 0) { s0h = new QHistoryState(s0); @@ -2724,6 +3060,7 @@ void tst_QStateMachine::historyStates() QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); s0h->setDefaultState(s0); QState *s1 = new QState(root); + DEFINE_ACTIVE_SPY(s1); QFinalState *s2 = new QFinalState(root); s00->addTransition(new StringTransition("a", s01)); @@ -2734,50 +3071,75 @@ void tst_QStateMachine::historyStates() root->setInitialState(s0); s0->setInitialState(s00); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.start(); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s0, 1); + TEST_ACTIVE_CHANGED(s00, 1); + TEST_ACTIVE_CHANGED(s01, 0); + TEST_ACTIVE_CHANGED(s1, 0); QCOMPARE(machine.configuration().size(), 2); QVERIFY(machine.configuration().contains(s0)); QVERIFY(machine.configuration().contains(s00)); machine.postEvent(new StringEvent("a")); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s0, 1); + TEST_ACTIVE_CHANGED(s00, 2); + TEST_ACTIVE_CHANGED(s01, 1); + TEST_ACTIVE_CHANGED(s1, 0); QCOMPARE(machine.configuration().size(), 2); QVERIFY(machine.configuration().contains(s0)); QVERIFY(machine.configuration().contains(s01)); machine.postEvent(new StringEvent("b")); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s0, 2); + TEST_ACTIVE_CHANGED(s00, 2); + TEST_ACTIVE_CHANGED(s01, 2); + TEST_ACTIVE_CHANGED(s1, 1); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s1)); machine.postEvent(new StringEvent("c")); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s0, 3); + TEST_ACTIVE_CHANGED(s00, 2); + TEST_ACTIVE_CHANGED(s01, 3); + TEST_ACTIVE_CHANGED(s1, 2); QCOMPARE(machine.configuration().size(), 2); QVERIFY(machine.configuration().contains(s0)); QVERIFY(machine.configuration().contains(s01)); machine.postEvent(new StringEvent("d")); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s0, 4); + TEST_ACTIVE_CHANGED(s00, 2); + TEST_ACTIVE_CHANGED(s01, 4); + TEST_ACTIVE_CHANGED(s1, 2); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s2)); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; } } void tst_QStateMachine::startAndStop() { QStateMachine machine; - QSignalSpy startedSpy(&machine, SIGNAL(started())); - QSignalSpy stoppedSpy(&machine, SIGNAL(stopped())); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy startedSpy(&machine, &QStateMachine::started); + QSignalSpy stoppedSpy(&machine, &QStateMachine::stopped); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); QVERIFY(startedSpy.isValid()); QVERIFY(stoppedSpy.isValid()); QVERIFY(finishedSpy.isValid()); + QVERIFY(runningSpy.isValid()); QVERIFY(!machine.isRunning()); QTest::ignoreMessage(QtWarningMsg, "QStateMachine::start: No initial state set for machine. Refusing to start."); @@ -2785,62 +3147,160 @@ void tst_QStateMachine::startAndStop() QCOMPARE(startedSpy.count(), 0); QCOMPARE(stoppedSpy.count(), 0); QCOMPARE(finishedSpy.count(), 0); + QCOMPARE(runningSpy.count(), 0); QVERIFY(!machine.isRunning()); machine.stop(); QCOMPARE(startedSpy.count(), 0); QCOMPARE(stoppedSpy.count(), 0); QCOMPARE(finishedSpy.count(), 0); + QCOMPARE(runningSpy.count(), 0); QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); machine.setInitialState(s1); machine.start(); + TEST_ACTIVE_CHANGED(s1, 1); QTRY_COMPARE(machine.isRunning(), true); QTRY_COMPARE(startedSpy.count(), 1); QCOMPARE(stoppedSpy.count(), 0); QCOMPARE(finishedSpy.count(), 0); + TEST_RUNNING_CHANGED(true); QCOMPARE(machine.configuration().count(), 1); QVERIFY(machine.configuration().contains(s1)); QTest::ignoreMessage(QtWarningMsg, "QStateMachine::start(): already running"); machine.start(); + QCOMPARE(runningSpy.count(), 0); machine.stop(); + TEST_ACTIVE_CHANGED(s1, 1); QTRY_COMPARE(machine.isRunning(), false); QTRY_COMPARE(stoppedSpy.count(), 1); QCOMPARE(startedSpy.count(), 1); QCOMPARE(finishedSpy.count(), 0); + TEST_RUNNING_CHANGED(false); QCOMPARE(machine.configuration().count(), 1); QVERIFY(machine.configuration().contains(s1)); machine.start(); + TEST_ACTIVE_CHANGED(s1, 3); machine.stop(); + TEST_ACTIVE_CHANGED(s1, 3); QTRY_COMPARE(startedSpy.count(), 2); + QTRY_COMPARE(stoppedSpy.count(), 2); + TEST_RUNNING_CHANGED_STARTED_STOPPED; +} + +void tst_QStateMachine::setRunning() +{ + QStateMachine machine; + QSignalSpy startedSpy(&machine, &QStateMachine::started); + QSignalSpy stoppedSpy(&machine, &QStateMachine::stopped); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + + QVERIFY(startedSpy.isValid()); + QVERIFY(stoppedSpy.isValid()); + QVERIFY(finishedSpy.isValid()); + QVERIFY(runningSpy.isValid()); + + QVERIFY(!machine.isRunning()); + QTest::ignoreMessage(QtWarningMsg, "QStateMachine::start: No initial state set for machine. Refusing to start."); + machine.setRunning(true); + QCOMPARE(startedSpy.count(), 0); + QCOMPARE(stoppedSpy.count(), 0); + QCOMPARE(finishedSpy.count(), 0); + QCOMPARE(runningSpy.count(), 0); + QVERIFY(!machine.isRunning()); + machine.setRunning(false); + QCOMPARE(startedSpy.count(), 0); + QCOMPARE(stoppedSpy.count(), 0); + QCOMPARE(finishedSpy.count(), 0); + QCOMPARE(runningSpy.count(), 0); + + QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); + machine.setInitialState(s1); + machine.setRunning(true); + TEST_ACTIVE_CHANGED(s1, 1); + QTRY_COMPARE(machine.isRunning(), true); + QTRY_COMPARE(startedSpy.count(), 1); + QCOMPARE(stoppedSpy.count(), 0); + QCOMPARE(finishedSpy.count(), 0); + TEST_RUNNING_CHANGED(true); + QCOMPARE(machine.configuration().count(), 1); + QVERIFY(machine.configuration().contains(s1)); + + QTest::ignoreMessage(QtWarningMsg, "QStateMachine::start(): already running"); + machine.setRunning(true); + TEST_ACTIVE_CHANGED(s1, 1); + QCOMPARE(runningSpy.count(), 0); + + machine.setRunning(false); + TEST_ACTIVE_CHANGED(s1, 1); + QTRY_COMPARE(machine.isRunning(), false); + QTRY_COMPARE(stoppedSpy.count(), 1); + QCOMPARE(startedSpy.count(), 1); + QCOMPARE(finishedSpy.count(), 0); + TEST_RUNNING_CHANGED(false); + QCOMPARE(machine.configuration().count(), 1); + QVERIFY(machine.configuration().contains(s1)); + + machine.setRunning(false); + QCOMPARE(runningSpy.count(), 0); + TEST_ACTIVE_CHANGED(s1, 1); + + machine.start(); + TEST_ACTIVE_CHANGED(s1, 3); + machine.setRunning(false); + TEST_ACTIVE_CHANGED(s1, 3); + QTRY_COMPARE(startedSpy.count(), 2); + QTRY_COMPARE(stoppedSpy.count(), 2); + TEST_RUNNING_CHANGED_STARTED_STOPPED; + QState *s1_1 = new QState(s1); + QFinalState *s1_2 = new QFinalState(s1); + s1_1->addTransition(s1_2); + s1->setInitialState(s1_1); + QFinalState *s2 = new QFinalState(&machine); + s1->addTransition(s1, SIGNAL(finished()), s2); + machine.setRunning(false); + QCOMPARE(runningSpy.count(), 0); + machine.setRunning(true); + TEST_ACTIVE_CHANGED(s1, 6); + TEST_RUNNING_CHANGED_STARTED_STOPPED; + QTRY_COMPARE(startedSpy.count(), 3); QCOMPARE(stoppedSpy.count(), 2); + QCOMPARE(finishedSpy.count(), 1); } void tst_QStateMachine::targetStateWithNoParent() { QStateMachine machine; QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); s1->setObjectName("s1"); QState s2; s1->addTransition(&s2); machine.setInitialState(s1); - QSignalSpy startedSpy(&machine, SIGNAL(started())); - QSignalSpy stoppedSpy(&machine, SIGNAL(stopped())); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy startedSpy(&machine, &QStateMachine::started); + QSignalSpy stoppedSpy(&machine, &QStateMachine::stopped); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); QVERIFY(startedSpy.isValid()); QVERIFY(stoppedSpy.isValid()); QVERIFY(finishedSpy.isValid()); + QVERIFY(runningSpy.isValid()); machine.start(); QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: No common ancestor for targets and source of transition from state 's1'"); + TEST_ACTIVE_CHANGED(s1, 2); QTRY_COMPARE(startedSpy.count(), 1); QCOMPARE(machine.isRunning(), false); QCOMPARE(stoppedSpy.count(), 1); QCOMPARE(finishedSpy.count(), 0); + TEST_RUNNING_CHANGED_STARTED_STOPPED; QCOMPARE(machine.error(), QStateMachine::NoCommonAncestorForTransitionError); } @@ -2865,12 +3325,15 @@ void tst_QStateMachine::defaultGlobalRestorePolicy() propertyHolder->setProperty("b", 2); QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); s1->assignProperty(propertyHolder, "a", 3); QState *s2 = new QState(&machine); + DEFINE_ACTIVE_SPY(s2); s2->assignProperty(propertyHolder, "b", 4); QState *s3 = new QState(&machine); + DEFINE_ACTIVE_SPY(s3); s1->addTransition(new EventTransition(QEvent::User, s2)); s2->addTransition(new EventTransition(QEvent::User, s3)); @@ -2879,18 +3342,28 @@ void tst_QStateMachine::defaultGlobalRestorePolicy() machine.start(); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s2, 0); + TEST_ACTIVE_CHANGED(s3, 0); QCOMPARE(propertyHolder->property("a").toInt(), 3); QCOMPARE(propertyHolder->property("b").toInt(), 2); machine.postEvent(new QEvent(QEvent::User)); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 1); + TEST_ACTIVE_CHANGED(s3, 0); QCOMPARE(propertyHolder->property("a").toInt(), 3); QCOMPARE(propertyHolder->property("b").toInt(), 4); machine.postEvent(new QEvent(QEvent::User)); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 2); + TEST_ACTIVE_CHANGED(s3, 1); + QVERIFY(machine.isRunning()); QCOMPARE(propertyHolder->property("a").toInt(), 3); QCOMPARE(propertyHolder->property("b").toInt(), 4); } @@ -2900,17 +3373,20 @@ void tst_QStateMachine::noInitialStateForInitialState() QStateMachine machine; QState *initialState = new QState(&machine); + DEFINE_ACTIVE_SPY(initialState); initialState->setObjectName("initialState"); machine.setInitialState(initialState); QState *childState = new QState(initialState); + DEFINE_ACTIVE_SPY(childState); (void)childState; QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: " "Missing initial state in compound state 'initialState'"); machine.start(); QCoreApplication::processEvents(); - + TEST_ACTIVE_CHANGED(initialState, 1); + TEST_ACTIVE_CHANGED(childState, 0); QCOMPARE(machine.isRunning(), false); QCOMPARE(int(machine.error()), int(QStateMachine::NoInitialStateError)); } @@ -2925,12 +3401,15 @@ void tst_QStateMachine::globalRestorePolicySetToDontRestore() propertyHolder->setProperty("b", 2); QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); s1->assignProperty(propertyHolder, "a", 3); QState *s2 = new QState(&machine); + DEFINE_ACTIVE_SPY(s2); s2->assignProperty(propertyHolder, "b", 4); QState *s3 = new QState(&machine); + DEFINE_ACTIVE_SPY(s3); s1->addTransition(new EventTransition(QEvent::User, s2)); s2->addTransition(new EventTransition(QEvent::User, s3)); @@ -2939,18 +3418,28 @@ void tst_QStateMachine::globalRestorePolicySetToDontRestore() machine.start(); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s2, 0); + TEST_ACTIVE_CHANGED(s3, 0); QCOMPARE(propertyHolder->property("a").toInt(), 3); QCOMPARE(propertyHolder->property("b").toInt(), 2); machine.postEvent(new QEvent(QEvent::User)); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 1); + TEST_ACTIVE_CHANGED(s3, 0); QCOMPARE(propertyHolder->property("a").toInt(), 3); QCOMPARE(propertyHolder->property("b").toInt(), 4); machine.postEvent(new QEvent(QEvent::User)); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 2); + TEST_ACTIVE_CHANGED(s3, 1); + QVERIFY(machine.isRunning()); QCOMPARE(propertyHolder->property("a").toInt(), 3); QCOMPARE(propertyHolder->property("b").toInt(), 4); } @@ -2965,12 +3454,15 @@ void tst_QStateMachine::globalRestorePolicySetToRestore() propertyHolder->setProperty("b", 2); QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); s1->assignProperty(propertyHolder, "a", 3); QState *s2 = new QState(&machine); + DEFINE_ACTIVE_SPY(s2); s2->assignProperty(propertyHolder, "b", 4); QState *s3 = new QState(&machine); + DEFINE_ACTIVE_SPY(s3); s1->addTransition(new EventTransition(QEvent::User, s2)); s2->addTransition(new EventTransition(QEvent::User, s3)); @@ -2979,18 +3471,28 @@ void tst_QStateMachine::globalRestorePolicySetToRestore() machine.start(); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s2, 0); + TEST_ACTIVE_CHANGED(s3, 0); QCOMPARE(propertyHolder->property("a").toInt(), 3); QCOMPARE(propertyHolder->property("b").toInt(), 2); machine.postEvent(new QEvent(QEvent::User)); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 1); + TEST_ACTIVE_CHANGED(s3, 0); QCOMPARE(propertyHolder->property("a").toInt(), 1); QCOMPARE(propertyHolder->property("b").toInt(), 4); machine.postEvent(new QEvent(QEvent::User)); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 2); + TEST_ACTIVE_CHANGED(s3, 1); + QVERIFY(machine.isRunning()); QCOMPARE(propertyHolder->property("a").toInt(), 1); QCOMPARE(propertyHolder->property("b").toInt(), 2); } @@ -3015,7 +3517,9 @@ void tst_QStateMachine::simpleAnimation() object->setProperty("fooBar", 1.0); QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); QState *s2 = new QState(&machine); + DEFINE_ACTIVE_SPY(s2); s2->assignProperty(object, "fooBar", 2.0); EventTransition *et = new EventTransition(QEvent::User, s2); @@ -3024,16 +3528,24 @@ void tst_QStateMachine::simpleAnimation() s1->addTransition(et); QState *s3 = new QState(&machine); + DEFINE_ACTIVE_SPY(s3); s2->addTransition(animation, SIGNAL(finished()), s3); QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); machine.setInitialState(s1); machine.start(); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s2, 0); + TEST_ACTIVE_CHANGED(s3, 0); machine.postEvent(new QEvent(QEvent::User)); QCOREAPPLICATION_EXEC(5000); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 2); + TEST_ACTIVE_CHANGED(s3, 1); + QVERIFY(machine.isRunning()); QVERIFY(machine.configuration().contains(s3)); QCOMPARE(object->property("fooBar").toDouble(), 2.0); } @@ -3059,7 +3571,9 @@ void tst_QStateMachine::twoAnimations() object->setProperty("bar", 3.0); QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); QState *s2 = new QState(&machine); + DEFINE_ACTIVE_SPY(s2); s2->assignProperty(object, "foo", 2.0); s2->assignProperty(object, "bar", 10.0); @@ -3077,15 +3591,23 @@ void tst_QStateMachine::twoAnimations() s1->addTransition(et); QState *s3 = new QState(&machine); + DEFINE_ACTIVE_SPY(s3); QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); s2->addTransition(s2, SIGNAL(propertiesAssigned()), s3); machine.setInitialState(s1); machine.start(); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s2, 0); + TEST_ACTIVE_CHANGED(s3, 0); machine.postEvent(new QEvent(QEvent::User)); QCOREAPPLICATION_EXEC(5000); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 2); + TEST_ACTIVE_CHANGED(s3, 1); + QVERIFY(machine.isRunning()); QVERIFY(machine.configuration().contains(s3)); QCOMPARE(object->property("foo").toDouble(), 2.0); @@ -3102,8 +3624,10 @@ void tst_QStateMachine::twoAnimatedTransitions() object->setProperty("foo", 1.0); QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); QState *s2 = new QState(&machine); + DEFINE_ACTIVE_SPY(s2); s2->assignProperty(object, "foo", 5.0); QPropertyAnimation *fooAnimation = new QPropertyAnimation(object, "foo", s2); EventTransition *trans = new EventTransition(QEvent::User, s2); @@ -3111,10 +3635,12 @@ void tst_QStateMachine::twoAnimatedTransitions() trans->addAnimation(fooAnimation); QState *s3 = new QState(&machine); + DEFINE_ACTIVE_SPY(s3); QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); s2->addTransition(fooAnimation, SIGNAL(finished()), s3); QState *s4 = new QState(&machine); + DEFINE_ACTIVE_SPY(s4); s4->assignProperty(object, "foo", 2.0); QPropertyAnimation *fooAnimation2 = new QPropertyAnimation(object, "foo", s4); trans = new EventTransition(QEvent::User, s4); @@ -3122,22 +3648,39 @@ void tst_QStateMachine::twoAnimatedTransitions() trans->addAnimation(fooAnimation2); QState *s5 = new QState(&machine); + DEFINE_ACTIVE_SPY(s5); QObject::connect(s5, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); s4->addTransition(fooAnimation2, SIGNAL(finished()), s5); machine.setInitialState(s1); machine.start(); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s2, 0); + TEST_ACTIVE_CHANGED(s3, 0); + TEST_ACTIVE_CHANGED(s4, 0); + TEST_ACTIVE_CHANGED(s5, 0); machine.postEvent(new QEvent(QEvent::User)); QCOREAPPLICATION_EXEC(5000); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 2); + TEST_ACTIVE_CHANGED(s3, 1); + TEST_ACTIVE_CHANGED(s4, 0); + TEST_ACTIVE_CHANGED(s5, 0); QVERIFY(machine.configuration().contains(s3)); QCOMPARE(object->property("foo").toDouble(), 5.0); machine.postEvent(new QEvent(QEvent::User)); QCOREAPPLICATION_EXEC(5000); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 2); + TEST_ACTIVE_CHANGED(s3, 2); + TEST_ACTIVE_CHANGED(s4, 2); + TEST_ACTIVE_CHANGED(s5, 1); + QVERIFY(machine.isRunning()); QVERIFY(machine.configuration().contains(s5)); QCOMPARE(object->property("foo").toDouble(), 2.0); } @@ -3150,8 +3693,10 @@ void tst_QStateMachine::playAnimationTwice() object->setProperty("foo", 1.0); QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); QState *s2 = new QState(&machine); + DEFINE_ACTIVE_SPY(s2); s2->assignProperty(object, "foo", 5.0); QPropertyAnimation *fooAnimation = new QPropertyAnimation(object, "foo", s2); EventTransition *trans = new EventTransition(QEvent::User, s2); @@ -3159,16 +3704,19 @@ void tst_QStateMachine::playAnimationTwice() trans->addAnimation(fooAnimation); QState *s3 = new QState(&machine); + DEFINE_ACTIVE_SPY(s3); QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); s2->addTransition(fooAnimation, SIGNAL(finished()), s3); QState *s4 = new QState(&machine); + DEFINE_ACTIVE_SPY(s4); s4->assignProperty(object, "foo", 2.0); trans = new EventTransition(QEvent::User, s4); s3->addTransition(trans); trans->addAnimation(fooAnimation); QState *s5 = new QState(&machine); + DEFINE_ACTIVE_SPY(s5); QObject::connect(s5, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); s4->addTransition(fooAnimation, SIGNAL(finished()), s5); @@ -3176,15 +3724,31 @@ void tst_QStateMachine::playAnimationTwice() machine.start(); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s2, 0); + TEST_ACTIVE_CHANGED(s3, 0); + TEST_ACTIVE_CHANGED(s4, 0); + TEST_ACTIVE_CHANGED(s5, 0); machine.postEvent(new QEvent(QEvent::User)); QCOREAPPLICATION_EXEC(5000); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 2); + TEST_ACTIVE_CHANGED(s3, 1); + TEST_ACTIVE_CHANGED(s4, 0); + TEST_ACTIVE_CHANGED(s5, 0); QVERIFY(machine.configuration().contains(s3)); QCOMPARE(object->property("foo").toDouble(), 5.0); machine.postEvent(new QEvent(QEvent::User)); QCOREAPPLICATION_EXEC(5000); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 2); + TEST_ACTIVE_CHANGED(s3, 2); + TEST_ACTIVE_CHANGED(s4, 2); + TEST_ACTIVE_CHANGED(s5, 1); + QVERIFY(machine.isRunning()); QVERIFY(machine.configuration().contains(s5)); QCOMPARE(object->property("foo").toDouble(), 2.0); } @@ -3200,15 +3764,19 @@ void tst_QStateMachine::nestedTargetStateForAnimation() SlotCalledCounter counter; QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); QState *s2 = new QState(&machine); + DEFINE_ACTIVE_SPY(s2); s2->assignProperty(object, "foo", 2.0); QState *s2Child = new QState(s2); + DEFINE_ACTIVE_SPY(s2Child); s2Child->assignProperty(object, "bar", 10.0); s2->setInitialState(s2Child); QState *s2Child2 = new QState(s2); + DEFINE_ACTIVE_SPY(s2Child2); s2Child2->assignProperty(object, "bar", 11.0); QAbstractTransition *at = new EventTransition(QEvent::User, s2Child2); s2Child->addTransition(at); @@ -3230,6 +3798,7 @@ void tst_QStateMachine::nestedTargetStateForAnimation() at->addAnimation(animation); QState *s3 = new QState(&machine); + DEFINE_ACTIVE_SPY(s3); s2->addTransition(s2Child, SIGNAL(propertiesAssigned()), s3); QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); @@ -3237,10 +3806,27 @@ void tst_QStateMachine::nestedTargetStateForAnimation() machine.setInitialState(s1); machine.start(); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s2, 0); + TEST_ACTIVE_CHANGED(s2Child, 0); + TEST_ACTIVE_CHANGED(s2Child2, 0); + TEST_ACTIVE_CHANGED(s3, 0); machine.postEvent(new QEvent(QEvent::User)); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 1); + TEST_ACTIVE_CHANGED(s2Child, 1); + TEST_ACTIVE_CHANGED(s2Child2, 0); + TEST_ACTIVE_CHANGED(s3, 0); + QCOREAPPLICATION_EXEC(5000); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 2); + TEST_ACTIVE_CHANGED(s2Child, 2); + TEST_ACTIVE_CHANGED(s2Child2, 0); + TEST_ACTIVE_CHANGED(s3, 1); + QVERIFY(machine.isRunning()); QVERIFY(machine.configuration().contains(s3)); QCOMPARE(object->property("foo").toDouble(), 2.0); QCOMPARE(object->property("bar").toDouble(), 10.0); @@ -3254,31 +3840,41 @@ void tst_QStateMachine::propertiesAssignedSignalTransitionsReuseAnimationGroup() object->setProperty("foo", 0); QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); s1->assignProperty(object, "foo", 123); QState *s2 = new QState(&machine); + DEFINE_ACTIVE_SPY(s2); s2->assignProperty(object, "foo", 456); QState *s3 = new QState(&machine); + DEFINE_ACTIVE_SPY(s3); s3->assignProperty(object, "foo", 789); QFinalState *s4 = new QFinalState(&machine); QParallelAnimationGroup animationGroup; animationGroup.addAnimation(new QPropertyAnimation(object, "foo")); - QSignalSpy animationFinishedSpy(&animationGroup, SIGNAL(finished())); + QSignalSpy animationFinishedSpy(&animationGroup, &QParallelAnimationGroup::finished); QVERIFY(animationFinishedSpy.isValid()); s1->addTransition(s1, SIGNAL(propertiesAssigned()), s2)->addAnimation(&animationGroup); s2->addTransition(s2, SIGNAL(propertiesAssigned()), s3)->addAnimation(&animationGroup); s3->addTransition(s3, SIGNAL(propertiesAssigned()), s4); machine.setInitialState(s1); - QSignalSpy machineFinishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy machineFinishedSpy(&machine, &QStateMachine::finished); QVERIFY(machineFinishedSpy.isValid()); machine.start(); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 2); + TEST_ACTIVE_CHANGED(s3, 2); QTRY_COMPARE(machineFinishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; + QVERIFY(!machine.isRunning()); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s4)); QCOMPARE(object->property("foo").toInt(), 789); - QCOMPARE(animationFinishedSpy.count(), 2); + } void tst_QStateMachine::animatedGlobalRestoreProperty() @@ -3292,12 +3888,16 @@ void tst_QStateMachine::animatedGlobalRestoreProperty() SlotCalledCounter counter; QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); QState *s2 = new QState(&machine); + DEFINE_ACTIVE_SPY(s2); s2->assignProperty(object, "foo", 2.0); QState *s3 = new QState(&machine); + DEFINE_ACTIVE_SPY(s3); QState *s4 = new QState(&machine); + DEFINE_ACTIVE_SPY(s4); QObject::connect(s4, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); QAbstractTransition *at = new EventTransition(QEvent::User, s2); @@ -3319,11 +3919,24 @@ void tst_QStateMachine::animatedGlobalRestoreProperty() machine.setInitialState(s1); machine.start(); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s2, 0); + TEST_ACTIVE_CHANGED(s3, 0); + TEST_ACTIVE_CHANGED(s4, 0); machine.postEvent(new QEvent(QEvent::User)); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 1); + TEST_ACTIVE_CHANGED(s3, 0); + TEST_ACTIVE_CHANGED(s4, 0); QCOREAPPLICATION_EXEC(5000); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 2); + TEST_ACTIVE_CHANGED(s3, 2); + TEST_ACTIVE_CHANGED(s4, 1); + QVERIFY(machine.isRunning()); QVERIFY(machine.configuration().contains(s4)); QCOMPARE(object->property("foo").toDouble(), 1.0); QCOMPARE(counter.counter, 2); @@ -3337,8 +3950,10 @@ void tst_QStateMachine::specificTargetValueOfAnimation() object->setProperty("foo", 1.0); QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); QState *s2 = new QState(&machine); + DEFINE_ACTIVE_SPY(s2); s2->assignProperty(object, "foo", 2.0); QPropertyAnimation *anim = new QPropertyAnimation(object, "foo"); @@ -3348,16 +3963,28 @@ void tst_QStateMachine::specificTargetValueOfAnimation() trans->addAnimation(anim); QState *s3 = new QState(&machine); + DEFINE_ACTIVE_SPY(s3); QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); s2->addTransition(anim, SIGNAL(finished()), s3); machine.setInitialState(s1); machine.start(); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s2, 0); + TEST_ACTIVE_CHANGED(s3, 0); machine.postEvent(new QEvent(QEvent::User)); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 1); + TEST_ACTIVE_CHANGED(s3, 0); + QCOREAPPLICATION_EXEC(5000); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 2); + TEST_ACTIVE_CHANGED(s3, 1); + QVERIFY(machine.isRunning()); QVERIFY(machine.configuration().contains(s3)); QCOMPARE(object->property("foo").toDouble(), 2.0); QCOMPARE(anim->endValue().toDouble(), 10.0); @@ -3373,11 +4000,14 @@ void tst_QStateMachine::addDefaultAnimation() object->setProperty("foo", 1.0); QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); QState *s2 = new QState(&machine); + DEFINE_ACTIVE_SPY(s2); s2->assignProperty(object, "foo", 2.0); QState *s3 = new QState(&machine); + DEFINE_ACTIVE_SPY(s3); QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); s1->addTransition(new EventTransition(QEvent::User, s2)); @@ -3389,10 +4019,21 @@ void tst_QStateMachine::addDefaultAnimation() machine.setInitialState(s1); machine.start(); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s2, 0); + TEST_ACTIVE_CHANGED(s3, 0); machine.postEvent(new QEvent(QEvent::User)); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 1); + TEST_ACTIVE_CHANGED(s3, 0); + QCOREAPPLICATION_EXEC(5000); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 2); + TEST_ACTIVE_CHANGED(s3, 1); + QVERIFY(machine.isRunning()); QVERIFY(machine.configuration().contains(s3)); QCOMPARE(object->property("foo").toDouble(), 2.0); @@ -3410,11 +4051,14 @@ void tst_QStateMachine::addDefaultAnimationWithUnusedAnimation() SlotCalledCounter counter; QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); QState *s2 = new QState(&machine); + DEFINE_ACTIVE_SPY(s2); s2->assignProperty(object, "foo", 2.0); QState *s3 = new QState(&machine); + DEFINE_ACTIVE_SPY(s3); QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); s1->addTransition(new EventTransition(QEvent::User, s2)); @@ -3431,10 +4075,21 @@ void tst_QStateMachine::addDefaultAnimationWithUnusedAnimation() machine.setInitialState(s1); machine.start(); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s2, 0); + TEST_ACTIVE_CHANGED(s3, 0); machine.postEvent(new QEvent(QEvent::User)); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 1); + TEST_ACTIVE_CHANGED(s3, 0); + QCOREAPPLICATION_EXEC(5000); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 2); + TEST_ACTIVE_CHANGED(s3, 1); + QVERIFY(machine.isRunning()); QVERIFY(machine.configuration().contains(s3)); QCOMPARE(object->property("foo").toDouble(), 2.0); QCOMPARE(counter.counter, 1); @@ -3491,12 +4146,15 @@ void tst_QStateMachine::overrideDefaultAnimationWithSpecific() SlotCalledCounter counter; QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); machine.setInitialState(s1); QState *s2 = new QState(&machine); + DEFINE_ACTIVE_SPY(s2); s2->assignProperty(object, "foo", 2.0); QState *s3 = new QState(&machine); + DEFINE_ACTIVE_SPY(s3); QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); QAbstractTransition *at = new EventTransition(QEvent::User, s2); @@ -3514,10 +4172,21 @@ void tst_QStateMachine::overrideDefaultAnimationWithSpecific() machine.start(); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s2, 0); + TEST_ACTIVE_CHANGED(s3, 0); machine.postEvent(new QEvent(QEvent::User)); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 1); + TEST_ACTIVE_CHANGED(s3, 0); + QCOREAPPLICATION_EXEC(5000); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 2); + TEST_ACTIVE_CHANGED(s3, 1); + QVERIFY(machine.isRunning()); QVERIFY(machine.configuration().contains(s3)); QCOMPARE(counter.counter, 2); // specific animation started and stopped @@ -3535,20 +4204,26 @@ void tst_QStateMachine::parallelStateAssignmentsDone() propertyHolder->setProperty("zoot", 789); QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); machine.setInitialState(s1); QState *parallelState = new QState(QState::ParallelStates, &machine); parallelState->assignProperty(propertyHolder, "foo", 321); QState *s2 = new QState(parallelState); + DEFINE_ACTIVE_SPY(s2); s2->assignProperty(propertyHolder, "bar", 654); QState *s3 = new QState(parallelState); + DEFINE_ACTIVE_SPY(s3); s3->assignProperty(propertyHolder, "zoot", 987); s1->addTransition(new EventTransition(QEvent::User, parallelState)); machine.start(); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s2, 0); + TEST_ACTIVE_CHANGED(s3, 0); QCOMPARE(propertyHolder->property("foo").toInt(), 123); QCOMPARE(propertyHolder->property("bar").toInt(), 456); @@ -3557,6 +4232,10 @@ void tst_QStateMachine::parallelStateAssignmentsDone() machine.postEvent(new QEvent(QEvent::User)); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 1); + TEST_ACTIVE_CHANGED(s3, 1); + QVERIFY(machine.isRunning()); QCOMPARE(propertyHolder->property("foo").toInt(), 321); QCOMPARE(propertyHolder->property("bar").toInt(), 654); QCOMPARE(propertyHolder->property("zoot").toInt(), 987); @@ -3567,21 +4246,27 @@ void tst_QStateMachine::transitionsFromParallelStateWithNoChildren() QStateMachine machine; QState *parallelState = new QState(QState::ParallelStates, &machine); + DEFINE_ACTIVE_SPY(parallelState); machine.setInitialState(parallelState); QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); parallelState->addTransition(new EventTransition(QEvent::User, s1)); machine.start(); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(parallelState, 1); + TEST_ACTIVE_CHANGED(s1, 0); QCOMPARE(1, machine.configuration().size()); QVERIFY(machine.configuration().contains(parallelState)); machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(parallelState, 2); + TEST_ACTIVE_CHANGED(s1, 1); + QVERIFY(machine.isRunning()); QCOMPARE(1, machine.configuration().size()); QVERIFY(machine.configuration().contains(s1)); } @@ -3591,23 +4276,35 @@ void tst_QStateMachine::parallelStateTransition() QStateMachine machine; QState *parallelState = new QState(QState::ParallelStates, &machine); + DEFINE_ACTIVE_SPY(parallelState); machine.setInitialState(parallelState); QState *s1 = new QState(parallelState); + DEFINE_ACTIVE_SPY(s1); QState *s2 = new QState(parallelState); + DEFINE_ACTIVE_SPY(s2); QState *s1InitialChild = new QState(s1); + DEFINE_ACTIVE_SPY(s1InitialChild); s1->setInitialState(s1InitialChild); QState *s2InitialChild = new QState(s2); + DEFINE_ACTIVE_SPY(s2InitialChild); s2->setInitialState(s2InitialChild); QState *s1OtherChild = new QState(s1); + DEFINE_ACTIVE_SPY(s1OtherChild); s1->addTransition(new EventTransition(QEvent::User, s1OtherChild)); machine.start(); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(parallelState, 1); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s1InitialChild, 1); + TEST_ACTIVE_CHANGED(s2, 1); + TEST_ACTIVE_CHANGED(s2InitialChild, 1); + TEST_ACTIVE_CHANGED(s1OtherChild, 0); QVERIFY(machine.configuration().contains(parallelState)); QVERIFY(machine.configuration().contains(s1)); @@ -3619,10 +4316,17 @@ void tst_QStateMachine::parallelStateTransition() machine.postEvent(new QEvent(QEvent::User)); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(parallelState, 1); + TEST_ACTIVE_CHANGED(s1, 3); + TEST_ACTIVE_CHANGED(s1InitialChild, 2); + TEST_ACTIVE_CHANGED(s2, 3); + TEST_ACTIVE_CHANGED(s2InitialChild, 3); + TEST_ACTIVE_CHANGED(s1OtherChild, 1); + QVERIFY(machine.isRunning()); + QVERIFY(machine.configuration().contains(parallelState)); QVERIFY(machine.configuration().contains(s1)); - QVERIFY(machine.configuration().contains(s2)); QVERIFY(machine.configuration().contains(s1OtherChild)); QVERIFY(machine.configuration().contains(s2InitialChild)); @@ -3640,16 +4344,20 @@ void tst_QStateMachine::nestedRestoreProperties() propertyHolder->setProperty("bar", 2); QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); machine.setInitialState(s1); QState *s2 = new QState(&machine); + DEFINE_ACTIVE_SPY(s2); s2->assignProperty(propertyHolder, "foo", 3); QState *s21 = new QState(s2); + DEFINE_ACTIVE_SPY(s21); s21->assignProperty(propertyHolder, "bar", 4); s2->setInitialState(s21); QState *s22 = new QState(s2); + DEFINE_ACTIVE_SPY(s22); s22->assignProperty(propertyHolder, "bar", 5); s1->addTransition(new EventTransition(QEvent::User, s2)); @@ -3658,6 +4366,10 @@ void tst_QStateMachine::nestedRestoreProperties() machine.start(); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s2, 0); + TEST_ACTIVE_CHANGED(s21, 0); + TEST_ACTIVE_CHANGED(s22, 0); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s1)); QCOMPARE(propertyHolder->property("foo").toInt(), 1); @@ -3666,6 +4378,10 @@ void tst_QStateMachine::nestedRestoreProperties() machine.postEvent(new QEvent(QEvent::User)); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 1); + TEST_ACTIVE_CHANGED(s21, 1); + TEST_ACTIVE_CHANGED(s22, 0); QCOMPARE(machine.configuration().size(), 2); QVERIFY(machine.configuration().contains(s2)); QVERIFY(machine.configuration().contains(s21)); @@ -3675,6 +4391,11 @@ void tst_QStateMachine::nestedRestoreProperties() machine.postEvent(new QEvent(QEvent::User)); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 1); + TEST_ACTIVE_CHANGED(s21, 2); + TEST_ACTIVE_CHANGED(s22, 1); + QVERIFY(machine.isRunning()); QCOMPARE(machine.configuration().size(), 2); QVERIFY(machine.configuration().contains(s2)); QVERIFY(machine.configuration().contains(s22)); @@ -3692,16 +4413,20 @@ void tst_QStateMachine::nestedRestoreProperties2() propertyHolder->setProperty("bar", 2); QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); machine.setInitialState(s1); QState *s2 = new QState(&machine); + DEFINE_ACTIVE_SPY(s2); s2->assignProperty(propertyHolder, "foo", 3); QState *s21 = new QState(s2); + DEFINE_ACTIVE_SPY(s21); s21->assignProperty(propertyHolder, "bar", 4); s2->setInitialState(s21); QState *s22 = new QState(s2); + DEFINE_ACTIVE_SPY(s22); s22->assignProperty(propertyHolder, "foo", 6); s22->assignProperty(propertyHolder, "bar", 5); @@ -3712,6 +4437,10 @@ void tst_QStateMachine::nestedRestoreProperties2() machine.start(); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s2, 0); + TEST_ACTIVE_CHANGED(s21, 0); + TEST_ACTIVE_CHANGED(s22, 0); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s1)); QCOMPARE(propertyHolder->property("foo").toInt(), 1); @@ -3720,6 +4449,10 @@ void tst_QStateMachine::nestedRestoreProperties2() machine.postEvent(new QEvent(QEvent::User)); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 1); + TEST_ACTIVE_CHANGED(s21, 1); + TEST_ACTIVE_CHANGED(s22, 0); QCOMPARE(machine.configuration().size(), 2); QVERIFY(machine.configuration().contains(s2)); QVERIFY(machine.configuration().contains(s21)); @@ -3729,6 +4462,10 @@ void tst_QStateMachine::nestedRestoreProperties2() machine.postEvent(new QEvent(QEvent::User)); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 1); + TEST_ACTIVE_CHANGED(s21, 2); + TEST_ACTIVE_CHANGED(s22, 1); QCOMPARE(machine.configuration().size(), 2); QVERIFY(machine.configuration().contains(s2)); QVERIFY(machine.configuration().contains(s22)); @@ -3738,6 +4475,10 @@ void tst_QStateMachine::nestedRestoreProperties2() machine.postEvent(new QEvent(QEvent::User)); QCoreApplication::processEvents(); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 1); + TEST_ACTIVE_CHANGED(s21, 3); + TEST_ACTIVE_CHANGED(s22, 2); QCOMPARE(machine.configuration().size(), 2); QVERIFY(machine.configuration().contains(s2)); QVERIFY(machine.configuration().contains(s21)); @@ -3750,6 +4491,7 @@ void tst_QStateMachine::nestedStateMachines() { QStateMachine machine; QState *group = new QState(&machine); + DEFINE_ACTIVE_SPY(group); group->setChildMode(QState::ParallelStates); QStateMachine *subMachines[3]; for (int i = 0; i < 3; ++i) { @@ -3770,23 +4512,29 @@ void tst_QStateMachine::nestedStateMachines() group->addTransition(group, SIGNAL(finished()), final); machine.setInitialState(group); - QSignalSpy startedSpy(&machine, SIGNAL(started())); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy startedSpy(&machine, &QStateMachine::started); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); QVERIFY(startedSpy.isValid()); QVERIFY(finishedSpy.isValid()); + QVERIFY(runningSpy.isValid()); machine.start(); QTRY_COMPARE(startedSpy.count(), 1); + TEST_RUNNING_CHANGED(true); QTRY_COMPARE(machine.configuration().count(), 1+2*3); QVERIFY(machine.configuration().contains(group)); for (int i = 0; i < 3; ++i) QVERIFY(machine.configuration().contains(subMachines[i])); QCoreApplication::processEvents(); // starts the submachines + TEST_ACTIVE_CHANGED(group, 1); for (int i = 0; i < 3; ++i) subMachines[i]->postEvent(new QEvent(QEvent::User)); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED(false); + TEST_ACTIVE_CHANGED(group, 2); } void tst_QStateMachine::goToState() @@ -3795,10 +4543,13 @@ void tst_QStateMachine::goToState() QState *s1 = new QState(&machine); QState *s2 = new QState(&machine); machine.setInitialState(s1); - QSignalSpy startedSpy(&machine, SIGNAL(started())); + QSignalSpy startedSpy(&machine, &QStateMachine::started); QVERIFY(startedSpy.isValid()); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); machine.start(); QTRY_COMPARE(startedSpy.count(), 1); + TEST_RUNNING_CHANGED(true); QStateMachinePrivate::get(&machine)->goToState(s2); QCoreApplication::processEvents(); @@ -3838,10 +4589,13 @@ void tst_QStateMachine::goToStateFromSourceWithTransition() s1->addTransition(new QSignalTransition); QState *s2 = new QState(&machine); machine.setInitialState(s1); - QSignalSpy startedSpy(&machine, SIGNAL(started())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy startedSpy(&machine, &QStateMachine::started); QVERIFY(startedSpy.isValid()); machine.start(); QTRY_COMPARE(startedSpy.count(), 1); + TEST_RUNNING_CHANGED(true); QStateMachinePrivate::get(&machine)->goToState(s2); QCoreApplication::processEvents(); @@ -3873,7 +4627,9 @@ void tst_QStateMachine::clonedSignals() SignalEmitter emitter; QStateMachine machine; QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); QState *s2 = new QState(&machine); + DEFINE_ACTIVE_SPY(s2); CloneSignalTransition *t1 = new CloneSignalTransition(&emitter, SIGNAL(signalWithDefaultArg()), s2); s1->addTransition(t1); @@ -3884,6 +4640,9 @@ void tst_QStateMachine::clonedSignals() emitter.emitSignalWithDefaultArg(); QTest::qWait(1); QCOMPARE(t1->eventSignalIndex, emitter.metaObject()->indexOfSignal("signalWithDefaultArg()")); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 1); + QVERIFY(machine.isRunning()); } class EventPosterThread : public QThread @@ -3928,10 +4687,13 @@ void tst_QStateMachine::postEventFromOtherThread() poster.start(); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.start(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; } #ifndef QT_NO_WIDGETS @@ -3979,25 +4741,29 @@ void tst_QStateMachine::stopInTransitionToFinalState() { QStateMachine machine; QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); QFinalState *s2 = new QFinalState(&machine); QAbstractTransition *t1 = s1->addTransition(s2); machine.setInitialState(s1); QObject::connect(t1, SIGNAL(triggered()), &machine, SLOT(stop())); - QSignalSpy stoppedSpy(&machine, SIGNAL(stopped())); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); - QSignalSpy s2EnteredSpy(s2, SIGNAL(entered())); + QSignalSpy stoppedSpy(&machine, &QStateMachine::stopped); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); + QSignalSpy s2EnteredSpy(s2, &QFinalState::entered); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); QVERIFY(stoppedSpy.isValid()); QVERIFY(finishedSpy.isValid()); QVERIFY(s2EnteredSpy.isValid()); + QVERIFY(runningSpy.isValid()); machine.start(); - // Stopping should take precedence over finished. QTRY_COMPARE(stoppedSpy.count(), 1); QCOMPARE(finishedSpy.count(), 0); QCOMPARE(s2EnteredSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s2)); + TEST_ACTIVE_CHANGED(s1, 2); } class StopInEventTestTransition : public QAbstractTransition @@ -4026,24 +4792,31 @@ void tst_QStateMachine::stopInEventTest() QStateMachine machine; QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); s1->addTransition(new StopInEventTestTransition()); machine.setInitialState(s1); - QSignalSpy startedSpy(&machine, SIGNAL(started())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy startedSpy(&machine, &QStateMachine::started); QVERIFY(startedSpy.isValid()); machine.start(); + TEST_ACTIVE_CHANGED(s1, 1); QTRY_COMPARE(startedSpy.count(), 1); + TEST_RUNNING_CHANGED(true); - QSignalSpy stoppedSpy(&machine, SIGNAL(stopped())); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy stoppedSpy(&machine, &QStateMachine::stopped); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(stoppedSpy.isValid()); QVERIFY(finishedSpy.isValid()); machine.postEvent(new QEvent(QEvent::User), QStateMachine::EventPriority(eventPriority)); QTRY_COMPARE(stoppedSpy.count(), 1); QCOMPARE(finishedSpy.count(), 0); + TEST_RUNNING_CHANGED(false); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s1)); + TEST_ACTIVE_CHANGED(s1, 1); } class IncrementReceiversTest : public QObject @@ -4064,26 +4837,33 @@ void tst_QStateMachine::testIncrementReceivers() { QStateMachine machine; QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); machine.setInitialState(s1); QFinalState *s2 = new QFinalState(&machine); IncrementReceiversTest testObject; s1->addTransition(&testObject, SIGNAL(mySignal()), s2); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); machine.start(); + TEST_RUNNING_CHANGED(true); QMetaObject::invokeMethod(&testObject, "mySignal", Qt::QueuedConnection); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED(false); QCOMPARE(testObject.signalList.size(), 1); QCOMPARE(testObject.signalList.at(0), QMetaMethod::fromSignal(&IncrementReceiversTest::mySignal)); + TEST_ACTIVE_CHANGED(s1, 2); } void tst_QStateMachine::initialStateIsEnteredBeforeStartedEmitted() { QStateMachine machine; QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); machine.setInitialState(s1); QFinalState *s2 = new QFinalState(&machine); @@ -4091,15 +4871,20 @@ void tst_QStateMachine::initialStateIsEnteredBeforeStartedEmitted() // transition should trigger. s1->addTransition(&machine, SIGNAL(started()), s2); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); machine.start(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; + TEST_ACTIVE_CHANGED(s1, 2); } void tst_QStateMachine::deletePropertyAssignmentObjectBeforeEntry() { QStateMachine machine; QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); machine.setInitialState(s1); QObject *o1 = new QObject; @@ -4114,6 +4899,8 @@ void tst_QStateMachine::deletePropertyAssignmentObjectBeforeEntry() QCOMPARE(o2->objectName(), QString::fromLatin1("bar")); delete o2; + TEST_ACTIVE_CHANGED(s1, 1); + QVERIFY(machine.isRunning()); } void tst_QStateMachine::deletePropertyAssignmentObjectBeforeRestore() @@ -4121,8 +4908,10 @@ void tst_QStateMachine::deletePropertyAssignmentObjectBeforeRestore() QStateMachine machine; machine.setGlobalRestorePolicy(QState::RestoreProperties); QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); machine.setInitialState(s1); QState *s2 = new QState(&machine); + DEFINE_ACTIVE_SPY(s2); s1->addTransition(new EventTransition(QEvent::User, s2)); QObject *o1 = new QObject; @@ -4133,6 +4922,8 @@ void tst_QStateMachine::deletePropertyAssignmentObjectBeforeRestore() QVERIFY(o1->objectName().isEmpty()); QVERIFY(o2->objectName().isEmpty()); machine.start(); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s2, 0); QTRY_VERIFY(machine.configuration().contains(s1)); QCOMPARE(o1->objectName(), QString::fromLatin1("foo")); QCOMPARE(o2->objectName(), QString::fromLatin1("bar")); @@ -4144,6 +4935,9 @@ void tst_QStateMachine::deletePropertyAssignmentObjectBeforeRestore() QVERIFY(o2->objectName().isEmpty()); delete o2; + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 1); + QVERIFY(machine.isRunning()); } void tst_QStateMachine::deleteInitialState() @@ -4167,24 +4961,36 @@ void tst_QStateMachine::setPropertyAfterRestore() object->setProperty("a", 1); QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); machine.setInitialState(s1); s1->assignProperty(object, "a", 2); QState *s2 = new QState(&machine); + DEFINE_ACTIVE_SPY(s2); s1->addTransition(new EventTransition(QEvent::User, s2)); QState *s3 = new QState(&machine); + DEFINE_ACTIVE_SPY(s3); s3->assignProperty(object, "a", 4); s2->addTransition(new EventTransition(QEvent::User, s3)); QState *s4 = new QState(&machine); + DEFINE_ACTIVE_SPY(s4); s3->addTransition(new EventTransition(QEvent::User, s4)); machine.start(); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s2, 0); + TEST_ACTIVE_CHANGED(s3, 0); + TEST_ACTIVE_CHANGED(s4, 0); QTRY_VERIFY(machine.configuration().contains(s1)); QCOMPARE(object->property("a").toInt(), 2); machine.postEvent(new QEvent(QEvent::User)); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 1); + TEST_ACTIVE_CHANGED(s3, 0); + TEST_ACTIVE_CHANGED(s4, 0); QTRY_VERIFY(machine.configuration().contains(s2)); QCOMPARE(object->property("a").toInt(), 1); // restored @@ -4193,10 +4999,19 @@ void tst_QStateMachine::setPropertyAfterRestore() object->setProperty("a", 3); machine.postEvent(new QEvent(QEvent::User)); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 2); + TEST_ACTIVE_CHANGED(s3, 1); + TEST_ACTIVE_CHANGED(s4, 0); QTRY_VERIFY(machine.configuration().contains(s3)); QCOMPARE(object->property("a").toInt(), 4); machine.postEvent(new QEvent(QEvent::User)); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 2); + TEST_ACTIVE_CHANGED(s3, 2); + TEST_ACTIVE_CHANGED(s4, 1); + QVERIFY(machine.isRunning()); QTRY_VERIFY(machine.configuration().contains(s4)); QCOMPARE(object->property("a").toInt(), 3); // restored @@ -4221,14 +5036,15 @@ void tst_QStateMachine::transitionWithNoTarget() object->setProperty("a", 1); QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); machine.setInitialState(s1); s1->assignProperty(object, "a", 2); EventTransition *t1 = new EventTransition(QEvent::User, /*target=*/0); s1->addTransition(t1); - QSignalSpy s1EnteredSpy(s1, SIGNAL(entered())); - QSignalSpy s1ExitedSpy(s1, SIGNAL(exited())); - QSignalSpy t1TriggeredSpy(t1, SIGNAL(triggered())); + QSignalSpy s1EnteredSpy(s1, &QState::entered); + QSignalSpy s1ExitedSpy(s1, &QState::exited); + QSignalSpy t1TriggeredSpy(t1, &EventTransition::triggered); machine.start(); QTRY_VERIFY(machine.configuration().contains(s1)); @@ -4254,6 +5070,8 @@ void tst_QStateMachine::transitionWithNoTarget() QCOMPARE(object->property("a").toInt(), 3); delete object; + TEST_ACTIVE_CHANGED(s1, 1); + QVERIFY(machine.isRunning()); } void tst_QStateMachine::initialStateIsFinal() @@ -4261,10 +5079,13 @@ void tst_QStateMachine::initialStateIsFinal() QStateMachine machine; QFinalState *f = new QFinalState(&machine); machine.setInitialState(f); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); machine.start(); QTRY_VERIFY(machine.configuration().contains(f)); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; } class PropertyObject : public QObject @@ -4293,53 +5114,95 @@ void tst_QStateMachine::restorePropertiesSimple() QCOMPARE(po->propWriteCount(), 1); QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); s1->assignProperty(po, "prop", 4); machine.setInitialState(s1); QState *s2 = new QState(&machine); + DEFINE_ACTIVE_SPY(s2); s1->addTransition(new EventTransition(QEvent::User, s2)); QState *s3 = new QState(&machine); + DEFINE_ACTIVE_SPY(s3); s3->assignProperty(po, "prop", 6); s2->addTransition(new EventTransition(QEvent::User, s3)); QState *s4 = new QState(&machine); + DEFINE_ACTIVE_SPY(s4); s4->assignProperty(po, "prop", 8); s3->addTransition(new EventTransition(QEvent::User, s4)); QState *s5 = new QState(&machine); + DEFINE_ACTIVE_SPY(s5); s4->addTransition(new EventTransition(QEvent::User, s5)); QState *s6 = new QState(&machine); + DEFINE_ACTIVE_SPY(s6); s5->addTransition(new EventTransition(QEvent::User, s6)); machine.start(); - + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s2, 0); + TEST_ACTIVE_CHANGED(s3, 0); + TEST_ACTIVE_CHANGED(s4, 0); + TEST_ACTIVE_CHANGED(s5, 0); + TEST_ACTIVE_CHANGED(s6, 0); QTRY_VERIFY(machine.configuration().contains(s1)); QCOMPARE(po->propWriteCount(), 2); QCOMPARE(po->prop(), 4); machine.postEvent(new QEvent(QEvent::User)); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 1); + TEST_ACTIVE_CHANGED(s3, 0); + TEST_ACTIVE_CHANGED(s4, 0); + TEST_ACTIVE_CHANGED(s5, 0); + TEST_ACTIVE_CHANGED(s6, 0); QTRY_VERIFY(machine.configuration().contains(s2)); QCOMPARE(po->propWriteCount(), 3); QCOMPARE(po->prop(), 2); // restored machine.postEvent(new QEvent(QEvent::User)); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 2); + TEST_ACTIVE_CHANGED(s3, 1); + TEST_ACTIVE_CHANGED(s4, 0); + TEST_ACTIVE_CHANGED(s5, 0); + TEST_ACTIVE_CHANGED(s6, 0); QTRY_VERIFY(machine.configuration().contains(s3)); QCOMPARE(po->propWriteCount(), 4); QCOMPARE(po->prop(), 6); machine.postEvent(new QEvent(QEvent::User)); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 2); + TEST_ACTIVE_CHANGED(s3, 2); + TEST_ACTIVE_CHANGED(s4, 1); + TEST_ACTIVE_CHANGED(s5, 0); + TEST_ACTIVE_CHANGED(s6, 0); QTRY_VERIFY(machine.configuration().contains(s4)); QCOMPARE(po->propWriteCount(), 5); QCOMPARE(po->prop(), 8); machine.postEvent(new QEvent(QEvent::User)); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 2); + TEST_ACTIVE_CHANGED(s3, 2); + TEST_ACTIVE_CHANGED(s4, 2); + TEST_ACTIVE_CHANGED(s5, 1); + TEST_ACTIVE_CHANGED(s6, 0); QTRY_VERIFY(machine.configuration().contains(s5)); QCOMPARE(po->propWriteCount(), 6); QCOMPARE(po->prop(), 2); // restored machine.postEvent(new QEvent(QEvent::User)); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 2); + TEST_ACTIVE_CHANGED(s3, 2); + TEST_ACTIVE_CHANGED(s4, 2); + TEST_ACTIVE_CHANGED(s5, 2); + TEST_ACTIVE_CHANGED(s6, 1); + QVERIFY(machine.isRunning()); QTRY_VERIFY(machine.configuration().contains(s6)); QCOMPARE(po->propWriteCount(), 6); @@ -4356,76 +5219,158 @@ void tst_QStateMachine::restoreProperties2() QCOMPARE(po->propWriteCount(), 1); QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); s1->assignProperty(po, "prop", 4); machine.setInitialState(s1); QState *s11 = new QState(s1); + DEFINE_ACTIVE_SPY(s11); s1->setInitialState(s11); QState *s12 = new QState(s1); + DEFINE_ACTIVE_SPY(s12); s11->addTransition(new EventTransition(QEvent::User, s12)); QState *s13 = new QState(s1); + DEFINE_ACTIVE_SPY(s13); s13->assignProperty(po, "prop", 6); s12->addTransition(new EventTransition(QEvent::User, s13)); QState *s14 = new QState(s1); + DEFINE_ACTIVE_SPY(s14); s14->assignProperty(po, "prop", 8); s13->addTransition(new EventTransition(QEvent::User, s14)); QState *s15 = new QState(s1); + DEFINE_ACTIVE_SPY(s15); s14->addTransition(new EventTransition(QEvent::User, s15)); QState *s16 = new QState(s1); + DEFINE_ACTIVE_SPY(s16); s15->addTransition(new EventTransition(QEvent::User, s16)); QState *s2 = new QState(&machine); + DEFINE_ACTIVE_SPY(s2); s2->assignProperty(po, "prop", 10); s16->addTransition(new EventTransition(QEvent::User, s2)); QState *s3 = new QState(&machine); + DEFINE_ACTIVE_SPY(s3); s2->addTransition(new EventTransition(QEvent::User, s3)); machine.start(); - + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s11, 1); + TEST_ACTIVE_CHANGED(s12, 0); + TEST_ACTIVE_CHANGED(s13, 0); + TEST_ACTIVE_CHANGED(s14, 0); + TEST_ACTIVE_CHANGED(s15, 0); + TEST_ACTIVE_CHANGED(s16, 0); + TEST_ACTIVE_CHANGED(s2, 0); + TEST_ACTIVE_CHANGED(s3, 0); QTRY_VERIFY(machine.configuration().contains(s11)); QCOMPARE(po->propWriteCount(), 2); QCOMPARE(po->prop(), 4); machine.postEvent(new QEvent(QEvent::User)); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s11, 2); + TEST_ACTIVE_CHANGED(s12, 1); + TEST_ACTIVE_CHANGED(s13, 0); + TEST_ACTIVE_CHANGED(s14, 0); + TEST_ACTIVE_CHANGED(s15, 0); + TEST_ACTIVE_CHANGED(s16, 0); + TEST_ACTIVE_CHANGED(s2, 0); + TEST_ACTIVE_CHANGED(s3, 0); QTRY_VERIFY(machine.configuration().contains(s12)); QCOMPARE(po->propWriteCount(), 2); machine.postEvent(new QEvent(QEvent::User)); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s11, 2); + TEST_ACTIVE_CHANGED(s12, 2); + TEST_ACTIVE_CHANGED(s13, 1); + TEST_ACTIVE_CHANGED(s14, 0); + TEST_ACTIVE_CHANGED(s15, 0); + TEST_ACTIVE_CHANGED(s16, 0); + TEST_ACTIVE_CHANGED(s2, 0); + TEST_ACTIVE_CHANGED(s3, 0); QTRY_VERIFY(machine.configuration().contains(s13)); QCOMPARE(po->propWriteCount(), 3); QCOMPARE(po->prop(), 6); machine.postEvent(new QEvent(QEvent::User)); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s11, 2); + TEST_ACTIVE_CHANGED(s12, 2); + TEST_ACTIVE_CHANGED(s13, 2); + TEST_ACTIVE_CHANGED(s14, 1); + TEST_ACTIVE_CHANGED(s15, 0); + TEST_ACTIVE_CHANGED(s16, 0); + TEST_ACTIVE_CHANGED(s2, 0); + TEST_ACTIVE_CHANGED(s3, 0); QTRY_VERIFY(machine.configuration().contains(s14)); QCOMPARE(po->propWriteCount(), 4); QCOMPARE(po->prop(), 8); machine.postEvent(new QEvent(QEvent::User)); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s11, 2); + TEST_ACTIVE_CHANGED(s12, 2); + TEST_ACTIVE_CHANGED(s13, 2); + TEST_ACTIVE_CHANGED(s14, 2); + TEST_ACTIVE_CHANGED(s15, 1); + TEST_ACTIVE_CHANGED(s16, 0); + TEST_ACTIVE_CHANGED(s2, 0); + TEST_ACTIVE_CHANGED(s3, 0); QTRY_VERIFY(machine.configuration().contains(s15)); QCOMPARE(po->propWriteCount(), 5); QCOMPARE(po->prop(), 4); // restored s1 machine.postEvent(new QEvent(QEvent::User)); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s11, 2); + TEST_ACTIVE_CHANGED(s12, 2); + TEST_ACTIVE_CHANGED(s13, 2); + TEST_ACTIVE_CHANGED(s14, 2); + TEST_ACTIVE_CHANGED(s15, 2); + TEST_ACTIVE_CHANGED(s16, 1); + TEST_ACTIVE_CHANGED(s2, 0); + TEST_ACTIVE_CHANGED(s3, 0); QTRY_VERIFY(machine.configuration().contains(s16)); QCOMPARE(po->propWriteCount(), 5); machine.postEvent(new QEvent(QEvent::User)); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s11, 2); + TEST_ACTIVE_CHANGED(s12, 2); + TEST_ACTIVE_CHANGED(s13, 2); + TEST_ACTIVE_CHANGED(s14, 2); + TEST_ACTIVE_CHANGED(s15, 2); + TEST_ACTIVE_CHANGED(s16, 2); + TEST_ACTIVE_CHANGED(s2, 1); + TEST_ACTIVE_CHANGED(s3, 0); QTRY_VERIFY(machine.configuration().contains(s2)); QCOMPARE(po->propWriteCount(), 6); QCOMPARE(po->prop(), 10); machine.postEvent(new QEvent(QEvent::User)); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s11, 2); + TEST_ACTIVE_CHANGED(s12, 2); + TEST_ACTIVE_CHANGED(s13, 2); + TEST_ACTIVE_CHANGED(s14, 2); + TEST_ACTIVE_CHANGED(s15, 2); + TEST_ACTIVE_CHANGED(s16, 2); + TEST_ACTIVE_CHANGED(s2, 2); + TEST_ACTIVE_CHANGED(s3, 1); + QVERIFY(machine.isRunning()); QTRY_VERIFY(machine.configuration().contains(s3)); QCOMPARE(po->propWriteCount(), 7); QCOMPARE(po->prop(), 2); // restored original delete po; + } void tst_QStateMachine::restoreProperties3() @@ -4438,40 +5383,66 @@ void tst_QStateMachine::restoreProperties3() QCOMPARE(po->propWriteCount(), 1); QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); s1->assignProperty(po, "prop", 4); machine.setInitialState(s1); QState *s11 = new QState(s1); + DEFINE_ACTIVE_SPY(s11); s11->assignProperty(po, "prop", 6); s1->setInitialState(s11); QState *s12 = new QState(s1); + DEFINE_ACTIVE_SPY(s12); s11->addTransition(new EventTransition(QEvent::User, s12)); QState *s13 = new QState(s1); + DEFINE_ACTIVE_SPY(s13); s13->assignProperty(po, "prop", 8); s12->addTransition(new EventTransition(QEvent::User, s13)); QState *s2 = new QState(&machine); + DEFINE_ACTIVE_SPY(s2); s13->addTransition(new EventTransition(QEvent::User, s2)); machine.start(); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s11, 1); + TEST_ACTIVE_CHANGED(s12, 0); + TEST_ACTIVE_CHANGED(s13, 0); + TEST_ACTIVE_CHANGED(s2, 0); QTRY_VERIFY(machine.configuration().contains(s11)); QCOMPARE(po->propWriteCount(), 3); QCOMPARE(po->prop(), 6); // s11 machine.postEvent(new QEvent(QEvent::User)); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s11, 2); + TEST_ACTIVE_CHANGED(s12, 1); + TEST_ACTIVE_CHANGED(s13, 0); + TEST_ACTIVE_CHANGED(s2, 0); QTRY_VERIFY(machine.configuration().contains(s12)); QCOMPARE(po->propWriteCount(), 4); QCOMPARE(po->prop(), 4); // restored s1 machine.postEvent(new QEvent(QEvent::User)); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s11, 2); + TEST_ACTIVE_CHANGED(s12, 2); + TEST_ACTIVE_CHANGED(s13, 1); + TEST_ACTIVE_CHANGED(s2, 0); QTRY_VERIFY(machine.configuration().contains(s13)); QCOMPARE(po->propWriteCount(), 5); QCOMPARE(po->prop(), 8); machine.postEvent(new QEvent(QEvent::User)); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s11, 2); + TEST_ACTIVE_CHANGED(s12, 2); + TEST_ACTIVE_CHANGED(s13, 2); + TEST_ACTIVE_CHANGED(s2, 1); + QVERIFY(machine.isRunning()); QTRY_VERIFY(machine.configuration().contains(s2)); QCOMPARE(po->propWriteCount(), 6); QCOMPARE(po->prop(), 2); // restored original @@ -4493,31 +5464,47 @@ void tst_QStateMachine::restoreProperties4() QCOMPARE(po2->propWriteCount(), 1); QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); s1->setChildMode(QState::ParallelStates); machine.setInitialState(s1); QState *s11 = new QState(s1); + DEFINE_ACTIVE_SPY(s11); QState *s111 = new QState(s11); + DEFINE_ACTIVE_SPY(s111); s111->assignProperty(po1, "prop", 6); s11->setInitialState(s111); QState *s112 = new QState(s11); + DEFINE_ACTIVE_SPY(s112); s112->assignProperty(po1, "prop", 8); s111->addTransition(new EventTransition(QEvent::User, s112)); QState *s12 = new QState(s1); + DEFINE_ACTIVE_SPY(s12); QState *s121 = new QState(s12); + DEFINE_ACTIVE_SPY(s121); s121->assignProperty(po2, "prop", 10); s12->setInitialState(s121); QState *s122 = new QState(s12); + DEFINE_ACTIVE_SPY(s122); s122->assignProperty(po2, "prop", 12); s121->addTransition(new EventTransition(static_cast<QEvent::Type>(QEvent::User+1), s122)); QState *s2 = new QState(&machine); s112->addTransition(new EventTransition(QEvent::User, s2)); + DEFINE_ACTIVE_SPY(s2); machine.start(); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s11, 1); + TEST_ACTIVE_CHANGED(s111, 1); + TEST_ACTIVE_CHANGED(s112, 0); + TEST_ACTIVE_CHANGED(s12, 1); + TEST_ACTIVE_CHANGED(s121, 1); + TEST_ACTIVE_CHANGED(s122, 0); + TEST_ACTIVE_CHANGED(s2, 0); QTRY_VERIFY(machine.configuration().contains(s1)); QVERIFY(machine.configuration().contains(s11)); @@ -4530,18 +5517,42 @@ void tst_QStateMachine::restoreProperties4() QCOMPARE(po2->prop(), 10); machine.postEvent(new QEvent(QEvent::User)); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s11, 1); + TEST_ACTIVE_CHANGED(s111, 2); + TEST_ACTIVE_CHANGED(s112, 1); + TEST_ACTIVE_CHANGED(s12, 1); + TEST_ACTIVE_CHANGED(s121, 1); + TEST_ACTIVE_CHANGED(s122, 0); + TEST_ACTIVE_CHANGED(s2, 0); QTRY_VERIFY(machine.configuration().contains(s112)); QCOMPARE(po1->propWriteCount(), 3); QCOMPARE(po1->prop(), 8); QCOMPARE(po2->propWriteCount(), 2); machine.postEvent(new QEvent(static_cast<QEvent::Type>(QEvent::User+1))); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s11, 1); + TEST_ACTIVE_CHANGED(s111, 2); + TEST_ACTIVE_CHANGED(s112, 1); + TEST_ACTIVE_CHANGED(s12, 1); + TEST_ACTIVE_CHANGED(s121, 2); + TEST_ACTIVE_CHANGED(s122, 1); + TEST_ACTIVE_CHANGED(s2, 0); QTRY_VERIFY(machine.configuration().contains(s122)); QCOMPARE(po1->propWriteCount(), 3); QCOMPARE(po2->propWriteCount(), 3); QCOMPARE(po2->prop(), 12); machine.postEvent(new QEvent(QEvent::User)); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s11, 2); + TEST_ACTIVE_CHANGED(s111, 2); + TEST_ACTIVE_CHANGED(s112, 2); + TEST_ACTIVE_CHANGED(s12, 2); + TEST_ACTIVE_CHANGED(s121, 2); + TEST_ACTIVE_CHANGED(s122, 2); + TEST_ACTIVE_CHANGED(s2, 1); QTRY_VERIFY(machine.configuration().contains(s2)); QCOMPARE(po1->propWriteCount(), 4); QCOMPARE(po1->prop(), 2); // restored original @@ -4562,27 +5573,37 @@ void tst_QStateMachine::restorePropertiesSelfTransition() QCOMPARE(po->propWriteCount(), 1); QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); s1->assignProperty(po, "prop", 4); s1->addTransition(new EventTransition(QEvent::User, s1)); machine.setInitialState(s1); QState *s2 = new QState(&machine); + DEFINE_ACTIVE_SPY(s2); s1->addTransition(new EventTransition(static_cast<QEvent::Type>(QEvent::User+1), s2)); machine.start(); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s2, 0); QTRY_VERIFY(machine.configuration().contains(s1)); QCOMPARE(po->propWriteCount(), 2); QCOMPARE(po->prop(), 4); machine.postEvent(new QEvent(QEvent::User)); + TEST_ACTIVE_CHANGED(s1, 3); + TEST_ACTIVE_CHANGED(s2, 0); QTRY_COMPARE(po->propWriteCount(), 3); QCOMPARE(po->prop(), 4); machine.postEvent(new QEvent(QEvent::User)); + TEST_ACTIVE_CHANGED(s1, 5); + TEST_ACTIVE_CHANGED(s2, 0); QTRY_COMPARE(po->propWriteCount(), 4); QCOMPARE(po->prop(), 4); machine.postEvent(new QEvent(static_cast<QEvent::Type>(QEvent::User+1))); + TEST_ACTIVE_CHANGED(s1, 6); + TEST_ACTIVE_CHANGED(s2, 1); QTRY_VERIFY(machine.configuration().contains(s2)); QCOMPARE(po->propWriteCount(), 5); QCOMPARE(po->prop(), 2); // restored @@ -4601,12 +5622,15 @@ void tst_QStateMachine::changeStateWhileAnimatingProperty() o2->setProperty("y", 20.); QState *group = new QState(&machine); + DEFINE_ACTIVE_SPY(group); machine.setInitialState(group); QState *s0 = new QState(group); + DEFINE_ACTIVE_SPY(s0); group->setInitialState(s0); QState *s1 = new QState(group); + DEFINE_ACTIVE_SPY(s1); s1->assignProperty(o1, "x", 15.); QPropertyAnimation *a1 = new QPropertyAnimation(o1, "x", s1); a1->setDuration(800); @@ -4614,6 +5638,7 @@ void tst_QStateMachine::changeStateWhileAnimatingProperty() group->addTransition(new EventTransition(QEvent::User, s1)); QState *s2 = new QState(group); + DEFINE_ACTIVE_SPY(s2); s2->assignProperty(o2, "y", 25.); QPropertyAnimation *a2 = new QPropertyAnimation(o2, "y", s2); a2->setDuration(800); @@ -4621,23 +5646,46 @@ void tst_QStateMachine::changeStateWhileAnimatingProperty() group->addTransition(new EventTransition(static_cast<QEvent::Type>(QEvent::User+1), s2)); machine.start(); + TEST_ACTIVE_CHANGED(group, 1); + TEST_ACTIVE_CHANGED(s0, 1); + TEST_ACTIVE_CHANGED(s1, 0); + TEST_ACTIVE_CHANGED(s2, 0); QTRY_VERIFY(machine.configuration().contains(s0)); machine.postEvent(new QEvent(QEvent::User)); + TEST_ACTIVE_CHANGED(group, 3); + TEST_ACTIVE_CHANGED(s0, 2); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s2, 0); QTRY_VERIFY(machine.configuration().contains(s1)); QCOREAPPLICATION_EXEC(400); machine.postEvent(new QEvent(static_cast<QEvent::Type>(QEvent::User+1))); + TEST_ACTIVE_CHANGED(group, 5); + TEST_ACTIVE_CHANGED(s0, 2); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 1); QTRY_VERIFY(machine.configuration().contains(s2)); QCOREAPPLICATION_EXEC(300); machine.postEvent(new QEvent(QEvent::User)); + TEST_ACTIVE_CHANGED(group, 7); + TEST_ACTIVE_CHANGED(s0, 2); + TEST_ACTIVE_CHANGED(s1, 3); + TEST_ACTIVE_CHANGED(s2, 2); QTRY_VERIFY(machine.configuration().contains(s1)); QCOREAPPLICATION_EXEC(200); machine.postEvent(new QEvent(static_cast<QEvent::Type>(QEvent::User+1))); + TEST_ACTIVE_CHANGED(group, 9); + TEST_ACTIVE_CHANGED(s0, 2); + TEST_ACTIVE_CHANGED(s1, 4); + TEST_ACTIVE_CHANGED(s2, 3); QTRY_VERIFY(machine.configuration().contains(s2)); QCOREAPPLICATION_EXEC(100); machine.postEvent(new QEvent(QEvent::User)); + TEST_ACTIVE_CHANGED(group, 11); + TEST_ACTIVE_CHANGED(s0, 2); + TEST_ACTIVE_CHANGED(s1, 5); + TEST_ACTIVE_CHANGED(s2, 4); QTRY_VERIFY(machine.configuration().contains(s1)); - QTRY_COMPARE(o1->property("x").toDouble(), 15.); QTRY_COMPARE(o2->property("y").toDouble(), 20.); @@ -4679,15 +5727,19 @@ void tst_QStateMachine::propertiesAreAssignedBeforeEntryCallbacks() machine.setGlobalRestorePolicy(static_cast<QState::RestorePolicy>(restorePolicy)); AssignPropertyTestState *s1 = new AssignPropertyTestState(&machine); + DEFINE_ACTIVE_SPY(s1); s1->assignProperty(s1, "wasAssigned", true); machine.setInitialState(s1); AssignPropertyTestState *s2 = new AssignPropertyTestState(&machine); + DEFINE_ACTIVE_SPY(s2); s2->assignProperty(s2, "wasAssigned", true); s1->addTransition(new EventTransition(QEvent::User, s2)); QVERIFY(!s1->property("wasAssigned").toBool()); machine.start(); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s2, 0); QTRY_VERIFY(machine.configuration().contains(s1)); QVERIFY(s1->onEntryPassed); @@ -4695,6 +5747,8 @@ void tst_QStateMachine::propertiesAreAssignedBeforeEntryCallbacks() QVERIFY(!s2->property("wasAssigned").toBool()); machine.postEvent(new QEvent(QEvent::User)); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 1); QTRY_VERIFY(machine.configuration().contains(s2)); QVERIFY(s2->onEntryPassed); @@ -4709,18 +5763,26 @@ void tst_QStateMachine::multiTargetTransitionInsideParallelStateGroup() QStateMachine machine; QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); machine.setInitialState(s1); QState *s2 = new QState(QState::ParallelStates, &machine); + DEFINE_ACTIVE_SPY(s2); QState *s21 = new QState(s2); + DEFINE_ACTIVE_SPY(s21); QState *s211 = new QState(s21); + DEFINE_ACTIVE_SPY(s211); QState *s212 = new QState(s21); + DEFINE_ACTIVE_SPY(s212); s21->setInitialState(s212); QState *s22 = new QState(s2); + DEFINE_ACTIVE_SPY(s22); QState *s221 = new QState(s22); + DEFINE_ACTIVE_SPY(s221); QState *s222 = new QState(s22); + DEFINE_ACTIVE_SPY(s222); s22->setInitialState(s222); QAbstractTransition *t1 = new EventTransition(QEvent::User, QList<QAbstractState *>() << s211 << s221); @@ -4728,7 +5790,14 @@ void tst_QStateMachine::multiTargetTransitionInsideParallelStateGroup() machine.start(); QTRY_VERIFY(machine.configuration().contains(s1)); - + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s2, 0); + TEST_ACTIVE_CHANGED(s21, 0); + TEST_ACTIVE_CHANGED(s211, 0); + TEST_ACTIVE_CHANGED(s212, 0); + TEST_ACTIVE_CHANGED(s22, 0); + TEST_ACTIVE_CHANGED(s221, 0); + TEST_ACTIVE_CHANGED(s222, 0); machine.postEvent(new QEvent(QEvent::User)); QTRY_VERIFY(machine.configuration().contains(s2)); QCOMPARE(machine.configuration().size(), 5); @@ -4736,19 +5805,31 @@ void tst_QStateMachine::multiTargetTransitionInsideParallelStateGroup() QVERIFY(machine.configuration().contains(s211)); QVERIFY(machine.configuration().contains(s22)); QVERIFY(machine.configuration().contains(s221)); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 1); + TEST_ACTIVE_CHANGED(s21, 1); + TEST_ACTIVE_CHANGED(s211, 1); + TEST_ACTIVE_CHANGED(s212, 0); + TEST_ACTIVE_CHANGED(s22, 1); + TEST_ACTIVE_CHANGED(s221, 1); + TEST_ACTIVE_CHANGED(s222, 0); } void tst_QStateMachine::signalTransitionNormalizeSignature() { QStateMachine machine; QState *s0 = new QState(&machine); + DEFINE_ACTIVE_SPY(s0); machine.setInitialState(s0); QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); SignalEmitter emitter; TestSignalTransition *t0 = new TestSignalTransition(&emitter, SIGNAL(signalWithNoArg()), s1); s0->addTransition(t0); machine.start(); + TEST_ACTIVE_CHANGED(s0, 1); + TEST_ACTIVE_CHANGED(s1, 0); QTRY_VERIFY(machine.configuration().contains(s0)); emitter.emitSignalWithNoArg(); QTRY_VERIFY(machine.configuration().contains(s1)); @@ -4759,44 +5840,60 @@ void tst_QStateMachine::signalTransitionNormalizeSignature() QCOMPARE(t0->transitionSenderReceived(), (QObject*)&emitter); QCOMPARE(t0->transitionSignalIndexReceived(), emitter.metaObject()->indexOfSignal("signalWithNoArg()")); QCOMPARE(t0->transitionArgumentsReceived().size(), 0); + TEST_ACTIVE_CHANGED(s0, 2); + TEST_ACTIVE_CHANGED(s1, 1); } void tst_QStateMachine::createSignalTransitionWhenRunning() { QStateMachine machine; QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); machine.setInitialState(s1); machine.start(); + TEST_ACTIVE_CHANGED(s1, 1); QTRY_VERIFY(machine.configuration().contains(s1)); - // Create by addTransition() QState *s2 = new QState(&machine); + DEFINE_ACTIVE_SPY(s2); SignalEmitter emitter; QAbstractTransition *t1 = s1->addTransition(&emitter, SIGNAL(signalWithNoArg()), s2); QCOMPARE(t1->sourceState(), s1); emitter.emitSignalWithNoArg(); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 1); QTRY_VERIFY(machine.configuration().contains(s2)); // Create by constructor that takes sender, signal, source (parent) state QState *s3 = new QState(&machine); + DEFINE_ACTIVE_SPY(s3); QSignalTransition *t2 = new QSignalTransition(&emitter, SIGNAL(signalWithNoArg()), s2); QCOMPARE(t2->sourceState(), s2); t2->setTargetState(s3); emitter.emitSignalWithNoArg(); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 2); + TEST_ACTIVE_CHANGED(s3, 1); QTRY_VERIFY(machine.configuration().contains(s3)); // Create by constructor that takes source (parent) state QState *s4 = new QState(&machine); + DEFINE_ACTIVE_SPY(s4); QSignalTransition *t3 = new QSignalTransition(s3); QCOMPARE(t3->sourceState(), s3); t3->setSenderObject(&emitter); t3->setSignal(SIGNAL(signalWithNoArg())); t3->setTargetState(s4); emitter.emitSignalWithNoArg(); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 2); + TEST_ACTIVE_CHANGED(s3, 2); + TEST_ACTIVE_CHANGED(s4, 1); QTRY_VERIFY(machine.configuration().contains(s4)); // Create by constructor without parent, then set the parent QState *s5 = new QState(&machine); + DEFINE_ACTIVE_SPY(s5); QSignalTransition *t4 = new QSignalTransition(); t4->setSenderObject(&emitter); t4->setParent(s4); @@ -4804,6 +5901,11 @@ void tst_QStateMachine::createSignalTransitionWhenRunning() t4->setSignal(SIGNAL(signalWithNoArg())); t4->setTargetState(s5); emitter.emitSignalWithNoArg(); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 2); + TEST_ACTIVE_CHANGED(s3, 2); + TEST_ACTIVE_CHANGED(s4, 2); + TEST_ACTIVE_CHANGED(s5, 1); QTRY_VERIFY(machine.configuration().contains(s5)); } @@ -4811,12 +5913,15 @@ void tst_QStateMachine::createEventTransitionWhenRunning() { QStateMachine machine; QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); machine.setInitialState(s1); machine.start(); + TEST_ACTIVE_CHANGED(s1, 1); QTRY_VERIFY(machine.configuration().contains(s1)); // Create by constructor that takes event source, type, source (parent) state QState *s2 = new QState(&machine); + DEFINE_ACTIVE_SPY(s2); QObject object; QEventTransition *t1 = new QEventTransition(&object, QEvent::Timer, s1); QCOMPARE(t1->sourceState(), s1); @@ -4827,6 +5932,7 @@ void tst_QStateMachine::createEventTransitionWhenRunning() // Create by constructor that takes source (parent) state QState *s3 = new QState(&machine); + DEFINE_ACTIVE_SPY(s3); QEventTransition *t2 = new QEventTransition(s2); QCOMPARE(t2->sourceState(), s2); t2->setEventSource(&object); @@ -4836,6 +5942,7 @@ void tst_QStateMachine::createEventTransitionWhenRunning() // Create by constructor without parent, then set the parent QState *s4 = new QState(&machine); + DEFINE_ACTIVE_SPY(s4); QEventTransition *t3 = new QEventTransition(); t3->setEventSource(&object); t3->setParent(s3); @@ -4843,6 +5950,10 @@ void tst_QStateMachine::createEventTransitionWhenRunning() t3->setEventType(QEvent::Timer); t3->setTargetState(s4); QTRY_VERIFY(machine.configuration().contains(s4)); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 2); + TEST_ACTIVE_CHANGED(s3, 2); + TEST_ACTIVE_CHANGED(s4, 1); } class SignalEmitterThread : public QThread @@ -4872,10 +5983,12 @@ void tst_QStateMachine::signalTransitionSenderInDifferentThread() { QStateMachine machine; QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); machine.setInitialState(s1); SignalEmitterThread thread; QState *s2 = new QState(&machine); + DEFINE_ACTIVE_SPY(s2); s1->addTransition(&thread, SIGNAL(signal1()), s2); QFinalState *s3 = new QFinalState(&machine); @@ -4885,29 +5998,41 @@ void tst_QStateMachine::signalTransitionSenderInDifferentThread() QTRY_VERIFY(thread.isRunning()); machine.start(); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s2, 0); QTRY_VERIFY(machine.configuration().contains(s1)); QMetaObject::invokeMethod(&thread, "emitSignals"); // thread emits both signal1() and signal2(), so we should end in s3 + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 2); + QTRY_VERIFY(!machine.isRunning()); QTRY_VERIFY(machine.configuration().contains(s3)); // Run the machine again; transitions should still be registered machine.start(); + TEST_ACTIVE_CHANGED(s1, 3); + TEST_ACTIVE_CHANGED(s2, 2); QTRY_VERIFY(machine.configuration().contains(s1)); QMetaObject::invokeMethod(&thread, "emitSignals"); QTRY_VERIFY(machine.configuration().contains(s3)); thread.quit(); QTRY_VERIFY(thread.wait()); + TEST_ACTIVE_CHANGED(s1, 4); + TEST_ACTIVE_CHANGED(s2, 4); + QVERIFY(!machine.isRunning()); } void tst_QStateMachine::signalTransitionSenderInDifferentThread2() { QStateMachine machine; QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); machine.setInitialState(s1); QState *s2 = new QState(&machine); + DEFINE_ACTIVE_SPY(s2); SignalEmitter emitter; // At the time of the transition creation, the machine and the emitter // are both in the same thread. @@ -4924,18 +6049,24 @@ void tst_QStateMachine::signalTransitionSenderInDifferentThread2() thread.start(); QTRY_VERIFY(thread.isRunning()); - QSignalSpy startedSpy(&machine, SIGNAL(started())); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy startedSpy(&machine, &QStateMachine::started); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); machine.start(); QTRY_COMPARE(startedSpy.count(), 1); + TEST_RUNNING_CHANGED(true); emitter.emitSignalWithNoArg(); // The second emission should not get "lost". emitter.emitSignalWithDefaultArg(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED(false); thread.quit(); QTRY_VERIFY(thread.wait()); + TEST_ACTIVE_CHANGED(s1, 2); + TEST_ACTIVE_CHANGED(s2, 2); } class SignalTransitionMutatorThread : public QThread @@ -4961,6 +6092,7 @@ void tst_QStateMachine::signalTransitionRegistrationThreadSafety() { QStateMachine machine; QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); machine.setInitialState(s1); machine.start(); QTRY_VERIFY(machine.configuration().contains(s1)); @@ -4985,6 +6117,8 @@ void tst_QStateMachine::signalTransitionRegistrationThreadSafety() thread.quit(); QTRY_VERIFY(thread.wait()); + TEST_ACTIVE_CHANGED(s1, 1); + QVERIFY(machine.isRunning()); } void tst_QStateMachine::childModeConstructor() |