diff options
author | Alexis Menard <alexis.menard@nokia.com> | 2009-05-12 12:51:15 (GMT) |
---|---|---|
committer | Alexis Menard <alexis.menard@nokia.com> | 2009-05-12 12:51:15 (GMT) |
commit | 90d801f05f64c645f0899e3d81b23ecf53bf4835 (patch) | |
tree | 14362a48f6c74709972ab1a92d7be81d910f788d /tests/auto | |
parent | 1898c46452beae9e28cf9be7851099b4b4d2779e (diff) | |
parent | c6add575d50ee30b19580fc2c1ebda5316a2f51b (diff) | |
download | Qt-90d801f05f64c645f0899e3d81b23ecf53bf4835.zip Qt-90d801f05f64c645f0899e3d81b23ecf53bf4835.tar.gz Qt-90d801f05f64c645f0899e3d81b23ecf53bf4835.tar.bz2 |
Merge branch 'kinetic-statemachine' of git@scm.dev.nokia.troll.no:qt/kinetic into kinetic-statemachine
Conflicts:
src/gui/graphicsview/qgraphicsitem.cpp
Diffstat (limited to 'tests/auto')
-rw-r--r-- | tests/auto/qanimationgroup/tst_qanimationgroup.cpp | 80 | ||||
-rw-r--r-- | tests/auto/qanimationstate/qanimationstate.pro | 5 | ||||
-rw-r--r-- | tests/auto/qanimationstate/tst_qanimationstate.cpp | 625 | ||||
-rw-r--r-- | tests/auto/qeasingcurve/tst_qeasingcurve.cpp | 199 | ||||
-rw-r--r-- | tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp | 30 | ||||
-rw-r--r-- | tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp | 67 | ||||
-rw-r--r-- | tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp | 88 | ||||
-rw-r--r-- | tests/auto/qstate/tst_qstate.cpp | 110 | ||||
-rw-r--r-- | tests/auto/qstatemachine/tst_qstatemachine.cpp | 1714 |
9 files changed, 1801 insertions, 1117 deletions
diff --git a/tests/auto/qanimationgroup/tst_qanimationgroup.cpp b/tests/auto/qanimationgroup/tst_qanimationgroup.cpp index ff5c3b4..2952a39 100644 --- a/tests/auto/qanimationgroup/tst_qanimationgroup.cpp +++ b/tests/auto/qanimationgroup/tst_qanimationgroup.cpp @@ -68,6 +68,8 @@ private slots: void statesAndSignals(); void setParentAutoAdd(); void beginNestedGroup(); + void addChildTwice(); + void loopWithoutStartValue(); }; tst_QAnimationGroup::tst_QAnimationGroup() @@ -207,7 +209,7 @@ void tst_QAnimationGroup::setCurrentTime() QVariantAnimation *a1_s_o1 = new QPropertyAnimation(&s_o1, "value"); QVariantAnimation *a2_s_o1 = new QPropertyAnimation(&s_o1, "value"); QVariantAnimation *a3_s_o1 = new QPropertyAnimation(&s_o1, "value"); - a2_s_o1->setIterationCount(3); + a2_s_o1->setLoopCount(3); sequence->addAnimation(a1_s_o1); sequence->addAnimation(a2_s_o1); sequence->addAnimation(a3_s_o1); @@ -224,7 +226,7 @@ void tst_QAnimationGroup::setCurrentTime() QVariantAnimation *a1_p_o1 = new QPropertyAnimation(&p_o1, "value"); QVariantAnimation *a1_p_o2 = new QPropertyAnimation(&p_o2, "value"); QVariantAnimation *a1_p_o3 = new QPropertyAnimation(&p_o3, "value"); - a1_p_o2->setIterationCount(3); + a1_p_o2->setLoopCount(3); parallel->addAnimation(a1_p_o1); parallel->addAnimation(a1_p_o2); parallel->addAnimation(a1_p_o3); @@ -233,7 +235,7 @@ void tst_QAnimationGroup::setCurrentTime() QCOMPARE(notTimeDriven->totalDuration(), -1); QVariantAnimation *loopsForever = new QPropertyAnimation(&t_o2, "value"); - loopsForever->setIterationCount(-1); + loopsForever->setLoopCount(-1); QCOMPARE(loopsForever->totalDuration(), -1); QParallelAnimationGroup group; @@ -281,11 +283,11 @@ void tst_QAnimationGroup::setCurrentTime() QCOMPARE(a1_s_o3->currentTime(), 0); QCOMPARE(a1_p_o1->currentTime(), 250); QCOMPARE(a1_p_o2->currentTime(), 0); - QCOMPARE(a1_p_o2->currentIteration(), 1); + QCOMPARE(a1_p_o2->currentLoop(), 1); QCOMPARE(a1_p_o3->currentTime(), 250); QCOMPARE(notTimeDriven->currentTime(), 250); QCOMPARE(loopsForever->currentTime(), 0); - QCOMPARE(loopsForever->currentIteration(), 1); + QCOMPARE(loopsForever->currentLoop(), 1); QCOMPARE(sequence->currentAnimation(), a2_s_o1); // Current time = 251 @@ -294,14 +296,14 @@ void tst_QAnimationGroup::setCurrentTime() QCOMPARE(sequence->currentTime(), 251); QCOMPARE(a1_s_o1->currentTime(), 250); QCOMPARE(a2_s_o1->currentTime(), 1); - QCOMPARE(a2_s_o1->currentIteration(), 0); + QCOMPARE(a2_s_o1->currentLoop(), 0); QCOMPARE(a3_s_o1->currentTime(), 0); QCOMPARE(sequence2->currentTime(), 251); QCOMPARE(a1_s_o2->currentTime(), 250); QCOMPARE(a1_s_o3->currentTime(), 1); QCOMPARE(a1_p_o1->currentTime(), 250); QCOMPARE(a1_p_o2->currentTime(), 1); - QCOMPARE(a1_p_o2->currentIteration(), 1); + QCOMPARE(a1_p_o2->currentLoop(), 1); QCOMPARE(a1_p_o3->currentTime(), 250); QCOMPARE(notTimeDriven->currentTime(), 251); QCOMPARE(loopsForever->currentTime(), 1); @@ -343,5 +345,69 @@ void tst_QAnimationGroup::beginNestedGroup() } } +void tst_QAnimationGroup::addChildTwice() +{ + QPropertyAnimation *subGroup; + QPropertyAnimation *subGroup2; + QAnimationGroup *parent = new QSequentialAnimationGroup(); + + subGroup = new QPropertyAnimation(); + subGroup->setParent(parent); + parent->addAnimation(subGroup); + QCOMPARE(parent->animationCount(), 1); + + parent->clearAnimations(); + + QCOMPARE(parent->animationCount(), 0); + + // adding the same item twice to a group will remove the item from its current position + // and append it to the end + subGroup = new QPropertyAnimation(parent); + subGroup2 = new QPropertyAnimation(parent); + + QCOMPARE(parent->animationCount(), 2); + QCOMPARE(parent->animationAt(0), subGroup); + QCOMPARE(parent->animationAt(1), subGroup2); + + parent->addAnimation(subGroup); + + QCOMPARE(parent->animationCount(), 2); + QCOMPARE(parent->animationAt(0), subGroup2); + QCOMPARE(parent->animationAt(1), subGroup); + + delete parent; +} + +void tst_QAnimationGroup::loopWithoutStartValue() +{ + QAnimationGroup *parent = new QSequentialAnimationGroup(); + QObject o; + o.setProperty("ole", 0); + QCOMPARE(o.property("ole").toInt(), 0); + + QPropertyAnimation anim1(&o, "ole"); + anim1.setEndValue(-50); + anim1.setDuration(100); + + QPropertyAnimation anim2(&o, "ole"); + anim2.setEndValue(50); + anim2.setDuration(100); + + parent->addAnimation(&anim1); + parent->addAnimation(&anim2); + + parent->setLoopCount(-1); + parent->start(); + + QVERIFY(anim1.startValue().isNull()); + QCOMPARE(anim1.currentValue().toInt(), 0); + QCOMPARE(parent->currentLoop(), 0); + + parent->setCurrentTime(200); + QCOMPARE(parent->currentLoop(), 1); + QCOMPARE(anim1.currentValue().toInt(), 50); + parent->stop(); +} + QTEST_MAIN(tst_QAnimationGroup) #include "tst_qanimationgroup.moc" diff --git a/tests/auto/qanimationstate/qanimationstate.pro b/tests/auto/qanimationstate/qanimationstate.pro deleted file mode 100644 index 8862c27..0000000 --- a/tests/auto/qanimationstate/qanimationstate.pro +++ /dev/null @@ -1,5 +0,0 @@ -load(qttest_p4) -QT = core -SOURCES += tst_qanimationstate.cpp - - diff --git a/tests/auto/qanimationstate/tst_qanimationstate.cpp b/tests/auto/qanimationstate/tst_qanimationstate.cpp deleted file mode 100644 index 085db24..0000000 --- a/tests/auto/qanimationstate/tst_qanimationstate.cpp +++ /dev/null @@ -1,625 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -****************************************************************************/ - -#include <QtTest/QtTest> -#include <QtCore/qstate.h> -#include <QtCore/qstatemachine.h> -#include <QtCore/qanimationstate.h> - -//TESTED_CLASS=QAnimationState -//TESTED_FILES= - -#define QTRY_COMPARE(__expr, __expected) \ - do { \ - const int __step = 50; \ - const int __timeout = 5000; \ - if ((__expr) != (__expected)) { \ - QTest::qWait(0); \ - } \ - for (int __i = 0; __i < __timeout && ((__expr) != (__expected)); __i+=__step) { \ - QTest::qWait(__step); \ - } \ - QCOMPARE(__expr, __expected); \ - } while(0) - - -class tst_QAnimationState : public QObject -{ - Q_OBJECT -public: - tst_QAnimationState(); - virtual ~tst_QAnimationState(); - -private slots: - void init(); - void cleanup(); - void construction(); - void noAnimation(); - void simpleAnimation(); - void twoAnimations(); - void reuseAnimation(); - void nestedTargetState(); - void parallelTargetState(); - void playTwice(); - void twoAnimatedTransitions(); - void globalRestoreProperty(); - void specificRestoreProperty(); - void someAnimationsNotSpecified(); - void someActionsNotAnimated(); - void specificTargetValueOfAnimation(); - void persistentTargetValueOfAnimation(); -}; - -tst_QAnimationState::tst_QAnimationState() -{ -} - -tst_QAnimationState::~tst_QAnimationState() -{ -} - -void tst_QAnimationState::init() -{ -} - -void tst_QAnimationState::cleanup() -{ -} - -void tst_QAnimationState::construction() -{ - QAnimationState as; -} - -class EventTransition : public QTransition -{ -public: - EventTransition(QEvent::Type type, QAbstractState *target) - : QTransition(), m_type(type) { - setTargetState(target); - } -protected: - virtual bool eventTest(QEvent *e) const { - return (e->type() == m_type); - } -private: - QEvent::Type m_type; -}; - -void tst_QAnimationState::noAnimation() -{ - QStateMachine machine; - - QState *s1 = new QState(machine.rootState()); - QState *s2 = new QState(machine.rootState()); - s2->setProperty("entered", false); - s2->setPropertyOnEntry(s2, "entered", true); - - s1->addAnimatedTransition(new EventTransition(QEvent::User, s2)); - s2->addTransition(new EventTransition(QEvent::User, s1)); - - machine.setInitialState(s1); - machine.start(); - QCoreApplication::processEvents(); - - QVERIFY(machine.configuration().contains(s1)); - - machine.postEvent(new QEvent(QEvent::User)); - - QTRY_COMPARE(s2->property("entered").toBool(), true); - QVERIFY(machine.configuration().contains(s2)); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - QVERIFY(machine.configuration().contains(s1)); - - s2->setProperty("entered", false); - machine.postEvent(new QEvent(QEvent::User)); - - QTRY_COMPARE(s2->property("entered").toBool(), true); - QVERIFY(machine.configuration().contains(s2)); -} - -class ValueCheckerState: public QState -{ -public: - ValueCheckerState(QState *parent) - : QState(parent) - { - } - - void addPropertyToCheck(const QObject *object, const char *propertyName) - { - m_objects.append(object); - m_propertyNames.append(propertyName); - valueOnEntry.append(QVariant()); - } - - QVariantList valueOnEntry; - -protected: - virtual void onEntry() - { - for (int i=0; i<m_objects.size(); ++i) - valueOnEntry[i] = m_objects.at(i)->property(m_propertyNames.at(i)); - - QState::onEntry(); - } - - QList<const QObject *> m_objects; - QList<QByteArray> m_propertyNames; - -}; - -void tst_QAnimationState::simpleAnimation() -{ - QStateMachine machine; - - QObject *object = new QObject(); - object->setProperty("fooBar", 1.0); - - QState *s1 = new QState(machine.rootState()); - ValueCheckerState *s2 = new ValueCheckerState(machine.rootState()); - s2->addPropertyToCheck(object, "fooBar"); - s2->setPropertyOnEntry(object, "fooBar", 2.0); - - QPropertyAnimation *animation = new QPropertyAnimation(object, "fooBar", s2); - s1->addAnimatedTransition(new EventTransition(QEvent::User, s2), animation); - - machine.setInitialState(s1); - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::User)); - - QTRY_COMPARE(s2->valueOnEntry.at(0).isValid(), true); - - QCOMPARE(s2->valueOnEntry.at(0).toDouble(), 2.0); -} - -void tst_QAnimationState::twoAnimations() -{ - QStateMachine machine; - - QObject *object = new QObject(); - object->setProperty("foo", 1.0); - object->setProperty("bar", 3.0); - - QState *s1 = new QState(machine.rootState()); - ValueCheckerState *s2 = new ValueCheckerState(machine.rootState()); - s2->addPropertyToCheck(object, "foo"); - s2->addPropertyToCheck(object, "bar"); - s2->setPropertyOnEntry(object, "foo", 2.0); - s2->setPropertyOnEntry(object, "bar", 10.0); - - QPropertyAnimation *animationFoo = new QPropertyAnimation(object, "foo", s2); - QPropertyAnimation *animationBar = new QPropertyAnimation(object, "bar", s2); - animationBar->setDuration(900); - QAnimationState *as = s1->addAnimatedTransition(new EventTransition(QEvent::User, s2)); - as->addAnimation(animationFoo); - as->addAnimation(animationBar); - - machine.setInitialState(s1); - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::User)); - - QTRY_COMPARE(s2->valueOnEntry.at(0).isValid(), true); - - QCOMPARE(s2->valueOnEntry.at(0).toDouble(), 2.0); - QCOMPARE(s2->valueOnEntry.at(1).toDouble(), 10.0); -} - -void tst_QAnimationState::parallelTargetState() -{ - QStateMachine machine; - - QObject *object = new QObject(); - object->setProperty("foo", 1.0); - object->setProperty("bar", 3.0); - - QState *s1 = new QState(machine.rootState()); - QState *s2 = new QState(QState::ParallelGroup, machine.rootState()); - - ValueCheckerState *c1 = new ValueCheckerState(s2); - c1->setPropertyOnEntry(object, "foo", 2.0); - c1->addPropertyToCheck(object, "foo"); - c1->addPropertyToCheck(object, "bar"); - - QState *c2 = new QState(s2); - c2->setPropertyOnEntry(object, "bar", 10.0); - - QAnimationState *as = s1->addAnimatedTransition(new EventTransition(QEvent::User, s2)); - as->addAnimation(new QPropertyAnimation(object, "foo", as)); - as->addAnimation(new QPropertyAnimation(object, "bar", as)); - - machine.setInitialState(s1); - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::User)); - - QTRY_COMPARE(c1->valueOnEntry.at(0).isValid(), true); - QCOMPARE(c1->valueOnEntry.at(0).toDouble(), 2.0); - QCOMPARE(c1->valueOnEntry.at(1).toDouble(), 10.0); -} - - -void tst_QAnimationState::twoAnimatedTransitions() -{ - QStateMachine machine; - - QObject *object = new QObject(); - object->setProperty("foo", 1.0); - - QState *s1 = new QState(machine.rootState()); - ValueCheckerState *s2 = new ValueCheckerState(machine.rootState()); - s2->addPropertyToCheck(object, "foo"); - s2->setPropertyOnEntry(object, "foo", 5.0); - ValueCheckerState *s3 = new ValueCheckerState(machine.rootState()); - s3->setPropertyOnEntry(object, "foo", 2.0); - s3->addPropertyToCheck(object, "foo"); - - s1->addAnimatedTransition(new EventTransition(QEvent::User, s2), - new QPropertyAnimation(object, "foo", s2)); - s2->addAnimatedTransition(new EventTransition(QEvent::User, s3), - new QPropertyAnimation(object, "foo", s2)); - - machine.setInitialState(s1); - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::User)); - QTRY_COMPARE(s2->valueOnEntry.at(0).isValid(), true); - QCOMPARE(s2->valueOnEntry.at(0).toDouble(), 5.0); - - machine.postEvent(new QEvent(QEvent::User)); - QTRY_COMPARE(s3->valueOnEntry.at(0).isValid(), true); - QCOMPARE(s3->valueOnEntry.at(0).toDouble(), 2.0); -} - -void tst_QAnimationState::playTwice() -{ - QStateMachine machine; - - QObject *object = new QObject(); - object->setProperty("foo", 1.0); - - QState *s1 = new QState(machine.rootState()); - ValueCheckerState *s2 = new ValueCheckerState(machine.rootState()); - s2->addPropertyToCheck(object, "foo"); - s2->setPropertyOnEntry(object, "foo", 5.0); - QState *s3 = new QState(machine.rootState()); - s3->setPropertyOnEntry(object, "foo", 2.0); - - s1->addAnimatedTransition(new EventTransition(QEvent::User, s2), - new QPropertyAnimation(object, "foo", s2)); - s2->addTransition(new EventTransition(QEvent::User, s3)); - s3->addTransition(s1); - - machine.setInitialState(s1); - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::User)); - QTRY_COMPARE(s2->valueOnEntry.at(0).isValid(), true); - QCOMPARE(s2->valueOnEntry.at(0).toDouble(), 5.0); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - QVERIFY(machine.configuration().contains(s1)); - QCOMPARE(object->property("foo").toDouble(), 2.0); - - s2->valueOnEntry[0] = QVariant(); - - machine.postEvent(new QEvent(QEvent::User)); - QTRY_COMPARE(s2->valueOnEntry.at(0).isValid(), true); - QCOMPARE(object->property("foo").toDouble(), 5.0); -} - -void tst_QAnimationState::nestedTargetState() -{ - QStateMachine machine; - - QObject *object = new QObject(); - object->setProperty("foo", 1.0); - object->setProperty("bar", 3.0); - - QState *s1 = new QState(machine.rootState()); - ValueCheckerState *s2 = new ValueCheckerState(machine.rootState()); - s2->addPropertyToCheck(object, "foo"); - s2->addPropertyToCheck(object, "bar"); - s2->setPropertyOnEntry(object, "foo", 2.0); - - QState *s2Child = new QState(s2); - s2Child->setPropertyOnEntry(object, "bar", 10.0); - s2->setInitialState(s2Child); - - QState *s2Child2 = new QState(s2); - s2Child2->setPropertyOnEntry(object, "bar", 11.0); - s2Child->addTransition(s2Child2); // should *not* be considered by QAnimationState as part of target - - QAnimationState *as = s1->addAnimatedTransition(new EventTransition(QEvent::User, s2)); - as->addAnimation(new QPropertyAnimation(object, "foo", as)); - as->addAnimation(new QPropertyAnimation(object, "bar", as)); - - machine.setInitialState(s1); - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::User)); - - QTRY_COMPARE(s2->valueOnEntry.at(0).isValid(), true); - - QCOMPARE(s2->valueOnEntry.at(0).toDouble(), 2.0); - QCOMPARE(s2->valueOnEntry.at(1).toDouble(), 10.0); - QCOMPARE(object->property("bar").toDouble(), 11.0); -} - -void tst_QAnimationState::reuseAnimation() -{ - QStateMachine machine; - - QObject *object = new QObject(); - object->setProperty("foo", 1.0); - - QState *s1 = new QState(machine.rootState()); - ValueCheckerState *s2 = new ValueCheckerState(machine.rootState()); - s2->addPropertyToCheck(object, "foo"); - s2->setPropertyOnEntry(object, "foo", 5.0); - ValueCheckerState *s3 = new ValueCheckerState(machine.rootState()); - s3->setPropertyOnEntry(object, "foo", 2.0); - s3->addPropertyToCheck(object, "foo"); - - QPropertyAnimation *anim = new QPropertyAnimation(object, "foo", s2); - s1->addAnimatedTransition(new EventTransition(QEvent::User, s2), anim); - s2->addAnimatedTransition(new EventTransition(QEvent::User, s3), anim); - - machine.setInitialState(s1); - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::User)); - QTRY_COMPARE(s2->valueOnEntry.at(0).isValid(), true); - QCOMPARE(s2->valueOnEntry.at(0).toDouble(), 5.0); - - machine.postEvent(new QEvent(QEvent::User)); - QTRY_COMPARE(s3->valueOnEntry.at(0).isValid(), true); - QCOMPARE(s3->valueOnEntry.at(0).toDouble(), 2.0); -} - -void tst_QAnimationState::globalRestoreProperty() -{ - QStateMachine machine; - machine.setGlobalRestorePolicy(QState::RestoreProperties); - - QObject *object = new QObject(); - object->setProperty("foo", 1.0); - object->setProperty("bar", 3.0); - - QState *s1 = new QState(machine.rootState()); - - ValueCheckerState *s2 = new ValueCheckerState(machine.rootState()); - s2->addPropertyToCheck(object, "foo"); - s2->addPropertyToCheck(object, "bar"); - s2->setPropertyOnEntry(object, "foo", 2.0); - - ValueCheckerState *s3 = new ValueCheckerState(machine.rootState()); - s3->addPropertyToCheck(object, "foo"); - s3->addPropertyToCheck(object, "bar"); - s3->setPropertyOnEntry(object, "bar", 5.0); - - ValueCheckerState *s4 = new ValueCheckerState(machine.rootState()); - s4->addPropertyToCheck(object, "foo"); - s4->addPropertyToCheck(object, "bar"); - - QAnimationState *as = s1->addAnimatedTransition(new EventTransition(QEvent::User, s2)); - as->addAnimation(new QPropertyAnimation(object, "foo", as)); - as->addAnimation(new QPropertyAnimation(object, "bar", as)); - - as = s2->addAnimatedTransition(new EventTransition(QEvent::User, s3)); - as->addAnimation(new QPropertyAnimation(object, "foo", as)); - as->addAnimation(new QPropertyAnimation(object, "bar", as)); - - as = s3->addAnimatedTransition(new EventTransition(QEvent::User, s4)); - as->addAnimation(new QPropertyAnimation(object, "foo", as)); - as->addAnimation(new QPropertyAnimation(object, "bar", as)); - - machine.setInitialState(s1); - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::User)); - QTRY_COMPARE(s2->valueOnEntry.at(0).isValid(), true); - QCOMPARE(s2->valueOnEntry.at(0).toDouble(), 2.0); - QCOMPARE(s2->valueOnEntry.at(1).toDouble(), 3.0); - - machine.postEvent(new QEvent(QEvent::User)); - QTRY_COMPARE(s3->valueOnEntry.at(0).isValid(), true); - QCOMPARE(s3->valueOnEntry.at(0).toDouble(), 1.0); - QCOMPARE(s3->valueOnEntry.at(1).toDouble(), 5.0); - - machine.postEvent(new QEvent(QEvent::User)); - QTRY_COMPARE(s4->valueOnEntry.at(0).isValid(), true); - QCOMPARE(s4->valueOnEntry.at(0).toDouble(), 1.0); - QCOMPARE(s4->valueOnEntry.at(1).toDouble(), 3.0); - -} - -void tst_QAnimationState::specificRestoreProperty() -{ - QStateMachine machine; - - QObject *object = new QObject(); - object->setProperty("foo", 1.0); - object->setProperty("bar", 3.0); - - QState *s1 = new QState(machine.rootState()); - - ValueCheckerState *s2 = new ValueCheckerState(machine.rootState()); - s2->setRestorePolicy(QState::RestoreProperties); - s2->addPropertyToCheck(object, "foo"); - s2->addPropertyToCheck(object, "bar"); - s2->setPropertyOnEntry(object, "foo", 2.0); - - ValueCheckerState *s3 = new ValueCheckerState(machine.rootState()); - s3->setRestorePolicy(QState::RestoreProperties); - s3->addPropertyToCheck(object, "foo"); - s3->addPropertyToCheck(object, "bar"); - s3->setPropertyOnEntry(object, "bar", 5.0); - - ValueCheckerState *s4 = new ValueCheckerState(machine.rootState()); - s4->setRestorePolicy(QState::RestoreProperties); - s4->addPropertyToCheck(object, "foo"); - s4->addPropertyToCheck(object, "bar"); - - QAnimationState *as = s1->addAnimatedTransition(new EventTransition(QEvent::User, s2)); - as->addAnimation(new QPropertyAnimation(object, "foo", as)); - - as = s2->addAnimatedTransition(new EventTransition(QEvent::User, s3)); - as->addAnimation(new QPropertyAnimation(object, "bar", as)); - - as = s3->addAnimatedTransition(new EventTransition(QEvent::User, s4)); - - machine.setInitialState(s1); - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::User)); - QTRY_COMPARE(s2->valueOnEntry.at(0).isValid(), true); - QCOMPARE(s2->valueOnEntry.at(0).toDouble(), 2.0); - QCOMPARE(s2->valueOnEntry.at(1).toDouble(), 3.0); - - machine.postEvent(new QEvent(QEvent::User)); - QTRY_COMPARE(s3->valueOnEntry.at(0).isValid(), true); - QCOMPARE(s3->valueOnEntry.at(0).toDouble(), 1.0); - QCOMPARE(s3->valueOnEntry.at(1).toDouble(), 5.0); - - machine.postEvent(new QEvent(QEvent::User)); - QTRY_COMPARE(s4->valueOnEntry.at(0).isValid(), true); - QCOMPARE(s4->valueOnEntry.at(0).toDouble(), 1.0); - QCOMPARE(s4->valueOnEntry.at(1).toDouble(), 3.0); -} - -void tst_QAnimationState::someAnimationsNotSpecified() -{ - QStateMachine machine; - - QObject *object = new QObject(); - object->setProperty("foo", 1.0); - object->setProperty("bar", 3.0); - - QState *s1 = new QState(machine.rootState()); - - ValueCheckerState *s2 = new ValueCheckerState(machine.rootState()); - s2->addPropertyToCheck(object, "foo"); - s2->addPropertyToCheck(object, "bar"); - s2->setPropertyOnEntry(object, "foo", 2.0); - - QAnimationState *as = s1->addAnimatedTransition(new EventTransition(QEvent::User, s2)); - as->addAnimation(new QPropertyAnimation(object, "foo", as)); - as->addAnimation(new QPropertyAnimation(object, "bar", as)); - - machine.setInitialState(s1); - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::User)); - QTRY_COMPARE(s2->valueOnEntry.at(0).isValid(), true); - QCOMPARE(s2->valueOnEntry.at(0).toDouble(), 2.0); - QCOMPARE(s2->valueOnEntry.at(1).toDouble(), 3.0); -} - -void tst_QAnimationState::someActionsNotAnimated() -{ - QStateMachine machine; - - QObject *object = new QObject(); - object->setProperty("foo", 1.0); - object->setProperty("bar", 3.0); - - QState *s1 = new QState(machine.rootState()); - - ValueCheckerState *s2 = new ValueCheckerState(machine.rootState()); - s2->addPropertyToCheck(object, "foo"); - s2->addPropertyToCheck(object, "bar"); - s2->setPropertyOnEntry(object, "foo", 2.0); - s2->setPropertyOnEntry(object, "bar", 5.0); - - s1->addAnimatedTransition(new EventTransition(QEvent::User, s2), - new QPropertyAnimation(object, "foo", s1)); - - machine.setInitialState(s1); - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::User)); - QTRY_COMPARE(s2->valueOnEntry.at(0).isValid(), true); - QCOMPARE(s2->valueOnEntry.at(0).toDouble(), 2.0); - QCOMPARE(s2->valueOnEntry.at(1).toDouble(), 3.0); - QCOMPARE(object->property("foo").toDouble(), 2.0); - QCOMPARE(object->property("bar").toDouble(), 5.0); -} - -void tst_QAnimationState::specificTargetValueOfAnimation() -{ - QStateMachine machine; - - QObject *object = new QObject(); - object->setProperty("foo", 1.0); - - QState *s1 = new QState(machine.rootState()); - - ValueCheckerState *s2 = new ValueCheckerState(machine.rootState()); - s2->addPropertyToCheck(object, "foo"); - s2->setPropertyOnEntry(object, "foo", 2.0); - - QPropertyAnimation *anim = new QPropertyAnimation(object, "foo"); - anim->setEndValue(10.0); - s1->addAnimatedTransition(new EventTransition(QEvent::User, s2), anim); - - machine.setInitialState(s1); - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::User)); - QTRY_COMPARE(s2->valueOnEntry.at(0).isValid(), true); - QCOMPARE(s2->valueOnEntry.at(0).toDouble(), 10.0); - QCOMPARE(object->property("foo").toDouble(), 2.0); -} - -void tst_QAnimationState::persistentTargetValueOfAnimation() -{ - QStateMachine machine; - - QObject *object = new QObject(); - object->setProperty("foo", 1.0); - - QState *s1 = new QState(machine.rootState()); - - ValueCheckerState *s2 = new ValueCheckerState(machine.rootState()); - s2->addPropertyToCheck(object, "foo"); - s2->setPropertyOnEntry(object, "foo", 2.0); - - QPropertyAnimation *anim = new QPropertyAnimation(object, "foo"); - s1->addAnimatedTransition(new EventTransition(QEvent::User, s2), anim); - - machine.setInitialState(s1); - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::User)); - QTRY_COMPARE(s2->valueOnEntry.at(0).isValid(), true); - QCOMPARE(s2->valueOnEntry.at(0).toDouble(), 2.0); - QCOMPARE(anim->endValue().isValid(), false); -} - - -QTEST_MAIN(tst_QAnimationState) -#include "tst_qanimationstate.moc" diff --git a/tests/auto/qeasingcurve/tst_qeasingcurve.cpp b/tests/auto/qeasingcurve/tst_qeasingcurve.cpp index 9e3ffcc..8d42e5e 100644 --- a/tests/auto/qeasingcurve/tst_qeasingcurve.cpp +++ b/tests/auto/qeasingcurve/tst_qeasingcurve.cpp @@ -96,17 +96,17 @@ void tst_QEasingCurve::type() QEasingCurve curve(QEasingCurve::Linear); QCOMPARE(curve.period(), 0.3); QCOMPARE(curve.amplitude(), 1.0); - + curve.setPeriod(5); curve.setAmplitude(3); QCOMPARE(curve.period(), 5.0); QCOMPARE(curve.amplitude(), 3.0); - + curve.setType(QEasingCurve::InElastic); QCOMPARE(curve.period(), 5.0); QCOMPARE(curve.amplitude(), 3.0); } - + { QEasingCurve curve(QEasingCurve::InElastic); QCOMPARE(curve.period(), 0.3); @@ -132,7 +132,7 @@ void tst_QEasingCurve::type() QTest::ignoreMessage(QtWarningMsg, QString::fromAscii("QEasingCurve: Invalid curve type %1") .arg(QEasingCurve::Custom).toLatin1().constData()); curve.setType(QEasingCurve::Custom); - QCOMPARE(curve.type(), QEasingCurve::InCubic); + QCOMPARE(curve.type(), QEasingCurve::InCubic); QTest::ignoreMessage(QtWarningMsg, QString::fromAscii("QEasingCurve: Invalid curve type %1") .arg(-1).toLatin1().constData()); curve.setType((QEasingCurve::Type)-1); @@ -191,185 +191,184 @@ void tst_QEasingCurve::valueForProgress_data() // integer values and avoid fp inaccuracies QTest::newRow("Linear") << int(QEasingCurve::Linear) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100); QTest::newRow("InQuad") << int(QEasingCurve::InQuad) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 4 << 16 << 36 << 64 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 1 << 4 << 9 << 16 << 25 << 36 << 48 << 64 << 81 << 100); QTest::newRow("OutQuad") << int(QEasingCurve::OutQuad) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 36 << 64 << 84 << 96 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 19 << 36 << 51 << 64 << 75 << 84 << 90 << 96 << 99 << 100); QTest::newRow("InOutQuad") << int(QEasingCurve::InOutQuad) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 8 << 32 << 68 << 92 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 2 << 8 << 18 << 32 << 50 << 68 << 82 << 92 << 98 << 100); QTest::newRow("OutInQuad") << int(QEasingCurve::OutInQuad) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 32 << 48 << 52 << 68 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 18 << 32 << 42 << 48 << 50 << 52 << 57 << 68 << 82 << 100); QTest::newRow("InCubic") << int(QEasingCurve::InCubic) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 0 << 6 << 21 << 51 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 0 << 0 << 2 << 6 << 12 << 21 << 34 << 51 << 72 << 100); QTest::newRow("OutCubic") << int(QEasingCurve::OutCubic) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 48 << 78 << 93 << 99 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 27 << 48 << 65 << 78 << 87 << 93 << 97 << 99 << 99 << 100); QTest::newRow("InOutCubic") << int(QEasingCurve::InOutCubic) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 3 << 25 << 74 << 96 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 0 << 3 << 10 << 25 << 50 << 74 << 89 << 96 << 99 << 100); QTest::newRow("OutInCubic") << int(QEasingCurve::OutInCubic) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 39 << 49 << 50 << 60 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 24 << 39 << 46 << 49 << 50 << 50 << 53 << 60 << 75 << 100); QTest::newRow("InQuart") << int(QEasingCurve::InQuart) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 0 << 2 << 12 << 40 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 0 << 0 << 0 << 2 << 6 << 12 << 24 << 40 << 65 << 100); QTest::newRow("OutQuart") << int(QEasingCurve::OutQuart) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 59 << 87 << 97 << 99 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 34 << 59 << 75 << 87 << 93 << 97 << 99 << 99 << 99 << 100); QTest::newRow("InOutQuart") << int(QEasingCurve::InOutQuart) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 1 << 20 << 79 << 98 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 0 << 1 << 6 << 20 << 50 << 79 << 93 << 98 << 99 << 100); QTest::newRow("OutInQuart") << int(QEasingCurve::OutInQuart) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 43 << 49 << 50 << 56 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 29 << 43 << 48 << 49 << 50 << 50 << 51 << 56 << 70 << 100); QTest::newRow("InQuint") << int(QEasingCurve::InQuint) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 0 << 1 << 7 << 32 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 0 << 0 << 0 << 1 << 3 << 7 << 16 << 32 << 59 << 100); QTest::newRow("OutQuint") << int(QEasingCurve::OutQuint) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 67 << 92 << 98 << 99 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 40 << 67 << 83 << 92 << 96 << 98 << 99 << 99 << 99 << 100); QTest::newRow("InOutQuint") << int(QEasingCurve::InOutQuint) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 0 << 16 << 83 << 99 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 0 << 0 << 3 << 16 << 50 << 83 << 96 << 99 << 99 << 100); QTest::newRow("OutInQuint") << int(QEasingCurve::OutInQuint) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 46 << 49 << 50 << 53 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 33 << 46 << 49 << 49 << 50 << 50 << 50 << 53 << 66 << 100); QTest::newRow("InSine") << int(QEasingCurve::InSine) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 4 << 19 << 41 << 69 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 1 << 4 << 10 << 19 << 29 << 41 << 54 << 69 << 84 << 100); QTest::newRow("OutSine") << int(QEasingCurve::OutSine) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 30 << 58 << 80 << 95 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 15 << 30 << 45 << 58 << 70 << 80 << 89 << 95 << 98 << 100); QTest::newRow("InOutSine") << int(QEasingCurve::InOutSine) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 9 << 34 << 65 << 90 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 2 << 9 << 20 << 34 << 49 << 65 << 79 << 90 << 97 << 100); QTest::newRow("OutInSine") << int(QEasingCurve::OutInSine) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 29 << 47 << 52 << 70 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 15 << 29 << 40 << 47 << 50 << 52 << 59 << 70 << 84 << 100); QTest::newRow("InExpo") << int(QEasingCurve::InExpo) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 0 << 1 << 6 << 24 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 0 << 0 << 0 << 1 << 3 << 6 << 12 << 24 << 49 << 100); QTest::newRow("OutExpo") << int(QEasingCurve::OutExpo) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 75 << 93 << 98 << 99 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 50 << 75 << 87 << 93 << 96 << 98 << 99 << 99 << 99 << 100); QTest::newRow("InOutExpo") << int(QEasingCurve::InOutExpo) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 0 << 12 << 87 << 99 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 0 << 0 << 3 << 12 << 50 << 87 << 96 << 99 << 99 << 100); QTest::newRow("OutInExpo") << int(QEasingCurve::OutInExpo) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 46 << 49 << 50 << 53 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 37 << 46 << 49 << 49 << 50 << 50 << 50 << 53 << 62 << 100); QTest::newRow("InCirc") << int(QEasingCurve::InCirc) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 2 << 8 << 19 << 40 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 0 << 2 << 4 << 8 << 13 << 19 << 28 << 40 << 56 << 100); QTest::newRow("OutCirc") << int(QEasingCurve::OutCirc) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 59 << 80 << 91 << 97 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 43 << 59 << 71 << 80 << 86 << 91 << 95 << 97 << 99 << 100); QTest::newRow("InOutCirc") << int(QEasingCurve::InOutCirc) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 4 << 20 << 80 << 95 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 1 << 4 << 9 << 20 << 50 << 80 << 89 << 95 << 98 << 100); QTest::newRow("OutInCirc") << int(QEasingCurve::OutInCirc) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 40 << 48 << 51 << 60 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 29 << 40 << 45 << 48 << 50 << 51 << 54 << 60 << 70 << 100); QTest::newRow("InElastic") << int(QEasingCurve::InElastic) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 0 << 1 << -3 << -12 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 0 << 0 << 0 << 1 << -1 << -3 << 12 << -12 << -25 << 100); QTest::newRow("OutElastic") << int(QEasingCurve::OutElastic) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 112 << 103 << 98 << 100 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 125 << 112 << 87 << 103 << 101 << 98 << 100 << 100 << 99 << 100); QTest::newRow("InOutElastic") << int(QEasingCurve::InOutElastic) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 0 << -6 << 106 << 99 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 0 << 0 << -1 << -6 << 50 << 106 << 101 << 99 << 100 << 100); QTest::newRow("OutInElastic") << int(QEasingCurve::OutInElastic) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 56 << 49 << 49 << 53 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 37 << 56 << 49 << 49 << 50 << 49 << 50 << 53 << 24 << 100); QTest::newRow("InBack") << int(QEasingCurve::InBack) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << -4 << -9 << -2 << 29 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << -1 << -4 << -8 << -9 << -8 << -2 << 9 << 29 << 59 << 100); QTest::newRow("OutBack") << int(QEasingCurve::OutBack) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 70 << 102 << 109 << 104 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 40 << 70 << 90 << 102 << 108 << 109 << 108 << 104 << 101 << 100); QTest::newRow("InOutBack") << int(QEasingCurve::InOutBack) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << -9 << 8 << 91 << 109 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << -3 << -9 << -7 << 8 << 50 << 91 << 107 << 109 << 103 << 100); QTest::newRow("OutInBack") << int(QEasingCurve::OutInBack) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 51 << 52 << 47 << 48 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 35 << 51 << 54 << 52 << 50 << 47 << 45 << 48 << 64 << 100); QTest::newRow("InBounce") << int(QEasingCurve::InBounce) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 6 << 22 << 8 << 69 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 1 << 6 << 6 << 22 << 23 << 9 << 31 << 69 << 92 << 100); QTest::newRow("OutBounce") << int(QEasingCurve::OutBounce) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 30 << 91 << 77 << 93 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 7 << 30 << 68 << 90 << 76 << 77 << 93 << 94 << 98 << 100); QTest::newRow("InOutBounce") << int(QEasingCurve::InOutBounce) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 11 << 34 << 65 << 88 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 3 << 11 << 4 << 34 << 50 << 65 << 95 << 88 << 97 << 100); QTest::newRow("OutInBounce") << int(QEasingCurve::OutInBounce) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 41 << 43 << 56 << 58 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 15 << 40 << 27 << 43 << 50 << 56 << 72 << 58 << 84 << 100); QTest::newRow("InCurve") << int(QEasingCurve::InCurve) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 10 << 37 << 60 << 80 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 2 << 10 << 23 << 37 << 50 << 60 << 70 << 80 << 90 << 100); QTest::newRow("OutCurve") << int(QEasingCurve::OutCurve) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 20 << 39 << 62 << 89 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 10 << 20 << 30 << 39 << 50 << 62 << 76 << 89 << 97 << 100); QTest::newRow("SineCurve") << int(QEasingCurve::SineCurve) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 0 << 34 << 90 << 90 << 34 << 0); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 9 << 34 << 65 << 90 << 100 << 90 << 65 << 34 << 9 << 0); QTest::newRow("CosineCurve") << int(QEasingCurve::CosineCurve) - << (IntList() << 0 << 20 << 40 << 60 << 80 << 100) - << (IntList() << 50 << 97 << 79 << 20 << 2 << 49); - + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 50 << 79 << 97 << 97 << 79 << 50 << 20 << 2 << 2 << 20 << 49); } @@ -386,12 +385,12 @@ void tst_QEasingCurve::valueForProgress() QString strCurve = QLatin1String(mo.enumerator(mo.indexOfEnumerator("Type")).key(c)); QString strInputs; QString strOutputs; - - for (int t = 0; t <= 100; t+= 20) { + + for (int t = 0; t <= 100; t+= 10) { qreal ease = curve.valueForProgress(t/qreal(100)); strInputs += QString::fromAscii(" << %1").arg(t); strOutputs += QString::fromAscii(" << %1").arg(int(100*ease)); - + } QString str = QString::fromAscii(" QTest::newRow(\"%1\") << int(QEasingCurve::%2)\n" "\t\t << (IntList() %3)\n" @@ -460,14 +459,14 @@ void tst_QEasingCurve::operators() QCOMPARE(curve2.valueForProgress(0.25), 0.2); QCOMPARE(curve2.valueForProgress(0.35), 0.3); QCOMPARE(curve2.valueForProgress(0.999999), 0.9); - + // operator== curve.setType(QEasingCurve::InBack); curve2 = curve; curve2.setOvershoot(qreal(1.70158f)); QCOMPARE(curve.overshoot(), curve2.overshoot()); QVERIFY(curve2 == curve); - + curve.setOvershoot(3.0); QVERIFY(curve2 != curve); curve2.setOvershoot(3.0); diff --git a/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp b/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp index c7f33b7..f2ab57a 100644 --- a/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp +++ b/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp @@ -71,8 +71,8 @@ private slots: void startGroupWithRunningChild(); void zeroDurationAnimation(); void stopUncontrolledAnimations(); - void iterationCount_data(); - void iterationCount(); + void loopCount_data(); + void loopCount(); void autoAdd(); }; @@ -194,7 +194,7 @@ void tst_QParallelAnimationGroup::setCurrentTime() QVariantAnimation *a1_p_o1 = new QPropertyAnimation(&p_o1, "value"); QVariantAnimation *a1_p_o2 = new QPropertyAnimation(&p_o2, "value"); QVariantAnimation *a1_p_o3 = new QPropertyAnimation(&p_o3, "value"); - a1_p_o2->setIterationCount(3); + a1_p_o2->setLoopCount(3); parallel->addAnimation(a1_p_o1); parallel->addAnimation(a1_p_o2); parallel->addAnimation(a1_p_o3); @@ -203,7 +203,7 @@ void tst_QParallelAnimationGroup::setCurrentTime() QCOMPARE(notTimeDriven->totalDuration(), -1); QVariantAnimation *loopsForever = new QPropertyAnimation(&t_o2, "value"); - loopsForever->setIterationCount(-1); + loopsForever->setLoopCount(-1); QCOMPARE(loopsForever->totalDuration(), -1); QParallelAnimationGroup group; @@ -233,18 +233,18 @@ void tst_QParallelAnimationGroup::setCurrentTime() QCOMPARE(group.currentTime(), 250); QCOMPARE(a1_p_o1->currentTime(), 250); QCOMPARE(a1_p_o2->currentTime(), 0); - QCOMPARE(a1_p_o2->currentIteration(), 1); + QCOMPARE(a1_p_o2->currentLoop(), 1); QCOMPARE(a1_p_o3->currentTime(), 250); QCOMPARE(notTimeDriven->currentTime(), 250); QCOMPARE(loopsForever->currentTime(), 0); - QCOMPARE(loopsForever->currentIteration(), 1); + QCOMPARE(loopsForever->currentLoop(), 1); // Current time = 251 group.setCurrentTime(251); QCOMPARE(group.currentTime(), 251); QCOMPARE(a1_p_o1->currentTime(), 250); QCOMPARE(a1_p_o2->currentTime(), 1); - QCOMPARE(a1_p_o2->currentIteration(), 1); + QCOMPARE(a1_p_o2->currentLoop(), 1); QCOMPARE(a1_p_o3->currentTime(), 250); QCOMPARE(notTimeDriven->currentTime(), 251); QCOMPARE(loopsForever->currentTime(), 1); @@ -589,7 +589,7 @@ void tst_QParallelAnimationGroup::zeroDurationAnimation() group.stop(); - group.setIterationCount(4); + group.setLoopCount(4); stateChangedSpy1.clear(); stateChangedSpy2.clear(); @@ -625,7 +625,7 @@ void tst_QParallelAnimationGroup::stopUncontrolledAnimations() loopsForever.setStartValue(0); loopsForever.setEndValue(100); loopsForever.setDuration(100); - loopsForever.setIterationCount(-1); + loopsForever.setLoopCount(-1); QSignalSpy stateChangedSpy(&anim1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); @@ -670,10 +670,10 @@ struct AnimState { #define Stopped QAbstractAnimation::Stopped Q_DECLARE_METATYPE(AnimState) -void tst_QParallelAnimationGroup::iterationCount_data() +void tst_QParallelAnimationGroup::loopCount_data() { QTest::addColumn<bool>("directionBackward"); - QTest::addColumn<int>("setIterationCount"); + QTest::addColumn<int>("setLoopCount"); QTest::addColumn<int>("initialGroupTime"); QTest::addColumn<int>("currentGroupTime"); QTest::addColumn<AnimState>("expected1"); @@ -742,10 +742,10 @@ void tst_QParallelAnimationGroup::iterationCount_data() } -void tst_QParallelAnimationGroup::iterationCount() +void tst_QParallelAnimationGroup::loopCount() { QFETCH(bool, directionBackward); - QFETCH(int, setIterationCount); + QFETCH(int, setLoopCount); QFETCH(int, initialGroupTime); QFETCH(int, currentGroupTime); QFETCH(AnimState, expected1); @@ -763,7 +763,7 @@ void tst_QParallelAnimationGroup::iterationCount() anim2.setStartValue(0); anim2.setEndValue(100); anim2.setDuration(60); //total 120 - anim2.setIterationCount(2); + anim2.setLoopCount(2); TestAnimation anim3; anim3.setStartValue(0); @@ -774,7 +774,7 @@ void tst_QParallelAnimationGroup::iterationCount() group.addAnimation(&anim2); group.addAnimation(&anim3); - group.setIterationCount(setIterationCount); + group.setLoopCount(setLoopCount); if (initialGroupTime >= 0) group.setCurrentTime(initialGroupTime); if (directionBackward) diff --git a/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp b/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp index f61df49..2e5fd00 100644 --- a/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp +++ b/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp @@ -42,7 +42,6 @@ #include <QtTest/QtTest> #include <QtCore/qpropertyanimation.h> -#include <QtGui/qitemanimation.h> #include <QtGui/qwidget.h> //TESTED_CLASS=QPropertyAnimation @@ -85,6 +84,7 @@ private slots: void deletion3(); void duration0(); void noStartValue(); + void noStartValueWithLoop(); void startWhenAnotherIsRunning(); void easingcurve_data(); void easingcurve(); @@ -144,7 +144,7 @@ void tst_QPropertyAnimation::construction() void tst_QPropertyAnimation::setCurrentTime_data() { QTest::addColumn<int>("duration"); - QTest::addColumn<int>("iterationCount"); + QTest::addColumn<int>("loopCount"); QTest::addColumn<int>("currentTime"); QTest::addColumn<int>("testCurrentTime"); QTest::addColumn<int>("testCurrentLoop"); @@ -177,7 +177,7 @@ void tst_QPropertyAnimation::setCurrentTime_data() void tst_QPropertyAnimation::setCurrentTime() { QFETCH(int, duration); - QFETCH(int, iterationCount); + QFETCH(int, loopCount); QFETCH(int, currentTime); QFETCH(int, testCurrentTime); QFETCH(int, testCurrentLoop); @@ -186,11 +186,11 @@ void tst_QPropertyAnimation::setCurrentTime() if (duration < 0) QTest::ignoreMessage(QtWarningMsg, "QVariantAnimation::setDuration: cannot set a negative duration"); animation.setDuration(duration); - animation.setIterationCount(iterationCount); + animation.setLoopCount(loopCount); animation.setCurrentTime(currentTime); QCOMPARE(animation.currentTime(), testCurrentTime); - QCOMPARE(animation.currentIteration(), testCurrentLoop); + QCOMPARE(animation.currentLoop(), testCurrentLoop); } void tst_QPropertyAnimation::statesAndSignals_data() @@ -208,7 +208,7 @@ void tst_QPropertyAnimation::statesAndSignals() QSignalSpy finishedSpy(anim, SIGNAL(finished())); QSignalSpy runningSpy(anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); - QSignalSpy currentLoopSpy(anim, SIGNAL(currentIterationChanged(int))); + QSignalSpy currentLoopSpy(anim, SIGNAL(currentLoopChanged(int))); anim->setCurrentTime(1); anim->setCurrentTime(100); @@ -217,23 +217,23 @@ void tst_QPropertyAnimation::statesAndSignals() QCOMPARE(currentLoopSpy.count(), 0); QCOMPARE(anim->state(), QAnimationGroup::Stopped); - anim->setIterationCount(3); + anim->setLoopCount(3); anim->setCurrentTime(101); if (uncontrolled) QSKIP("Uncontrolled animations don't handle looping", SkipSingle); QCOMPARE(currentLoopSpy.count(), 1); - QCOMPARE(anim->currentIteration(), 1); + QCOMPARE(anim->currentLoop(), 1); anim->setCurrentTime(0); QCOMPARE(currentLoopSpy.count(), 2); - QCOMPARE(anim->currentIteration(), 0); + QCOMPARE(anim->currentLoop(), 0); anim->start(); QCOMPARE(anim->state(), QAnimationGroup::Running); QCOMPARE(runningSpy.count(), 1); //anim must have started - QCOMPARE(anim->currentIteration(), 0); + QCOMPARE(anim->currentLoop(), 0); runningSpy.clear(); anim->stop(); @@ -241,7 +241,7 @@ void tst_QPropertyAnimation::statesAndSignals() QCOMPARE(runningSpy.count(), 1); //anim must have stopped QCOMPARE(finishedSpy.count(), 0); QCOMPARE(anim->currentTime(), 0); - QCOMPARE(anim->currentIteration(), 0); + QCOMPARE(anim->currentLoop(), 0); QCOMPARE(currentLoopSpy.count(), 2); runningSpy.clear(); @@ -252,24 +252,24 @@ void tst_QPropertyAnimation::statesAndSignals() runningSpy.clear(); QCOMPARE(finishedSpy.count(), 1); QCOMPARE(anim->currentTime(), 100); - QCOMPARE(anim->currentIteration(), 2); + QCOMPARE(anim->currentLoop(), 2); QCOMPARE(currentLoopSpy.count(), 4); anim->start(); // auto-rewinds QCOMPARE(anim->state(), QAnimationGroup::Running); QCOMPARE(anim->currentTime(), 0); - QCOMPARE(anim->currentIteration(), 0); + QCOMPARE(anim->currentLoop(), 0); QCOMPARE(currentLoopSpy.count(), 5); QCOMPARE(runningSpy.count(), 1); // anim has started QCOMPARE(finishedSpy.count(), 1); - QCOMPARE(anim->currentIteration(), 0); + QCOMPARE(anim->currentLoop(), 0); runningSpy.clear(); QTest::qWait(1000); QCOMPARE(currentLoopSpy.count(), 7); QCOMPARE(anim->state(), QAnimationGroup::Stopped); - QCOMPARE(anim->currentIteration(), 2); + QCOMPARE(anim->currentLoop(), 2); QCOMPARE(runningSpy.count(), 1); // anim has stopped QCOMPARE(finishedSpy.count(), 2); QCOMPARE(anim->currentTime(), 100); @@ -340,7 +340,7 @@ void tst_QPropertyAnimation::deletion2() QCOMPARE(runningSpy.count(), 1); QCOMPARE(finishedSpy.count(), 0); - //we can't call deletaLater directly because the delete would only happen in the next iteration of _this_ event loop + //we can't call deletaLater directly because the delete would only happen in the next loop of _this_ event loop QTimer::singleShot(0, object, SLOT(deleteLater())); QTest::qWait(50); @@ -417,6 +417,27 @@ void tst_QPropertyAnimation::noStartValue() QCOMPARE(o.values.last(), 420); } +void tst_QPropertyAnimation::noStartValueWithLoop() +{ + StartValueTester o; + o.setProperty("ole", 42); + o.values.clear(); + + QPropertyAnimation a(&o, "ole"); + a.setEndValue(420); + a.setDuration(250); + a.setLoopCount(2); + a.start(); + + a.setCurrentTime(250); + QCOMPARE(o.values.first(), 42); + QCOMPARE(a.currentValue().toInt(), 42); + QCOMPARE(o.values.last(), 42); + + a.setCurrentTime(500); + QCOMPARE(a.currentValue().toInt(), 420); +} + void tst_QPropertyAnimation::startWhenAnotherIsRunning() { StartValueTester o; @@ -526,13 +547,14 @@ void tst_QPropertyAnimation::startWithoutStartValue() anim.setEndValue(110); anim.start(); current = anim.currentValue().toInt(); - QCOMPARE(current, 42); // the initial default start value - + // the default start value will reevaluate the current property + // and set it to the end value of the last iteration + QCOMPARE(current, 100); QTest::qWait(100); current = anim.currentValue().toInt(); //it is somewhere in the animation - QVERIFY(current > 42); - QVERIFY(current < 110); + QVERIFY(current >= 100); + QVERIFY(current <= 110); } void tst_QPropertyAnimation::playForwardBackward() @@ -602,6 +624,7 @@ QVariant xaxisQPointInterpolator(const QPointF &f, const QPointF &t, qreal progr void tst_QPropertyAnimation::interpolated() { QObject o; + o.setProperty("point", QPointF()); //this will avoid warnings o.setProperty("number", qVariantFromValue<Number>(Number(42))); QCOMPARE(qVariantValue<Number>(o.property("number")), Number(42)); { @@ -627,9 +650,9 @@ void tst_QPropertyAnimation::interpolated() anim.start(); anim.pause(); anim.setCurrentTime(100); - QCOMPARE(o.property("point").toPointF(), QPointF(10, 0)); + QCOMPARE(o.property("point"), QVariant(QPointF(10, 0))); anim.setCurrentTime(500); - QCOMPARE(o.property("point").toPointF(), QPointF(50, 0)); + QCOMPARE(o.property("point"), QVariant(QPointF(50, 0))); } { // unregister it and see if we get back the default behaviour diff --git a/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp b/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp index 18b57b2..0631343 100644 --- a/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp +++ b/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp @@ -173,7 +173,7 @@ void tst_QSequentialAnimationGroup::setCurrentTime() QVariantAnimation *a1_s_o1 = new QPropertyAnimation(&s_o1, "value"); QVariantAnimation *a2_s_o1 = new QPropertyAnimation(&s_o1, "value"); QVariantAnimation *a3_s_o1 = new QPropertyAnimation(&s_o1, "value"); - a2_s_o1->setIterationCount(3); + a2_s_o1->setLoopCount(3); sequence->addAnimation(a1_s_o1); sequence->addAnimation(a2_s_o1); sequence->addAnimation(a3_s_o1); @@ -221,7 +221,7 @@ void tst_QSequentialAnimationGroup::setCurrentTime() QCOMPARE(sequence->currentTime(), 251); QCOMPARE(a1_s_o1->currentTime(), 250); QCOMPARE(a2_s_o1->currentTime(), 1); - QCOMPARE(a2_s_o1->currentIteration(), 0); + QCOMPARE(a2_s_o1->currentLoop(), 0); QCOMPARE(a3_s_o1->currentTime(), 0); QCOMPARE(sequence2->currentTime(), 0); QCOMPARE(a1_s_o2->currentTime(), 0); @@ -233,7 +233,7 @@ void tst_QSequentialAnimationGroup::setCurrentTime() QCOMPARE(sequence->currentTime(), 750); QCOMPARE(a1_s_o1->currentTime(), 250); QCOMPARE(a2_s_o1->currentTime(), 0); - QCOMPARE(a2_s_o1->currentIteration(), 2); + QCOMPARE(a2_s_o1->currentLoop(), 2); QCOMPARE(a3_s_o1->currentTime(), 0); QCOMPARE(sequence2->currentTime(), 0); QCOMPARE(a1_s_o2->currentTime(), 0); @@ -245,7 +245,7 @@ void tst_QSequentialAnimationGroup::setCurrentTime() QCOMPARE(sequence->currentTime(), 1000); QCOMPARE(a1_s_o1->currentTime(), 250); QCOMPARE(a2_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentIteration(), 2); + QCOMPARE(a2_s_o1->currentLoop(), 2); QCOMPARE(a3_s_o1->currentTime(), 0); QCOMPARE(sequence2->currentTime(), 0); QCOMPARE(a1_s_o2->currentTime(), 0); @@ -257,7 +257,7 @@ void tst_QSequentialAnimationGroup::setCurrentTime() QCOMPARE(sequence->currentTime(), 1010); QCOMPARE(a1_s_o1->currentTime(), 250); QCOMPARE(a2_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentIteration(), 2); + QCOMPARE(a2_s_o1->currentLoop(), 2); QCOMPARE(a3_s_o1->currentTime(), 10); QCOMPARE(sequence2->currentTime(), 0); QCOMPARE(a1_s_o2->currentTime(), 0); @@ -269,7 +269,7 @@ void tst_QSequentialAnimationGroup::setCurrentTime() QCOMPARE(sequence->currentTime(), 1250); QCOMPARE(a1_s_o1->currentTime(), 250); QCOMPARE(a2_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentIteration(), 2); + QCOMPARE(a2_s_o1->currentLoop(), 2); QCOMPARE(a3_s_o1->currentTime(), 250); QCOMPARE(sequence2->currentTime(), 0); QCOMPARE(a1_s_o2->currentTime(), 0); @@ -281,7 +281,7 @@ void tst_QSequentialAnimationGroup::setCurrentTime() QCOMPARE(sequence->currentTime(), 1250); QCOMPARE(a1_s_o1->currentTime(), 250); QCOMPARE(a2_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentIteration(), 2); + QCOMPARE(a2_s_o1->currentLoop(), 2); QCOMPARE(a3_s_o1->currentTime(), 250); QCOMPARE(sequence2->currentTime(), 250); QCOMPARE(a1_s_o2->currentTime(), 250); @@ -293,7 +293,7 @@ void tst_QSequentialAnimationGroup::setCurrentTime() QCOMPARE(sequence->currentTime(), 1250); QCOMPARE(a1_s_o1->currentTime(), 250); QCOMPARE(a2_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentIteration(), 2); + QCOMPARE(a2_s_o1->currentLoop(), 2); QCOMPARE(a3_s_o1->currentTime(), 250); QCOMPARE(sequence2->currentTime(), 500); QCOMPARE(a1_s_o2->currentTime(), 250); @@ -305,7 +305,7 @@ void tst_QSequentialAnimationGroup::setCurrentTime() QCOMPARE(sequence->currentTime(), 1250); QCOMPARE(a1_s_o1->currentTime(), 250); QCOMPARE(a2_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentIteration(), 2); + QCOMPARE(a2_s_o1->currentLoop(), 2); QCOMPARE(a3_s_o1->currentTime(), 250); QCOMPARE(sequence2->currentTime(), 500); QCOMPARE(a1_s_o2->currentTime(), 250); @@ -330,7 +330,7 @@ void tst_QSequentialAnimationGroup::setCurrentTimeWithUncontrolledAnimation() QCOMPARE(notTimeDriven->totalDuration(), -1); QVariantAnimation *loopsForever = new QPropertyAnimation(&t_o2, "value"); - loopsForever->setIterationCount(-1); + loopsForever->setLoopCount(-1); QCOMPARE(loopsForever->totalDuration(), -1); QSequentialAnimationGroup group; @@ -436,7 +436,7 @@ void tst_QSequentialAnimationGroup::seekingForwards() QVariantAnimation *a1_s_o1 = new QPropertyAnimation(&s_o1, "value"); QVariantAnimation *a2_s_o1 = new QPropertyAnimation(&s_o1, "value"); QVariantAnimation *a3_s_o1 = new QPropertyAnimation(&s_o1, "value"); - a2_s_o1->setIterationCount(3); + a2_s_o1->setLoopCount(3); sequence->addAnimation(a1_s_o1); sequence->addAnimation(a2_s_o1); sequence->addAnimation(a3_s_o1); @@ -476,7 +476,7 @@ void tst_QSequentialAnimationGroup::seekingForwards() QCOMPARE(sequence->currentTime(), 1250); QCOMPARE(a1_s_o1->currentTime(), 250); QCOMPARE(a2_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentIteration(), 2); + QCOMPARE(a2_s_o1->currentLoop(), 2); QCOMPARE(a3_s_o1->currentTime(), 250); QCOMPARE(sequence2->currentTime(), 250); QCOMPARE(a1_s_o2->currentTime(), 250); @@ -498,7 +498,7 @@ void tst_QSequentialAnimationGroup::seekingForwards() QCOMPARE(sequence->currentTime(), 1250); QCOMPARE(a1_s_o1->currentTime(), 250); QCOMPARE(a2_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentIteration(), 2); + QCOMPARE(a2_s_o1->currentLoop(), 2); QCOMPARE(a3_s_o1->currentTime(), 250); QCOMPARE(sequence2->currentTime(), 500); QCOMPARE(a1_s_o2->currentTime(), 250); @@ -516,7 +516,7 @@ void tst_QSequentialAnimationGroup::seekingBackwards() QVariantAnimation *a1_s_o1 = new QPropertyAnimation(&s_o1, "value"); QVariantAnimation *a2_s_o1 = new QPropertyAnimation(&s_o1, "value"); QVariantAnimation *a3_s_o1 = new QPropertyAnimation(&s_o1, "value"); - a2_s_o1->setIterationCount(3); + a2_s_o1->setLoopCount(3); sequence->addAnimation(a1_s_o1); sequence->addAnimation(a2_s_o1); sequence->addAnimation(a3_s_o1); @@ -540,7 +540,7 @@ void tst_QSequentialAnimationGroup::seekingBackwards() QCOMPARE(sequence->currentTime(), 1250); QCOMPARE(a1_s_o1->currentTime(), 250); QCOMPARE(a2_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentIteration(), 2); + QCOMPARE(a2_s_o1->currentLoop(), 2); QCOMPARE(a3_s_o1->currentTime(), 250); QCOMPARE(sequence2->currentTime(), 350); QCOMPARE(a1_s_o2->currentTime(), 250); @@ -564,7 +564,7 @@ void tst_QSequentialAnimationGroup::seekingBackwards() QCOMPARE(a2_s_o1->currentTime(), 0); QEXPECT_FAIL("", "rewinding in nested groups is considered as a restart from the children," "hence they don't reset from their current animation", Continue); - QCOMPARE(a2_s_o1->currentIteration(), 0); + QCOMPARE(a2_s_o1->currentLoop(), 0); QEXPECT_FAIL("", "rewinding in nested groups is considered as a restart from the children," "hence they don't reset from their current animation", Continue); QCOMPARE(a3_s_o1->currentTime(), 0); @@ -585,7 +585,7 @@ void tst_QSequentialAnimationGroup::seekingBackwards() QCOMPARE(sequence->currentTime(), 1250); QCOMPARE(a1_s_o1->currentTime(), 250); QCOMPARE(a2_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentIteration(), 2); + QCOMPARE(a2_s_o1->currentLoop(), 2); QCOMPARE(a3_s_o1->currentTime(), 250); QCOMPARE(sequence2->currentTime(), 500); QCOMPARE(a1_s_o2->currentTime(), 250); @@ -656,11 +656,11 @@ void tst_QSequentialAnimationGroup::pauseAndResume() QVariantAnimation *a1_s_o1 = new QPropertyAnimation(&s_o1, "value"); QVariantAnimation *a2_s_o1 = new QPropertyAnimation(&s_o1, "value"); QVariantAnimation *a3_s_o1 = new QPropertyAnimation(&s_o1, "value"); - a2_s_o1->setIterationCount(2); + a2_s_o1->setLoopCount(2); sequence->addAnimation(a1_s_o1); sequence->addAnimation(a2_s_o1); sequence->addAnimation(a3_s_o1); - sequence->setIterationCount(2); + sequence->setLoopCount(2); QSignalSpy a1StateChangedSpy(a1_s_o1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); QSignalSpy seqStateChangedSpy(sequence, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); @@ -675,11 +675,11 @@ void tst_QSequentialAnimationGroup::pauseAndResume() group.setCurrentTime(1751); QCOMPARE(group.currentTime(), 1751); QCOMPARE(sequence->currentTime(), 751); - QCOMPARE(sequence->currentIteration(), 1); + QCOMPARE(sequence->currentLoop(), 1); QCOMPARE(a1_s_o1->currentTime(), 250); QCOMPARE(a2_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentIteration(), 1); - QCOMPARE(a3_s_o1->currentIteration(), 0); + QCOMPARE(a2_s_o1->currentLoop(), 1); + QCOMPARE(a3_s_o1->currentLoop(), 0); QCOMPARE(a3_s_o1->currentTime(), 1); QCOMPARE(group.state(), QAnimationGroup::Paused); @@ -723,11 +723,11 @@ void tst_QSequentialAnimationGroup::pauseAndResume() QVERIFY(group.currentTime() >= 1751); QVERIFY(sequence->currentTime() >= 751); - QCOMPARE(sequence->currentIteration(), 1); + QCOMPARE(sequence->currentLoop(), 1); QCOMPARE(a1_s_o1->currentTime(), 250); QCOMPARE(a2_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentIteration(), 1); - QCOMPARE(a3_s_o1->currentIteration(), 0); + QCOMPARE(a2_s_o1->currentLoop(), 1); + QCOMPARE(a3_s_o1->currentLoop(), 0); QVERIFY(a3_s_o1->currentTime() >= 1); QCOMPARE(seqStateChangedSpy.count(), 3); // Running,Paused,Running @@ -744,11 +744,11 @@ void tst_QSequentialAnimationGroup::pauseAndResume() QVERIFY(group.currentTime() >= 1751); QVERIFY(sequence->currentTime() >= 751); - QCOMPARE(sequence->currentIteration(), 1); + QCOMPARE(sequence->currentLoop(), 1); QCOMPARE(a1_s_o1->currentTime(), 250); QCOMPARE(a2_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentIteration(), 1); - QCOMPARE(a3_s_o1->currentIteration(), 0); + QCOMPARE(a2_s_o1->currentLoop(), 1); + QCOMPARE(a3_s_o1->currentLoop(), 0); QVERIFY(a3_s_o1->currentTime() >= 1); QCOMPARE(seqStateChangedSpy.count(), 4); // Running,Paused,Running,Paused @@ -780,11 +780,11 @@ void tst_QSequentialAnimationGroup::restart() animsStateChanged[i] = new QSignalSpy(anims[i], SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); } - anims[1]->setIterationCount(2); + anims[1]->setLoopCount(2); sequence->addAnimation(anims[0]); sequence->addAnimation(anims[1]); sequence->addAnimation(anims[2]); - sequence->setIterationCount(2); + sequence->setLoopCount(2); QSequentialAnimationGroup group; group.addAnimation(sequence); @@ -845,17 +845,17 @@ void tst_QSequentialAnimationGroup::looping() QSignalSpy a3Spy(a3_s_o1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); QSignalSpy seqSpy(sequence, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); - a2_s_o1->setIterationCount(2); + a2_s_o1->setLoopCount(2); sequence->addAnimation(a1_s_o1); sequence->addAnimation(a2_s_o1); sequence->addAnimation(a3_s_o1); - sequence->setIterationCount(2); + sequence->setLoopCount(2); QSequentialAnimationGroup group; QSignalSpy groupSpy(&group, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); group.addAnimation(sequence); - group.setIterationCount(2); + group.setLoopCount(2); group.start(); group.pause(); @@ -864,12 +864,12 @@ void tst_QSequentialAnimationGroup::looping() group.setCurrentTime(1750); QCOMPARE(group.currentTime(), 1750); QCOMPARE(sequence->currentTime(), 750); - QCOMPARE(sequence->currentIteration(), 1); + QCOMPARE(sequence->currentLoop(), 1); QCOMPARE(a1_s_o1->currentTime(), 250); QCOMPARE(a2_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentIteration(), 1); + QCOMPARE(a2_s_o1->currentLoop(), 1); // this animation is at the beginning because it is the current one inside sequence - QCOMPARE(a3_s_o1->currentIteration(), 0); + QCOMPARE(a3_s_o1->currentLoop(), 0); QCOMPARE(a3_s_o1->currentTime(), 0); QCOMPARE(sequence->currentAnimation(), a3_s_o1); @@ -898,14 +898,14 @@ void tst_QSequentialAnimationGroup::looping() // Looping, current time = duration + 1 group.setCurrentTime(group.duration() + 1); QCOMPARE(group.currentTime(), 1); - QCOMPARE(group.currentIteration(), 1); + QCOMPARE(group.currentLoop(), 1); QCOMPARE(sequence->currentTime(), 1); - QCOMPARE(sequence->currentIteration(), 0); + QCOMPARE(sequence->currentLoop(), 0); QCOMPARE(a1_s_o1->currentTime(), 1); QCOMPARE(a2_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentIteration(), 1); + QCOMPARE(a2_s_o1->currentLoop(), 1); // this animation is at the end because it was run on the previous loop - QCOMPARE(a3_s_o1->currentIteration(), 0); + QCOMPARE(a3_s_o1->currentLoop(), 0); QCOMPARE(a3_s_o1->currentTime(), 250); QCOMPARE(group.state(), QAnimationGroup::Paused); @@ -1367,7 +1367,7 @@ void tst_QSequentialAnimationGroup::zeroDurationAnimation() group.addAnimation(anim1); group.addAnimation(anim2); group.addAnimation(anim3); - group.setIterationCount(2); + group.setLoopCount(2); group.start(); QCOMPARE(stateChangedSpy.count(), 2); @@ -1401,7 +1401,7 @@ void tst_QSequentialAnimationGroup::stopUncontrolledAnimations() loopsForever.setStartValue(0); loopsForever.setEndValue(100); loopsForever.setDuration(100); - loopsForever.setIterationCount(-1); + loopsForever.setLoopCount(-1); group.addAnimation(¬TimeDriven); group.addAnimation(&loopsForever); @@ -1592,11 +1592,11 @@ void tst_QSequentialAnimationGroup::currentAnimationWithZeroDuration() void tst_QSequentialAnimationGroup::insertAnimation() { QSequentialAnimationGroup group; - group.setIterationCount(2); + group.setLoopCount(2); QPropertyAnimation *anim = new QPropertyAnimation(&group); QCOMPARE(group.duration(), anim->duration()); group.setCurrentTime(300); - QCOMPARE(group.currentIteration(), 1); + QCOMPARE(group.currentLoop(), 1); //this will crash if the sequential group calls duration on the created animation new QPropertyAnimation(&group); diff --git a/tests/auto/qstate/tst_qstate.cpp b/tests/auto/qstate/tst_qstate.cpp index c4a0050..bb7de20 100644 --- a/tests/auto/qstate/tst_qstate.cpp +++ b/tests/auto/qstate/tst_qstate.cpp @@ -9,9 +9,7 @@ #include "qstate.h" #include "qstatemachine.h" -#include "qtransition.h" #include "qsignaltransition.h" -#include "qstateaction.h" // Will try to wait for the condition while allowing event processing #define QTRY_COMPARE(__expr, __expected) \ @@ -42,15 +40,15 @@ private slots: #if 0 void test(); #endif - void setPropertyOnEntry(); - void setPropertyOnEntryTwice(); - void setPropertyOnExit(); - void setPropertyOnExitTwice(); + void assignProperty(); + void assignPropertyTwice(); void historyInitialState(); - void addEntryAction(); + +private: + bool functionCalled; }; -tst_QState::tst_QState() +tst_QState::tst_QState() : functionCalled(false) { } @@ -200,20 +198,20 @@ void tst_QState::test() } #endif -void tst_QState::addEntryAction() +class TestClass: public QObject { - QStateMachine sm; - QState *s0 = new QState(sm.rootState()); - s0->addEntryAction(new QStateSetPropertyAction(this, "objectName", "commandTest")); - sm.setInitialState(s0); + Q_OBJECT +public: + TestClass() : called(false) {} + bool called; + +public slots: + void slot() { called = true; } - sm.start(); - QCoreApplication::processEvents(); - QCOMPARE(this->objectName(), QString::fromLatin1("commandTest")); -} +}; -void tst_QState::setPropertyOnEntry() +void tst_QState::assignProperty() { QStateMachine machine; @@ -221,7 +219,7 @@ void tst_QState::setPropertyOnEntry() object->setProperty("fooBar", 10); QState *s1 = new QState(machine.rootState()); - s1->setPropertyOnEntry(object, "fooBar", 20); + s1->assignProperty(object, "fooBar", 20); machine.setInitialState(s1); machine.start(); @@ -230,7 +228,7 @@ void tst_QState::setPropertyOnEntry() QCOMPARE(object->property("fooBar").toInt(), 20); } -void tst_QState::setPropertyOnEntryTwice() +void tst_QState::assignPropertyTwice() { QStateMachine machine; @@ -238,8 +236,8 @@ void tst_QState::setPropertyOnEntryTwice() object->setProperty("fooBar", 10); QState *s1 = new QState(machine.rootState()); - s1->setPropertyOnEntry(object, "fooBar", 20); - s1->setPropertyOnEntry(object, "fooBar", 30); + s1->assignProperty(object, "fooBar", 20); + s1->assignProperty(object, "fooBar", 30); machine.setInitialState(s1); machine.start(); @@ -248,56 +246,26 @@ void tst_QState::setPropertyOnEntryTwice() QCOMPARE(object->property("fooBar").toInt(), 30); } -void tst_QState::setPropertyOnExit() +class EventTestTransition: public QAbstractTransition { - QStateMachine machine; - - QObject *object = new QObject(); - object->setProperty("fooBar", 10); - - QState *s1 = new QState(machine.rootState()); - s1->setPropertyOnExit(object, "fooBar", 20); - - QState *s2 = new QState(machine.rootState()); - s1->addTransition(new QTransition(QEvent::User), s2); - - machine.setInitialState(s1); - machine.start(); - QCoreApplication::processEvents(); - - QCOMPARE(object->property("fooBar").toInt(), 10); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - QCOMPARE(object->property("fooBar").toInt(), 20); -} - -void tst_QState::setPropertyOnExitTwice() -{ - QStateMachine machine; +public: + EventTestTransition(QEvent::Type type, QState *targetState) + : QAbstractTransition(QList<QAbstractState*>() << targetState), m_type(type) + { + } - QObject *object = new QObject(); - object->setProperty("fooBar", 10); +protected: + bool eventTest(QEvent *e) const + { + return e->type() == m_type; + } - QState *s1 = new QState(machine.rootState()); - s1->setPropertyOnExit(object, "fooBar", 20); - s1->setPropertyOnExit(object, "fooBar", 30); + void onTransition(QEvent *) {} - QState *s2 = new QState(machine.rootState()); - s1->addTransition(new QTransition(QEvent::User), s2); +private: + QEvent::Type m_type; - machine.setInitialState(s1); - machine.start(); - QCoreApplication::processEvents(); - - QCOMPARE(object->property("fooBar").toInt(), 10); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - QCOMPARE(object->property("fooBar").toInt(), 30); -} +}; void tst_QState::historyInitialState() { @@ -306,7 +274,7 @@ void tst_QState::historyInitialState() QState *s1 = new QState(machine.rootState()); QState *s2 = new QState(machine.rootState()); - QHistoryState *h1 = s2->addHistoryState(); + QHistoryState *h1 = new QHistoryState(s2); s2->setInitialState(h1); @@ -315,9 +283,9 @@ void tst_QState::historyInitialState() QState *s4 = new QState(s2); - s1->addTransition(new QTransition(QEvent::User), s2); - s2->addTransition(new QTransition(QEvent::User), s1); - s3->addTransition(new QTransition(QEvent::Type(QEvent::User+1)), s4); + s1->addTransition(new EventTestTransition(QEvent::User, s2)); + s2->addTransition(new EventTestTransition(QEvent::User, s1)); + s3->addTransition(new EventTestTransition(QEvent::Type(QEvent::User+1), s4)); machine.setInitialState(s1); machine.start(); diff --git a/tests/auto/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/tst_qstatemachine.cpp index c906d53..9058cb6 100644 --- a/tests/auto/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/qstatemachine/tst_qstatemachine.cpp @@ -45,10 +45,10 @@ #include "qstatemachine.h" #include "qstate.h" -#include "qtransition.h" #include "qhistorystate.h" #include "qkeyeventtransition.h" #include "qmouseeventtransition.h" +#include "private/qstate_p.h" #include "private/qstatemachine_p.h" // Will try to wait for the condition while allowing event processing @@ -70,6 +70,17 @@ static int globalTick; +// Run exec for a maximum of TIMEOUT msecs +#define QCOREAPPLICATION_EXEC(TIMEOUT) \ +{ \ + QTimer timer; \ + timer.setSingleShot(true); \ + timer.setInterval(TIMEOUT); \ + timer.start(); \ + connect(&timer, SIGNAL(timeout()), QCoreApplication::instance(), SLOT(quit())); \ + QCoreApplication::exec(); \ +} + class tst_QStateMachine : public QObject { Q_OBJECT @@ -84,6 +95,8 @@ private slots: void rootState(); void addAndRemoveState(); void stateEntryAndExit(); + void assignProperty(); + void assignPropertyWithAnimation(); void postEvent(); void stateFinished(); void parallelStates(); @@ -91,8 +104,9 @@ private slots: void signalTransitions(); void eventTransitions(); void historyStates(); - void stateActions(); - void transitionActions(); + void startAndStop(); + void targetStateWithNoParent(); + void targetStateDeleted(); void transitionToRootState(); void transitionEntersParent(); @@ -109,19 +123,51 @@ private slots: void customErrorStateIsNull(); void clearError(); void historyStateHasNowhereToGo(); + void historyStateAsInitialState(); void brokenStateIsNeverEntered(); void customErrorStateNotInGraph(); void transitionToStateNotInGraph(); void restoreProperties(); + void defaultGlobalRestorePolicy(); void globalRestorePolicySetToRestore(); void globalRestorePolicySetToDoNotRestore(); - void restorePolicyNotInherited(); - void mixedRestoreProperties(); - void setRestorePolicyToDoNotRestore(); - void setGlobalRestorePolicyToGlobalRestore(); - void restorePolicyOnChildState(); + + //void restorePolicyNotInherited(); + //void mixedRestoreProperties(); + //void setRestorePolicyToDoNotRestore(); + //void setGlobalRestorePolicyToGlobalRestore(); + //void restorePolicyOnChildState(); + void transitionWithParent(); + void transitionsFromParallelStateWithNoChildren(); + void parallelStateTransition(); + void parallelStateAssignmentsDone(); + void nestedRestoreProperties(); + void nestedRestoreProperties2(); + + void simpleAnimation(); + void twoAnimations(); + void twoAnimatedTransitions(); + void playAnimationTwice(); + void nestedTargetStateForAnimation(); + void animatedGlobalRestoreProperty(); + void specificTargetValueOfAnimation(); + + void addDefaultAnimation(); + void addDefaultAnimationWithUnusedAnimation(); + void removeDefaultAnimation(); + void overrideDefaultAnimationWithSpecific(); + +// void addDefaultAnimationForSource(); +// void addDefaultAnimationForTarget(); +// void removeDefaultAnimationForSource(); +// void removeDefaultAnimationForTarget(); +// void overrideDefaultAnimationWithSource(); +// void overrideDefaultAnimationWithTarget(); +// void overrideDefaultSourceAnimationWithSpecific(); +// void overrideDefaultTargetAnimationWithSpecific(); +// void overrideDefaultTargetAnimationWithSource(); }; tst_QStateMachine::tst_QStateMachine() @@ -143,10 +189,10 @@ public: : QState(parent) {} QList<QPair<int, Event> > events; protected: - virtual void onEntry() { + virtual void onEntry(QEvent *) { events.append(qMakePair(globalTick++, Entry)); } - virtual void onExit() { + virtual void onExit(QEvent *) { events.append(qMakePair(globalTick++, Exit)); } }; @@ -161,7 +207,7 @@ protected: virtual bool eventTest(QEvent *) const { return true; } - virtual void onTransition() { + virtual void onTransition(QEvent *) { triggers.append(globalTick++); } }; @@ -194,21 +240,24 @@ void tst_QStateMachine::cleanup() qInstallMsgHandler(s_oldHandler); } -class EventTransition : public QTransition +class EventTransition : public QAbstractTransition { public: EventTransition(QEvent::Type type, QAbstractState *target, QState *parent = 0) - : QTransition(QList<QAbstractState*>() << target, parent), m_type(type) {} + : QAbstractTransition(QList<QAbstractState*>() << target, parent), m_type(type) {} protected: virtual bool eventTest(QEvent *e) const { return (e->type() == m_type); } + virtual void onTransition(QEvent *) {} private: QEvent::Type m_type; }; void tst_QStateMachine::transitionToRootState() { + s_countWarnings = false; + QStateMachine machine; QState *initialState = new QState(); @@ -220,16 +269,14 @@ void tst_QStateMachine::transitionToRootState() machine.start(); QCoreApplication::processEvents(); - QCOMPARE(machine.configuration().count(), 2); + QCOMPARE(machine.configuration().count(), 1); QVERIFY(machine.configuration().contains(initialState)); - QVERIFY(machine.configuration().contains(machine.rootState())); machine.postEvent(new QEvent(QEvent::User)); QCoreApplication::processEvents(); - QCOMPARE(machine.configuration().count(), 2); + QCOMPARE(machine.configuration().count(), 1); QVERIFY(machine.configuration().contains(initialState)); - QVERIFY(machine.configuration().contains(machine.rootState())); } void tst_QStateMachine::transitionEntersParent() @@ -245,21 +292,21 @@ void tst_QStateMachine::transitionEntersParent() QState *greatGrandParent = new QState(); greatGrandParent->setObjectName("grandParent"); - greatGrandParent->setPropertyOnEntry(entryController, "greatGrandParentEntered", true); + greatGrandParent->assignProperty(entryController, "greatGrandParentEntered", true); machine.addState(greatGrandParent); machine.setInitialState(greatGrandParent); QState *grandParent = new QState(greatGrandParent); grandParent->setObjectName("grandParent"); - grandParent->setPropertyOnEntry(entryController, "grandParentEntered", true); + grandParent->assignProperty(entryController, "grandParentEntered", true); QState *parent = new QState(grandParent); parent->setObjectName("parent"); - parent->setPropertyOnEntry(entryController, "parentEntered", true); + parent->assignProperty(entryController, "parentEntered", true); QState *state = new QState(parent); state->setObjectName("state"); - state->setPropertyOnEntry(entryController, "stateEntered", true); + state->assignProperty(entryController, "stateEntered", true); QState *initialStateOfGreatGrandParent = new QState(greatGrandParent); initialStateOfGreatGrandParent->setObjectName("initialStateOfGreatGrandParent"); @@ -336,7 +383,7 @@ public: { } - void onEntry() + void onEntry(QEvent *) { error = m_machine->error(); errorString = m_machine->errorString(); @@ -625,6 +672,8 @@ void tst_QStateMachine::errorStateHasErrors() void tst_QStateMachine::errorStateIsRootState() { + s_countWarnings = false; + QStateMachine machine; machine.setErrorState(machine.rootState()); @@ -648,9 +697,8 @@ void tst_QStateMachine::errorStateIsRootState() machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 1))); QCoreApplication::processEvents(); - QEXPECT_FAIL("", "Covered by transitionToRootState test. Remove this when that test passes", Continue); QCOMPARE(machine.configuration().count(), 1); - QVERIFY(machine.configuration().contains(initialState)); + QVERIFY(machine.configuration().contains(machine.errorState())); } void tst_QStateMachine::errorStateEntersParentFirst() @@ -666,21 +714,21 @@ void tst_QStateMachine::errorStateEntersParentFirst() QState *greatGrandParent = new QState(); greatGrandParent->setObjectName("greatGrandParent"); - greatGrandParent->setPropertyOnEntry(entryController, "greatGrandParentEntered", true); + greatGrandParent->assignProperty(entryController, "greatGrandParentEntered", true); machine.addState(greatGrandParent); machine.setInitialState(greatGrandParent); QState *grandParent = new QState(greatGrandParent); grandParent->setObjectName("grandParent"); - grandParent->setPropertyOnEntry(entryController, "grandParentEntered", true); + grandParent->assignProperty(entryController, "grandParentEntered", true); QState *parent = new QState(grandParent); parent->setObjectName("parent"); - parent->setPropertyOnEntry(entryController, "parentEntered", true); + parent->assignProperty(entryController, "parentEntered", true); QState *errorState = new QState(parent); errorState->setObjectName("errorState"); - errorState->setPropertyOnEntry(entryController, "errorStateEntered", true); + errorState->assignProperty(entryController, "errorStateEntered", true); machine.setErrorState(errorState); QState *initialStateOfGreatGrandParent = new QState(greatGrandParent); @@ -777,6 +825,40 @@ void tst_QStateMachine::clearError() QVERIFY(machine.errorString().isEmpty()); } +void tst_QStateMachine::historyStateAsInitialState() +{ + QStateMachine machine; + + QHistoryState *hs = new QHistoryState(machine.rootState()); + machine.setInitialState(hs); + + QState *s1 = new QState(machine.rootState()); + hs->setDefaultState(s1); + + QState *s2 = new QState(machine.rootState()); + + QHistoryState *s2h = new QHistoryState(s2); + s2->setInitialState(s2h); + + QState *s21 = new QState(s2); + s2h->setDefaultState(s21); + + s1->addTransition(new EventTransition(QEvent::User, s2)); + + machine.start(); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s1)); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().size(), 2); + QVERIFY(machine.configuration().contains(s2)); + QVERIFY(machine.configuration().contains(s21)); +} + void tst_QStateMachine::historyStateHasNowhereToGo() { QStateMachine machine; @@ -789,7 +871,7 @@ void tst_QStateMachine::historyStateHasNowhereToGo() brokenState->setObjectName("brokenState"); brokenState->setInitialState(new QState(brokenState)); - QHistoryState *historyState = brokenState->addHistoryState(); + QHistoryState *historyState = new QHistoryState(brokenState); historyState->setObjectName("historyState"); initialState->addTransition(new EventTransition(QEvent::User, historyState)); @@ -801,8 +883,8 @@ void tst_QStateMachine::historyStateHasNowhereToGo() QCOMPARE(machine.configuration().count(), 1); QVERIFY(machine.configuration().contains(machine.errorState())); - QCOMPARE(machine.error(), QStateMachine::NoDefaultStateInHistoryState); - QCOMPARE(machine.errorString(), QString::fromLatin1("Missing transition from history state 'historyState'")); + QCOMPARE(machine.error(), QStateMachine::NoDefaultStateInHistoryStateError); + QCOMPARE(machine.errorString(), QString::fromLatin1("Missing default state in history state 'historyState'")); } void tst_QStateMachine::brokenStateIsNeverEntered() @@ -818,15 +900,15 @@ void tst_QStateMachine::brokenStateIsNeverEntered() machine.setInitialState(initialState); QState *errorState = new QState(machine.rootState()); - errorState->setPropertyOnEntry(entryController, "errorStateEntered", true); + errorState->assignProperty(entryController, "errorStateEntered", true); machine.setErrorState(errorState); QState *brokenState = new QState(machine.rootState()); - brokenState->setPropertyOnEntry(entryController, "brokenStateEntered", true); + brokenState->assignProperty(entryController, "brokenStateEntered", true); brokenState->setObjectName("brokenState"); QState *childState = new QState(brokenState); - childState->setPropertyOnEntry(entryController, "childStateEntered", true); + childState->assignProperty(entryController, "childStateEntered", true); initialState->addTransition(new EventTransition(QEvent::User, brokenState)); @@ -843,8 +925,6 @@ void tst_QStateMachine::brokenStateIsNeverEntered() void tst_QStateMachine::transitionToStateNotInGraph() { - QSKIP("Hangs", SkipAll); - s_countWarnings = false; QStateMachine machine; @@ -854,13 +934,14 @@ void tst_QStateMachine::transitionToStateNotInGraph() machine.setInitialState(initialState); QState *independentState = new QState(); + independentState->setObjectName("independentState"); initialState->addTransition(independentState); machine.start(); QCoreApplication::processEvents(); QCOMPARE(machine.configuration().count(), 1); - QVERIFY(machine.configuration().contains(initialState)); + QVERIFY(machine.configuration().contains(qobject_cast<QState*>(machine.rootState())->errorState())); } void tst_QStateMachine::customErrorStateNotInGraph() @@ -893,22 +974,20 @@ void tst_QStateMachine::restoreProperties() object->setProperty("b", 2); QStateMachine machine; + machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); QState *S1 = new QState(); S1->setObjectName("S1"); - S1->setPropertyOnEntry(object, "a", 3); - S1->setRestorePolicy(QState::RestoreProperties); + S1->assignProperty(object, "a", 3); machine.addState(S1); QState *S2 = new QState(); S2->setObjectName("S2"); - S2->setPropertyOnEntry(object, "b", 5); - S2->setRestorePolicy(QState::RestoreProperties); + S2->assignProperty(object, "b", 5); machine.addState(S2); QState *S3 = new QState(); S3->setObjectName("S3"); - S3->setRestorePolicy(QState::RestoreProperties); machine.addState(S3); QFinalState *S4 = new QFinalState(); @@ -957,8 +1036,9 @@ void tst_QStateMachine::rootState() void tst_QStateMachine::addAndRemoveState() { QStateMachine machine; - QCOMPARE(machine.states().size(), 1); // the error state - QCOMPARE(machine.states().at(0), (QAbstractState*)machine.errorState()); + QStatePrivate *root_d = QStatePrivate::get(machine.rootState()); + QCOMPARE(root_d->childStates().size(), 1); // the error state + QCOMPARE(root_d->childStates().at(0), (QAbstractState*)machine.errorState()); QTest::ignoreMessage(QtWarningMsg, "QStateMachine::addState: cannot add null state"); machine.addState(0); @@ -967,9 +1047,9 @@ void tst_QStateMachine::addAndRemoveState() QCOMPARE(s1->parentState(), (QState*)0); machine.addState(s1); QCOMPARE(s1->parentState(), machine.rootState()); - QCOMPARE(machine.states().size(), 2); - QCOMPARE(machine.states().at(0), (QAbstractState*)machine.errorState()); - QCOMPARE(machine.states().at(1), (QAbstractState*)s1); + QCOMPARE(root_d->childStates().size(), 2); + QCOMPARE(root_d->childStates().at(0), (QAbstractState*)machine.errorState()); + QCOMPARE(root_d->childStates().at(1), (QAbstractState*)s1); QTest::ignoreMessage(QtWarningMsg, "QStateMachine::addState: state has already been added to this machine"); machine.addState(s1); @@ -978,24 +1058,24 @@ void tst_QStateMachine::addAndRemoveState() QCOMPARE(s2->parentState(), (QState*)0); machine.addState(s2); QCOMPARE(s2->parentState(), machine.rootState()); - QCOMPARE(machine.states().size(), 3); - QCOMPARE(machine.states().at(0), (QAbstractState*)machine.errorState()); - QCOMPARE(machine.states().at(1), (QAbstractState*)s1); - QCOMPARE(machine.states().at(2), (QAbstractState*)s2); + QCOMPARE(root_d->childStates().size(), 3); + QCOMPARE(root_d->childStates().at(0), (QAbstractState*)machine.errorState()); + QCOMPARE(root_d->childStates().at(1), (QAbstractState*)s1); + QCOMPARE(root_d->childStates().at(2), (QAbstractState*)s2); QTest::ignoreMessage(QtWarningMsg, "QStateMachine::addState: state has already been added to this machine"); machine.addState(s2); machine.removeState(s1); QCOMPARE(s1->parentState(), (QState*)0); - QCOMPARE(machine.states().size(), 2); - QCOMPARE(machine.states().at(0), (QAbstractState*)machine.errorState()); - QCOMPARE(machine.states().at(1), (QAbstractState*)s2); + QCOMPARE(root_d->childStates().size(), 2); + QCOMPARE(root_d->childStates().at(0), (QAbstractState*)machine.errorState()); + QCOMPARE(root_d->childStates().at(1), (QAbstractState*)s2); machine.removeState(s2); QCOMPARE(s2->parentState(), (QState*)0); - QCOMPARE(machine.states().size(), 1); - QCOMPARE(machine.states().at(0), (QAbstractState*)machine.errorState()); + QCOMPARE(root_d->childStates().size(), 1); + QCOMPARE(root_d->childStates().at(0), (QAbstractState*)machine.errorState()); QTest::ignoreMessage(QtWarningMsg, "QStateMachine::removeState: cannot remove null state"); machine.removeState(0); @@ -1013,21 +1093,41 @@ void tst_QStateMachine::stateEntryAndExit() QStateMachine machine; TestState *s1 = new TestState(machine.rootState()); + QTest::ignoreMessage(QtWarningMsg, "QState::addTransition: cannot add transition to null state"); + s1->addTransition((QAbstractState*)0); + QTest::ignoreMessage(QtWarningMsg, "QState::addTransition: cannot add null transition"); + s1->addTransition((QAbstractTransition*)0); + QTest::ignoreMessage(QtWarningMsg, "QState::removeTransition: cannot remove null transition"); + s1->removeTransition((QAbstractTransition*)0); + TestState *s2 = new TestState(machine.rootState()); QFinalState *s3 = new QFinalState(machine.rootState()); TestTransition *t = new TestTransition(s2); - s1->addTransition(t); - s2->addTransition(s3); + QCOMPARE(s1->addTransition(t), (QAbstractTransition*)t); + { + QAbstractTransition *trans = s2->addTransition(s3); + QVERIFY(trans != 0); + QCOMPARE(trans->sourceState(), (QAbstractState*)s2); + QCOMPARE(trans->targetState(), (QAbstractState*)s3); + s2->removeTransition(trans); + QCOMPARE(trans->sourceState(), (QAbstractState*)0); + QCOMPARE(trans->targetState(), (QAbstractState*)s3); + QCOMPARE(s2->addTransition(trans), trans); + QCOMPARE(trans->sourceState(), (QAbstractState*)s2); + } QSignalSpy startedSpy(&machine, SIGNAL(started())); + QSignalSpy stoppedSpy(&machine, SIGNAL(stopped())); QSignalSpy finishedSpy(&machine, SIGNAL(finished())); machine.setInitialState(s1); QVERIFY(machine.configuration().isEmpty()); globalTick = 0; + QVERIFY(!machine.isRunning()); machine.start(); QTRY_COMPARE(startedSpy.count(), 1); QTRY_COMPARE(finishedSpy.count(), 1); + QTRY_COMPARE(stoppedSpy.count(), 0); QCOMPARE(machine.configuration().count(), 1); QVERIFY(machine.configuration().contains(s3)); @@ -1113,6 +1213,170 @@ void tst_QStateMachine::stateEntryAndExit() } } +void tst_QStateMachine::assignProperty() +{ + QStateMachine machine; + QState *s1 = new QState(machine.rootState()); + + QTest::ignoreMessage(QtWarningMsg, "QState::assignProperty: cannot assign property 'foo' of null object"); + s1->assignProperty(0, "foo", QVariant()); + + s1->assignProperty(s1, "objectName", "s1"); + QFinalState *s2 = new QFinalState(machine.rootState()); + s1->addTransition(s2); + machine.setInitialState(s1); + machine.start(); + QCoreApplication::processEvents(); + QCOMPARE(s1->objectName(), QString::fromLatin1("s1")); + + s1->assignProperty(s1, "objectName", "foo"); + machine.start(); + QCoreApplication::processEvents(); + QCOMPARE(s1->objectName(), QString::fromLatin1("foo")); + + s1->assignProperty(s1, "noSuchProperty", 123); + machine.start(); + QCoreApplication::processEvents(); + QCOMPARE(s1->objectName(), QString::fromLatin1("foo")); + QCOMPARE(s1->dynamicPropertyNames().size(), 1); + QCOMPARE(s1->dynamicPropertyNames().at(0), QByteArray("noSuchProperty")); + + QSignalSpy polishedSpy(s1, SIGNAL(polished())); + machine.start(); + QCoreApplication::processEvents(); + QCOMPARE(polishedSpy.count(), 1); +} + +void tst_QStateMachine::assignPropertyWithAnimation() +{ + // Single animation + { + QStateMachine machine; + QObject obj; + obj.setProperty("foo", 321); + obj.setProperty("bar", 654); + QState *s1 = new QState(machine.rootState()); + s1->assignProperty(&obj, "foo", 123); + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(&obj, "foo", 456); + s2->assignProperty(&obj, "bar", 789); + QAbstractTransition *trans = s1->addTransition(s2); + QPropertyAnimation anim(&obj, "foo"); + anim.setDuration(250); + trans->addAnimation(&anim); + QFinalState *s3 = new QFinalState(machine.rootState()); + s2->addTransition(s2, SIGNAL(polished()), s3); + + machine.setInitialState(s1); + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + machine.start(); + QTRY_COMPARE(finishedSpy.count(), 1); + QCOMPARE(obj.property("foo").toInt(), 456); + QCOMPARE(obj.property("bar").toInt(), 789); + } + // Two animations + { + QStateMachine machine; + QObject obj; + obj.setProperty("foo", 321); + obj.setProperty("bar", 654); + QState *s1 = new QState(machine.rootState()); + s1->assignProperty(&obj, "foo", 123); + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(&obj, "foo", 456); + s2->assignProperty(&obj, "bar", 789); + QAbstractTransition *trans = s1->addTransition(s2); + QPropertyAnimation anim(&obj, "foo"); + anim.setDuration(150); + trans->addAnimation(&anim); + QPropertyAnimation anim2(&obj, "bar"); + anim2.setDuration(150); + trans->addAnimation(&anim2); + QFinalState *s3 = new QFinalState(machine.rootState()); + s2->addTransition(s2, SIGNAL(polished()), s3); + + machine.setInitialState(s1); + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + machine.start(); + QTRY_COMPARE(finishedSpy.count(), 1); + QCOMPARE(obj.property("foo").toInt(), 456); + QCOMPARE(obj.property("bar").toInt(), 789); + } + // Animation group + { + QStateMachine machine; + QObject obj; + obj.setProperty("foo", 321); + obj.setProperty("bar", 654); + QState *s1 = new QState(machine.rootState()); + s1->assignProperty(&obj, "foo", 123); + s1->assignProperty(&obj, "bar", 321); + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(&obj, "foo", 456); + s2->assignProperty(&obj, "bar", 654); + s2->assignProperty(&obj, "baz", 789); + QAbstractTransition *trans = s1->addTransition(s2); + QSequentialAnimationGroup group; + group.addAnimation(new QPropertyAnimation(&obj, "foo")); + group.addAnimation(new QPropertyAnimation(&obj, "bar")); + trans->addAnimation(&group); + QFinalState *s3 = new QFinalState(machine.rootState()); + s2->addTransition(s2, SIGNAL(polished()), s3); + + machine.setInitialState(s1); + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + machine.start(); + QTRY_COMPARE(finishedSpy.count(), 1); + QCOMPARE(obj.property("foo").toInt(), 456); + QCOMPARE(obj.property("bar").toInt(), 654); + QCOMPARE(obj.property("baz").toInt(), 789); + } + // Nested states + { + QStateMachine machine; + QObject obj; + obj.setProperty("foo", 321); + obj.setProperty("bar", 654); + QState *s1 = new QState(machine.rootState()); + QCOMPARE(s1->childMode(), QState::ExclusiveStates); + QCOMPARE(s1->initialState(), (QAbstractState*)0); + s1->setObjectName("s1"); + s1->assignProperty(&obj, "foo", 123); + s1->assignProperty(&obj, "bar", 456); + QState *s2 = new QState(machine.rootState()); + s2->setObjectName("s2"); + s2->assignProperty(&obj, "foo", 321); + QState *s21 = new QState(s2); + s21->setObjectName("s21"); + s21->assignProperty(&obj, "bar", 654); + QState *s22 = new QState(s2); + s22->setObjectName("s22"); + s22->assignProperty(&obj, "bar", 789); + s2->setInitialState(s21); + QCOMPARE(s2->initialState(), (QAbstractState*)s21); + + QAbstractTransition *trans = s1->addTransition(s2); + QPropertyAnimation anim(&obj, "foo"); + anim.setDuration(500); + trans->addAnimation(&anim); + QPropertyAnimation anim2(&obj, "bar"); + anim2.setDuration(250); + trans->addAnimation(&anim2); + + s21->addTransition(s21, SIGNAL(polished()), s22); + + QFinalState *s3 = new QFinalState(machine.rootState()); + s22->addTransition(s2, SIGNAL(polished()), s3); + + machine.setInitialState(s1); + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + machine.start(); + QTRY_COMPARE(finishedSpy.count(), 1); + QCOMPARE(obj.property("foo").toInt(), 321); + QCOMPARE(obj.property("bar").toInt(), 789); + } +} + struct StringEvent : public QEvent { public: @@ -1137,7 +1401,7 @@ protected: StringEvent *se = static_cast<StringEvent*>(e); return (m_value == se->value) && (!m_cond.isValid() || (m_cond.indexIn(m_value) != -1)); } - virtual void onTransition() {} + virtual void onTransition(QEvent *) {} private: QString m_value; @@ -1154,11 +1418,11 @@ public: { m_value = value; } protected: - virtual void onEntry() + virtual void onEntry(QEvent *) { m_machine->postEvent(new StringEvent(m_value)); } - virtual void onExit() {} + virtual void onExit(QEvent *) {} private: QStateMachine *m_machine; @@ -1200,7 +1464,7 @@ void tst_QStateMachine::stateFinished() s1_1->addTransition(s1_2); s1->setInitialState(s1_1); QFinalState *s2 = new QFinalState(machine.rootState()); - s1->addTransition(new QStateFinishedTransition(s1, QList<QAbstractState*>() << s2)); + s1->addTransition(s1, SIGNAL(finished()), s2); machine.setInitialState(s1); QSignalSpy finishedSpy(&machine, SIGNAL(finished())); machine.start(); @@ -1213,7 +1477,8 @@ void tst_QStateMachine::parallelStates() { QStateMachine machine; - QState *s1 = new QState(QState::ParallelGroup); + QState *s1 = new QState(QState::ParallelStates); + QCOMPARE(s1->childMode(), QState::ParallelStates); QState *s1_1 = new QState(s1); QState *s1_1_1 = new QState(s1_1); QFinalState *s1_1_f = new QFinalState(s1_1); @@ -1229,12 +1494,14 @@ void tst_QStateMachine::parallelStates() QFinalState *s2 = new QFinalState(); machine.addState(s2); - s1->addFinishedTransition(s2); + s1->addTransition(s1, SIGNAL(finished()), s2); machine.setInitialState(s1); QSignalSpy finishedSpy(&machine, SIGNAL(finished())); machine.start(); QTRY_COMPARE(finishedSpy.count(), 1); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s2)); } void tst_QStateMachine::allSourceToTargetConfigurations() @@ -1345,9 +1612,28 @@ void tst_QStateMachine::signalTransitions() { QStateMachine machine; QState *s0 = new QState(machine.rootState()); - QFinalState *s1 = new QFinalState(machine.rootState()); + QTest::ignoreMessage(QtWarningMsg, "QState::addTransition: sender cannot be null"); + QCOMPARE(s0->addTransition(0, SIGNAL(noSuchSignal()), 0), (QObject*)0); + SignalEmitter emitter; - s0->addTransition(&emitter, SIGNAL(signalWithNoArg()), s1); + QTest::ignoreMessage(QtWarningMsg, "QState::addTransition: signal cannot be null"); + QCOMPARE(s0->addTransition(&emitter, 0, 0), (QObject*)0); + + QTest::ignoreMessage(QtWarningMsg, "QState::addTransition: cannot add transition to null state"); + QCOMPARE(s0->addTransition(&emitter, SIGNAL(signalWithNoArg()), 0), (QObject*)0); + + QFinalState *s1 = new QFinalState(machine.rootState()); + QTest::ignoreMessage(QtWarningMsg, "QState::addTransition: no such signal SignalEmitter::noSuchSignal()"); + QCOMPARE(s0->addTransition(&emitter, SIGNAL(noSuchSignal()), s1), (QObject*)0); + + { + QSignalTransition *trans = s0->addTransition(&emitter, SIGNAL(signalWithNoArg()), s1); + QVERIFY(trans != 0); + QCOMPARE(trans->sourceState(), s0); + QCOMPARE(trans->targetState(), (QAbstractState*)s1); + QCOMPARE(trans->senderObject(), (QObject*)&emitter); + QCOMPARE(trans->signal(), QByteArray(SIGNAL(signalWithNoArg()))); + } QSignalSpy finishedSpy(&machine, SIGNAL(finished())); machine.setInitialState(s0); @@ -1357,6 +1643,8 @@ void tst_QStateMachine::signalTransitions() emitter.emitSignalWithNoArg(); QTRY_COMPARE(finishedSpy.count(), 1); + + emitter.emitSignalWithNoArg(); } { QStateMachine machine; @@ -1448,6 +1736,8 @@ void tst_QStateMachine::eventTransitions() QCoreApplication::processEvents(); QTRY_COMPARE(finishedSpy.count(), 1); + + QTest::mousePress(&button, Qt::LeftButton); } { QStateMachine machine; @@ -1455,10 +1745,10 @@ void tst_QStateMachine::eventTransitions() QFinalState *s1 = new QFinalState(machine.rootState()); QEventTransition *trans = new QEventTransition(); - QCOMPARE(trans->eventSource(), (QObject*)0); + QCOMPARE(trans->eventObject(), (QObject*)0); QCOMPARE(trans->eventType(), QEvent::None); - trans->setEventSource(&button); - QCOMPARE(trans->eventSource(), (QObject*)&button); + trans->setEventObject(&button); + QCOMPARE(trans->eventObject(), (QObject*)&button); trans->setEventType(QEvent::MouseButtonPress); QCOMPARE(trans->eventType(), QEvent::MouseButtonPress); trans->setTargetState(s1); @@ -1480,10 +1770,10 @@ void tst_QStateMachine::eventTransitions() QFinalState *s1 = new QFinalState(machine.rootState()); QMouseEventTransition *trans = new QMouseEventTransition(); - QCOMPARE(trans->eventSource(), (QObject*)0); + QCOMPARE(trans->eventObject(), (QObject*)0); QCOMPARE(trans->eventType(), QEvent::None); QCOMPARE(trans->button(), Qt::NoButton); - trans->setEventSource(&button); + trans->setEventObject(&button); trans->setEventType(QEvent::MouseButtonPress); trans->setButton(Qt::LeftButton); trans->setTargetState(s1); @@ -1527,10 +1817,10 @@ void tst_QStateMachine::eventTransitions() QFinalState *s1 = new QFinalState(machine.rootState()); QKeyEventTransition *trans = new QKeyEventTransition(); - QCOMPARE(trans->eventSource(), (QObject*)0); + QCOMPARE(trans->eventObject(), (QObject*)0); QCOMPARE(trans->eventType(), QEvent::None); QCOMPARE(trans->key(), 0); - trans->setEventSource(&button); + trans->setEventObject(&button); trans->setEventType(QEvent::KeyPress); trans->setKey(Qt::Key_A); trans->setTargetState(s1); @@ -1555,7 +1845,7 @@ void tst_QStateMachine::historyStates() QState *s0 = new QState(root); QState *s00 = new QState(s0); QState *s01 = new QState(s0); - QHistoryState *s0h = s0->addHistoryState(); + QHistoryState *s0h = new QHistoryState(s0); QState *s1 = new QState(root); QFinalState *s2 = new QFinalState(root); @@ -1599,152 +1889,76 @@ void tst_QStateMachine::historyStates() QTRY_COMPARE(finishedSpy.count(), 1); } -class TestStateAction : public QStateAction -{ -public: - TestStateAction() : m_didExecute(false) - {} - bool didExecute() const { - return m_didExecute; - } -protected: - void execute() { - m_didExecute = true; - } -private: - bool m_didExecute; -}; - -void tst_QStateMachine::stateActions() +void tst_QStateMachine::startAndStop() { QStateMachine machine; - QState *s1 = new QState(machine.rootState()); - - QVERIFY(s1->entryActions().isEmpty()); - QVERIFY(s1->exitActions().isEmpty()); - - QTest::ignoreMessage(QtWarningMsg, "QActionState::addEntryAction: cannot add null action"); - s1->addEntryAction(0); - QTest::ignoreMessage(QtWarningMsg, "QActionState::addExitAction: cannot add null action"); - s1->addExitAction(0); - QTest::ignoreMessage(QtWarningMsg, "QActionState::removeEntryAction: cannot remove null action"); - s1->removeEntryAction(0); - QTest::ignoreMessage(QtWarningMsg, "QActionState::removeExitAction: cannot remove null action"); - s1->removeExitAction(0); - - QFinalState *s2 = new QFinalState(machine.rootState()); - s1->addTransition(s2); - - machine.setInitialState(s1); + QSignalSpy startedSpy(&machine, SIGNAL(started())); + QSignalSpy stoppedSpy(&machine, SIGNAL(stopped())); QSignalSpy finishedSpy(&machine, SIGNAL(finished())); - - QObject *obj = new QObject(); - QStateInvokeMethodAction *ima = new QStateInvokeMethodAction(obj, "deleteLater"); - QPointer<QObject> ptr(obj); - QVERIFY(ptr != 0); - s1->addEntryAction(ima); - finishedSpy.clear(); + QVERIFY(!machine.isRunning()); + QTest::ignoreMessage(QtWarningMsg, "QStateMachine::start: No initial state set for machine. Refusing to start."); machine.start(); - QTRY_COMPARE(finishedSpy.count(), 1); - QCoreApplication::processEvents(); - QVERIFY(ptr == 0); - - s1->removeEntryAction(ima); + QCOMPARE(startedSpy.count(), 0); + QCOMPARE(stoppedSpy.count(), 0); + QCOMPARE(finishedSpy.count(), 0); + QVERIFY(!machine.isRunning()); + machine.stop(); + QCOMPARE(startedSpy.count(), 0); + QCOMPARE(stoppedSpy.count(), 0); + QCOMPARE(finishedSpy.count(), 0); - s1->invokeMethodOnEntry(ima, "deleteLater"); - QCOMPARE(s1->entryActions().size(), 1); - - ptr = ima; - QVERIFY(ptr != 0); - finishedSpy.clear(); - machine.start(); - QTRY_COMPARE(finishedSpy.count(), 1); - QCoreApplication::processEvents(); - QVERIFY(ptr == 0); - - while (!s1->entryActions().isEmpty()) { - QStateAction *act = s1->entryActions().first(); - s1->removeEntryAction(act); - delete act; - } - - TestStateAction *act1 = new TestStateAction(); - s1->addEntryAction(act1); - TestStateAction *act2 = new TestStateAction(); - s1->addExitAction(act2); - QVERIFY(!act1->didExecute()); - QVERIFY(!act2->didExecute()); - - finishedSpy.clear(); + QState *s1 = new QState(machine.rootState()); + machine.setInitialState(s1); machine.start(); - QTRY_COMPARE(finishedSpy.count(), 1); - - QVERIFY(act1->didExecute()); - QVERIFY(act2->didExecute()); + QTRY_COMPARE(machine.isRunning(), true); + QTRY_COMPARE(startedSpy.count(), 1); + QCOMPARE(stoppedSpy.count(), 0); + QCOMPARE(finishedSpy.count(), 0); + QCOMPARE(machine.configuration().count(), 1); + QVERIFY(machine.configuration().contains(s1)); - QCOMPARE(s1->entryActions().size(), 1); - QCOMPARE(s2->entryActions().size(), 0); - s2->addEntryAction(act1); // should remove it from s1 - QCOMPARE(s1->entryActions().size(), 0); - QCOMPARE(s2->entryActions().size(), 1); - QCOMPARE(act1->parent(), (QObject*)s2); + machine.stop(); + QTRY_COMPARE(machine.isRunning(), false); + QTRY_COMPARE(stoppedSpy.count(), 1); + QCOMPARE(startedSpy.count(), 1); + QCOMPARE(finishedSpy.count(), 0); - QCOMPARE(s2->exitActions().size(), 0); - s2->addExitAction(act1); // should remove entry action - QCOMPARE(s2->exitActions().size(), 1); - QCOMPARE(s2->entryActions().size(), 0); - QCOMPARE(act1->parent(), (QObject*)s2); + QCOMPARE(machine.configuration().count(), 1); + QVERIFY(machine.configuration().contains(s1)); } -void tst_QStateMachine::transitionActions() +void tst_QStateMachine::targetStateWithNoParent() { QStateMachine machine; QState *s1 = new QState(machine.rootState()); - - QFinalState *s2 = new QFinalState(machine.rootState()); - QTransition *trans = new EventTransition(QEvent::User, s2); - s1->addTransition(trans); - QVERIFY(trans->actions().isEmpty()); - QTest::ignoreMessage(QtWarningMsg, "QTransition::addAction: cannot add null action"); - trans->addAction(0); - QVERIFY(trans->actions().isEmpty()); - - TestStateAction *act = new TestStateAction(); - trans->addAction(act); - QCOMPARE(trans->actions().size(), 1); - QCOMPARE(trans->actions().at(0), (QStateAction*)act); - QCOMPARE(act->parent(), (QObject*)trans); - QVERIFY(!act->didExecute()); - - trans->removeAction(act); - QVERIFY(trans->actions().isEmpty()); - QCOMPARE(act->parent(), (QObject*)0); - - trans->addAction(act); - - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + s1->setObjectName("s1"); + QState *s2 = new QState(); + s1->addTransition(s2); machine.setInitialState(s1); + QSignalSpy startedSpy(&machine, SIGNAL(started())); + QSignalSpy stoppedSpy(&machine, SIGNAL(stopped())); + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - QTRY_COMPARE(finishedSpy.count(), 1); - QVERIFY(act->didExecute()); - - trans->invokeMethodOnTransition(act, "deleteLater"); - - QPointer<QStateAction> ptr(act); - QVERIFY(ptr != 0); - finishedSpy.clear(); - machine.start(); - QCoreApplication::processEvents(); + QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: No common ancestor for targets and source of transition from state 's1'"); + QTRY_COMPARE(machine.isRunning(), true); + QTRY_COMPARE(startedSpy.count(), 1); + QCOMPARE(stoppedSpy.count(), 0); + QCOMPARE(finishedSpy.count(), 0); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(machine.errorState())); + QCOMPARE(machine.error(), QStateMachine::NoCommonAncestorForTransitionError); +} - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - QTRY_COMPARE(finishedSpy.count(), 1); - QCoreApplication::processEvents(); - QVERIFY(ptr == 0); +void tst_QStateMachine::targetStateDeleted() +{ + QStateMachine machine; + QState *s1 = new QState(machine.rootState()); + s1->setObjectName("s1"); + QState *s2 = new QState(machine.rootState()); + QAbstractTransition *trans = s1->addTransition(s2); + delete s2; + QCOMPARE(trans->targetState(), (QAbstractState*)0); + QVERIFY(trans->targetStates().isEmpty()); } void tst_QStateMachine::defaultGlobalRestorePolicy() @@ -1756,10 +1970,10 @@ void tst_QStateMachine::defaultGlobalRestorePolicy() propertyHolder->setProperty("b", 2); QState *s1 = new QState(machine.rootState()); - s1->setPropertyOnEntry(propertyHolder, "a", 3); + s1->assignProperty(propertyHolder, "a", 3); QState *s2 = new QState(machine.rootState()); - s2->setPropertyOnEntry(propertyHolder, "b", 4); + s2->assignProperty(propertyHolder, "b", 4); QState *s3 = new QState(machine.rootState()); @@ -1786,6 +2000,7 @@ void tst_QStateMachine::defaultGlobalRestorePolicy() QCOMPARE(propertyHolder->property("b").toInt(), 4); } +/* void tst_QStateMachine::restorePolicyNotInherited() { QStateMachine machine; @@ -1800,12 +2015,12 @@ void tst_QStateMachine::restorePolicyNotInherited() QState *s1 = new QState(parentState); s1->setObjectName("s1"); - s1->setPropertyOnEntry(propertyHolder, "a", 3); + s1->assignProperty(propertyHolder, "a", 3); parentState->setInitialState(s1); QState *s2 = new QState(parentState); s2->setObjectName("s2"); - s2->setPropertyOnEntry(propertyHolder, "b", 4); + s2->assignProperty(propertyHolder, "b", 4); QState *s3 = new QState(parentState); s3->setObjectName("s3"); @@ -1832,22 +2047,22 @@ void tst_QStateMachine::restorePolicyNotInherited() QCOMPARE(propertyHolder->property("a").toInt(), 3); QCOMPARE(propertyHolder->property("b").toInt(), 4); -} +}*/ void tst_QStateMachine::globalRestorePolicySetToDoNotRestore() { QStateMachine machine; - machine.setGlobalRestorePolicy(QState::DoNotRestoreProperties); + machine.setGlobalRestorePolicy(QStateMachine::DoNotRestoreProperties); QObject *propertyHolder = new QObject(); propertyHolder->setProperty("a", 1); propertyHolder->setProperty("b", 2); QState *s1 = new QState(machine.rootState()); - s1->setPropertyOnEntry(propertyHolder, "a", 3); + s1->assignProperty(propertyHolder, "a", 3); QState *s2 = new QState(machine.rootState()); - s2->setPropertyOnEntry(propertyHolder, "b", 4); + s2->assignProperty(propertyHolder, "b", 4); QState *s3 = new QState(machine.rootState()); @@ -1874,6 +2089,7 @@ void tst_QStateMachine::globalRestorePolicySetToDoNotRestore() QCOMPARE(propertyHolder->property("b").toInt(), 4); } +/* void tst_QStateMachine::setRestorePolicyToDoNotRestore() { QObject *object = new QObject(); @@ -1884,13 +2100,13 @@ void tst_QStateMachine::setRestorePolicyToDoNotRestore() QState *S1 = new QState(); S1->setObjectName("S1"); - S1->setPropertyOnEntry(object, "a", 3); + S1->assignProperty(object, "a", 3); S1->setRestorePolicy(QState::DoNotRestoreProperties); machine.addState(S1); QState *S2 = new QState(); S2->setObjectName("S2"); - S2->setPropertyOnEntry(object, "b", 5); + S2->assignProperty(object, "b", 5); S2->setRestorePolicy(QState::DoNotRestoreProperties); machine.addState(S2); @@ -1930,19 +2146,20 @@ void tst_QStateMachine::setGlobalRestorePolicyToGlobalRestore() { s_countWarnings = false; QStateMachine machine; - machine.setGlobalRestorePolicy(QState::GlobalRestorePolicy); + machine.setGlobalRestorePolicy(QStateMachine::GlobalRestorePolicy); - QCOMPARE(machine.globalRestorePolicy(), QState::DoNotRestoreProperties); + QCOMPARE(machine.globalRestorePolicy(), QStateMachine::DoNotRestoreProperties); QCOMPARE(s_msgType, QtWarningMsg); s_msgType = QtDebugMsg; - machine.setGlobalRestorePolicy(QState::RestoreProperties); - machine.setGlobalRestorePolicy(QState::GlobalRestorePolicy); + machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); + machine.setGlobalRestorePolicy(QStateMachine::GlobalRestorePolicy); - QCOMPARE(machine.globalRestorePolicy(), QState::RestoreProperties); + QCOMPARE(machine.globalRestorePolicy(), QStateMachine::RestoreProperties); QCOMPARE(s_msgType, QtWarningMsg); } + void tst_QStateMachine::restorePolicyOnChildState() { QStateMachine machine; @@ -1957,13 +2174,13 @@ void tst_QStateMachine::restorePolicyOnChildState() QState *s1 = new QState(parentState); s1->setRestorePolicy(QState::RestoreProperties); s1->setObjectName("s1"); - s1->setPropertyOnEntry(propertyHolder, "a", 3); + s1->assignProperty(propertyHolder, "a", 3); parentState->setInitialState(s1); QState *s2 = new QState(parentState); s2->setRestorePolicy(QState::RestoreProperties); s2->setObjectName("s2"); - s2->setPropertyOnEntry(propertyHolder, "b", 4); + s2->assignProperty(propertyHolder, "b", 4); QState *s3 = new QState(parentState); s3->setRestorePolicy(QState::RestoreProperties); @@ -1991,21 +2208,22 @@ void tst_QStateMachine::restorePolicyOnChildState() QCOMPARE(propertyHolder->property("a").toInt(), 1); QCOMPARE(propertyHolder->property("b").toInt(), 2); } +*/ void tst_QStateMachine::globalRestorePolicySetToRestore() { QStateMachine machine; - machine.setGlobalRestorePolicy(QState::RestoreProperties); + machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); QObject *propertyHolder = new QObject(); propertyHolder->setProperty("a", 1); propertyHolder->setProperty("b", 2); QState *s1 = new QState(machine.rootState()); - s1->setPropertyOnEntry(propertyHolder, "a", 3); + s1->assignProperty(propertyHolder, "a", 3); QState *s2 = new QState(machine.rootState()); - s2->setPropertyOnEntry(propertyHolder, "b", 4); + s2->assignProperty(propertyHolder, "b", 4); QState *s3 = new QState(machine.rootState()); @@ -2032,6 +2250,7 @@ void tst_QStateMachine::globalRestorePolicySetToRestore() QCOMPARE(propertyHolder->property("b").toInt(), 2); } +/* void tst_QStateMachine::mixedRestoreProperties() { QStateMachine machine; @@ -2041,19 +2260,19 @@ void tst_QStateMachine::mixedRestoreProperties() QState *s1 = new QState(machine.rootState()); s1->setRestorePolicy(QState::RestoreProperties); - s1->setPropertyOnEntry(propertyHolder, "a", 3); + s1->assignProperty(propertyHolder, "a", 3); QState *s2 = new QState(machine.rootState()); - s2->setPropertyOnEntry(propertyHolder, "a", 4); + s2->assignProperty(propertyHolder, "a", 4); QState *s3 = new QState(machine.rootState()); QState *s4 = new QState(machine.rootState()); - s4->setPropertyOnEntry(propertyHolder, "a", 5); + s4->assignProperty(propertyHolder, "a", 5); QState *s5 = new QState(machine.rootState()); s5->setRestorePolicy(QState::RestoreProperties); - s5->setPropertyOnEntry(propertyHolder, "a", 6); + s5->assignProperty(propertyHolder, "a", 6); s1->addTransition(new EventTransition(QEvent::User, s2)); s2->addTransition(new EventTransition(QEvent::User, s3)); @@ -2098,6 +2317,7 @@ void tst_QStateMachine::mixedRestoreProperties() // Enter s3, restore QCOMPARE(propertyHolder->property("a").toInt(), 5); } +*/ void tst_QStateMachine::transitionWithParent() { @@ -2111,5 +2331,1043 @@ void tst_QStateMachine::transitionWithParent() QCOMPARE(trans->targetStates().at(0), (QAbstractState*)s2); } +void tst_QStateMachine::simpleAnimation() +{ + QStateMachine machine; + + QObject *object = new QObject(); + object->setProperty("fooBar", 1.0); + + QState *s1 = new QState(machine.rootState()); + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(object, "fooBar", 2.0); + + EventTransition *et = new EventTransition(QEvent::User, s2); + QPropertyAnimation *animation = new QPropertyAnimation(object, "fooBar", s2); + et->addAnimation(animation); + s1->addTransition(et); + + QState *s3 = new QState(machine.rootState()); + s2->addTransition(animation, SIGNAL(finished()), s3); + QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); + + machine.setInitialState(s1); + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::User)); + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s3)); + QCOMPARE(object->property("fooBar").toDouble(), 2.0); +} + +class SlotCalledCounter: public QObject +{ + Q_OBJECT +public: + SlotCalledCounter() : counter(0) {} + + int counter; + +public slots: + void slot() { counter++; } +}; + +void tst_QStateMachine::twoAnimations() +{ + QStateMachine machine; + + QObject *object = new QObject(); + object->setProperty("foo", 1.0); + object->setProperty("bar", 3.0); + + QState *s1 = new QState(machine.rootState()); + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(object, "foo", 2.0); + s2->assignProperty(object, "bar", 10.0); + + QPropertyAnimation *animationFoo = new QPropertyAnimation(object, "foo", s2); + QPropertyAnimation *animationBar = new QPropertyAnimation(object, "bar", s2); + animationBar->setDuration(900); + + SlotCalledCounter counter; + connect(animationFoo, SIGNAL(finished()), &counter, SLOT(slot())); + connect(animationBar, SIGNAL(finished()), &counter, SLOT(slot())); + + EventTransition *et = new EventTransition(QEvent::User, s2); + et->addAnimation(animationFoo); + et->addAnimation(animationBar); + s1->addTransition(et); + + QState *s3 = new QState(machine.rootState()); + QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); + s2->addTransition(s2, SIGNAL(polished()), s3); + + machine.setInitialState(s1); + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::User)); + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s3)); + QCOMPARE(object->property("foo").toDouble(), 2.0); + QCOMPARE(object->property("bar").toDouble(), 10.0); + + QCOMPARE(counter.counter, 2); +} + +void tst_QStateMachine::twoAnimatedTransitions() +{ + QStateMachine machine; + + QObject *object = new QObject(); + object->setProperty("foo", 1.0); + + QState *s1 = new QState(machine.rootState()); + + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(object, "foo", 5.0); + QPropertyAnimation *fooAnimation = new QPropertyAnimation(object, "foo", s2); + s1->addTransition(new EventTransition(QEvent::User, s2))->addAnimation(fooAnimation); + + QState *s3 = new QState(machine.rootState()); + QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); + s2->addTransition(fooAnimation, SIGNAL(finished()), s3); + + QState *s4 = new QState(machine.rootState()); + s4->assignProperty(object, "foo", 2.0); + QPropertyAnimation *fooAnimation2 = new QPropertyAnimation(object, "foo", s4); + s3->addTransition(new EventTransition(QEvent::User, s4))->addAnimation(fooAnimation2); + + QState *s5 = new QState(machine.rootState()); + QObject::connect(s5, SIGNAL(entered()), QApplication::instance(), SLOT(quit())); + s4->addTransition(fooAnimation2, SIGNAL(finished()), s5); + + machine.setInitialState(s1); + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::User)); + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s3)); + QCOMPARE(object->property("foo").toDouble(), 5.0); + + machine.postEvent(new QEvent(QEvent::User)); + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s5)); + QCOMPARE(object->property("foo").toDouble(), 2.0); +} + +void tst_QStateMachine::playAnimationTwice() +{ + QStateMachine machine; + + QObject *object = new QObject(); + object->setProperty("foo", 1.0); + + QState *s1 = new QState(machine.rootState()); + + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(object, "foo", 5.0); + QPropertyAnimation *fooAnimation = new QPropertyAnimation(object, "foo", s2); + s1->addTransition(new EventTransition(QEvent::User, s2))->addAnimation(fooAnimation); + + QState *s3 = new QState(machine.rootState()); + QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); + s2->addTransition(fooAnimation, SIGNAL(finished()), s3); + + QState *s4 = new QState(machine.rootState()); + s4->assignProperty(object, "foo", 2.0); + s3->addTransition(new EventTransition(QEvent::User, s4))->addAnimation(fooAnimation); + + QState *s5 = new QState(machine.rootState()); + QObject::connect(s5, SIGNAL(entered()), QApplication::instance(), SLOT(quit())); + s4->addTransition(fooAnimation, SIGNAL(finished()), s5); + + machine.setInitialState(s1); + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::User)); + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s3)); + QCOMPARE(object->property("foo").toDouble(), 5.0); + + machine.postEvent(new QEvent(QEvent::User)); + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s5)); + QCOMPARE(object->property("foo").toDouble(), 2.0); +} + +void tst_QStateMachine::nestedTargetStateForAnimation() +{ + QStateMachine machine; + + QObject *object = new QObject(); + object->setProperty("foo", 1.0); + object->setProperty("bar", 3.0); + + SlotCalledCounter counter; + + QState *s1 = new QState(machine.rootState()); + QState *s2 = new QState(machine.rootState()); + + s2->assignProperty(object, "foo", 2.0); + + QState *s2Child = new QState(s2); + s2Child->assignProperty(object, "bar", 10.0); + s2->setInitialState(s2Child); + + QState *s2Child2 = new QState(s2); + s2Child2->assignProperty(object, "bar", 11.0); + QAbstractTransition *at = s2Child->addTransition(new EventTransition(QEvent::User, s2Child2)); + + 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)); + + animation = new QPropertyAnimation(object, "foo", s2); + connect(animation, SIGNAL(finished()), &counter, SLOT(slot())); + at->addAnimation(animation); + + animation = new QPropertyAnimation(object, "bar", s2); + connect(animation, SIGNAL(finished()), &counter, SLOT(slot())); + at->addAnimation(animation); + + QState *s3 = new QState(machine.rootState()); + s2->addTransition(s2Child, SIGNAL(polished()), s3); + + QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); + + machine.setInitialState(s1); + machine.start(); + QCoreApplication::processEvents(); + machine.postEvent(new QEvent(QEvent::User)); + + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s3)); + QCOMPARE(object->property("foo").toDouble(), 2.0); + QCOMPARE(object->property("bar").toDouble(), 10.0); + QCOMPARE(counter.counter, 2); +} + +void tst_QStateMachine::animatedGlobalRestoreProperty() +{ + QStateMachine machine; + machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); + + QObject *object = new QObject(); + object->setProperty("foo", 1.0); + + SlotCalledCounter counter; + + QState *s1 = new QState(machine.rootState()); + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(object, "foo", 2.0); + + QState *s3 = new QState(machine.rootState()); + + QState *s4 = new QState(machine.rootState()); + QObject::connect(s4, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); + + QAbstractTransition *at = s1->addTransition(new EventTransition(QEvent::User, s2)); + QPropertyAnimation *pa = new QPropertyAnimation(object, "foo", s2); + connect(pa, SIGNAL(finished()), &counter, SLOT(slot())); + at->addAnimation(pa); + + at = s2->addTransition(pa, SIGNAL(finished()), s3); + pa = new QPropertyAnimation(object, "foo", s3); + connect(pa, SIGNAL(finished()), &counter, SLOT(slot())); + at->addAnimation(pa); + + at = s3->addTransition(pa, SIGNAL(finished()), s4); + pa = new QPropertyAnimation(object, "foo", s4); + connect(pa, SIGNAL(finished()), &counter, SLOT(slot())); + at->addAnimation(pa); + + machine.setInitialState(s1); + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::User)); + + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s4)); + QCOMPARE(object->property("foo").toDouble(), 1.0); + QCOMPARE(counter.counter, 2); +} + +void tst_QStateMachine::specificTargetValueOfAnimation() +{ + QStateMachine machine; + + QObject *object = new QObject(); + object->setProperty("foo", 1.0); + + QState *s1 = new QState(machine.rootState()); + + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(object, "foo", 2.0); + + QPropertyAnimation *anim = new QPropertyAnimation(object, "foo"); + anim->setEndValue(10.0); + s1->addTransition(new EventTransition(QEvent::User, s2))->addAnimation(anim); + + QState *s3 = new QState(machine.rootState()); + QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); + s2->addTransition(anim, SIGNAL(finished()), s3); + + machine.setInitialState(s1); + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::User)); + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s3)); + QCOMPARE(object->property("foo").toDouble(), 2.0); + QCOMPARE(anim->endValue().toDouble(), 10.0); +} + +void tst_QStateMachine::addDefaultAnimation() +{ + QStateMachine machine; + + QObject *object = new QObject(); + object->setProperty("foo", 1.0); + + QState *s1 = new QState(machine.rootState()); + + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(object, "foo", 2.0); + + QState *s3 = new QState(machine.rootState()); + QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); + + s1->addTransition(new EventTransition(QEvent::User, s2)); + + QPropertyAnimation *pa = new QPropertyAnimation(object, "foo", &machine); + machine.addDefaultAnimation(pa); + s2->addTransition(pa, SIGNAL(finished()), s3); + + machine.setInitialState(s1); + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::User)); + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s3)); + QCOMPARE(object->property("foo").toDouble(), 2.0); +} + +void tst_QStateMachine::addDefaultAnimationWithUnusedAnimation() +{ + QStateMachine machine; + + QObject *object = new QObject(); + object->setProperty("foo", 1.0); + object->setProperty("bar", 2.0); + + SlotCalledCounter counter; + + QState *s1 = new QState(machine.rootState()); + + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(object, "foo", 2.0); + + QState *s3 = new QState(machine.rootState()); + QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); + + s1->addTransition(new EventTransition(QEvent::User, s2)); + + QPropertyAnimation *pa = new QPropertyAnimation(object, "foo", &machine); + connect(pa, SIGNAL(finished()), &counter, SLOT(slot())); + machine.addDefaultAnimation(pa); + s2->addTransition(pa, SIGNAL(finished()), s3); + + pa = new QPropertyAnimation(object, "bar", &machine); + connect(pa, SIGNAL(finished()), &counter, SLOT(slot())); + machine.addDefaultAnimation(pa); + + machine.setInitialState(s1); + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::User)); + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s3)); + QCOMPARE(object->property("foo").toDouble(), 2.0); + QCOMPARE(counter.counter, 1); +} + +void tst_QStateMachine::removeDefaultAnimation() +{ + QStateMachine machine; + + QObject propertyHolder; + propertyHolder.setProperty("foo", 0); + + QCOMPARE(machine.defaultAnimations().size(), 0); + + QPropertyAnimation *anim = new QPropertyAnimation(&propertyHolder, "foo"); + + machine.addDefaultAnimation(anim); + + QCOMPARE(machine.defaultAnimations().size(), 1); + QVERIFY(machine.defaultAnimations().contains(anim)); + + machine.removeDefaultAnimation(anim); + + QCOMPARE(machine.defaultAnimations().size(), 0); + + machine.addDefaultAnimation(anim); + + QPropertyAnimation *anim2 = new QPropertyAnimation(&propertyHolder, "foo"); + machine.addDefaultAnimation(anim2); + + QCOMPARE(machine.defaultAnimations().size(), 2); + QVERIFY(machine.defaultAnimations().contains(anim)); + QVERIFY(machine.defaultAnimations().contains(anim2)); + + machine.removeDefaultAnimation(anim); + + QCOMPARE(machine.defaultAnimations().size(), 1); + QVERIFY(machine.defaultAnimations().contains(anim2)); + + machine.removeDefaultAnimation(anim2); + QCOMPARE(machine.defaultAnimations().size(), 0); +} + +void tst_QStateMachine::overrideDefaultAnimationWithSpecific() +{ + QStateMachine machine; + + QObject *object = new QObject(); + object->setProperty("foo", 1.0); + + SlotCalledCounter counter; + + QState *s1 = new QState(machine.rootState()); + machine.setInitialState(s1); + + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(object, "foo", 2.0); + + QState *s3 = new QState(machine.rootState()); + QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); + + QAbstractTransition *at = s1->addTransition(new EventTransition(QEvent::User, s2)); + + QPropertyAnimation *defaultAnimation = new QPropertyAnimation(object, "foo"); + connect(defaultAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); + + QPropertyAnimation *moreSpecificAnimation = new QPropertyAnimation(object, "foo"); + s2->addTransition(moreSpecificAnimation, SIGNAL(finished()), s3); + connect(moreSpecificAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); + + machine.addDefaultAnimation(defaultAnimation); + at->addAnimation(moreSpecificAnimation); + + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::User)); + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s3)); + QCOMPARE(counter.counter, 2); // specific animation started and stopped +} + +/* +void tst_QStateMachine::addDefaultAnimationForSource() +{ + QStateMachine machine; + + QObject *object = new QObject(); + object->setProperty("foo", 1.0); + + QState *s1 = new QState(machine.rootState()); + + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(object, "foo", 2.0); + + QState *s3 = new QState(machine.rootState()); + QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); + + s1->addTransition(new EventTransition(QEvent::User, s2)); + + QPropertyAnimation *pa = new QPropertyAnimation(object, "foo", &machine); + machine.addDefaultAnimationForSourceState(s1, pa); + s2->addTransition(pa, SIGNAL(finished()), s3); + + machine.setInitialState(s1); + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::User)); + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s3)); + QCOMPARE(object->property("foo").toDouble(), 2.0); +} + +void tst_QStateMachine::addDefaultAnimationForTarget() +{ + QStateMachine machine; + + QObject *object = new QObject(); + object->setProperty("foo", 1.0); + + QState *s1 = new QState(machine.rootState()); + + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(object, "foo", 2.0); + + QState *s3 = new QState(machine.rootState()); + QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); + + s1->addTransition(new EventTransition(QEvent::User, s2)); + + QPropertyAnimation *pa = new QPropertyAnimation(object, "foo", &machine); + machine.addDefaultAnimationForTargetState(s2, pa); + s2->addTransition(pa, SIGNAL(finished()), s3); + + machine.setInitialState(s1); + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::User)); + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s3)); + QCOMPARE(object->property("foo").toDouble(), 2.0); +} + +void tst_QStateMachine::removeDefaultAnimationForSource() +{ + QStateMachine machine; + + QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 0); + + QPropertyAnimation *anim = new QPropertyAnimation(this, "foo"); + + machine.addDefaultAnimationForSourceState(machine.rootState(), anim); + + QCOMPARE(machine.defaultAnimations().size(), 0); + QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 0); + QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 1); + QVERIFY(machine.defaultAnimationsForSourceState(machine.rootState()).contains(anim)); + + machine.removeDefaultAnimationForTargetState(machine.rootState(), anim); + + QCOMPARE(machine.defaultAnimations().size(), 0); + QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 0); + QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 1); + QVERIFY(machine.defaultAnimationsForSourceState(machine.rootState()).contains(anim)); + + machine.removeDefaultAnimationForSourceState(machine.rootState(), anim); + + QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 0); + + machine.addDefaultAnimationForSourceState(machine.rootState(), anim); + + QPropertyAnimation *anim2 = new QPropertyAnimation(this, "foo"); + machine.addDefaultAnimationForSourceState(machine.rootState(), anim2); + + QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 2); + QVERIFY(machine.defaultAnimationsForSourceState(machine.rootState()).contains(anim)); + QVERIFY(machine.defaultAnimationsForSourceState(machine.rootState()).contains(anim2)); + + machine.removeDefaultAnimationForSourceState(machine.rootState(), anim); + + QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 1); + QVERIFY(machine.defaultAnimationsForSourceState(machine.rootState()).contains(anim2)); + + machine.removeDefaultAnimationForSourceState(machine.rootState(), anim2); + QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 0); +} + +void tst_QStateMachine::removeDefaultAnimationForTarget() +{ + QStateMachine machine; + + QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 0); + + QPropertyAnimation *anim = new QPropertyAnimation(this, "foo"); + + machine.addDefaultAnimationForTargetState(machine.rootState(), anim); + + QCOMPARE(machine.defaultAnimations().size(), 0); + QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 0); + QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 1); + QVERIFY(machine.defaultAnimationsForTargetState(machine.rootState()).contains(anim)); + + machine.removeDefaultAnimationForSourceState(machine.rootState(), anim); + + QCOMPARE(machine.defaultAnimations().size(), 0); + QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 0); + QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 1); + QVERIFY(machine.defaultAnimationsForTargetState(machine.rootState()).contains(anim)); + + machine.removeDefaultAnimationForTargetState(machine.rootState(), anim); + + QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 0); + + machine.addDefaultAnimationForTargetState(machine.rootState(), anim); + + QPropertyAnimation *anim2 = new QPropertyAnimation(this, "foo"); + machine.addDefaultAnimationForTargetState(machine.rootState(), anim2); + + QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 2); + QVERIFY(machine.defaultAnimationsForTargetState(machine.rootState()).contains(anim)); + QVERIFY(machine.defaultAnimationsForTargetState(machine.rootState()).contains(anim2)); + + machine.removeDefaultAnimationForTargetState(machine.rootState(), anim); + + QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 1); + QVERIFY(machine.defaultAnimationsForTargetState(machine.rootState()).contains(anim2)); + + machine.removeDefaultAnimationForTargetState(machine.rootState(), anim2); + QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 0); +} + +void tst_QStateMachine::overrideDefaultAnimationWithSource() +{ + QStateMachine machine; + + QObject *object = new QObject(); + object->setProperty("foo", 1.0); + + SlotCalledCounter counter; + + QState *s1 = new QState(machine.rootState()); + machine.setInitialState(s1); + + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(object, "foo", 2.0); + + QState *s3 = new QState(machine.rootState()); + QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); + + s1->addTransition(new EventTransition(QEvent::User, s2)); + + QPropertyAnimation *defaultAnimation = new QPropertyAnimation(object, "foo"); + connect(defaultAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); + + QPropertyAnimation *moreSpecificAnimation = new QPropertyAnimation(object, "foo"); + s2->addTransition(moreSpecificAnimation, SIGNAL(finished()), s3); + connect(moreSpecificAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); + + machine.addDefaultAnimation(defaultAnimation); + machine.addDefaultAnimationForSourceState(s1, moreSpecificAnimation); + + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::User)); + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s3)); + QCOMPARE(counter.counter, 2); // specific animation started and stopped +} + +void tst_QStateMachine::overrideDefaultAnimationWithTarget() +{ + QStateMachine machine; + + QObject *object = new QObject(); + object->setProperty("foo", 1.0); + + SlotCalledCounter counter; + + QState *s1 = new QState(machine.rootState()); + machine.setInitialState(s1); + + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(object, "foo", 2.0); + + QState *s3 = new QState(machine.rootState()); + QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); + + s1->addTransition(new EventTransition(QEvent::User, s2)); + + QPropertyAnimation *defaultAnimation = new QPropertyAnimation(object, "foo"); + connect(defaultAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); + + QPropertyAnimation *moreSpecificAnimation = new QPropertyAnimation(object, "foo"); + s2->addTransition(moreSpecificAnimation, SIGNAL(finished()), s3); + connect(moreSpecificAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); + + machine.addDefaultAnimation(defaultAnimation); + machine.addDefaultAnimationForTargetState(s2, moreSpecificAnimation); + + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::User)); + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s3)); + QCOMPARE(counter.counter, 2); // specific animation started and stopped + +} + +void tst_QStateMachine::overrideDefaultSourceAnimationWithSpecific() +{ + QStateMachine machine; + + QObject *object = new QObject(); + object->setProperty("foo", 1.0); + + SlotCalledCounter counter; + + QState *s1 = new QState(machine.rootState()); + machine.setInitialState(s1); + + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(object, "foo", 2.0); + + QState *s3 = new QState(machine.rootState()); + QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); + + QAbstractTransition *at = s1->addTransition(new EventTransition(QEvent::User, s2)); + + QPropertyAnimation *defaultAnimation = new QPropertyAnimation(object, "foo"); + connect(defaultAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); + + QPropertyAnimation *moreSpecificAnimation = new QPropertyAnimation(object, "foo"); + s2->addTransition(moreSpecificAnimation, SIGNAL(finished()), s3); + connect(moreSpecificAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); + + machine.addDefaultAnimationForSourceState(s1, defaultAnimation); + at->addAnimation(moreSpecificAnimation); + + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::User)); + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s3)); + QCOMPARE(counter.counter, 2); // specific animation started and stopped +} + +void tst_QStateMachine::overrideDefaultTargetAnimationWithSpecific() +{ + QStateMachine machine; + + QObject *object = new QObject(); + object->setProperty("foo", 1.0); + + SlotCalledCounter counter; + + QState *s1 = new QState(machine.rootState()); + machine.setInitialState(s1); + + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(object, "foo", 2.0); + + QState *s3 = new QState(machine.rootState()); + QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); + + QAbstractTransition *at = s1->addTransition(new EventTransition(QEvent::User, s2)); + + QPropertyAnimation *defaultAnimation = new QPropertyAnimation(object, "foo"); + connect(defaultAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); + + QPropertyAnimation *moreSpecificAnimation = new QPropertyAnimation(object, "foo"); + s2->addTransition(moreSpecificAnimation, SIGNAL(finished()), s3); + connect(moreSpecificAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); + + machine.addDefaultAnimationForTargetState(s2, defaultAnimation); + at->addAnimation(moreSpecificAnimation); + + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::User)); + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s3)); + QCOMPARE(counter.counter, 2); // specific animation started and stopped +} + +void tst_QStateMachine::overrideDefaultTargetAnimationWithSource() +{ + QStateMachine machine; + + QObject *object = new QObject(); + object->setProperty("foo", 1.0); + + SlotCalledCounter counter; + + QState *s1 = new QState(machine.rootState()); + machine.setInitialState(s1); + + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(object, "foo", 2.0); + + QState *s3 = new QState(machine.rootState()); + QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); + + s1->addTransition(new EventTransition(QEvent::User, s2)); + + QPropertyAnimation *defaultAnimation = new QPropertyAnimation(object, "foo"); + connect(defaultAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); + + QPropertyAnimation *moreSpecificAnimation = new QPropertyAnimation(object, "foo"); + s2->addTransition(moreSpecificAnimation, SIGNAL(finished()), s3); + connect(moreSpecificAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); + + machine.addDefaultAnimationForTargetState(s2, defaultAnimation); + machine.addDefaultAnimationForSourceState(s1, moreSpecificAnimation); + + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::User)); + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s3)); + QCOMPARE(counter.counter, 2); // specific animation started and stopped +} + +*/ + +void tst_QStateMachine::parallelStateAssignmentsDone() +{ + QStateMachine machine; + + QObject *propertyHolder = new QObject(&machine); + propertyHolder->setProperty("foo", 123); + propertyHolder->setProperty("bar", 456); + propertyHolder->setProperty("zoot", 789); + + QState *s1 = new QState(machine.rootState()); + machine.setInitialState(s1); + + QState *parallelState = new QState(QState::ParallelStates, machine.rootState()); + parallelState->assignProperty(propertyHolder, "foo", 321); + + QState *s2 = new QState(parallelState); + s2->assignProperty(propertyHolder, "bar", 654); + + QState *s3 = new QState(parallelState); + s3->assignProperty(propertyHolder, "zoot", 987); + + s1->addTransition(new EventTransition(QEvent::User, parallelState)); + machine.start(); + QCoreApplication::processEvents(); + + QCOMPARE(propertyHolder->property("foo").toInt(), 123); + QCOMPARE(propertyHolder->property("bar").toInt(), 456); + QCOMPARE(propertyHolder->property("zoot").toInt(), 789); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(propertyHolder->property("foo").toInt(), 321); + QCOMPARE(propertyHolder->property("bar").toInt(), 654); + QCOMPARE(propertyHolder->property("zoot").toInt(), 987); +} + +void tst_QStateMachine::transitionsFromParallelStateWithNoChildren() +{ + QStateMachine machine; + + QState *parallelState = new QState(QState::ParallelStates, machine.rootState()); + machine.setInitialState(parallelState); + + QState *s1 = new QState(machine.rootState()); + parallelState->addTransition(new EventTransition(QEvent::User, s1)); + + machine.start(); + QCoreApplication::processEvents(); + + QCOMPARE(1, machine.configuration().size()); + QVERIFY(machine.configuration().contains(parallelState)); + + machine.postEvent(new QEvent(QEvent::User)); + + QCoreApplication::processEvents(); + + QCOMPARE(1, machine.configuration().size()); + QVERIFY(machine.configuration().contains(s1)); +} + +void tst_QStateMachine::parallelStateTransition() +{ + QStateMachine machine; + + QState *parallelState = new QState(QState::ParallelStates, machine.rootState()); + machine.setInitialState(parallelState); + + QState *s1 = new QState(parallelState); + QState *s2 = new QState(parallelState); + + QState *s1InitialChild = new QState(s1); + s1->setInitialState(s1InitialChild); + + QState *s2InitialChild = new QState(s2); + s2->setInitialState(s2InitialChild); + + QState *s1OtherChild = new QState(s1); + + s1->addTransition(new EventTransition(QEvent::User, s1OtherChild)); + + machine.start(); + QCoreApplication::processEvents(); + + QVERIFY(machine.configuration().contains(parallelState)); + QVERIFY(machine.configuration().contains(s1)); + QVERIFY(machine.configuration().contains(s2)); + QVERIFY(machine.configuration().contains(s1InitialChild)); + QVERIFY(machine.configuration().contains(s2InitialChild)); + QCOMPARE(machine.configuration().size(), 5); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + 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)); + QCOMPARE(machine.configuration().size(), 5); + +} + +void tst_QStateMachine::nestedRestoreProperties() +{ + QStateMachine machine; + machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); + + QObject *propertyHolder = new QObject(&machine); + propertyHolder->setProperty("foo", 1); + propertyHolder->setProperty("bar", 2); + + QState *s1 = new QState(machine.rootState()); + machine.setInitialState(s1); + + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(propertyHolder, "foo", 3); + + QState *s21 = new QState(s2); + s21->assignProperty(propertyHolder, "bar", 4); + s2->setInitialState(s21); + + QState *s22 = new QState(s2); + s22->assignProperty(propertyHolder, "bar", 5); + + s1->addTransition(new EventTransition(QEvent::User, s2)); + s21->addTransition(new EventTransition(QEvent::User, s22)); + + machine.start(); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s1)); + QCOMPARE(propertyHolder->property("foo").toInt(), 1); + QCOMPARE(propertyHolder->property("bar").toInt(), 2); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().size(), 2); + QVERIFY(machine.configuration().contains(s2)); + QVERIFY(machine.configuration().contains(s21)); + QCOMPARE(propertyHolder->property("foo").toInt(), 3); + QCOMPARE(propertyHolder->property("bar").toInt(), 4); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().size(), 2); + QVERIFY(machine.configuration().contains(s2)); + QVERIFY(machine.configuration().contains(s22)); + QCOMPARE(propertyHolder->property("foo").toInt(), 3); + QCOMPARE(propertyHolder->property("bar").toInt(), 5); +} + +void tst_QStateMachine::nestedRestoreProperties2() +{ + QStateMachine machine; + machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); + + QObject *propertyHolder = new QObject(&machine); + propertyHolder->setProperty("foo", 1); + propertyHolder->setProperty("bar", 2); + + QState *s1 = new QState(machine.rootState()); + machine.setInitialState(s1); + + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(propertyHolder, "foo", 3); + + QState *s21 = new QState(s2); + s21->assignProperty(propertyHolder, "bar", 4); + s2->setInitialState(s21); + + QState *s22 = new QState(s2); + s22->assignProperty(propertyHolder, "foo", 6); + s22->assignProperty(propertyHolder, "bar", 5); + + s1->addTransition(new EventTransition(QEvent::User, s2)); + s21->addTransition(new EventTransition(QEvent::User, s22)); + s22->addTransition(new EventTransition(QEvent::User, s21)); + + machine.start(); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s1)); + QCOMPARE(propertyHolder->property("foo").toInt(), 1); + QCOMPARE(propertyHolder->property("bar").toInt(), 2); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().size(), 2); + QVERIFY(machine.configuration().contains(s2)); + QVERIFY(machine.configuration().contains(s21)); + QCOMPARE(propertyHolder->property("foo").toInt(), 3); + QCOMPARE(propertyHolder->property("bar").toInt(), 4); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().size(), 2); + QVERIFY(machine.configuration().contains(s2)); + QVERIFY(machine.configuration().contains(s22)); + QCOMPARE(propertyHolder->property("foo").toInt(), 6); + QCOMPARE(propertyHolder->property("bar").toInt(), 5); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().size(), 2); + QVERIFY(machine.configuration().contains(s2)); + QVERIFY(machine.configuration().contains(s21)); + QCOMPARE(propertyHolder->property("foo").toInt(), 3); + QCOMPARE(propertyHolder->property("bar").toInt(), 4); + +} + + QTEST_MAIN(tst_QStateMachine) #include "tst_qstatemachine.moc" |