tests/auto/qstatemachine/tst_qstatemachine.cpp
changeset 3 41300fa6a67c
parent 0 1918ee327afb
child 4 3b1da2848fc7
--- a/tests/auto/qstatemachine/tst_qstatemachine.cpp	Tue Jan 26 12:42:25 2010 +0200
+++ b/tests/auto/qstatemachine/tst_qstatemachine.cpp	Tue Feb 02 00:43:10 2010 +0200
@@ -117,6 +117,7 @@
     void cleanup();
 
     void rootState();
+    void machineWithParent();
     void addAndRemoveState();
     void stateEntryAndExit();
     void assignProperty();
@@ -124,6 +125,7 @@
     void postEvent();
     void cancelDelayedEvent();
     void postDelayedEventAndStop();
+    void stopAndPostEvent();
     void stateFinished();
     void parallelStates();
     void parallelRootState();
@@ -160,7 +162,7 @@
 
     void defaultGlobalRestorePolicy();
     void globalRestorePolicySetToRestore();
-    void globalRestorePolicySetToDoNotRestore();
+    void globalRestorePolicySetToDontRestore();
 
     void noInitialStateForInitialState();
 
@@ -182,7 +184,7 @@
     void twoAnimatedTransitions();
     void playAnimationTwice();
     void nestedTargetStateForAnimation();
-    void polishedSignalTransitionsReuseAnimationGroup();
+    void propertiesAssignedSignalTransitionsReuseAnimationGroup();
     void animatedGlobalRestoreProperty();
     void specificTargetValueOfAnimation();
 
@@ -205,6 +207,9 @@
     void goToState();
 
     void task260403_clonedSignals();
+    void postEventFromOtherThread();
+    void eventFilterForApplication();
+    void eventClassesExported();
 };
 
 tst_QStateMachine::tst_QStateMachine()
@@ -283,8 +288,8 @@
     machine.addState(initialState);
     machine.setInitialState(initialState);
 
-    QAbstractTransition *trans = initialState->addTransition(new EventTransition(QEvent::User, &machine));
-    QVERIFY(trans != 0);
+    QAbstractTransition *trans = new EventTransition(QEvent::User, &machine);
+    initialState->addTransition(trans);
     QCOMPARE(trans->sourceState(), initialState);
     QCOMPARE(trans->targetState(), static_cast<QAbstractState *>(&machine));
 
@@ -307,7 +312,7 @@
     QState *root = &machine;
     QState *s1 = new QState(root);
     EventTransition *trans = new EventTransition(QEvent::User, s1);
-    QCOMPARE(root->addTransition(trans), static_cast<QAbstractTransition *>(trans));
+    root->addTransition(trans);
     QCOMPARE(trans->sourceState(), root);
     QCOMPARE(trans->targetState(), static_cast<QAbstractState *>(s1));
 }
@@ -981,7 +986,7 @@
 void tst_QStateMachine::restoreProperties()
 {
     QStateMachine machine;
-    QCOMPARE(machine.globalRestorePolicy(), QStateMachine::DoNotRestoreProperties);
+    QCOMPARE(machine.globalRestorePolicy(), QStateMachine::DontRestoreProperties);
     machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties);
 
     QObject *object = new QObject(&machine);
@@ -1043,6 +1048,14 @@
     QCOMPARE(s2->parentState(), static_cast<QState*>(&machine));
 }
 
+void tst_QStateMachine::machineWithParent()
+{
+    QObject object;
+    QStateMachine *machine = new QStateMachine(&object);
+    QCOMPARE(machine->parent(), &object);
+    QCOMPARE(machine->parentState(), (QObject*)0);
+}
+
 void tst_QStateMachine::addAndRemoveState()
 {
 #ifdef QT_BUILD_INTERNAL
@@ -1144,7 +1157,7 @@
         QCOMPARE(t->targetState(), (QAbstractState*)s2);
         QCOMPARE(t->targetStates().size(), 1);
         QCOMPARE(t->targetStates().at(0), (QAbstractState*)s2);
-        QCOMPARE(s1->addTransition(t), (QAbstractTransition*)t);
+        s1->addTransition(t);
         QCOMPARE(t->sourceState(), (QState*)s1);
         QCOMPARE(t->machine(), &machine);
 
@@ -1162,7 +1175,7 @@
             s2->removeTransition(trans);
             QCOMPARE(trans->sourceState(), (QState*)0);
             QCOMPARE(trans->targetState(), (QAbstractState*)s3);
-            QCOMPARE(s2->addTransition(trans), trans);
+            s2->addTransition(trans);
             QCOMPARE(trans->sourceState(), (QState*)s2);
         }
 
@@ -1308,9 +1321,9 @@
     QCOMPARE(s1->objectName(), QString::fromLatin1("foo"));
 
     {
-        QSignalSpy polishedSpy(s1, SIGNAL(polished()));
+        QSignalSpy propertiesAssignedSpy(s1, SIGNAL(propertiesAssigned()));
         machine.start();
-        QTRY_COMPARE(polishedSpy.count(), 1);
+        QTRY_COMPARE(propertiesAssignedSpy.count(), 1);
     }
 
     // nested states
@@ -1329,11 +1342,11 @@
     // Single animation
     {
         QStateMachine machine;
-        QVERIFY(machine.animationsEnabled());
-        machine.setAnimationsEnabled(false);
-        QVERIFY(!machine.animationsEnabled());
-        machine.setAnimationsEnabled(true);
-        QVERIFY(machine.animationsEnabled());
+        QVERIFY(machine.isAnimated());
+        machine.setAnimated(false);
+        QVERIFY(!machine.isAnimated());
+        machine.setAnimated(true);
+        QVERIFY(machine.isAnimated());
         QObject obj;
         obj.setProperty("foo", 321);
         obj.setProperty("bar", 654);
@@ -1360,7 +1373,7 @@
         QCOMPARE(trans->animations().size(), 1);
         QCOMPARE(trans->animations().at(0), (QAbstractAnimation*)&anim);
         QFinalState *s3 = new QFinalState(&machine);
-        s2->addTransition(s2, SIGNAL(polished()), s3);
+        s2->addTransition(s2, SIGNAL(propertiesAssigned()), s3);
 
         machine.setInitialState(s1);
         QSignalSpy finishedSpy(&machine, SIGNAL(finished()));
@@ -1388,7 +1401,7 @@
         anim2.setDuration(150);
         trans->addAnimation(&anim2);
         QFinalState *s3 = new QFinalState(&machine);
-        s2->addTransition(s2, SIGNAL(polished()), s3);
+        s2->addTransition(s2, SIGNAL(propertiesAssigned()), s3);
 
         machine.setInitialState(s1);
         QSignalSpy finishedSpy(&machine, SIGNAL(finished()));
@@ -1416,7 +1429,7 @@
         group.addAnimation(new QPropertyAnimation(&obj, "bar"));
         trans->addAnimation(&group);
         QFinalState *s3 = new QFinalState(&machine);
-        s2->addTransition(s2, SIGNAL(polished()), s3);
+        s2->addTransition(s2, SIGNAL(propertiesAssigned()), s3);
 
         machine.setInitialState(s1);
         QSignalSpy finishedSpy(&machine, SIGNAL(finished()));
@@ -1462,10 +1475,10 @@
         anim2.setDuration(250);
         trans->addAnimation(&anim2);
 
-        s21->addTransition(s21, SIGNAL(polished()), s22);
+        s21->addTransition(s21, SIGNAL(propertiesAssigned()), s22);
 
         QFinalState *s3 = new QFinalState(&machine);
-        s22->addTransition(s2, SIGNAL(polished()), s3);
+        s22->addTransition(s2, SIGNAL(propertiesAssigned()), s3);
 
         machine.setInitialState(s1);
         QSignalSpy finishedSpy(&machine, SIGNAL(finished()));
@@ -1502,13 +1515,13 @@
         machine.setInitialState(group);
         machine.start();
         QTRY_COMPARE(machine.configuration().contains(s1), true);
-        QSignalSpy polishedSpy(s2, SIGNAL(polished()));
+        QSignalSpy propertiesAssignedSpy(s2, SIGNAL(propertiesAssigned()));
         emitter.emitSignalWithNoArg();
         QTRY_COMPARE(machine.configuration().contains(s2), true);
-        QVERIFY(polishedSpy.isEmpty());
+        QVERIFY(propertiesAssignedSpy.isEmpty());
         emitter.emitSignalWithNoArg(); // will cause animations from s1-->s2 to abort
         QTRY_COMPARE(machine.configuration().contains(s3), true);
-        QVERIFY(polishedSpy.isEmpty());
+        QVERIFY(propertiesAssignedSpy.isEmpty());
         QCOMPARE(obj.property("foo").toInt(), 911);
         QCOMPARE(obj.property("bar").toInt(), 789);
     }
@@ -1681,6 +1694,22 @@
     QVERIFY(machine.configuration().contains(s1));
 }
 
+void tst_QStateMachine::stopAndPostEvent()
+{
+    QStateMachine machine;
+    QState *s1 = new QState(&machine);
+    machine.setInitialState(s1);
+    QSignalSpy startedSpy(&machine, SIGNAL(started()));
+    machine.start();
+    QTRY_COMPARE(startedSpy.count(), 1);
+    QSignalSpy stoppedSpy(&machine, SIGNAL(stopped()));
+    machine.stop();
+    QCOMPARE(stoppedSpy.count(), 0);
+    machine.postEvent(new QEvent(QEvent::User));
+    QTRY_COMPARE(stoppedSpy.count(), 1);
+    QCoreApplication::processEvents();
+}
+
 void tst_QStateMachine::stateFinished()
 {
     QStateMachine machine;
@@ -2709,10 +2738,10 @@
 
 }*/
 
-void tst_QStateMachine::globalRestorePolicySetToDoNotRestore()
+void tst_QStateMachine::globalRestorePolicySetToDontRestore()
 {
     QStateMachine machine;
-    machine.setGlobalRestorePolicy(QStateMachine::DoNotRestoreProperties);
+    machine.setGlobalRestorePolicy(QStateMachine::DontRestoreProperties);
 
     QObject *propertyHolder = new QObject(&machine);
     propertyHolder->setProperty("a", 1);
@@ -3062,7 +3091,7 @@
 
     QState *s3 = new QState(&machine);
     QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit()));
-    s2->addTransition(s2, SIGNAL(polished()), s3);
+    s2->addTransition(s2, SIGNAL(propertiesAssigned()), s3);
 
     machine.setInitialState(s1);
     machine.start();
@@ -3090,7 +3119,9 @@
     QState *s2 = new QState(&machine);
     s2->assignProperty(object, "foo", 5.0);
     QPropertyAnimation *fooAnimation = new QPropertyAnimation(object, "foo", s2);
-    s1->addTransition(new EventTransition(QEvent::User, s2))->addAnimation(fooAnimation);
+    EventTransition *trans = new EventTransition(QEvent::User, s2);
+    s1->addTransition(trans);
+    trans->addAnimation(fooAnimation);
 
     QState *s3 = new QState(&machine);
     QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit()));
@@ -3099,7 +3130,9 @@
     QState *s4 = new QState(&machine);
     s4->assignProperty(object, "foo", 2.0);
     QPropertyAnimation *fooAnimation2 = new QPropertyAnimation(object, "foo", s4);
-    s3->addTransition(new EventTransition(QEvent::User, s4))->addAnimation(fooAnimation2);
+    trans = new EventTransition(QEvent::User, s4);
+    s3->addTransition(trans);
+    trans->addAnimation(fooAnimation2);
 
     QState *s5 = new QState(&machine);
     QObject::connect(s5, SIGNAL(entered()), QApplication::instance(), SLOT(quit()));
@@ -3134,7 +3167,9 @@
     QState *s2 = new QState(&machine);
     s2->assignProperty(object, "foo", 5.0);
     QPropertyAnimation *fooAnimation = new QPropertyAnimation(object, "foo", s2);
-    s1->addTransition(new EventTransition(QEvent::User, s2))->addAnimation(fooAnimation);
+    EventTransition *trans = new EventTransition(QEvent::User, s2);
+    s1->addTransition(trans);
+    trans->addAnimation(fooAnimation);
 
     QState *s3 = new QState(&machine);
     QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit()));
@@ -3142,7 +3177,9 @@
 
     QState *s4 = new QState(&machine);
     s4->assignProperty(object, "foo", 2.0);
-    s3->addTransition(new EventTransition(QEvent::User, s4))->addAnimation(fooAnimation);
+    trans = new EventTransition(QEvent::User, s4);
+    s3->addTransition(trans);
+    trans->addAnimation(fooAnimation);
 
     QState *s5 = new QState(&machine);
     QObject::connect(s5, SIGNAL(entered()), QApplication::instance(), SLOT(quit()));
@@ -3186,14 +3223,16 @@
 
     QState *s2Child2 = new QState(s2);
     s2Child2->assignProperty(object, "bar", 11.0);
-    QAbstractTransition *at = s2Child->addTransition(new EventTransition(QEvent::User, s2Child2));
+    QAbstractTransition *at = new EventTransition(QEvent::User, s2Child2);
+    s2Child->addTransition(at);
 
     QPropertyAnimation *animation = new QPropertyAnimation(object, "bar", s2);
     animation->setDuration(2000);
     connect(animation, SIGNAL(finished()), &counter, SLOT(slot()));
     at->addAnimation(animation);
 
-    at = s1->addTransition(new EventTransition(QEvent::User, s2));
+    at = new EventTransition(QEvent::User, s2);
+    s1->addTransition(at);
 
     animation = new QPropertyAnimation(object, "foo", s2);
     connect(animation, SIGNAL(finished()), &counter, SLOT(slot()));
@@ -3204,7 +3243,7 @@
     at->addAnimation(animation);
 
     QState *s3 = new QState(&machine);
-    s2->addTransition(s2Child, SIGNAL(polished()), s3);
+    s2->addTransition(s2Child, SIGNAL(propertiesAssigned()), s3);
 
     QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit()));
 
@@ -3221,7 +3260,7 @@
     QCOMPARE(counter.counter, 2);
 }
 
-void tst_QStateMachine::polishedSignalTransitionsReuseAnimationGroup()
+void tst_QStateMachine::propertiesAssignedSignalTransitionsReuseAnimationGroup()
 {
     QStateMachine machine;
     QObject *object = new QObject(&machine);
@@ -3238,9 +3277,9 @@
     QParallelAnimationGroup animationGroup;
     animationGroup.addAnimation(new QPropertyAnimation(object, "foo"));
     QSignalSpy animationFinishedSpy(&animationGroup, SIGNAL(finished()));
-    s1->addTransition(s1, SIGNAL(polished()), s2)->addAnimation(&animationGroup);
-    s2->addTransition(s2, SIGNAL(polished()), s3)->addAnimation(&animationGroup);
-    s3->addTransition(s3, SIGNAL(polished()), s4);
+    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()));
@@ -3272,7 +3311,8 @@
     QState *s4 = new QState(&machine);
     QObject::connect(s4, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit()));
 
-    QAbstractTransition *at = s1->addTransition(new EventTransition(QEvent::User, s2));
+    QAbstractTransition *at = new EventTransition(QEvent::User, s2);
+    s1->addTransition(at);
     QPropertyAnimation *pa = new QPropertyAnimation(object, "foo", s2);
     connect(pa, SIGNAL(finished()), &counter, SLOT(slot()));
     at->addAnimation(pa);
@@ -3314,7 +3354,9 @@
 
     QPropertyAnimation *anim = new QPropertyAnimation(object, "foo");
     anim->setEndValue(10.0);
-    s1->addTransition(new EventTransition(QEvent::User, s2))->addAnimation(anim);
+    EventTransition *trans = new EventTransition(QEvent::User, s2);
+    s1->addTransition(trans);
+    trans->addAnimation(anim);
 
     QState *s3 = new QState(&machine);
     QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit()));
@@ -3468,7 +3510,8 @@
     QState *s3 = new QState(&machine);
     QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit()));
 
-    QAbstractTransition *at = s1->addTransition(new EventTransition(QEvent::User, s2));
+    QAbstractTransition *at = new EventTransition(QEvent::User, s2);
+    s1->addTransition(at);
 
     QPropertyAnimation *defaultAnimation = new QPropertyAnimation(object, "foo");
     connect(defaultAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot()));
@@ -4188,5 +4231,89 @@
     QCOMPARE(t1->eventSignalIndex, emitter.metaObject()->indexOfSignal("signalWithDefaultArg()"));
 }
 
+class EventPosterThread : public QThread
+{
+    Q_OBJECT
+public:
+    EventPosterThread(QStateMachine *machine, QObject *parent = 0)
+        : QThread(parent), m_machine(machine), m_count(0)
+    {
+        moveToThread(this);
+        QObject::connect(m_machine, SIGNAL(started()),
+                         this, SLOT(postEvent()));
+    }
+protected:
+    virtual void run()
+    {
+        exec();
+    }
+private Q_SLOTS:
+    void postEvent()
+    {
+        m_machine->postEvent(new QEvent(QEvent::User));
+        if (++m_count < 10000)
+            QTimer::singleShot(0, this, SLOT(postEvent()));
+        else
+            quit();
+    }
+private:
+    QStateMachine *m_machine;
+    int m_count;
+};
+
+void tst_QStateMachine::postEventFromOtherThread()
+{
+    QStateMachine machine;
+    EventPosterThread poster(&machine);
+    StringEventPoster *s1 = new StringEventPoster("foo", &machine);
+    s1->addTransition(new EventTransition(QEvent::User, s1));
+    QFinalState *f = new QFinalState(&machine);
+    s1->addTransition(&poster, SIGNAL(finished()), f);
+    machine.setInitialState(s1);
+
+    poster.start();
+
+    QSignalSpy finishedSpy(&machine, SIGNAL(finished()));
+    machine.start();
+    QTRY_COMPARE(finishedSpy.count(), 1);
+}
+
+void tst_QStateMachine::eventFilterForApplication()
+{
+    QStateMachine machine;
+
+    QState *s1 = new QState(&machine);
+    {
+        machine.setInitialState(s1);
+    }
+
+    QState *s2 = new QState(&machine);
+
+    QEventTransition *transition = new QEventTransition(QCoreApplication::instance(),
+                                                        QEvent::ApplicationActivate);
+    transition->setTargetState(s2);
+    s1->addTransition(transition);
+
+    machine.start();
+    QCoreApplication::processEvents();
+
+    QCOMPARE(machine.configuration().size(), 1);
+    QVERIFY(machine.configuration().contains(s1));
+
+    QCoreApplication::postEvent(QCoreApplication::instance(),
+                                new QEvent(QEvent::ApplicationActivate));
+    QCoreApplication::processEvents();
+
+    QCOMPARE(machine.configuration().size(), 1);
+    QVERIFY(machine.configuration().contains(s2));
+}
+
+void tst_QStateMachine::eventClassesExported()
+{
+    // make sure this links
+    QStateMachine::WrappedEvent *wrappedEvent = new QStateMachine::WrappedEvent(0, 0);
+    QStateMachine::SignalEvent *signalEvent = new QStateMachine::SignalEvent(0, 0, QList<QVariant>());
+}
+
 QTEST_MAIN(tst_QStateMachine)
 #include "tst_qstatemachine.moc"