util/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp
changeset 7 f7bc934e204c
equal deleted inserted replaced
3:41300fa6a67c 7:f7bc934e204c
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the test suite of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include <QtTest/QtTest>
       
    43 #include "../../shared/util.h"
       
    44 
       
    45 #include <QtCore/qanimationgroup.h>
       
    46 #include <QtCore/qsequentialanimationgroup.h>
       
    47 
       
    48 //TESTED_CLASS=QSequentialAnimationGroup
       
    49 //TESTED_FILES=
       
    50 
       
    51 Q_DECLARE_METATYPE(QAbstractAnimation::State)
       
    52 Q_DECLARE_METATYPE(QAbstractAnimation*)
       
    53 
       
    54 class tst_QSequentialAnimationGroup : public QObject
       
    55 {
       
    56   Q_OBJECT
       
    57 public:
       
    58     tst_QSequentialAnimationGroup();
       
    59     virtual ~tst_QSequentialAnimationGroup();
       
    60 
       
    61 public Q_SLOTS:
       
    62     void init();
       
    63     void cleanup();
       
    64 
       
    65 private slots:
       
    66     void construction();
       
    67     void setCurrentTime();
       
    68     void setCurrentTimeWithUncontrolledAnimation();
       
    69     void seekingForwards();
       
    70     void seekingBackwards();
       
    71     void pauseAndResume();
       
    72     void restart();
       
    73     void looping();
       
    74     void startDelay();
       
    75     void clearGroup();
       
    76     void groupWithZeroDurationAnimations();
       
    77     void propagateGroupUpdateToChildren();
       
    78     void updateChildrenWithRunningGroup();
       
    79     void deleteChildrenWithRunningGroup();
       
    80     void startChildrenWithStoppedGroup();
       
    81     void stopGroupWithRunningChild();
       
    82     void startGroupWithRunningChild();
       
    83     void zeroDurationAnimation();
       
    84     void stopUncontrolledAnimations();
       
    85     void finishWithUncontrolledAnimation();
       
    86     void addRemoveAnimation();
       
    87     void currentAnimation();
       
    88     void currentAnimationWithZeroDuration();
       
    89     void insertAnimation();
       
    90     void clear();
       
    91     void pauseResume();
       
    92 };
       
    93 
       
    94 tst_QSequentialAnimationGroup::tst_QSequentialAnimationGroup()
       
    95 {
       
    96 }
       
    97 
       
    98 tst_QSequentialAnimationGroup::~tst_QSequentialAnimationGroup()
       
    99 {
       
   100 }
       
   101 
       
   102 void tst_QSequentialAnimationGroup::init()
       
   103 {
       
   104     qRegisterMetaType<QAbstractAnimation::State>("QAbstractAnimation::State");
       
   105     qRegisterMetaType<QAbstractAnimation*>("QAbstractAnimation*");
       
   106 }
       
   107 
       
   108 void tst_QSequentialAnimationGroup::cleanup()
       
   109 {
       
   110 }
       
   111 
       
   112 void tst_QSequentialAnimationGroup::construction()
       
   113 {
       
   114     QSequentialAnimationGroup animationgroup;
       
   115 }
       
   116 
       
   117 class AnimationObject : public QObject
       
   118 {
       
   119     Q_OBJECT
       
   120     Q_PROPERTY(int value READ value WRITE setValue)
       
   121 public:
       
   122     AnimationObject(int startValue = 0)
       
   123         : v(startValue)
       
   124     { }
       
   125 
       
   126     int value() const { return v; }
       
   127     void setValue(int value) { v = value; }
       
   128 
       
   129     int v;
       
   130 };
       
   131 
       
   132 class TestAnimation : public QVariantAnimation
       
   133 {
       
   134     Q_OBJECT
       
   135 public:
       
   136     virtual void updateCurrentValue(const QVariant &value) { Q_UNUSED(value)};
       
   137     virtual void updateState(QAbstractAnimation::State newState,
       
   138                              QAbstractAnimation::State oldState)
       
   139     {
       
   140         Q_UNUSED(oldState)
       
   141         Q_UNUSED(newState)
       
   142     };
       
   143 };
       
   144 
       
   145 class DummyPropertyAnimation : public QPropertyAnimation
       
   146 {
       
   147 public:
       
   148     DummyPropertyAnimation(QObject *parent = 0) : QPropertyAnimation(parent)
       
   149     {
       
   150         setTargetObject(&o);
       
   151         this->setPropertyName("value");
       
   152         setEndValue(0);
       
   153     }
       
   154 
       
   155     AnimationObject o;
       
   156 };
       
   157 
       
   158 class UncontrolledAnimation : public QPropertyAnimation
       
   159 {
       
   160     Q_OBJECT
       
   161 public:
       
   162     UncontrolledAnimation(QObject *target, QObject *parent = 0)
       
   163         : QPropertyAnimation(target, "value", parent)
       
   164     {
       
   165         setDuration(250);
       
   166         setEndValue(0);
       
   167     }
       
   168 
       
   169     int duration() const { return -1; /* not time driven */ }
       
   170 
       
   171 protected:
       
   172     void updateCurrentTime(int currentTime)
       
   173     {
       
   174         QPropertyAnimation::updateCurrentTime(currentTime);
       
   175         if (currentTime >= QPropertyAnimation::duration())
       
   176             stop();
       
   177     }
       
   178 };
       
   179 
       
   180 void tst_QSequentialAnimationGroup::setCurrentTime()
       
   181 {
       
   182     // sequence operating on same object/property
       
   183     QAnimationGroup *sequence = new QSequentialAnimationGroup();
       
   184     QVariantAnimation *a1_s_o1 = new DummyPropertyAnimation;
       
   185     QVariantAnimation *a2_s_o1 = new DummyPropertyAnimation;
       
   186     QVariantAnimation *a3_s_o1 = new DummyPropertyAnimation;
       
   187     a2_s_o1->setLoopCount(3);
       
   188     sequence->addAnimation(a1_s_o1);
       
   189     sequence->addAnimation(a2_s_o1);
       
   190     sequence->addAnimation(a3_s_o1);
       
   191 
       
   192     // sequence operating on different object/properties
       
   193     QAnimationGroup *sequence2 = new QSequentialAnimationGroup();
       
   194     QVariantAnimation *a1_s_o2 = new DummyPropertyAnimation;
       
   195     QVariantAnimation *a1_s_o3 = new DummyPropertyAnimation;
       
   196     sequence2->addAnimation(a1_s_o2);
       
   197     sequence2->addAnimation(a1_s_o3);
       
   198 
       
   199     QSequentialAnimationGroup group;
       
   200     group.addAnimation(sequence);
       
   201     group.addAnimation(sequence2);
       
   202 
       
   203     // Current time = 1
       
   204     group.setCurrentTime(1);
       
   205     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
   206     QCOMPARE(sequence->state(), QAnimationGroup::Stopped);
       
   207     QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped);
       
   208     QCOMPARE(sequence2->state(), QAnimationGroup::Stopped);
       
   209     QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped);
       
   210 
       
   211     QCOMPARE(group.currentLoopTime(), 1);
       
   212     QCOMPARE(sequence->currentLoopTime(), 1);
       
   213     QCOMPARE(a1_s_o1->currentLoopTime(), 1);
       
   214     QCOMPARE(a2_s_o1->currentLoopTime(), 0);
       
   215     QCOMPARE(a3_s_o1->currentLoopTime(), 0);
       
   216     QCOMPARE(a1_s_o2->currentLoopTime(), 0);
       
   217     QCOMPARE(a1_s_o3->currentLoopTime(), 0);
       
   218 
       
   219     // Current time = 250
       
   220     group.setCurrentTime(250);
       
   221     QCOMPARE(group.currentLoopTime(), 250);
       
   222     QCOMPARE(sequence->currentLoopTime(), 250);
       
   223     QCOMPARE(a1_s_o1->currentLoopTime(), 250);
       
   224     QCOMPARE(a2_s_o1->currentLoopTime(), 0);
       
   225     QCOMPARE(a3_s_o1->currentLoopTime(), 0);
       
   226     QCOMPARE(a1_s_o2->currentLoopTime(), 0);
       
   227     QCOMPARE(a1_s_o3->currentLoopTime(), 0);
       
   228 
       
   229     // Current time = 251
       
   230     group.setCurrentTime(251);
       
   231     QCOMPARE(group.currentLoopTime(), 251);
       
   232     QCOMPARE(sequence->currentLoopTime(), 251);
       
   233     QCOMPARE(a1_s_o1->currentLoopTime(), 250);
       
   234     QCOMPARE(a2_s_o1->currentLoopTime(), 1);
       
   235     QCOMPARE(a2_s_o1->currentLoop(), 0);
       
   236     QCOMPARE(a3_s_o1->currentLoopTime(), 0);
       
   237     QCOMPARE(sequence2->currentLoopTime(), 0);
       
   238     QCOMPARE(a1_s_o2->currentLoopTime(), 0);
       
   239     QCOMPARE(a1_s_o3->currentLoopTime(), 0);
       
   240 
       
   241     // Current time = 750
       
   242     group.setCurrentTime(750);
       
   243     QCOMPARE(group.currentLoopTime(), 750);
       
   244     QCOMPARE(sequence->currentLoopTime(), 750);
       
   245     QCOMPARE(a1_s_o1->currentLoopTime(), 250);
       
   246     QCOMPARE(a2_s_o1->currentLoopTime(), 0);
       
   247     QCOMPARE(a2_s_o1->currentLoop(), 2);
       
   248     QCOMPARE(a3_s_o1->currentLoopTime(), 0);
       
   249     QCOMPARE(sequence2->currentLoopTime(), 0);
       
   250     QCOMPARE(a1_s_o2->currentLoopTime(), 0);
       
   251     QCOMPARE(a1_s_o3->currentLoopTime(), 0);
       
   252 
       
   253     // Current time = 1000
       
   254     group.setCurrentTime(1000);
       
   255     QCOMPARE(group.currentLoopTime(), 1000);
       
   256     QCOMPARE(sequence->currentLoopTime(), 1000);
       
   257     QCOMPARE(a1_s_o1->currentLoopTime(), 250);
       
   258     QCOMPARE(a2_s_o1->currentLoopTime(), 250);
       
   259     QCOMPARE(a2_s_o1->currentLoop(), 2);
       
   260     QCOMPARE(a3_s_o1->currentLoopTime(), 0);
       
   261     QCOMPARE(sequence2->currentLoopTime(), 0);
       
   262     QCOMPARE(a1_s_o2->currentLoopTime(), 0);
       
   263     QCOMPARE(a1_s_o3->currentLoopTime(), 0);
       
   264 
       
   265     // Current time = 1010
       
   266     group.setCurrentTime(1010);
       
   267     QCOMPARE(group.currentLoopTime(), 1010);
       
   268     QCOMPARE(sequence->currentLoopTime(), 1010);
       
   269     QCOMPARE(a1_s_o1->currentLoopTime(), 250);
       
   270     QCOMPARE(a2_s_o1->currentLoopTime(), 250);
       
   271     QCOMPARE(a2_s_o1->currentLoop(), 2);
       
   272     QCOMPARE(a3_s_o1->currentLoopTime(), 10);
       
   273     QCOMPARE(sequence2->currentLoopTime(), 0);
       
   274     QCOMPARE(a1_s_o2->currentLoopTime(), 0);
       
   275     QCOMPARE(a1_s_o3->currentLoopTime(), 0);
       
   276 
       
   277     // Current time = 1250
       
   278     group.setCurrentTime(1250);
       
   279     QCOMPARE(group.currentLoopTime(), 1250);
       
   280     QCOMPARE(sequence->currentLoopTime(), 1250);
       
   281     QCOMPARE(a1_s_o1->currentLoopTime(), 250);
       
   282     QCOMPARE(a2_s_o1->currentLoopTime(), 250);
       
   283     QCOMPARE(a2_s_o1->currentLoop(), 2);
       
   284     QCOMPARE(a3_s_o1->currentLoopTime(), 250);
       
   285     QCOMPARE(sequence2->currentLoopTime(), 0);
       
   286     QCOMPARE(a1_s_o2->currentLoopTime(), 0);
       
   287     QCOMPARE(a1_s_o3->currentLoopTime(), 0);
       
   288 
       
   289     // Current time = 1500
       
   290     group.setCurrentTime(1500);
       
   291     QCOMPARE(group.currentLoopTime(), 1500);
       
   292     QCOMPARE(sequence->currentLoopTime(), 1250);
       
   293     QCOMPARE(a1_s_o1->currentLoopTime(), 250);
       
   294     QCOMPARE(a2_s_o1->currentLoopTime(), 250);
       
   295     QCOMPARE(a2_s_o1->currentLoop(), 2);
       
   296     QCOMPARE(a3_s_o1->currentLoopTime(), 250);
       
   297     QCOMPARE(sequence2->currentLoopTime(), 250);
       
   298     QCOMPARE(a1_s_o2->currentLoopTime(), 250);
       
   299     QCOMPARE(a1_s_o3->currentLoopTime(), 0);
       
   300 
       
   301     // Current time = 1750
       
   302     group.setCurrentTime(1750);
       
   303     QCOMPARE(group.currentLoopTime(), 1750);
       
   304     QCOMPARE(sequence->currentLoopTime(), 1250);
       
   305     QCOMPARE(a1_s_o1->currentLoopTime(), 250);
       
   306     QCOMPARE(a2_s_o1->currentLoopTime(), 250);
       
   307     QCOMPARE(a2_s_o1->currentLoop(), 2);
       
   308     QCOMPARE(a3_s_o1->currentLoopTime(), 250);
       
   309     QCOMPARE(sequence2->currentLoopTime(), 500);
       
   310     QCOMPARE(a1_s_o2->currentLoopTime(), 250);
       
   311     QCOMPARE(a1_s_o3->currentLoopTime(), 250);
       
   312 
       
   313     // Current time = 2000
       
   314     group.setCurrentTime(2000);
       
   315     QCOMPARE(group.currentLoopTime(), 1750);
       
   316     QCOMPARE(sequence->currentLoopTime(), 1250);
       
   317     QCOMPARE(a1_s_o1->currentLoopTime(), 250);
       
   318     QCOMPARE(a2_s_o1->currentLoopTime(), 250);
       
   319     QCOMPARE(a2_s_o1->currentLoop(), 2);
       
   320     QCOMPARE(a3_s_o1->currentLoopTime(), 250);
       
   321     QCOMPARE(sequence2->currentLoopTime(), 500);
       
   322     QCOMPARE(a1_s_o2->currentLoopTime(), 250);
       
   323     QCOMPARE(a1_s_o3->currentLoopTime(), 250);
       
   324 }
       
   325 
       
   326 void tst_QSequentialAnimationGroup::setCurrentTimeWithUncontrolledAnimation()
       
   327 {
       
   328     AnimationObject t_o1;
       
   329 
       
   330     // sequence operating on different object/properties
       
   331     QAnimationGroup *sequence = new QSequentialAnimationGroup();
       
   332     QPropertyAnimation *a1_s_o1 = new DummyPropertyAnimation;
       
   333     QPropertyAnimation *a1_s_o2 = new DummyPropertyAnimation;
       
   334     sequence->addAnimation(a1_s_o1);
       
   335     sequence->addAnimation(a1_s_o2);
       
   336 
       
   337     QPropertyAnimation *notTimeDriven = new UncontrolledAnimation(&t_o1);
       
   338     QCOMPARE(notTimeDriven->totalDuration(), -1);
       
   339 
       
   340     QAbstractAnimation *loopsForever = new DummyPropertyAnimation;
       
   341     loopsForever->setLoopCount(-1);
       
   342     QCOMPARE(loopsForever->totalDuration(), -1);
       
   343 
       
   344     QSequentialAnimationGroup group;
       
   345     group.addAnimation(sequence);
       
   346     group.addAnimation(notTimeDriven);
       
   347     group.addAnimation(loopsForever);
       
   348     group.start();
       
   349     group.pause(); // this allows the group to listen for the finish signal of its children
       
   350 
       
   351     // Current time = 1
       
   352     group.setCurrentTime(1);
       
   353     QCOMPARE(group.state(), QAnimationGroup::Paused);
       
   354     QCOMPARE(sequence->state(), QAnimationGroup::Paused);
       
   355     QCOMPARE(a1_s_o1->state(), QAnimationGroup::Paused);
       
   356     QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped);
       
   357     QCOMPARE(notTimeDriven->state(), QAnimationGroup::Stopped);
       
   358     QCOMPARE(loopsForever->state(), QAnimationGroup::Stopped);
       
   359 
       
   360     QCOMPARE(group.currentLoopTime(), 1);
       
   361     QCOMPARE(sequence->currentLoopTime(), 1);
       
   362     QCOMPARE(a1_s_o1->currentLoopTime(), 1);
       
   363     QCOMPARE(a1_s_o2->currentLoopTime(), 0);
       
   364     QCOMPARE(notTimeDriven->currentLoopTime(), 0);
       
   365     QCOMPARE(loopsForever->currentLoopTime(), 0);
       
   366 
       
   367     // Current time = 250
       
   368     group.setCurrentTime(250);
       
   369     QCOMPARE(group.currentLoopTime(), 250);
       
   370     QCOMPARE(sequence->currentLoopTime(), 250);
       
   371     QCOMPARE(a1_s_o1->currentLoopTime(), 250);
       
   372     QCOMPARE(a1_s_o2->currentLoopTime(), 0);
       
   373     QCOMPARE(notTimeDriven->currentLoopTime(), 0);
       
   374     QCOMPARE(loopsForever->currentLoopTime(), 0);
       
   375 
       
   376     // Current time = 500
       
   377     group.setCurrentTime(500);
       
   378     QCOMPARE(group.currentLoopTime(), 500);
       
   379     QCOMPARE(sequence->currentLoopTime(), 500);
       
   380     QCOMPARE(a1_s_o1->currentLoopTime(), 250);
       
   381     QCOMPARE(a1_s_o2->currentLoopTime(), 250);
       
   382     QCOMPARE(notTimeDriven->currentLoopTime(), 0);
       
   383     QCOMPARE(loopsForever->currentLoopTime(), 0);
       
   384     QCOMPARE(group.currentAnimation(), notTimeDriven);
       
   385 
       
   386     // Current time = 505
       
   387     group.setCurrentTime(505);
       
   388     QCOMPARE(group.currentLoopTime(), 505);
       
   389     QCOMPARE(sequence->currentLoopTime(), 500);
       
   390     QCOMPARE(a1_s_o1->currentLoopTime(), 250);
       
   391     QCOMPARE(a1_s_o2->currentLoopTime(), 250);
       
   392     QCOMPARE(notTimeDriven->currentLoopTime(), 5);
       
   393     QCOMPARE(loopsForever->currentLoopTime(), 0);
       
   394     QCOMPARE(group.currentAnimation(), notTimeDriven);
       
   395     QCOMPARE(sequence->state(), QAnimationGroup::Stopped);
       
   396     QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped);
       
   397     QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped);
       
   398     QCOMPARE(notTimeDriven->state(), QAnimationGroup::Paused);
       
   399     QCOMPARE(loopsForever->state(), QAnimationGroup::Stopped);
       
   400 
       
   401     // Current time = 750 (end of notTimeDriven animation)
       
   402     group.setCurrentTime(750);
       
   403     QCOMPARE(group.currentLoopTime(), 750);
       
   404     QCOMPARE(sequence->currentLoopTime(), 500);
       
   405     QCOMPARE(a1_s_o1->currentLoopTime(), 250);
       
   406     QCOMPARE(a1_s_o2->currentLoopTime(), 250);
       
   407     QCOMPARE(notTimeDriven->currentLoopTime(), 250);
       
   408     QCOMPARE(loopsForever->currentLoopTime(), 0);
       
   409     QCOMPARE(group.currentAnimation(), loopsForever);
       
   410     QCOMPARE(sequence->state(), QAnimationGroup::Stopped);
       
   411     QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped);
       
   412     QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped);
       
   413     QCOMPARE(notTimeDriven->state(), QAnimationGroup::Stopped);
       
   414     QCOMPARE(loopsForever->state(), QAnimationGroup::Paused);
       
   415 
       
   416     // Current time = 800 (as notTimeDriven was finished at 750, loopsforever should still run)
       
   417     group.setCurrentTime(800);
       
   418     QCOMPARE(group.currentLoopTime(), 800);
       
   419     QCOMPARE(group.currentAnimation(), loopsForever);
       
   420     QCOMPARE(sequence->currentLoopTime(), 500);
       
   421     QCOMPARE(a1_s_o1->currentLoopTime(), 250);
       
   422     QCOMPARE(a1_s_o2->currentLoopTime(), 250);
       
   423     QCOMPARE(notTimeDriven->currentLoopTime(), 250);
       
   424     QCOMPARE(loopsForever->currentLoopTime(), 50);
       
   425 
       
   426     loopsForever->stop(); // this should stop the group
       
   427 
       
   428     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
   429     QCOMPARE(sequence->state(), QAnimationGroup::Stopped);
       
   430     QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped);
       
   431     QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped);
       
   432     QCOMPARE(notTimeDriven->state(), QAnimationGroup::Stopped);
       
   433     QCOMPARE(loopsForever->state(), QAnimationGroup::Stopped);
       
   434 }
       
   435 
       
   436 void tst_QSequentialAnimationGroup::seekingForwards()
       
   437 {
       
   438 
       
   439     // sequence operating on same object/property
       
   440     QAnimationGroup *sequence = new QSequentialAnimationGroup;
       
   441     QVariantAnimation *a1_s_o1 = new DummyPropertyAnimation;
       
   442     QVariantAnimation *a2_s_o1 = new DummyPropertyAnimation;
       
   443     QVariantAnimation *a3_s_o1 = new DummyPropertyAnimation;
       
   444     a2_s_o1->setLoopCount(3);
       
   445     sequence->addAnimation(a1_s_o1);
       
   446     sequence->addAnimation(a2_s_o1);
       
   447     sequence->addAnimation(a3_s_o1);
       
   448 
       
   449     // sequence operating on different object/properties
       
   450     QAnimationGroup *sequence2 = new QSequentialAnimationGroup;
       
   451     QVariantAnimation *a1_s_o2 = new DummyPropertyAnimation;
       
   452     QVariantAnimation *a1_s_o3 = new DummyPropertyAnimation;
       
   453     sequence2->addAnimation(a1_s_o2);
       
   454     sequence2->addAnimation(a1_s_o3);
       
   455 
       
   456     QSequentialAnimationGroup group;
       
   457     group.addAnimation(sequence);
       
   458     group.addAnimation(sequence2);
       
   459 
       
   460     // Current time = 1
       
   461     group.setCurrentTime(1);
       
   462     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
   463     QCOMPARE(sequence->state(), QAnimationGroup::Stopped);
       
   464     QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped);
       
   465     QCOMPARE(sequence2->state(), QAnimationGroup::Stopped);
       
   466     QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped);
       
   467     QCOMPARE(a1_s_o3->state(), QAnimationGroup::Stopped);
       
   468 
       
   469     QCOMPARE(group.currentLoopTime(), 1);
       
   470     QCOMPARE(sequence->currentLoopTime(), 1);
       
   471     QCOMPARE(a1_s_o1->currentLoopTime(), 1);
       
   472     QCOMPARE(a2_s_o1->currentLoopTime(), 0);
       
   473     QCOMPARE(a3_s_o1->currentLoopTime(), 0);
       
   474     QCOMPARE(sequence2->currentLoopTime(), 0);
       
   475     QCOMPARE(a1_s_o2->currentLoopTime(), 0);
       
   476     QCOMPARE(a1_s_o3->currentLoopTime(), 0);
       
   477 
       
   478     // Current time = 1500
       
   479     group.setCurrentTime(1500);
       
   480     QCOMPARE(group.currentLoopTime(), 1500);
       
   481     QCOMPARE(sequence->currentLoopTime(), 1250);
       
   482     QCOMPARE(a1_s_o1->currentLoopTime(), 250);
       
   483     QCOMPARE(a2_s_o1->currentLoopTime(), 250);
       
   484     QCOMPARE(a2_s_o1->currentLoop(), 2);
       
   485     QCOMPARE(a3_s_o1->currentLoopTime(), 250);
       
   486     QCOMPARE(sequence2->currentLoopTime(), 250);
       
   487     QCOMPARE(a1_s_o2->currentLoopTime(), 250);
       
   488     QCOMPARE(a1_s_o3->currentLoopTime(), 0);
       
   489 
       
   490     // this will restart the group
       
   491     group.start();
       
   492     group.pause();
       
   493     QCOMPARE(group.state(), QAnimationGroup::Paused);
       
   494     QCOMPARE(sequence->state(), QAnimationGroup::Paused);
       
   495     QCOMPARE(a1_s_o1->state(), QAnimationGroup::Paused);
       
   496     QCOMPARE(sequence2->state(), QAnimationGroup::Stopped);
       
   497     QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped);
       
   498     QCOMPARE(a1_s_o3->state(), QAnimationGroup::Stopped);
       
   499 
       
   500     // Current time = 1750
       
   501     group.setCurrentTime(1750);
       
   502     QCOMPARE(group.currentLoopTime(), 1750);
       
   503     QCOMPARE(sequence->currentLoopTime(), 1250);
       
   504     QCOMPARE(a1_s_o1->currentLoopTime(), 250);
       
   505     QCOMPARE(a2_s_o1->currentLoopTime(), 250);
       
   506     QCOMPARE(a2_s_o1->currentLoop(), 2);
       
   507     QCOMPARE(a3_s_o1->currentLoopTime(), 250);
       
   508     QCOMPARE(sequence2->currentLoopTime(), 500);
       
   509     QCOMPARE(a1_s_o2->currentLoopTime(), 250);
       
   510     QCOMPARE(a1_s_o3->currentLoopTime(), 250);
       
   511 }
       
   512 
       
   513 void tst_QSequentialAnimationGroup::seekingBackwards()
       
   514 {
       
   515     // sequence operating on same object/property
       
   516     QAnimationGroup *sequence = new QSequentialAnimationGroup();
       
   517     QVariantAnimation *a1_s_o1 = new DummyPropertyAnimation;
       
   518     QVariantAnimation *a2_s_o1 = new DummyPropertyAnimation;
       
   519     QVariantAnimation *a3_s_o1 = new DummyPropertyAnimation;
       
   520     a2_s_o1->setLoopCount(3);
       
   521     sequence->addAnimation(a1_s_o1);
       
   522     sequence->addAnimation(a2_s_o1);
       
   523     sequence->addAnimation(a3_s_o1);
       
   524 
       
   525     // sequence operating on different object/properties
       
   526     QAnimationGroup *sequence2 = new QSequentialAnimationGroup();
       
   527     QVariantAnimation *a1_s_o2 = new DummyPropertyAnimation;
       
   528     QVariantAnimation *a1_s_o3 = new DummyPropertyAnimation;
       
   529     sequence2->addAnimation(a1_s_o2);
       
   530     sequence2->addAnimation(a1_s_o3);
       
   531 
       
   532     QSequentialAnimationGroup group;
       
   533     group.addAnimation(sequence);
       
   534     group.addAnimation(sequence2);
       
   535 
       
   536     group.start();
       
   537 
       
   538     // Current time = 1600
       
   539     group.setCurrentTime(1600);
       
   540     QCOMPARE(group.currentLoopTime(), 1600);
       
   541     QCOMPARE(sequence->currentLoopTime(), 1250);
       
   542     QCOMPARE(a1_s_o1->currentLoopTime(), 250);
       
   543     QCOMPARE(a2_s_o1->currentLoopTime(), 250);
       
   544     QCOMPARE(a2_s_o1->currentLoop(), 2);
       
   545     QCOMPARE(a3_s_o1->currentLoopTime(), 250);
       
   546     QCOMPARE(sequence2->currentLoopTime(), 350);
       
   547     QCOMPARE(a1_s_o2->currentLoopTime(), 250);
       
   548     QCOMPARE(a1_s_o3->currentLoopTime(), 100);
       
   549 
       
   550     QCOMPARE(group.state(), QAnimationGroup::Running);
       
   551     QCOMPARE(sequence->state(), QAnimationGroup::Stopped);
       
   552     QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped);
       
   553     QCOMPARE(sequence2->state(), QAnimationGroup::Running);
       
   554     QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped);
       
   555     QCOMPARE(a1_s_o3->state(), QAnimationGroup::Running);
       
   556 
       
   557     // Seeking backwards, current time = 1
       
   558     group.setCurrentTime(1);
       
   559     QCOMPARE(group.currentLoopTime(), 1);
       
   560     QCOMPARE(sequence->currentLoopTime(), 1);
       
   561     QCOMPARE(a1_s_o1->currentLoopTime(), 1);
       
   562 
       
   563     QEXPECT_FAIL("", "rewinding in nested groups is considered as a restart from the children,"
       
   564         "hence they don't reset from their current animation", Continue);
       
   565     QCOMPARE(a2_s_o1->currentLoopTime(), 0);
       
   566     QEXPECT_FAIL("", "rewinding in nested groups is considered as a restart from the children,"
       
   567         "hence they don't reset from their current animation", Continue);
       
   568     QCOMPARE(a2_s_o1->currentLoop(), 0);
       
   569     QEXPECT_FAIL("", "rewinding in nested groups is considered as a restart from the children,"
       
   570         "hence they don't reset from their current animation", Continue);
       
   571     QCOMPARE(a3_s_o1->currentLoopTime(), 0);
       
   572     QCOMPARE(sequence2->currentLoopTime(), 0);
       
   573     QCOMPARE(a1_s_o2->currentLoopTime(), 0);
       
   574     QCOMPARE(a1_s_o3->currentLoopTime(), 0);
       
   575 
       
   576     QCOMPARE(group.state(), QAnimationGroup::Running);
       
   577     QCOMPARE(sequence->state(), QAnimationGroup::Running);
       
   578     QCOMPARE(a1_s_o1->state(), QAnimationGroup::Running);
       
   579     QCOMPARE(sequence2->state(), QAnimationGroup::Stopped);
       
   580     QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped);
       
   581     QCOMPARE(a1_s_o3->state(), QAnimationGroup::Stopped);
       
   582 
       
   583     // Current time = 2000
       
   584     group.setCurrentTime(2000);
       
   585     QCOMPARE(group.currentLoopTime(), 1750);
       
   586     QCOMPARE(sequence->currentLoopTime(), 1250);
       
   587     QCOMPARE(a1_s_o1->currentLoopTime(), 250);
       
   588     QCOMPARE(a2_s_o1->currentLoopTime(), 250);
       
   589     QCOMPARE(a2_s_o1->currentLoop(), 2);
       
   590     QCOMPARE(a3_s_o1->currentLoopTime(), 250);
       
   591     QCOMPARE(sequence2->currentLoopTime(), 500);
       
   592     QCOMPARE(a1_s_o2->currentLoopTime(), 250);
       
   593     QCOMPARE(a1_s_o3->currentLoopTime(), 250);
       
   594 
       
   595     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
   596     QCOMPARE(sequence->state(), QAnimationGroup::Stopped);
       
   597     QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped);
       
   598     QCOMPARE(sequence2->state(), QAnimationGroup::Stopped);
       
   599     QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped);
       
   600     QCOMPARE(a1_s_o3->state(), QAnimationGroup::Stopped);
       
   601 }
       
   602 
       
   603 typedef QList<QAbstractAnimation::State> StateList;
       
   604 
       
   605 static bool compareStates(const QSignalSpy& spy, const StateList &expectedStates)
       
   606 {
       
   607     bool equals = true;
       
   608     for (int i = 0; i < qMax(expectedStates.count(), spy.count()); ++i) {
       
   609         if (i >= spy.count() || i >= expectedStates.count()) {
       
   610             equals = false;
       
   611             break;
       
   612         }
       
   613         QList<QVariant> args = spy.at(i);
       
   614         QAbstractAnimation::State st = expectedStates.at(i);
       
   615         QAbstractAnimation::State actual = qVariantValue<QAbstractAnimation::State>(args.first());
       
   616         if (equals && actual != st) {
       
   617             equals = false;
       
   618             break;
       
   619         }
       
   620     }
       
   621     if (!equals) {
       
   622         const char *stateStrings[] = {"Stopped", "Paused", "Running"};
       
   623         QString e,a;
       
   624         for (int i = 0; i < qMax(expectedStates.count(), spy.count()); ++i) {
       
   625             if (i < expectedStates.count()) {
       
   626                 int exp = int(expectedStates.at(i));
       
   627                     if (!e.isEmpty())
       
   628                         e += QLatin1String(", ");
       
   629                 e += QLatin1String(stateStrings[exp]);
       
   630             }
       
   631             if (i < spy.count()) {
       
   632                 QList<QVariant> args = spy.at(i);
       
   633                 QAbstractAnimation::State actual = qVariantValue<QAbstractAnimation::State>(args.value(1));
       
   634                 if (!a.isEmpty())
       
   635                     a += QLatin1String(", ");
       
   636                 if (int(actual) >= 0 && int(actual) <= 2) {
       
   637                     a += QLatin1String(stateStrings[int(actual)]);
       
   638                 } else {
       
   639                     a += QLatin1String("NaN");
       
   640                 }
       
   641             }
       
   642 
       
   643         }
       
   644         qDebug("\n"
       
   645                "expected (count == %d): %s\n"
       
   646                "actual   (count == %d): %s\n", expectedStates.count(), qPrintable(e), spy.count(), qPrintable(a));
       
   647     }
       
   648     return equals;
       
   649 }
       
   650 
       
   651 void tst_QSequentialAnimationGroup::pauseAndResume()
       
   652 {
       
   653     // sequence operating on same object/property
       
   654     QAnimationGroup *sequence = new QSequentialAnimationGroup();
       
   655     QVariantAnimation *a1_s_o1 = new DummyPropertyAnimation;
       
   656     QVariantAnimation *a2_s_o1 = new DummyPropertyAnimation;
       
   657     QVariantAnimation *a3_s_o1 = new DummyPropertyAnimation;
       
   658     a2_s_o1->setLoopCount(2);
       
   659     sequence->addAnimation(a1_s_o1);
       
   660     sequence->addAnimation(a2_s_o1);
       
   661     sequence->addAnimation(a3_s_o1);
       
   662     sequence->setLoopCount(2);
       
   663 
       
   664     QSignalSpy a1StateChangedSpy(a1_s_o1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
       
   665     QSignalSpy seqStateChangedSpy(sequence, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
       
   666 
       
   667     QSequentialAnimationGroup group;
       
   668     group.addAnimation(sequence);
       
   669 
       
   670     group.start();
       
   671     group.pause();
       
   672 
       
   673     // Current time = 1751
       
   674     group.setCurrentTime(1751);
       
   675     QCOMPARE(group.currentLoopTime(), 1751);
       
   676     QCOMPARE(sequence->currentLoopTime(), 751);
       
   677     QCOMPARE(sequence->currentLoop(), 1);
       
   678     QCOMPARE(a1_s_o1->currentLoopTime(), 250);
       
   679     QCOMPARE(a2_s_o1->currentLoopTime(), 250);
       
   680     QCOMPARE(a2_s_o1->currentLoop(), 1);
       
   681     QCOMPARE(a3_s_o1->currentLoop(), 0);
       
   682     QCOMPARE(a3_s_o1->currentLoopTime(), 1);
       
   683 
       
   684     QCOMPARE(group.state(), QAnimationGroup::Paused);
       
   685     QCOMPARE(sequence->state(), QAnimationGroup::Paused);
       
   686     QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped);
       
   687     QCOMPARE(a2_s_o1->state(), QAnimationGroup::Stopped);
       
   688     QCOMPARE(a3_s_o1->state(), QAnimationGroup::Paused);
       
   689 
       
   690     QCOMPARE(a1StateChangedSpy.count(), 5);     // Running,Paused,Stopped,Running,Stopped
       
   691     QCOMPARE(seqStateChangedSpy.count(), 2);    // Running,Paused
       
   692 
       
   693     QVERIFY(compareStates(a1StateChangedSpy, (StateList() << QAbstractAnimation::Running
       
   694                                               << QAbstractAnimation::Paused
       
   695                                               << QAbstractAnimation::Stopped
       
   696                                               << QAbstractAnimation::Running
       
   697                                               << QAbstractAnimation::Stopped)));
       
   698 
       
   699     QCOMPARE(qVariantValue<QAbstractAnimation::State>(a1StateChangedSpy.at(0).first()),
       
   700              QAnimationGroup::Running);
       
   701     QCOMPARE(qVariantValue<QAbstractAnimation::State>(a1StateChangedSpy.at(1).first()),
       
   702              QAnimationGroup::Paused);
       
   703     QCOMPARE(qVariantValue<QAbstractAnimation::State>(a1StateChangedSpy.at(2).first()),
       
   704              QAnimationGroup::Stopped);
       
   705     QCOMPARE(qVariantValue<QAbstractAnimation::State>(a1StateChangedSpy.at(3).first()),
       
   706              QAnimationGroup::Running);
       
   707     QCOMPARE(qVariantValue<QAbstractAnimation::State>(a1StateChangedSpy.at(4).first()),
       
   708              QAnimationGroup::Stopped);
       
   709 
       
   710     QCOMPARE(qVariantValue<QAbstractAnimation::State>(seqStateChangedSpy.at(0).first()),
       
   711              QAnimationGroup::Running);
       
   712     QCOMPARE(qVariantValue<QAbstractAnimation::State>(seqStateChangedSpy.at(1).first()),
       
   713              QAnimationGroup::Paused);
       
   714 
       
   715     group.resume();
       
   716 
       
   717     QCOMPARE(group.state(), QAnimationGroup::Running);
       
   718     QCOMPARE(sequence->state(), QAnimationGroup::Running);
       
   719     QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped);
       
   720     QCOMPARE(a2_s_o1->state(), QAnimationGroup::Stopped);
       
   721     QCOMPARE(a3_s_o1->state(), QAnimationGroup::Running);
       
   722 
       
   723     QVERIFY(group.currentLoopTime() >= 1751);
       
   724     QVERIFY(sequence->currentLoopTime() >= 751);
       
   725     QCOMPARE(sequence->currentLoop(), 1);
       
   726     QCOMPARE(a1_s_o1->currentLoopTime(), 250);
       
   727     QCOMPARE(a2_s_o1->currentLoopTime(), 250);
       
   728     QCOMPARE(a2_s_o1->currentLoop(), 1);
       
   729     QCOMPARE(a3_s_o1->currentLoop(), 0);
       
   730     QVERIFY(a3_s_o1->currentLoopTime() >= 1);
       
   731 
       
   732     QCOMPARE(seqStateChangedSpy.count(), 3);    // Running,Paused,Running
       
   733     QCOMPARE(qVariantValue<QAbstractAnimation::State>(seqStateChangedSpy.at(2).first()),
       
   734              QAnimationGroup::Running);
       
   735 
       
   736     group.pause();
       
   737 
       
   738     QCOMPARE(group.state(), QAnimationGroup::Paused);
       
   739     QCOMPARE(sequence->state(), QAnimationGroup::Paused);
       
   740     QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped);
       
   741     QCOMPARE(a2_s_o1->state(), QAnimationGroup::Stopped);
       
   742     QCOMPARE(a3_s_o1->state(), QAnimationGroup::Paused);
       
   743 
       
   744     QVERIFY(group.currentLoopTime() >= 1751);
       
   745     QVERIFY(sequence->currentLoopTime() >= 751);
       
   746     QCOMPARE(sequence->currentLoop(), 1);
       
   747     QCOMPARE(a1_s_o1->currentLoopTime(), 250);
       
   748     QCOMPARE(a2_s_o1->currentLoopTime(), 250);
       
   749     QCOMPARE(a2_s_o1->currentLoop(), 1);
       
   750     QCOMPARE(a3_s_o1->currentLoop(), 0);
       
   751     QVERIFY(a3_s_o1->currentLoopTime() >= 1);
       
   752 
       
   753     QCOMPARE(seqStateChangedSpy.count(), 4);    // Running,Paused,Running,Paused
       
   754     QCOMPARE(qVariantValue<QAbstractAnimation::State>(seqStateChangedSpy.at(3).first()),
       
   755              QAnimationGroup::Paused);
       
   756 
       
   757     group.stop();
       
   758 
       
   759     QCOMPARE(seqStateChangedSpy.count(), 5);    // Running,Paused,Running,Paused,Stopped
       
   760     QCOMPARE(qVariantValue<QAbstractAnimation::State>(seqStateChangedSpy.at(4).first()),
       
   761              QAnimationGroup::Stopped);
       
   762 }
       
   763 
       
   764 void tst_QSequentialAnimationGroup::restart()
       
   765 {
       
   766     // sequence operating on same object/property
       
   767     QAnimationGroup *sequence = new QSequentialAnimationGroup();
       
   768     QSignalSpy seqCurrentAnimChangedSpy(sequence, SIGNAL(currentAnimationChanged(QAbstractAnimation*)));
       
   769     QSignalSpy seqStateChangedSpy(sequence, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
       
   770 
       
   771     QVariantAnimation *anims[3];
       
   772     QSignalSpy *animsStateChanged[3];
       
   773 
       
   774     for (int i = 0; i < 3; i++) {
       
   775         anims[i] = new DummyPropertyAnimation;
       
   776         anims[i]->setDuration(100);
       
   777         animsStateChanged[i] = new QSignalSpy(anims[i], SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
       
   778     }
       
   779 
       
   780     anims[1]->setLoopCount(2);
       
   781     sequence->addAnimation(anims[0]);
       
   782     sequence->addAnimation(anims[1]);
       
   783     sequence->addAnimation(anims[2]);
       
   784     sequence->setLoopCount(2);
       
   785 
       
   786     QSequentialAnimationGroup group;
       
   787     group.addAnimation(sequence);
       
   788 
       
   789     group.start();
       
   790 
       
   791     QTest::qWait(500);
       
   792 
       
   793     QCOMPARE(group.state(), QAnimationGroup::Running);
       
   794 
       
   795     QTest::qWait(300);
       
   796     QTRY_COMPARE(group.state(), QAnimationGroup::Stopped);
       
   797 
       
   798     for (int i = 0; i < 3; i++) {
       
   799         QCOMPARE(animsStateChanged[i]->count(), 4);
       
   800         QCOMPARE(qVariantValue<QAbstractAnimation::State>(animsStateChanged[i]->at(0).first()),
       
   801                  QAnimationGroup::Running);
       
   802         QCOMPARE(qVariantValue<QAbstractAnimation::State>(animsStateChanged[i]->at(1).first()),
       
   803                  QAnimationGroup::Stopped);
       
   804         QCOMPARE(qVariantValue<QAbstractAnimation::State>(animsStateChanged[i]->at(2).first()),
       
   805                  QAnimationGroup::Running);
       
   806         QCOMPARE(qVariantValue<QAbstractAnimation::State>(animsStateChanged[i]->at(3).first()),
       
   807                  QAnimationGroup::Stopped);
       
   808     }
       
   809 
       
   810     QCOMPARE(seqStateChangedSpy.count(), 2);
       
   811     QCOMPARE(qVariantValue<QAbstractAnimation::State>(seqStateChangedSpy.at(0).first()),
       
   812              QAnimationGroup::Running);
       
   813     QCOMPARE(qVariantValue<QAbstractAnimation::State>(seqStateChangedSpy.at(1).first()),
       
   814              QAnimationGroup::Stopped);
       
   815 
       
   816     QCOMPARE(seqCurrentAnimChangedSpy.count(), 6);
       
   817     for(int i=0; i<seqCurrentAnimChangedSpy.count(); i++)
       
   818             QCOMPARE(static_cast<QAbstractAnimation*>(anims[i%3]), qVariantValue<QAbstractAnimation*>(seqCurrentAnimChangedSpy.at(i).at(0)));
       
   819 
       
   820     group.start();
       
   821 
       
   822     QCOMPARE(animsStateChanged[0]->count(), 5);
       
   823     QCOMPARE(animsStateChanged[1]->count(), 4);
       
   824     QCOMPARE(animsStateChanged[2]->count(), 4);
       
   825     QCOMPARE(seqStateChangedSpy.count(), 3);
       
   826 }
       
   827 
       
   828 void tst_QSequentialAnimationGroup::looping()
       
   829 {
       
   830     // sequence operating on same object/property
       
   831     QSequentialAnimationGroup *sequence = new QSequentialAnimationGroup();
       
   832     QAbstractAnimation *a1_s_o1 = new DummyPropertyAnimation;
       
   833     QAbstractAnimation *a2_s_o1 = new DummyPropertyAnimation;
       
   834     QAbstractAnimation *a3_s_o1 = new DummyPropertyAnimation;
       
   835 
       
   836     QSignalSpy a1Spy(a1_s_o1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
       
   837     QSignalSpy a2Spy(a2_s_o1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
       
   838     QSignalSpy a3Spy(a3_s_o1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
       
   839     QSignalSpy seqSpy(sequence, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
       
   840 
       
   841     a2_s_o1->setLoopCount(2);
       
   842     sequence->addAnimation(a1_s_o1);
       
   843     sequence->addAnimation(a2_s_o1);
       
   844     sequence->addAnimation(a3_s_o1);
       
   845     sequence->setLoopCount(2);
       
   846 
       
   847     QSequentialAnimationGroup group;
       
   848     QSignalSpy groupSpy(&group, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
       
   849 
       
   850     group.addAnimation(sequence);
       
   851     group.setLoopCount(2);
       
   852 
       
   853     group.start();
       
   854     group.pause();
       
   855 
       
   856     // Current time = 1750
       
   857     group.setCurrentTime(1750);
       
   858     QCOMPARE(group.currentLoopTime(), 1750);
       
   859     QCOMPARE(sequence->currentLoopTime(), 750);
       
   860     QCOMPARE(sequence->currentLoop(), 1);
       
   861     QCOMPARE(a1_s_o1->currentLoopTime(), 250);
       
   862     QCOMPARE(a2_s_o1->currentLoopTime(), 250);
       
   863     QCOMPARE(a2_s_o1->currentLoop(), 1);
       
   864     // this animation is at the beginning because it is the current one inside sequence
       
   865     QCOMPARE(a3_s_o1->currentLoop(), 0);
       
   866     QCOMPARE(a3_s_o1->currentLoopTime(), 0);
       
   867     QCOMPARE(sequence->currentAnimation(), a3_s_o1);
       
   868 
       
   869     QCOMPARE(group.state(), QAnimationGroup::Paused);
       
   870     QCOMPARE(sequence->state(), QAnimationGroup::Paused);
       
   871     QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped);
       
   872     QCOMPARE(a2_s_o1->state(), QAnimationGroup::Stopped);
       
   873     QCOMPARE(a3_s_o1->state(), QAnimationGroup::Paused);
       
   874 
       
   875     QCOMPARE(a1Spy.count(), 5);     // Running,Paused,Stopped,Running,Stopped
       
   876     QVERIFY(compareStates(a1Spy, (StateList() << QAbstractAnimation::Running
       
   877                                               << QAbstractAnimation::Paused
       
   878                                               << QAbstractAnimation::Stopped
       
   879                                               << QAbstractAnimation::Running
       
   880                                               << QAbstractAnimation::Stopped)));
       
   881 
       
   882     QCOMPARE(a2Spy.count(), 4);     // Running,Stopped,Running,Stopped
       
   883     QVERIFY(compareStates(a3Spy, (StateList() << QAbstractAnimation::Running
       
   884                                               << QAbstractAnimation::Stopped
       
   885                                               << QAbstractAnimation::Running
       
   886                                               << QAbstractAnimation::Paused)));
       
   887 
       
   888     QCOMPARE(seqSpy.count(), 2);    // Running,Paused
       
   889     QCOMPARE(groupSpy.count(), 2);  // Running,Paused
       
   890 
       
   891     // Looping, current time = duration + 1
       
   892     group.setCurrentTime(group.duration() + 1);
       
   893     QCOMPARE(group.currentLoopTime(), 1);
       
   894     QCOMPARE(group.currentLoop(), 1);
       
   895     QCOMPARE(sequence->currentLoopTime(), 1);
       
   896     QCOMPARE(sequence->currentLoop(), 0);
       
   897     QCOMPARE(a1_s_o1->currentLoopTime(), 1);
       
   898     QCOMPARE(a2_s_o1->currentLoopTime(), 250);
       
   899     QCOMPARE(a2_s_o1->currentLoop(), 1);
       
   900     // this animation is at the end because it was run on the previous loop
       
   901     QCOMPARE(a3_s_o1->currentLoop(), 0);
       
   902     QCOMPARE(a3_s_o1->currentLoopTime(), 250);
       
   903 
       
   904     QCOMPARE(group.state(), QAnimationGroup::Paused);
       
   905     QCOMPARE(sequence->state(), QAnimationGroup::Paused);
       
   906     QCOMPARE(a1_s_o1->state(), QAnimationGroup::Paused);
       
   907     QCOMPARE(a2_s_o1->state(), QAnimationGroup::Stopped);
       
   908     QCOMPARE(a3_s_o1->state(), QAnimationGroup::Stopped);
       
   909 
       
   910     QCOMPARE(a1Spy.count(), 7); // Running,Paused,Stopped,Running,Stopped,Running,Stopped
       
   911     QCOMPARE(a2Spy.count(), 4); // Running, Stopped, Running, Stopped
       
   912     QVERIFY(compareStates(a3Spy, (StateList() << QAbstractAnimation::Running
       
   913                                               << QAbstractAnimation::Stopped
       
   914                                               << QAbstractAnimation::Running
       
   915                                               << QAbstractAnimation::Paused
       
   916                                               << QAbstractAnimation::Stopped)));
       
   917     QVERIFY(compareStates(seqSpy, (StateList() << QAbstractAnimation::Running
       
   918                                                << QAbstractAnimation::Paused
       
   919                                                << QAbstractAnimation::Stopped
       
   920                                                << QAbstractAnimation::Running
       
   921                                                << QAbstractAnimation::Paused)));
       
   922     QCOMPARE(groupSpy.count(), 2);
       
   923 }
       
   924 
       
   925 void tst_QSequentialAnimationGroup::startDelay()
       
   926 {
       
   927     QSequentialAnimationGroup group;
       
   928     group.addPause(250);
       
   929     group.addPause(125);
       
   930     QCOMPARE(group.totalDuration(), 375);
       
   931 
       
   932     group.start();
       
   933     QCOMPARE(group.state(), QAnimationGroup::Running);
       
   934 
       
   935     QTest::qWait(500);
       
   936 
       
   937     QTRY_COMPARE(group.state(), QAnimationGroup::Stopped);
       
   938     QVERIFY(group.currentLoopTime() == 375);
       
   939 }
       
   940 
       
   941 void tst_QSequentialAnimationGroup::clearGroup()
       
   942 {
       
   943     QSequentialAnimationGroup group;
       
   944 	
       
   945 	static const int animationCount = 20;
       
   946 
       
   947     for (int i = 0; i < animationCount/2; ++i) {
       
   948         QSequentialAnimationGroup *subGroup = new QSequentialAnimationGroup(&group);
       
   949         group.addPause(100);
       
   950         subGroup->addPause(10);
       
   951     }
       
   952 
       
   953     QCOMPARE(group.animationCount(), animationCount);
       
   954 
       
   955     QPointer<QAbstractAnimation> children[animationCount];
       
   956     for (int i = 0; i < animationCount; ++i) {
       
   957         QVERIFY(group.animationAt(i) != 0);
       
   958         children[i] = group.animationAt(i);
       
   959     }
       
   960 
       
   961     group.clear();
       
   962     QCOMPARE(group.animationCount(), 0);
       
   963     QCOMPARE(group.currentLoopTime(), 0);
       
   964     for (int i = 0; i < animationCount; ++i)
       
   965         QVERIFY(children[i].isNull());
       
   966 }
       
   967 
       
   968 void tst_QSequentialAnimationGroup::groupWithZeroDurationAnimations()
       
   969 {
       
   970     QObject o;
       
   971     QObject o2;
       
   972 
       
   973     o.setProperty("myProperty", 42);
       
   974     o.setProperty("myOtherProperty", 13);
       
   975     o2.setProperty("myProperty", 42);
       
   976     o2.setProperty("myOtherProperty", 13);
       
   977 
       
   978     QSequentialAnimationGroup group;
       
   979 
       
   980     QVariantAnimation *a1 = new QPropertyAnimation(&o, "myProperty");
       
   981     a1->setDuration(0);
       
   982     a1->setEndValue(43);
       
   983     group.addAnimation(a1);
       
   984 
       
   985     //this should just run fine and change nothing
       
   986     group.setCurrentTime(0);
       
   987     QCOMPARE(group.currentAnimation(), static_cast<QAbstractAnimation*>(a1));
       
   988 
       
   989     QVariantAnimation *a2 = new QPropertyAnimation(&o2, "myOtherProperty");
       
   990     a2->setDuration(500);
       
   991     a2->setEndValue(31);
       
   992     group.addAnimation(a2);
       
   993 
       
   994     QVariantAnimation *a3 = new QPropertyAnimation(&o, "myProperty");
       
   995     a3->setDuration(0);
       
   996     a3->setEndValue(44);
       
   997     group.addAnimation(a3);
       
   998 
       
   999     QVariantAnimation *a4 = new QPropertyAnimation(&o, "myOtherProperty");
       
  1000     a4->setDuration(250);
       
  1001     a4->setEndValue(75);
       
  1002     group.addAnimation(a4);
       
  1003 
       
  1004     QVariantAnimation *a5 = new QPropertyAnimation(&o2, "myProperty");
       
  1005     a5->setDuration(0);
       
  1006     a5->setEndValue(12);
       
  1007     group.addAnimation(a5);
       
  1008 
       
  1009     QCOMPARE(o.property("myProperty").toInt(), 42);
       
  1010     QCOMPARE(o.property("myOtherProperty").toInt(), 13);
       
  1011     QCOMPARE(o2.property("myProperty").toInt(), 42);
       
  1012     QCOMPARE(o2.property("myOtherProperty").toInt(), 13);
       
  1013 
       
  1014 
       
  1015     group.start();
       
  1016 
       
  1017     QCOMPARE(o.property("myProperty").toInt(), 43);
       
  1018     QCOMPARE(o.property("myOtherProperty").toInt(), 13);
       
  1019     QCOMPARE(o2.property("myProperty").toInt(), 42);
       
  1020     QCOMPARE(o2.property("myOtherProperty").toInt(), 13);
       
  1021 
       
  1022     QTest::qWait(100);
       
  1023 
       
  1024     int o2val = o2.property("myOtherProperty").toInt();
       
  1025     QVERIFY(o2val > 13);
       
  1026     QVERIFY(o2val < 31);
       
  1027     QCOMPARE(o.property("myProperty").toInt(), 43);
       
  1028     QCOMPARE(o.property("myOtherProperty").toInt(), 13);
       
  1029 
       
  1030     QTest::qWait(500);
       
  1031 
       
  1032     QTRY_COMPARE(o.property("myProperty").toInt(), 44);
       
  1033     QCOMPARE(o2.property("myProperty").toInt(), 42);
       
  1034     QCOMPARE(o2.property("myOtherProperty").toInt(), 31);
       
  1035     QCOMPARE(a1->state(), QAnimationGroup::Stopped);
       
  1036     QCOMPARE(a2->state(), QAnimationGroup::Stopped);
       
  1037     QCOMPARE(a3->state(), QAnimationGroup::Stopped);
       
  1038     QCOMPARE(a4->state(), QAnimationGroup::Running);
       
  1039     QCOMPARE(a5->state(), QAnimationGroup::Stopped);
       
  1040     QCOMPARE(group.state(), QAnimationGroup::Running);
       
  1041     QTest::qWait(500);
       
  1042 
       
  1043     QTRY_COMPARE(group.state(), QAnimationGroup::Stopped);
       
  1044     QCOMPARE(o.property("myProperty").toInt(), 44);
       
  1045     QCOMPARE(o.property("myOtherProperty").toInt(), 75);
       
  1046     QCOMPARE(o2.property("myProperty").toInt(), 12);
       
  1047     QCOMPARE(o2.property("myOtherProperty").toInt(), 31);
       
  1048     QCOMPARE(a1->state(), QAnimationGroup::Stopped);
       
  1049     QCOMPARE(a2->state(), QAnimationGroup::Stopped);
       
  1050     QCOMPARE(a3->state(), QAnimationGroup::Stopped);
       
  1051     QCOMPARE(a4->state(), QAnimationGroup::Stopped);
       
  1052     QCOMPARE(a5->state(), QAnimationGroup::Stopped);
       
  1053 }
       
  1054 
       
  1055 void tst_QSequentialAnimationGroup::propagateGroupUpdateToChildren()
       
  1056 {
       
  1057     // this test verifies if group state changes are updating its children correctly
       
  1058     QSequentialAnimationGroup group;
       
  1059 
       
  1060     QObject o;
       
  1061     o.setProperty("ole", 42);
       
  1062     QCOMPARE(o.property("ole").toInt(), 42);
       
  1063 
       
  1064     QPropertyAnimation anim1(&o, "ole");
       
  1065     anim1.setEndValue(43);
       
  1066     anim1.setDuration(100);
       
  1067     QVERIFY(!anim1.currentValue().isValid());
       
  1068     QCOMPARE(anim1.currentValue().toInt(), 0);
       
  1069     QCOMPARE(o.property("ole").toInt(), 42);
       
  1070 
       
  1071     TestAnimation anim2;
       
  1072     anim2.setStartValue(0);
       
  1073     anim2.setEndValue(100);
       
  1074     anim2.setDuration(200);
       
  1075 
       
  1076     QVERIFY(anim2.currentValue().isValid());
       
  1077     QCOMPARE(anim2.currentValue().toInt(), 0);
       
  1078 
       
  1079     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
  1080     QCOMPARE(anim1.state(), QAnimationGroup::Stopped);
       
  1081     QCOMPARE(anim2.state(), QAnimationGroup::Stopped);
       
  1082 
       
  1083     group.addAnimation(&anim1);
       
  1084     group.addAnimation(&anim2);
       
  1085 
       
  1086     group.start();
       
  1087 
       
  1088     QCOMPARE(group.state(), QAnimationGroup::Running);
       
  1089     QCOMPARE(anim1.state(), QAnimationGroup::Running);
       
  1090     QCOMPARE(anim2.state(), QAnimationGroup::Stopped);
       
  1091 
       
  1092     group.pause();
       
  1093 
       
  1094     QCOMPARE(group.state(), QAnimationGroup::Paused);
       
  1095     QCOMPARE(anim1.state(), QAnimationGroup::Paused);
       
  1096     QCOMPARE(anim2.state(), QAnimationGroup::Stopped);
       
  1097 
       
  1098     group.stop();
       
  1099 
       
  1100     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
  1101     QCOMPARE(anim1.state(), QAnimationGroup::Stopped);
       
  1102     QCOMPARE(anim2.state(), QAnimationGroup::Stopped);
       
  1103 }
       
  1104 
       
  1105 void tst_QSequentialAnimationGroup::updateChildrenWithRunningGroup()
       
  1106 {
       
  1107     // assert that its possible to modify a child's state directly while their group is running
       
  1108     QSequentialAnimationGroup group;
       
  1109 
       
  1110     TestAnimation anim;
       
  1111     anim.setStartValue(0);
       
  1112     anim.setEndValue(100);
       
  1113     anim.setDuration(200);
       
  1114 
       
  1115     QSignalSpy groupStateChangedSpy(&group, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
       
  1116     QSignalSpy childStateChangedSpy(&anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
       
  1117 
       
  1118     QCOMPARE(groupStateChangedSpy.count(), 0);
       
  1119     QCOMPARE(childStateChangedSpy.count(), 0);
       
  1120     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
  1121     QCOMPARE(anim.state(), QAnimationGroup::Stopped);
       
  1122 
       
  1123     group.addAnimation(&anim);
       
  1124 
       
  1125     group.start();
       
  1126 
       
  1127     QCOMPARE(group.state(), QAnimationGroup::Running);
       
  1128     QCOMPARE(anim.state(), QAnimationGroup::Running);
       
  1129 
       
  1130     QCOMPARE(groupStateChangedSpy.count(), 1);
       
  1131     QCOMPARE(childStateChangedSpy.count(), 1);
       
  1132 
       
  1133     QCOMPARE(qVariantValue<QAbstractAnimation::State>(groupStateChangedSpy.at(0).first()),
       
  1134              QAnimationGroup::Running);
       
  1135     QCOMPARE(qVariantValue<QAbstractAnimation::State>(childStateChangedSpy.at(0).first()),
       
  1136              QAnimationGroup::Running);
       
  1137 
       
  1138     // starting directly a running child will not have any effect
       
  1139     anim.start();
       
  1140 
       
  1141     QCOMPARE(groupStateChangedSpy.count(), 1);
       
  1142     QCOMPARE(childStateChangedSpy.count(), 1);
       
  1143 
       
  1144     anim.pause();
       
  1145 
       
  1146     QCOMPARE(group.state(), QAnimationGroup::Running);
       
  1147     QCOMPARE(anim.state(), QAnimationGroup::Paused);
       
  1148 
       
  1149     // in the animation stops directly, the group will still be running
       
  1150     anim.stop();
       
  1151 
       
  1152     QCOMPARE(group.state(), QAnimationGroup::Running);
       
  1153     QCOMPARE(anim.state(), QAnimationGroup::Stopped);
       
  1154 }
       
  1155 
       
  1156 void tst_QSequentialAnimationGroup::deleteChildrenWithRunningGroup()
       
  1157 {
       
  1158     // test if children can be activated when their group is stopped
       
  1159     QSequentialAnimationGroup group;
       
  1160 
       
  1161     QVariantAnimation *anim1 = new TestAnimation;
       
  1162     anim1->setStartValue(0);
       
  1163     anim1->setEndValue(100);
       
  1164     anim1->setDuration(200);
       
  1165     group.addAnimation(anim1);
       
  1166 
       
  1167     QCOMPARE(group.duration(), anim1->duration());
       
  1168 
       
  1169     group.start();
       
  1170     QCOMPARE(group.state(), QAnimationGroup::Running);
       
  1171     QCOMPARE(anim1->state(), QAnimationGroup::Running);
       
  1172 
       
  1173     QTest::qWait(100);
       
  1174     QTRY_VERIFY(group.currentLoopTime() > 0);
       
  1175 
       
  1176     delete anim1;
       
  1177     QCOMPARE(group.animationCount(), 0);
       
  1178     QCOMPARE(group.duration(), 0);
       
  1179     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
  1180     QCOMPARE(group.currentLoopTime(), 0); //that's the invariant
       
  1181 }
       
  1182 
       
  1183 void tst_QSequentialAnimationGroup::startChildrenWithStoppedGroup()
       
  1184 {
       
  1185     // test if children can be activated when their group is stopped
       
  1186     QSequentialAnimationGroup group;
       
  1187 
       
  1188     TestAnimation anim1;
       
  1189     anim1.setStartValue(0);
       
  1190     anim1.setEndValue(100);
       
  1191     anim1.setDuration(200);
       
  1192 
       
  1193     TestAnimation anim2;
       
  1194     anim2.setStartValue(0);
       
  1195     anim2.setEndValue(100);
       
  1196     anim2.setDuration(200);
       
  1197 
       
  1198     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
  1199     QCOMPARE(anim1.state(), QAnimationGroup::Stopped);
       
  1200     QCOMPARE(anim2.state(), QAnimationGroup::Stopped);
       
  1201 
       
  1202     group.addAnimation(&anim1);
       
  1203     group.addAnimation(&anim2);
       
  1204 
       
  1205     group.stop();
       
  1206 
       
  1207     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
  1208     QCOMPARE(anim1.state(), QAnimationGroup::Stopped);
       
  1209     QCOMPARE(anim2.state(), QAnimationGroup::Stopped);
       
  1210 
       
  1211     anim1.start();
       
  1212     anim2.start();
       
  1213     anim2.pause();
       
  1214 
       
  1215     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
  1216     QCOMPARE(anim1.state(), QAnimationGroup::Running);
       
  1217     QCOMPARE(anim2.state(), QAnimationGroup::Paused);
       
  1218 }
       
  1219 
       
  1220 void tst_QSequentialAnimationGroup::stopGroupWithRunningChild()
       
  1221 {
       
  1222     // children that started independently will not be affected by a group stop
       
  1223     QSequentialAnimationGroup group;
       
  1224 
       
  1225     TestAnimation anim1;
       
  1226     anim1.setStartValue(0);
       
  1227     anim1.setEndValue(100);
       
  1228     anim1.setDuration(200);
       
  1229 
       
  1230     TestAnimation anim2;
       
  1231     anim2.setStartValue(0);
       
  1232     anim2.setEndValue(100);
       
  1233     anim2.setDuration(200);
       
  1234 
       
  1235     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
  1236     QCOMPARE(anim1.state(), QAnimationGroup::Stopped);
       
  1237     QCOMPARE(anim2.state(), QAnimationGroup::Stopped);
       
  1238 
       
  1239     group.addAnimation(&anim1);
       
  1240     group.addAnimation(&anim2);
       
  1241 
       
  1242     anim1.start();
       
  1243     anim2.start();
       
  1244     anim2.pause();
       
  1245 
       
  1246     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
  1247     QCOMPARE(anim1.state(), QAnimationGroup::Running);
       
  1248     QCOMPARE(anim2.state(), QAnimationGroup::Paused);
       
  1249 
       
  1250     group.stop();
       
  1251 
       
  1252     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
  1253     QCOMPARE(anim1.state(), QAnimationGroup::Running);
       
  1254     QCOMPARE(anim2.state(), QAnimationGroup::Paused);
       
  1255 
       
  1256     anim1.stop();
       
  1257     anim2.stop();
       
  1258 
       
  1259     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
  1260     QCOMPARE(anim1.state(), QAnimationGroup::Stopped);
       
  1261     QCOMPARE(anim2.state(), QAnimationGroup::Stopped);
       
  1262 }
       
  1263 
       
  1264 void tst_QSequentialAnimationGroup::startGroupWithRunningChild()
       
  1265 {
       
  1266     // as the group has precedence over its children, starting a group will restart all the children
       
  1267     QSequentialAnimationGroup group;
       
  1268 
       
  1269     TestAnimation *anim1 = new TestAnimation();
       
  1270     anim1->setStartValue(0);
       
  1271     anim1->setEndValue(100);
       
  1272     anim1->setDuration(200);
       
  1273 
       
  1274     TestAnimation *anim2 = new TestAnimation();
       
  1275     anim2->setStartValue(0);
       
  1276     anim2->setEndValue(100);
       
  1277     anim2->setDuration(200);
       
  1278 
       
  1279     QSignalSpy stateChangedSpy1(anim1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
       
  1280     QSignalSpy stateChangedSpy2(anim2, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
       
  1281 
       
  1282     QCOMPARE(stateChangedSpy1.count(), 0);
       
  1283     QCOMPARE(stateChangedSpy2.count(), 0);
       
  1284     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
  1285     QCOMPARE(anim1->state(), QAnimationGroup::Stopped);
       
  1286     QCOMPARE(anim2->state(), QAnimationGroup::Stopped);
       
  1287 
       
  1288     group.addAnimation(anim1);
       
  1289     group.addAnimation(anim2);
       
  1290 
       
  1291     anim1->start();
       
  1292     anim2->start();
       
  1293     anim2->pause();
       
  1294 
       
  1295     QVERIFY(compareStates(stateChangedSpy1, (StateList() << QAbstractAnimation::Running)));
       
  1296 
       
  1297     QVERIFY(compareStates(stateChangedSpy2, (StateList() << QAbstractAnimation::Running
       
  1298                                                          << QAbstractAnimation::Paused)));
       
  1299 
       
  1300     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
  1301     QCOMPARE(anim1->state(), QAnimationGroup::Running);
       
  1302     QCOMPARE(anim2->state(), QAnimationGroup::Paused);
       
  1303 
       
  1304     group.start();
       
  1305 
       
  1306     QVERIFY(compareStates(stateChangedSpy1, (StateList() << QAbstractAnimation::Running
       
  1307                                                          << QAbstractAnimation::Stopped
       
  1308                                                          << QAbstractAnimation::Running)));
       
  1309     QVERIFY(compareStates(stateChangedSpy2, (StateList() << QAbstractAnimation::Running
       
  1310                                                          << QAbstractAnimation::Paused)));
       
  1311 
       
  1312     QCOMPARE(group.state(), QAnimationGroup::Running);
       
  1313     QCOMPARE(anim1->state(), QAnimationGroup::Running);
       
  1314     QCOMPARE(anim2->state(), QAnimationGroup::Paused);
       
  1315 
       
  1316     QTest::qWait(300);
       
  1317 
       
  1318     QCOMPARE(group.state(), QAnimationGroup::Running);
       
  1319     QCOMPARE(anim1->state(), QAnimationGroup::Stopped);
       
  1320     QCOMPARE(anim2->state(), QAnimationGroup::Running);
       
  1321 
       
  1322     QCOMPARE(stateChangedSpy2.count(), 4);
       
  1323     QCOMPARE(qVariantValue<QAbstractAnimation::State>(stateChangedSpy2.at(2).first()),
       
  1324              QAnimationGroup::Stopped);
       
  1325     QCOMPARE(qVariantValue<QAbstractAnimation::State>(stateChangedSpy2.at(3).first()),
       
  1326              QAnimationGroup::Running);
       
  1327 
       
  1328     group.stop();
       
  1329 
       
  1330     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
  1331     QCOMPARE(anim1->state(), QAnimationGroup::Stopped);
       
  1332     QCOMPARE(anim2->state(), QAnimationGroup::Stopped);
       
  1333 }
       
  1334 
       
  1335 void tst_QSequentialAnimationGroup::zeroDurationAnimation()
       
  1336 {
       
  1337     QSequentialAnimationGroup group;
       
  1338 
       
  1339     TestAnimation *anim1 = new TestAnimation();
       
  1340     anim1->setStartValue(0);
       
  1341     anim1->setEndValue(100);
       
  1342     anim1->setDuration(0);
       
  1343 
       
  1344     TestAnimation *anim2 = new TestAnimation();
       
  1345     anim2->setStartValue(0);
       
  1346     anim2->setEndValue(100);
       
  1347     anim2->setDuration(100);
       
  1348 
       
  1349     DummyPropertyAnimation *anim3 = new DummyPropertyAnimation;
       
  1350     anim3->setEndValue(100);
       
  1351     anim3->setDuration(0);
       
  1352 
       
  1353     QSignalSpy stateChangedSpy(anim1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
       
  1354 
       
  1355     group.addAnimation(anim1);
       
  1356     group.addAnimation(anim2);
       
  1357     group.addAnimation(anim3);
       
  1358     group.setLoopCount(2);
       
  1359     group.start();
       
  1360 
       
  1361     QCOMPARE(stateChangedSpy.count(), 2);
       
  1362     QCOMPARE(qVariantValue<QAbstractAnimation::State>(stateChangedSpy.at(0).first()),
       
  1363              QAnimationGroup::Running);
       
  1364     QCOMPARE(qVariantValue<QAbstractAnimation::State>(stateChangedSpy.at(1).first()),
       
  1365              QAnimationGroup::Stopped);
       
  1366 
       
  1367     QCOMPARE(anim1->state(), QAnimationGroup::Stopped);
       
  1368     QCOMPARE(anim2->state(), QAnimationGroup::Running);
       
  1369     QCOMPARE(group.state(), QAnimationGroup::Running);
       
  1370 
       
  1371     //now let's try to seek to the next loop
       
  1372     group.setCurrentTime(group.duration() + 1);
       
  1373     QCOMPARE(anim1->state(), QAnimationGroup::Stopped);
       
  1374     QCOMPARE(anim2->state(), QAnimationGroup::Running);
       
  1375     QCOMPARE(anim3->state(), QAnimationGroup::Stopped);
       
  1376     QCOMPARE(group.state(), QAnimationGroup::Running);
       
  1377     QCOMPARE(anim3->o.value(), 100); //anim3 should have been run
       
  1378 }
       
  1379 
       
  1380 void tst_QSequentialAnimationGroup::stopUncontrolledAnimations()
       
  1381 {
       
  1382     QSequentialAnimationGroup group;
       
  1383 
       
  1384     AnimationObject o1;
       
  1385     UncontrolledAnimation notTimeDriven(&o1);
       
  1386     QCOMPARE(notTimeDriven.totalDuration(), -1);
       
  1387 
       
  1388     TestAnimation loopsForever;
       
  1389     loopsForever.setStartValue(0);
       
  1390     loopsForever.setEndValue(100);
       
  1391     loopsForever.setDuration(100);
       
  1392     loopsForever.setLoopCount(-1);
       
  1393 
       
  1394     group.addAnimation(&notTimeDriven);
       
  1395     group.addAnimation(&loopsForever);
       
  1396 
       
  1397     group.start();
       
  1398 
       
  1399     QCOMPARE(group.state(), QAnimationGroup::Running);
       
  1400     QCOMPARE(notTimeDriven.state(), QAnimationGroup::Running);
       
  1401     QCOMPARE(loopsForever.state(), QAnimationGroup::Stopped);
       
  1402 
       
  1403     notTimeDriven.stop();
       
  1404 
       
  1405     QCOMPARE(group.state(), QAnimationGroup::Running);
       
  1406     QCOMPARE(notTimeDriven.state(), QAnimationGroup::Stopped);
       
  1407     QCOMPARE(loopsForever.state(), QAnimationGroup::Running);
       
  1408 
       
  1409     loopsForever.stop();
       
  1410 
       
  1411     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
  1412     QCOMPARE(notTimeDriven.state(), QAnimationGroup::Stopped);
       
  1413     QCOMPARE(loopsForever.state(), QAnimationGroup::Stopped);
       
  1414 }
       
  1415 
       
  1416 void tst_QSequentialAnimationGroup::finishWithUncontrolledAnimation()
       
  1417 {
       
  1418     AnimationObject o1;
       
  1419 
       
  1420     //1st case:
       
  1421     //first we test a group with one uncontrolled animation
       
  1422     QSequentialAnimationGroup group;
       
  1423     UncontrolledAnimation notTimeDriven(&o1, &group);
       
  1424     QSignalSpy spy(&group, SIGNAL(finished()));
       
  1425 
       
  1426     group.start();
       
  1427     QCOMPARE(group.state(), QAnimationGroup::Running);
       
  1428     QCOMPARE(notTimeDriven.state(), QAnimationGroup::Running);
       
  1429     QCOMPARE(group.currentLoopTime(), 0);
       
  1430     QCOMPARE(notTimeDriven.currentLoopTime(), 0);
       
  1431 
       
  1432     QTest::qWait(300); //wait for the end of notTimeDriven
       
  1433     QTRY_COMPARE(notTimeDriven.state(), QAnimationGroup::Stopped);
       
  1434     const int actualDuration = notTimeDriven.currentLoopTime();
       
  1435     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
  1436     QCOMPARE(group.currentLoopTime(), actualDuration);
       
  1437     QCOMPARE(spy.count(), 1);
       
  1438 
       
  1439     //2nd case:
       
  1440     // lets make sure the seeking will work again
       
  1441     spy.clear();
       
  1442     DummyPropertyAnimation anim(&group);
       
  1443     QSignalSpy animStateChangedSpy(&anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
       
  1444 
       
  1445     group.setCurrentTime(300);
       
  1446     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
  1447     QCOMPARE(notTimeDriven.currentLoopTime(), actualDuration);
       
  1448     QCOMPARE(group.currentAnimation(), static_cast<QAbstractAnimation*>(&anim));
       
  1449 
       
  1450     //3rd case:
       
  1451     //now let's add a perfectly defined animation at the end
       
  1452     QCOMPARE(animStateChangedSpy.count(), 0);
       
  1453     group.start();
       
  1454     QCOMPARE(group.state(), QAnimationGroup::Running);
       
  1455     QCOMPARE(notTimeDriven.state(), QAnimationGroup::Running);
       
  1456     QCOMPARE(group.currentLoopTime(), 0);
       
  1457     QCOMPARE(notTimeDriven.currentLoopTime(), 0);
       
  1458 
       
  1459     QCOMPARE(animStateChangedSpy.count(), 0);
       
  1460 
       
  1461     QTest::qWait(300); //wait for the end of notTimeDriven
       
  1462     QTRY_COMPARE(notTimeDriven.state(), QAnimationGroup::Stopped);
       
  1463     QCOMPARE(group.state(), QAnimationGroup::Running);
       
  1464     QCOMPARE(anim.state(), QAnimationGroup::Running);
       
  1465     QCOMPARE(group.currentAnimation(), static_cast<QAbstractAnimation*>(&anim));
       
  1466     QCOMPARE(animStateChangedSpy.count(), 1);
       
  1467     QTest::qWait(300); //wait for the end of anim
       
  1468 
       
  1469     QTRY_COMPARE(anim.state(), QAnimationGroup::Stopped);
       
  1470     QCOMPARE(anim.currentLoopTime(), anim.duration());
       
  1471 
       
  1472     //we should simply be at the end
       
  1473     QCOMPARE(spy.count(), 1);
       
  1474     QCOMPARE(animStateChangedSpy.count(), 2);
       
  1475     QCOMPARE(group.currentLoopTime(), notTimeDriven.currentLoopTime() + anim.currentLoopTime());
       
  1476 }
       
  1477 
       
  1478 void tst_QSequentialAnimationGroup::addRemoveAnimation()
       
  1479 {
       
  1480     //this test is specific to the sequential animation group
       
  1481     QSequentialAnimationGroup group;
       
  1482 
       
  1483     QCOMPARE(group.duration(), 0);
       
  1484     QCOMPARE(group.currentLoopTime(), 0);
       
  1485     QAbstractAnimation *anim1 = new QPropertyAnimation;
       
  1486     group.addAnimation(anim1);
       
  1487     QCOMPARE(group.duration(), 250);
       
  1488     QCOMPARE(group.currentLoopTime(), 0);
       
  1489     QCOMPARE(group.currentAnimation(), anim1);
       
  1490 
       
  1491     //let's append an animation
       
  1492     QAbstractAnimation *anim2 = new QPropertyAnimation;
       
  1493     group.addAnimation(anim2);
       
  1494     QCOMPARE(group.duration(), 500);
       
  1495     QCOMPARE(group.currentLoopTime(), 0);
       
  1496     QCOMPARE(group.currentAnimation(), anim1);
       
  1497 
       
  1498     //let's prepend an animation
       
  1499     QAbstractAnimation *anim0 = new QPropertyAnimation;
       
  1500     group.insertAnimation(0, anim0);
       
  1501     QCOMPARE(group.duration(), 750);
       
  1502     QCOMPARE(group.currentLoopTime(), 0);
       
  1503     QCOMPARE(group.currentAnimation(), anim0); //anim0 has become the new currentAnimation
       
  1504 
       
  1505     group.setCurrentTime(300); //anim0 | anim1 | anim2
       
  1506     QCOMPARE(group.currentLoopTime(), 300);
       
  1507     QCOMPARE(group.currentAnimation(), anim1);
       
  1508     QCOMPARE(anim1->currentLoopTime(), 50);
       
  1509 
       
  1510     group.removeAnimation(anim0); //anim1 | anim2
       
  1511     QCOMPARE(group.currentLoopTime(), 50);
       
  1512     QCOMPARE(group.currentAnimation(), anim1);
       
  1513     QCOMPARE(anim1->currentLoopTime(), 50);
       
  1514 
       
  1515     group.setCurrentTime(0);
       
  1516     group.insertAnimation(0, anim0); //anim0 | anim1 | anim2
       
  1517     group.setCurrentTime(300);
       
  1518     QCOMPARE(group.currentLoopTime(), 300);
       
  1519     QCOMPARE(group.currentAnimation(), anim1);
       
  1520     QCOMPARE(anim1->currentLoopTime(), 50);
       
  1521 
       
  1522     group.removeAnimation(anim1); //anim0 | anim2
       
  1523     QCOMPARE(group.currentLoopTime(), 250);
       
  1524     QCOMPARE(group.currentAnimation(), anim2);
       
  1525     QCOMPARE(anim0->currentLoopTime(), 250);
       
  1526 }
       
  1527 
       
  1528 void tst_QSequentialAnimationGroup::currentAnimation()
       
  1529 {
       
  1530     QSequentialAnimationGroup group;
       
  1531     QVERIFY(group.currentAnimation() == 0);
       
  1532 
       
  1533     QPropertyAnimation anim;
       
  1534     anim.setDuration(0);
       
  1535     group.addAnimation(&anim);
       
  1536     QCOMPARE(group.currentAnimation(), static_cast<QAbstractAnimation*>(&anim));
       
  1537 }
       
  1538 
       
  1539 void tst_QSequentialAnimationGroup::currentAnimationWithZeroDuration()
       
  1540 {
       
  1541     QSequentialAnimationGroup group;
       
  1542     QVERIFY(group.currentAnimation() == 0);
       
  1543 
       
  1544     QPropertyAnimation zero1;
       
  1545     zero1.setDuration(0);
       
  1546     QPropertyAnimation zero2;
       
  1547     zero2.setDuration(0);
       
  1548 
       
  1549     QPropertyAnimation anim;
       
  1550 
       
  1551     QPropertyAnimation zero3;
       
  1552     zero3.setDuration(0);
       
  1553     QPropertyAnimation zero4;
       
  1554     zero4.setDuration(0);
       
  1555 
       
  1556 
       
  1557     group.addAnimation(&zero1);
       
  1558     group.addAnimation(&zero2);
       
  1559     group.addAnimation(&anim);
       
  1560     group.addAnimation(&zero3);
       
  1561     group.addAnimation(&zero4);
       
  1562 
       
  1563     QCOMPARE(group.currentAnimation(), static_cast<QAbstractAnimation*>(&zero1));
       
  1564 
       
  1565     group.setCurrentTime(0);
       
  1566     QCOMPARE(group.currentAnimation(), static_cast<QAbstractAnimation*>(&anim));
       
  1567 
       
  1568     group.setCurrentTime(group.duration());
       
  1569     QCOMPARE(group.currentAnimation(), static_cast<QAbstractAnimation*>(&zero4));
       
  1570 
       
  1571     group.setDirection(QAbstractAnimation::Backward);
       
  1572 
       
  1573     group.setCurrentTime(0);
       
  1574     QCOMPARE(group.currentAnimation(), static_cast<QAbstractAnimation*>(&zero1));
       
  1575 
       
  1576     group.setCurrentTime(group.duration());
       
  1577     QCOMPARE(group.currentAnimation(), static_cast<QAbstractAnimation*>(&anim));
       
  1578 }
       
  1579 
       
  1580 void tst_QSequentialAnimationGroup::insertAnimation()
       
  1581 {
       
  1582     QSequentialAnimationGroup group;
       
  1583     group.setLoopCount(2);
       
  1584     QPropertyAnimation *anim = new DummyPropertyAnimation(&group);
       
  1585     QCOMPARE(group.duration(), anim->duration());
       
  1586     group.setCurrentTime(300);
       
  1587     QCOMPARE(group.currentLoop(), 1);
       
  1588 
       
  1589     //this will crash if the sequential group calls duration on the created animation
       
  1590     new QPropertyAnimation(&group);
       
  1591 }
       
  1592 
       
  1593 
       
  1594 class SequentialAnimationGroup : public QSequentialAnimationGroup
       
  1595 {
       
  1596     Q_OBJECT
       
  1597 public slots:
       
  1598     void clear()
       
  1599     {
       
  1600         QSequentialAnimationGroup::clear();
       
  1601     }
       
  1602 
       
  1603     void refill()
       
  1604     {
       
  1605         stop();
       
  1606         clear();
       
  1607         new DummyPropertyAnimation(this);
       
  1608         start();
       
  1609     }
       
  1610 
       
  1611 };
       
  1612 
       
  1613 
       
  1614 void tst_QSequentialAnimationGroup::clear()
       
  1615 {
       
  1616     SequentialAnimationGroup group;
       
  1617     QPointer<QAbstractAnimation> anim1 = new DummyPropertyAnimation(&group);
       
  1618     group.connect(anim1, SIGNAL(finished()), SLOT(clear()));
       
  1619     new DummyPropertyAnimation(&group);
       
  1620     QCOMPARE(group.animationCount(), 2);
       
  1621 
       
  1622     group.start();
       
  1623     QTest::qWait(anim1->duration() + 100);
       
  1624     QTRY_COMPARE(group.animationCount(), 0);
       
  1625     QCOMPARE(group.state(), QAbstractAnimation::Stopped);
       
  1626     QCOMPARE(group.currentLoopTime(), 0);
       
  1627 
       
  1628     anim1 = new DummyPropertyAnimation(&group);
       
  1629     group.connect(anim1, SIGNAL(finished()), SLOT(refill()));
       
  1630     group.start();
       
  1631     QTest::qWait(anim1->duration() + 100);
       
  1632     QTRY_COMPARE(group.state(), QAbstractAnimation::Running);
       
  1633     QVERIFY(anim1 == 0); //anim1 should have been deleted
       
  1634 }
       
  1635 
       
  1636 void tst_QSequentialAnimationGroup::pauseResume()
       
  1637 {
       
  1638     QObject dummy;
       
  1639     dummy.setProperty("foo", 0);
       
  1640     QParallelAnimationGroup group;
       
  1641     QPropertyAnimation *anim = new QPropertyAnimation(&dummy, "foo", &group);
       
  1642     anim->setDuration(250);
       
  1643     anim->setEndValue(250);
       
  1644     QSignalSpy spy(anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
       
  1645     QCOMPARE(group.duration(), 250);
       
  1646     group.start();
       
  1647     QTest::qWait(100);
       
  1648     QTRY_COMPARE(group.state(), QAnimationGroup::Running);
       
  1649     QCOMPARE(anim->state(), QAnimationGroup::Running);
       
  1650     QCOMPARE(spy.count(), 1);
       
  1651     spy.clear();
       
  1652     const int currentTime = group.currentLoopTime();
       
  1653     QCOMPARE(anim->currentLoopTime(), currentTime);
       
  1654 
       
  1655     group.pause();
       
  1656     QCOMPARE(group.state(), QAnimationGroup::Paused);
       
  1657     QCOMPARE(group.currentLoopTime(), currentTime);
       
  1658     QCOMPARE(anim->state(), QAnimationGroup::Paused);
       
  1659     QCOMPARE(anim->currentLoopTime(), currentTime);
       
  1660     QCOMPARE(spy.count(), 1);
       
  1661     spy.clear();
       
  1662 
       
  1663     group.resume();
       
  1664     QCOMPARE(group.state(), QAnimationGroup::Running);
       
  1665     QCOMPARE(group.currentLoopTime(), currentTime);
       
  1666     QCOMPARE(anim->state(), QAnimationGroup::Running);
       
  1667     QCOMPARE(anim->currentLoopTime(), currentTime);
       
  1668     QCOMPARE(spy.count(), 1);
       
  1669 }
       
  1670 
       
  1671 QTEST_MAIN(tst_QSequentialAnimationGroup)
       
  1672 #include "tst_qsequentialanimationgroup.moc"