summaryrefslogtreecommitdiffstats
path: root/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp')
-rw-r--r--tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp865
1 files changed, 865 insertions, 0 deletions
diff --git a/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp b/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp
new file mode 100644
index 0000000..293ea11
--- /dev/null
+++ b/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp
@@ -0,0 +1,865 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+
+#include <QtCore/qparallelanimationgroup.h>
+
+//TESTED_CLASS=QParallelAnimationGroup
+//TESTED_FILES=
+
+Q_DECLARE_METATYPE(QAbstractAnimation::State)
+
+class tst_QParallelAnimationGroup : public QObject
+{
+ Q_OBJECT
+public:
+ tst_QParallelAnimationGroup();
+ virtual ~tst_QParallelAnimationGroup();
+
+public Q_SLOTS:
+ void init();
+ void cleanup();
+
+private slots:
+ void construction();
+ void setCurrentTime();
+ void clearGroup();
+ void propagateGroupUpdateToChildren();
+ void updateChildrenWithRunningGroup();
+ void deleteChildrenWithRunningGroup();
+ void startChildrenWithStoppedGroup();
+ void stopGroupWithRunningChild();
+ void startGroupWithRunningChild();
+ void zeroDurationAnimation();
+ void stopUncontrolledAnimations();
+ void loopCount_data();
+ void loopCount();
+ void autoAdd();
+ void pauseResume();
+};
+
+tst_QParallelAnimationGroup::tst_QParallelAnimationGroup()
+{
+}
+
+tst_QParallelAnimationGroup::~tst_QParallelAnimationGroup()
+{
+}
+
+void tst_QParallelAnimationGroup::init()
+{
+ qRegisterMetaType<QAbstractAnimation::State>("QAbstractAnimation::State");
+}
+
+void tst_QParallelAnimationGroup::cleanup()
+{
+}
+
+void tst_QParallelAnimationGroup::construction()
+{
+ QParallelAnimationGroup animationgroup;
+}
+
+class AnimationObject : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int value READ value WRITE setValue)
+public:
+ AnimationObject(int startValue = 0)
+ : v(startValue)
+ { }
+
+ int value() const { return v; }
+ void setValue(int value) { v = value; }
+
+ int v;
+};
+
+class TestAnimation : public QVariantAnimation
+{
+ Q_OBJECT
+public:
+ virtual void updateCurrentValue(const QVariant &value) { Q_UNUSED(value)};
+ virtual void updateState(QAbstractAnimation::State oldState,
+ QAbstractAnimation::State newState)
+ {
+ Q_UNUSED(oldState)
+ Q_UNUSED(newState)
+ };
+};
+
+class TestAnimation2 : public QVariantAnimation
+{
+ Q_OBJECT
+public:
+ TestAnimation2(QAbstractAnimation *animation) : QVariantAnimation(animation) {}
+ TestAnimation2(int duration, QAbstractAnimation *animation) : QVariantAnimation(animation), m_duration(duration) {}
+
+ virtual void updateCurrentValue(const QVariant &value) { Q_UNUSED(value)};
+ virtual void updateState(QAbstractAnimation::State oldState,
+ QAbstractAnimation::State newState)
+ {
+ Q_UNUSED(oldState)
+ Q_UNUSED(newState)
+ };
+
+ virtual int duration() const {
+ return m_duration;
+ }
+private:
+ int m_duration;
+};
+
+class UncontrolledAnimation : public QPropertyAnimation
+{
+ Q_OBJECT
+public:
+ UncontrolledAnimation(QObject *target, const QByteArray &propertyName, QObject *parent = 0)
+ : QPropertyAnimation(target, propertyName, parent), id(0)
+ {
+ setDuration(250);
+ }
+
+ int duration() const { return -1; /* not time driven */ }
+
+protected:
+ void timerEvent(QTimerEvent *event)
+ {
+ if (event->timerId() == id)
+ stop();
+ }
+
+ void updateRunning(bool running)
+ {
+ if (running) {
+ id = startTimer(500);
+ } else {
+ killTimer(id);
+ id = 0;
+ }
+ }
+
+private:
+ int id;
+};
+
+void tst_QParallelAnimationGroup::setCurrentTime()
+{
+ AnimationObject p_o1;
+ AnimationObject p_o2;
+ AnimationObject p_o3;
+ AnimationObject t_o1;
+ AnimationObject t_o2;
+
+ // parallel operating on different object/properties
+ QAnimationGroup *parallel = new QParallelAnimationGroup();
+ 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->setLoopCount(3);
+ parallel->addAnimation(a1_p_o1);
+ parallel->addAnimation(a1_p_o2);
+ parallel->addAnimation(a1_p_o3);
+
+ UncontrolledAnimation *notTimeDriven = new UncontrolledAnimation(&t_o1, "value");
+ QCOMPARE(notTimeDriven->totalDuration(), -1);
+
+ QVariantAnimation *loopsForever = new QPropertyAnimation(&t_o2, "value");
+ loopsForever->setLoopCount(-1);
+ QCOMPARE(loopsForever->totalDuration(), -1);
+
+ QParallelAnimationGroup group;
+ group.addAnimation(parallel);
+ group.addAnimation(notTimeDriven);
+ group.addAnimation(loopsForever);
+
+ // Current time = 1
+ group.setCurrentTime(1);
+ QCOMPARE(group.state(), QAnimationGroup::Stopped);
+ QCOMPARE(parallel->state(), QAnimationGroup::Stopped);
+ QCOMPARE(a1_p_o1->state(), QAnimationGroup::Stopped);
+ QCOMPARE(a1_p_o2->state(), QAnimationGroup::Stopped);
+ QCOMPARE(a1_p_o3->state(), QAnimationGroup::Stopped);
+ QCOMPARE(notTimeDriven->state(), QAnimationGroup::Stopped);
+ QCOMPARE(loopsForever->state(), QAnimationGroup::Stopped);
+
+ QCOMPARE(group.currentTime(), 1);
+ QCOMPARE(a1_p_o1->currentTime(), 1);
+ QCOMPARE(a1_p_o2->currentTime(), 1);
+ QCOMPARE(a1_p_o3->currentTime(), 1);
+ QCOMPARE(notTimeDriven->currentTime(), 1);
+ QCOMPARE(loopsForever->currentTime(), 1);
+
+ // Current time = 250
+ group.setCurrentTime(250);
+ QCOMPARE(group.currentTime(), 250);
+ QCOMPARE(a1_p_o1->currentTime(), 250);
+ QCOMPARE(a1_p_o2->currentTime(), 0);
+ QCOMPARE(a1_p_o2->currentLoop(), 1);
+ QCOMPARE(a1_p_o3->currentTime(), 250);
+ QCOMPARE(notTimeDriven->currentTime(), 250);
+ QCOMPARE(loopsForever->currentTime(), 0);
+ 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->currentLoop(), 1);
+ QCOMPARE(a1_p_o3->currentTime(), 250);
+ QCOMPARE(notTimeDriven->currentTime(), 251);
+ QCOMPARE(loopsForever->currentTime(), 1);
+}
+
+void tst_QParallelAnimationGroup::clearGroup()
+{
+ QParallelAnimationGroup group;
+ static const int animationCount = 10;
+
+ for (int i = 0; i < animationCount; ++i) {
+ new QParallelAnimationGroup(&group);
+ }
+
+ QCOMPARE(group.animationCount(), animationCount);
+
+ QPointer<QAbstractAnimation> children[animationCount];
+ for (int i = 0; i < animationCount; ++i) {
+ QVERIFY(group.animationAt(i) != 0);
+ children[i] = group.animationAt(i);
+ }
+
+ group.clearAnimations();
+ QCOMPARE(group.animationCount(), 0);
+ QCOMPARE(group.currentTime(), 0);
+ for (int i = 0; i < animationCount; ++i)
+ QVERIFY(children[i].isNull());
+}
+
+void tst_QParallelAnimationGroup::propagateGroupUpdateToChildren()
+{
+ // this test verifies if group state changes are updating its children correctly
+ QParallelAnimationGroup group;
+
+ QObject o;
+ o.setProperty("ole", 42);
+ QCOMPARE(o.property("ole").toInt(), 42);
+
+ QPropertyAnimation anim1(&o, "ole");
+ anim1.setEndValue(43);
+ anim1.setDuration(100);
+ QVERIFY(!anim1.currentValue().isValid());
+ QCOMPARE(anim1.currentValue().toInt(), 0);
+ QCOMPARE(o.property("ole").toInt(), 42);
+
+ TestAnimation anim2;
+ anim2.setStartValue(0);
+ anim2.setEndValue(100);
+ anim2.setDuration(200);
+
+ QVERIFY(anim2.currentValue().isValid());
+ QCOMPARE(anim2.currentValue().toInt(), 0);
+
+ QCOMPARE(group.state(), QAnimationGroup::Stopped);
+ QCOMPARE(anim1.state(), QAnimationGroup::Stopped);
+ QCOMPARE(anim2.state(), QAnimationGroup::Stopped);
+
+ group.addAnimation(&anim1);
+ group.addAnimation(&anim2);
+
+ group.start();
+
+ QCOMPARE(group.state(), QAnimationGroup::Running);
+ QCOMPARE(anim1.state(), QAnimationGroup::Running);
+ QCOMPARE(anim2.state(), QAnimationGroup::Running);
+
+ group.pause();
+
+ QCOMPARE(group.state(), QAnimationGroup::Paused);
+ QCOMPARE(anim1.state(), QAnimationGroup::Paused);
+ QCOMPARE(anim2.state(), QAnimationGroup::Paused);
+
+ group.stop();
+
+ QCOMPARE(group.state(), QAnimationGroup::Stopped);
+ QCOMPARE(anim1.state(), QAnimationGroup::Stopped);
+ QCOMPARE(anim2.state(), QAnimationGroup::Stopped);
+}
+
+void tst_QParallelAnimationGroup::updateChildrenWithRunningGroup()
+{
+ // assert that its possible to modify a child's state directly while their group is running
+ QParallelAnimationGroup group;
+
+ TestAnimation anim;
+ anim.setStartValue(0);
+ anim.setEndValue(100);
+ anim.setDuration(200);
+
+ QSignalSpy groupStateChangedSpy(&group, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
+ QSignalSpy childStateChangedSpy(&anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
+
+ QCOMPARE(groupStateChangedSpy.count(), 0);
+ QCOMPARE(childStateChangedSpy.count(), 0);
+ QCOMPARE(group.state(), QAnimationGroup::Stopped);
+ QCOMPARE(anim.state(), QAnimationGroup::Stopped);
+
+ group.addAnimation(&anim);
+
+ group.start();
+
+ QCOMPARE(group.state(), QAnimationGroup::Running);
+ QCOMPARE(anim.state(), QAnimationGroup::Running);
+
+ QCOMPARE(groupStateChangedSpy.count(), 1);
+ QCOMPARE(childStateChangedSpy.count(), 1);
+
+ QCOMPARE(qVariantValue<QAbstractAnimation::State>(groupStateChangedSpy.at(0).at(1)),
+ QAnimationGroup::Running);
+ QCOMPARE(qVariantValue<QAbstractAnimation::State>(childStateChangedSpy.at(0).at(1)),
+ QAnimationGroup::Running);
+
+ // starting directly a running child will not have any effect
+ anim.start();
+
+ QCOMPARE(groupStateChangedSpy.count(), 1);
+ QCOMPARE(childStateChangedSpy.count(), 1);
+
+ anim.pause();
+
+ QCOMPARE(group.state(), QAnimationGroup::Running);
+ QCOMPARE(anim.state(), QAnimationGroup::Paused);
+
+ // in the animation stops directly, the group will still be running
+ anim.stop();
+
+ QCOMPARE(group.state(), QAnimationGroup::Running);
+ QCOMPARE(anim.state(), QAnimationGroup::Stopped);
+}
+
+void tst_QParallelAnimationGroup::deleteChildrenWithRunningGroup()
+{
+ // test if children can be activated when their group is stopped
+ QParallelAnimationGroup group;
+
+ QVariantAnimation *anim1 = new TestAnimation;
+ anim1->setStartValue(0);
+ anim1->setEndValue(100);
+ anim1->setDuration(200);
+ group.addAnimation(anim1);
+
+ QCOMPARE(group.duration(), anim1->duration());
+
+ group.start();
+ QCOMPARE(group.state(), QAnimationGroup::Running);
+ QCOMPARE(anim1->state(), QAnimationGroup::Running);
+
+ QTest::qWait(50);
+ QVERIFY(group.currentTime() > 0);
+
+ delete anim1;
+ QVERIFY(group.animationCount() == 0);
+ QCOMPARE(group.duration(), 0);
+ QCOMPARE(group.state(), QAnimationGroup::Stopped);
+ QCOMPARE(group.currentTime(), 0); //that's the invariant
+}
+
+void tst_QParallelAnimationGroup::startChildrenWithStoppedGroup()
+{
+ // test if children can be activated when their group is stopped
+ QParallelAnimationGroup group;
+
+ TestAnimation anim1;
+ anim1.setStartValue(0);
+ anim1.setEndValue(100);
+ anim1.setDuration(200);
+
+ TestAnimation anim2;
+ anim2.setStartValue(0);
+ anim2.setEndValue(100);
+ anim2.setDuration(200);
+
+ QCOMPARE(group.state(), QAnimationGroup::Stopped);
+ QCOMPARE(anim1.state(), QAnimationGroup::Stopped);
+ QCOMPARE(anim2.state(), QAnimationGroup::Stopped);
+
+ group.addAnimation(&anim1);
+ group.addAnimation(&anim2);
+
+ group.stop();
+
+ QCOMPARE(group.state(), QAnimationGroup::Stopped);
+ QCOMPARE(anim1.state(), QAnimationGroup::Stopped);
+ QCOMPARE(anim2.state(), QAnimationGroup::Stopped);
+
+ anim1.start();
+ anim2.start();
+ anim2.pause();
+
+ QCOMPARE(group.state(), QAnimationGroup::Stopped);
+ QCOMPARE(anim1.state(), QAnimationGroup::Running);
+ QCOMPARE(anim2.state(), QAnimationGroup::Paused);
+}
+
+void tst_QParallelAnimationGroup::stopGroupWithRunningChild()
+{
+ // children that started independently will not be affected by a group stop
+ QParallelAnimationGroup group;
+
+ TestAnimation anim1;
+ anim1.setStartValue(0);
+ anim1.setEndValue(100);
+ anim1.setDuration(200);
+
+ TestAnimation anim2;
+ anim2.setStartValue(0);
+ anim2.setEndValue(100);
+ anim2.setDuration(200);
+
+ QCOMPARE(group.state(), QAnimationGroup::Stopped);
+ QCOMPARE(anim1.state(), QAnimationGroup::Stopped);
+ QCOMPARE(anim2.state(), QAnimationGroup::Stopped);
+
+ group.addAnimation(&anim1);
+ group.addAnimation(&anim2);
+
+ anim1.start();
+ anim2.start();
+ anim2.pause();
+
+ QCOMPARE(group.state(), QAnimationGroup::Stopped);
+ QCOMPARE(anim1.state(), QAnimationGroup::Running);
+ QCOMPARE(anim2.state(), QAnimationGroup::Paused);
+
+ group.stop();
+
+ QCOMPARE(group.state(), QAnimationGroup::Stopped);
+ QCOMPARE(anim1.state(), QAnimationGroup::Running);
+ QCOMPARE(anim2.state(), QAnimationGroup::Paused);
+
+ anim1.stop();
+ anim2.stop();
+
+ QCOMPARE(group.state(), QAnimationGroup::Stopped);
+ QCOMPARE(anim1.state(), QAnimationGroup::Stopped);
+ QCOMPARE(anim2.state(), QAnimationGroup::Stopped);
+}
+
+void tst_QParallelAnimationGroup::startGroupWithRunningChild()
+{
+ // as the group has precedence over its children, starting a group will restart all the children
+ QParallelAnimationGroup group;
+
+ TestAnimation anim1;
+ anim1.setStartValue(0);
+ anim1.setEndValue(100);
+ anim1.setDuration(200);
+
+ TestAnimation anim2;
+ anim2.setStartValue(0);
+ anim2.setEndValue(100);
+ anim2.setDuration(200);
+
+ QSignalSpy stateChangedSpy1(&anim1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
+ QSignalSpy stateChangedSpy2(&anim2, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
+
+ QCOMPARE(stateChangedSpy1.count(), 0);
+ QCOMPARE(stateChangedSpy2.count(), 0);
+ QCOMPARE(group.state(), QAnimationGroup::Stopped);
+ QCOMPARE(anim1.state(), QAnimationGroup::Stopped);
+ QCOMPARE(anim2.state(), QAnimationGroup::Stopped);
+
+ group.addAnimation(&anim1);
+ group.addAnimation(&anim2);
+
+ anim1.start();
+ anim2.start();
+ anim2.pause();
+
+ QCOMPARE(qVariantValue<QAbstractAnimation::State>(stateChangedSpy1.at(0).at(1)),
+ QAnimationGroup::Running);
+ QCOMPARE(qVariantValue<QAbstractAnimation::State>(stateChangedSpy2.at(0).at(1)),
+ QAnimationGroup::Running);
+ QCOMPARE(qVariantValue<QAbstractAnimation::State>(stateChangedSpy2.at(1).at(1)),
+ QAnimationGroup::Paused);
+
+ QCOMPARE(group.state(), QAnimationGroup::Stopped);
+ QCOMPARE(anim1.state(), QAnimationGroup::Running);
+ QCOMPARE(anim2.state(), QAnimationGroup::Paused);
+
+ group.start();
+
+ QCOMPARE(stateChangedSpy1.count(), 3);
+ QCOMPARE(qVariantValue<QAbstractAnimation::State>(stateChangedSpy1.at(1).at(1)),
+ QAnimationGroup::Stopped);
+ QCOMPARE(qVariantValue<QAbstractAnimation::State>(stateChangedSpy1.at(2).at(1)),
+ QAnimationGroup::Running);
+
+ QCOMPARE(stateChangedSpy2.count(), 4);
+ QCOMPARE(qVariantValue<QAbstractAnimation::State>(stateChangedSpy2.at(2).at(1)),
+ QAnimationGroup::Stopped);
+ QCOMPARE(qVariantValue<QAbstractAnimation::State>(stateChangedSpy2.at(3).at(1)),
+ QAnimationGroup::Running);
+
+ QCOMPARE(group.state(), QAnimationGroup::Running);
+ QCOMPARE(anim1.state(), QAnimationGroup::Running);
+ QCOMPARE(anim2.state(), QAnimationGroup::Running);
+}
+
+void tst_QParallelAnimationGroup::zeroDurationAnimation()
+{
+ QParallelAnimationGroup group;
+
+ TestAnimation anim1;
+ anim1.setStartValue(0);
+ anim1.setEndValue(100);
+ anim1.setDuration(0);
+
+ TestAnimation anim2;
+ anim2.setStartValue(0);
+ anim2.setEndValue(100);
+ anim2.setDuration(100);
+
+ QSignalSpy stateChangedSpy1(&anim1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
+ QSignalSpy finishedSpy1(&anim1, SIGNAL(finished()));
+
+ QSignalSpy stateChangedSpy2(&anim2, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
+ QSignalSpy finishedSpy2(&anim2, SIGNAL(finished()));
+
+ group.addAnimation(&anim1);
+ group.addAnimation(&anim2);
+ QCOMPARE(stateChangedSpy1.count(), 0);
+ group.start();
+ QCOMPARE(stateChangedSpy1.count(), 2);
+ QCOMPARE(finishedSpy1.count(), 1);
+ QCOMPARE(qVariantValue<QAbstractAnimation::State>(stateChangedSpy1.at(0).at(1)),
+ QAnimationGroup::Running);
+ QCOMPARE(qVariantValue<QAbstractAnimation::State>(stateChangedSpy1.at(1).at(1)),
+ QAnimationGroup::Stopped);
+
+ QCOMPARE(stateChangedSpy2.count(), 1);
+ QCOMPARE(finishedSpy2.count(), 0);
+ QCOMPARE(qVariantValue<QAbstractAnimation::State>(stateChangedSpy1.at(0).at(1)),
+ QAnimationGroup::Running);
+
+
+ QCOMPARE(anim1.state(), QAnimationGroup::Stopped);
+ QCOMPARE(anim2.state(), QAnimationGroup::Running);
+ QCOMPARE(group.state(), QAnimationGroup::Running);
+
+
+ group.stop();
+ group.setLoopCount(4);
+ stateChangedSpy1.clear();
+ stateChangedSpy2.clear();
+
+ group.start();
+ QCOMPARE(stateChangedSpy1.count(), 2);
+ QCOMPARE(stateChangedSpy2.count(), 1);
+ group.setCurrentTime(50);
+ QCOMPARE(stateChangedSpy1.count(), 2);
+ QCOMPARE(stateChangedSpy2.count(), 1);
+ group.setCurrentTime(150);
+ QCOMPARE(stateChangedSpy1.count(), 4);
+ QCOMPARE(stateChangedSpy2.count(), 3);
+ group.setCurrentTime(50);
+ QCOMPARE(stateChangedSpy1.count(), 6);
+ QCOMPARE(stateChangedSpy2.count(), 5);
+
+}
+
+void tst_QParallelAnimationGroup::stopUncontrolledAnimations()
+{
+ QParallelAnimationGroup group;
+
+ TestAnimation anim1;
+ anim1.setStartValue(0);
+ anim1.setEndValue(100);
+ anim1.setDuration(0);
+
+ AnimationObject o1;
+ UncontrolledAnimation notTimeDriven(&o1, "value");
+ QCOMPARE(notTimeDriven.totalDuration(), -1);
+
+ TestAnimation loopsForever;
+ loopsForever.setStartValue(0);
+ loopsForever.setEndValue(100);
+ loopsForever.setDuration(100);
+ loopsForever.setLoopCount(-1);
+
+ QSignalSpy stateChangedSpy(&anim1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
+
+ group.addAnimation(&anim1);
+ group.addAnimation(&notTimeDriven);
+ group.addAnimation(&loopsForever);
+
+ group.start();
+
+ QCOMPARE(stateChangedSpy.count(), 2);
+ QCOMPARE(qVariantValue<QAbstractAnimation::State>(stateChangedSpy.at(0).at(1)),
+ QAnimationGroup::Running);
+ QCOMPARE(qVariantValue<QAbstractAnimation::State>(stateChangedSpy.at(1).at(1)),
+ QAnimationGroup::Stopped);
+
+ QCOMPARE(group.state(), QAnimationGroup::Running);
+ QCOMPARE(notTimeDriven.state(), QAnimationGroup::Running);
+ QCOMPARE(loopsForever.state(), QAnimationGroup::Running);
+ QCOMPARE(anim1.state(), QAnimationGroup::Stopped);
+
+ notTimeDriven.stop();
+
+ QCOMPARE(group.state(), QAnimationGroup::Running);
+ QCOMPARE(notTimeDriven.state(), QAnimationGroup::Stopped);
+ QCOMPARE(loopsForever.state(), QAnimationGroup::Running);
+
+ loopsForever.stop();
+
+ QCOMPARE(group.state(), QAnimationGroup::Stopped);
+ QCOMPARE(notTimeDriven.state(), QAnimationGroup::Stopped);
+ QCOMPARE(loopsForever.state(), QAnimationGroup::Stopped);
+}
+
+struct AnimState {
+ AnimState(int time = -1) : time(time), state(-1) {}
+ AnimState(int time, int state) : time(time), state(state) {}
+ int time;
+ int state;
+};
+
+#define Running QAbstractAnimation::Running
+#define Stopped QAbstractAnimation::Stopped
+
+Q_DECLARE_METATYPE(AnimState)
+void tst_QParallelAnimationGroup::loopCount_data()
+{
+ QTest::addColumn<bool>("directionBackward");
+ QTest::addColumn<int>("setLoopCount");
+ QTest::addColumn<int>("initialGroupTime");
+ QTest::addColumn<int>("currentGroupTime");
+ QTest::addColumn<AnimState>("expected1");
+ QTest::addColumn<AnimState>("expected2");
+ QTest::addColumn<AnimState>("expected3");
+
+ // D U R A T I O N
+ // 100 60*2 0
+ // direction = Forward
+ QTest::newRow("50") << false << 3 << 0 << 50 << AnimState( 50, Running) << AnimState( 50, Running) << AnimState( 0, Stopped);
+ QTest::newRow("100") << false << 3 << 0 << 100 << AnimState(100 ) << AnimState( 40, Running) << AnimState( 0, Stopped);
+ QTest::newRow("110") << false << 3 << 0 << 110 << AnimState(100, Stopped) << AnimState( 50, Running) << AnimState( 0, Stopped);
+ QTest::newRow("120") << false << 3 << 0 << 120 << AnimState( 0, Running) << AnimState( 0, Running) << AnimState( 0, Stopped);
+
+ QTest::newRow("170") << false << 3 << 0 << 170 << AnimState( 50, Running) << AnimState( 50, Running) << AnimState( 0, Stopped);
+ QTest::newRow("220") << false << 3 << 0 << 220 << AnimState(100 ) << AnimState( 40, Running) << AnimState( 0, Stopped);
+ QTest::newRow("230") << false << 3 << 0 << 230 << AnimState(100, Stopped) << AnimState( 50, Running) << AnimState( 0, Stopped);
+ QTest::newRow("240") << false << 3 << 0 << 240 << AnimState( 0, Running) << AnimState( 0, Running) << AnimState( 0, Stopped);
+
+ QTest::newRow("290") << false << 3 << 0 << 290 << AnimState( 50, Running) << AnimState( 50, Running) << AnimState( 0, Stopped);
+ QTest::newRow("340") << false << 3 << 0 << 340 << AnimState(100 ) << AnimState( 40, Running) << AnimState( 0, Stopped);
+ QTest::newRow("350") << false << 3 << 0 << 350 << AnimState(100, Stopped) << AnimState( 50, Running) << AnimState( 0, Stopped);
+ QTest::newRow("360") << false << 3 << 0 << 360 << AnimState(100, Stopped) << AnimState( 60 ) << AnimState( 0, Stopped);
+
+ QTest::newRow("410") << false << 3 << 0 << 410 << AnimState(100, Stopped) << AnimState( 60, Stopped) << AnimState( 0, Stopped);
+ QTest::newRow("460") << false << 3 << 0 << 460 << AnimState(100, Stopped) << AnimState( 60, Stopped) << AnimState( 0, Stopped);
+ QTest::newRow("470") << false << 3 << 0 << 470 << AnimState(100, Stopped) << AnimState( 60, Stopped) << AnimState( 0, Stopped);
+ QTest::newRow("480") << false << 3 << 0 << 480 << AnimState(100, Stopped) << AnimState( 60, Stopped) << AnimState( 0, Stopped);
+
+ // direction = Forward, rewind
+ QTest::newRow("120-110") << false << 3 << 120 << 110 << AnimState( 0, Stopped) << AnimState( 50, Running) << AnimState( 0, Stopped);
+ QTest::newRow("120-50") << false << 3 << 120 << 50 << AnimState( 50, Running) << AnimState( 50, Running) << AnimState( 0, Stopped);
+ QTest::newRow("120-0") << false << 3 << 120 << 0 << AnimState( 0, Running) << AnimState( 0, Running) << AnimState( 0, Stopped);
+ QTest::newRow("300-110") << false << 3 << 300 << 110 << AnimState( 0, Stopped) << AnimState( 50, Running) << AnimState( 0, Stopped);
+ QTest::newRow("300-50") << false << 3 << 300 << 50 << AnimState( 50, Running) << AnimState( 50, Running) << AnimState( 0, Stopped);
+ QTest::newRow("300-0") << false << 3 << 300 << 0 << AnimState( 0, Running) << AnimState( 0, Running) << AnimState( 0, Stopped);
+ QTest::newRow("115-105") << false << 3 << 115 << 105 << AnimState( 42, Stopped) << AnimState( 45, Running) << AnimState( 0, Stopped);
+
+ // direction = Backward
+ QTest::newRow("b120-120") << true << 3 << 120 << 120 << AnimState( 42, Stopped) << AnimState( 60, Running) << AnimState( 0, Stopped);
+ QTest::newRow("b120-110") << true << 3 << 120 << 110 << AnimState( 42, Stopped) << AnimState( 50, Running) << AnimState( 0, Stopped);
+ QTest::newRow("b120-100") << true << 3 << 120 << 100 << AnimState(100, Running) << AnimState( 40, Running) << AnimState( 0, Stopped);
+ QTest::newRow("b120-50") << true << 3 << 120 << 50 << AnimState( 50, Running) << AnimState( 50, Running) << AnimState( 0, Stopped);
+ QTest::newRow("b120-0") << true << 3 << 120 << 0 << AnimState( 0, Stopped) << AnimState( 0, Stopped) << AnimState( 0, Stopped);
+ QTest::newRow("b360-170") << true << 3 << 360 << 170 << AnimState( 50, Running) << AnimState( 50, Running) << AnimState( 0, Stopped);
+ QTest::newRow("b360-220") << true << 3 << 360 << 220 << AnimState(100, Running) << AnimState( 40, Running) << AnimState( 0, Stopped);
+ QTest::newRow("b360-210") << true << 3 << 360 << 210 << AnimState( 90, Running) << AnimState( 30, Running) << AnimState( 0, Stopped);
+ QTest::newRow("b360-120") << true << 3 << 360 << 120 << AnimState( 0, Stopped) << AnimState( 60, Running) << AnimState( 0, Stopped);
+
+ // rewind, direction = Backward
+ QTest::newRow("b50-110") << true << 3 << 50 << 110 << AnimState(100, Stopped) << AnimState( 50, Running) << AnimState( 0, Stopped);
+ QTest::newRow("b50-120") << true << 3 << 50 << 120 << AnimState(100, Stopped) << AnimState( 60, Running) << AnimState( 0, Stopped);
+ QTest::newRow("b50-140") << true << 3 << 50 << 140 << AnimState( 20, Running) << AnimState( 20, Running) << AnimState( 0, Stopped);
+ QTest::newRow("b50-240") << true << 3 << 50 << 240 << AnimState(100, Stopped) << AnimState( 60, Running) << AnimState( 0, Stopped);
+ QTest::newRow("b50-260") << true << 3 << 50 << 260 << AnimState( 20, Running) << AnimState( 20, Running) << AnimState( 0, Stopped);
+ QTest::newRow("b50-350") << true << 3 << 50 << 350 << AnimState(100, Stopped) << AnimState( 50, Running) << AnimState( 0, Stopped);
+
+ // infinite looping
+ QTest::newRow("inf1220") << false << -1 << 0 << 1220 << AnimState( 20, Running) << AnimState( 20, Running) << AnimState( 0, Stopped);
+ QTest::newRow("inf1310") << false << -1 << 0 << 1310 << AnimState( 100, Stopped) << AnimState( 50, Running) << AnimState( 0, Stopped);
+ // infinite looping, direction = Backward (will only loop once)
+ QTest::newRow("b.inf120-120") << true << -1 << 120 << 120 << AnimState( 42, Stopped) << AnimState( 60, Running) << AnimState( 0, Stopped);
+ QTest::newRow("b.inf120-20") << true << -1 << 120 << 20 << AnimState( 20, Running) << AnimState( 20, Running) << AnimState( 0, Stopped);
+ QTest::newRow("b.inf120-110") << true << -1 << 120 << 110 << AnimState( 42, Stopped) << AnimState( 50, Running) << AnimState( 0, Stopped);
+
+
+}
+
+void tst_QParallelAnimationGroup::loopCount()
+{
+ QFETCH(bool, directionBackward);
+ QFETCH(int, setLoopCount);
+ QFETCH(int, initialGroupTime);
+ QFETCH(int, currentGroupTime);
+ QFETCH(AnimState, expected1);
+ QFETCH(AnimState, expected2);
+ QFETCH(AnimState, expected3);
+
+ QParallelAnimationGroup group;
+
+ TestAnimation anim1;
+ anim1.setStartValue(0);
+ anim1.setEndValue(100);
+ anim1.setDuration(100);
+
+ TestAnimation anim2;
+ anim2.setStartValue(0);
+ anim2.setEndValue(100);
+ anim2.setDuration(60); //total 120
+ anim2.setLoopCount(2);
+
+ TestAnimation anim3;
+ anim3.setStartValue(0);
+ anim3.setEndValue(100);
+ anim3.setDuration(0);
+
+ group.addAnimation(&anim1);
+ group.addAnimation(&anim2);
+ group.addAnimation(&anim3);
+
+ group.setLoopCount(setLoopCount);
+ if (initialGroupTime >= 0)
+ group.setCurrentTime(initialGroupTime);
+ if (directionBackward)
+ group.setDirection(QAbstractAnimation::Backward);
+
+ group.start();
+ if (initialGroupTime >= 0)
+ group.setCurrentTime(initialGroupTime);
+
+ anim1.setCurrentTime(42); // 42 is "untouched"
+ anim2.setCurrentTime(42);
+
+ group.setCurrentTime(currentGroupTime);
+
+ QCOMPARE(anim1.currentTime(), expected1.time);
+ QCOMPARE(anim2.currentTime(), expected2.time);
+ QCOMPARE(anim3.currentTime(), expected3.time);
+
+ if (expected1.state >=0)
+ QCOMPARE(int(anim1.state()), expected1.state);
+ if (expected2.state >=0)
+ QCOMPARE(int(anim2.state()), expected2.state);
+ if (expected3.state >=0)
+ QCOMPARE(int(anim3.state()), expected3.state);
+
+}
+
+void tst_QParallelAnimationGroup::autoAdd()
+{
+ QParallelAnimationGroup group;
+ QCOMPARE(group.duration(), 0);
+ TestAnimation2 *test = new TestAnimation2(250, &group); // 0, duration = 250;
+ QCOMPARE(test->group(), static_cast<QAnimationGroup*>(&group));
+ QCOMPARE(test->duration(), 250);
+ QCOMPARE(group.duration(), 250);
+
+ test = new TestAnimation2(750, &group); // 1
+ QCOMPARE(test->group(), static_cast<QAnimationGroup*>(&group));
+ QCOMPARE(group.duration(), 750);
+ test = new TestAnimation2(500, &group); // 2
+ QCOMPARE(test->group(), static_cast<QAnimationGroup*>(&group));
+ QCOMPARE(group.duration(), 750);
+
+ delete group.animationAt(1); // remove the one with duration = 750
+ QCOMPARE(group.duration(), 500);
+
+ delete group.animationAt(1); // remove the one with duration = 500
+ QCOMPARE(group.duration(), 250);
+
+ test = static_cast<TestAnimation2*>(group.animationAt(0));
+ test->setParent(0); // remove the last one (with duration = 250)
+ QCOMPARE(test->group(), static_cast<QAnimationGroup*>(0));
+ QCOMPARE(group.duration(), 0);
+}
+
+void tst_QParallelAnimationGroup::pauseResume()
+{
+ QParallelAnimationGroup group;
+ TestAnimation2 *anim = new TestAnimation2(250, &group); // 0, duration = 250;
+ QSignalSpy spy(anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
+ QCOMPARE(group.duration(), 250);
+ group.start();
+ QTest::qWait(100);
+ QCOMPARE(group.state(), QAnimationGroup::Running);
+ QCOMPARE(anim->state(), QAnimationGroup::Running);
+ QCOMPARE(spy.count(), 1);
+ spy.clear();
+ const int currentTime = group.currentTime();
+ QCOMPARE(anim->currentTime(), currentTime);
+
+ group.pause();
+ QCOMPARE(group.state(), QAnimationGroup::Paused);
+ QCOMPARE(group.currentTime(), currentTime);
+ QCOMPARE(anim->state(), QAnimationGroup::Paused);
+ QCOMPARE(anim->currentTime(), currentTime);
+ QCOMPARE(spy.count(), 1);
+ spy.clear();
+
+ group.resume();
+ QCOMPARE(group.state(), QAnimationGroup::Running);
+ QCOMPARE(group.currentTime(), currentTime);
+ QCOMPARE(anim->state(), QAnimationGroup::Running);
+ QCOMPARE(anim->currentTime(), currentTime);
+ QCOMPARE(spy.count(), 1);
+}
+
+
+QTEST_MAIN(tst_QParallelAnimationGroup)
+#include "tst_qparallelanimationgroup.moc"