tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 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 clearAnimations();
       
    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 oldState,
       
   138                              QAbstractAnimation::State newState)
       
   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.currentTime(), 1);
       
   212     QCOMPARE(sequence->currentTime(), 1);
       
   213     QCOMPARE(a1_s_o1->currentTime(), 1);
       
   214     QCOMPARE(a2_s_o1->currentTime(), 0);
       
   215     QCOMPARE(a3_s_o1->currentTime(), 0);
       
   216     QCOMPARE(a1_s_o2->currentTime(), 0);
       
   217     QCOMPARE(a1_s_o3->currentTime(), 0);
       
   218 
       
   219     // Current time = 250
       
   220     group.setCurrentTime(250);
       
   221     QCOMPARE(group.currentTime(), 250);
       
   222     QCOMPARE(sequence->currentTime(), 250);
       
   223     QCOMPARE(a1_s_o1->currentTime(), 250);
       
   224     QCOMPARE(a2_s_o1->currentTime(), 0);
       
   225     QCOMPARE(a3_s_o1->currentTime(), 0);
       
   226     QCOMPARE(a1_s_o2->currentTime(), 0);
       
   227     QCOMPARE(a1_s_o3->currentTime(), 0);
       
   228 
       
   229     // Current time = 251
       
   230     group.setCurrentTime(251);
       
   231     QCOMPARE(group.currentTime(), 251);
       
   232     QCOMPARE(sequence->currentTime(), 251);
       
   233     QCOMPARE(a1_s_o1->currentTime(), 250);
       
   234     QCOMPARE(a2_s_o1->currentTime(), 1);
       
   235     QCOMPARE(a2_s_o1->currentLoop(), 0);
       
   236     QCOMPARE(a3_s_o1->currentTime(), 0);
       
   237     QCOMPARE(sequence2->currentTime(), 0);
       
   238     QCOMPARE(a1_s_o2->currentTime(), 0);
       
   239     QCOMPARE(a1_s_o3->currentTime(), 0);
       
   240 
       
   241     // Current time = 750
       
   242     group.setCurrentTime(750);
       
   243     QCOMPARE(group.currentTime(), 750);
       
   244     QCOMPARE(sequence->currentTime(), 750);
       
   245     QCOMPARE(a1_s_o1->currentTime(), 250);
       
   246     QCOMPARE(a2_s_o1->currentTime(), 0);
       
   247     QCOMPARE(a2_s_o1->currentLoop(), 2);
       
   248     QCOMPARE(a3_s_o1->currentTime(), 0);
       
   249     QCOMPARE(sequence2->currentTime(), 0);
       
   250     QCOMPARE(a1_s_o2->currentTime(), 0);
       
   251     QCOMPARE(a1_s_o3->currentTime(), 0);
       
   252 
       
   253     // Current time = 1000
       
   254     group.setCurrentTime(1000);
       
   255     QCOMPARE(group.currentTime(), 1000);
       
   256     QCOMPARE(sequence->currentTime(), 1000);
       
   257     QCOMPARE(a1_s_o1->currentTime(), 250);
       
   258     QCOMPARE(a2_s_o1->currentTime(), 250);
       
   259     QCOMPARE(a2_s_o1->currentLoop(), 2);
       
   260     QCOMPARE(a3_s_o1->currentTime(), 0);
       
   261     QCOMPARE(sequence2->currentTime(), 0);
       
   262     QCOMPARE(a1_s_o2->currentTime(), 0);
       
   263     QCOMPARE(a1_s_o3->currentTime(), 0);
       
   264 
       
   265     // Current time = 1010
       
   266     group.setCurrentTime(1010);
       
   267     QCOMPARE(group.currentTime(), 1010);
       
   268     QCOMPARE(sequence->currentTime(), 1010);
       
   269     QCOMPARE(a1_s_o1->currentTime(), 250);
       
   270     QCOMPARE(a2_s_o1->currentTime(), 250);
       
   271     QCOMPARE(a2_s_o1->currentLoop(), 2);
       
   272     QCOMPARE(a3_s_o1->currentTime(), 10);
       
   273     QCOMPARE(sequence2->currentTime(), 0);
       
   274     QCOMPARE(a1_s_o2->currentTime(), 0);
       
   275     QCOMPARE(a1_s_o3->currentTime(), 0);
       
   276 
       
   277     // Current time = 1250
       
   278     group.setCurrentTime(1250);
       
   279     QCOMPARE(group.currentTime(), 1250);
       
   280     QCOMPARE(sequence->currentTime(), 1250);
       
   281     QCOMPARE(a1_s_o1->currentTime(), 250);
       
   282     QCOMPARE(a2_s_o1->currentTime(), 250);
       
   283     QCOMPARE(a2_s_o1->currentLoop(), 2);
       
   284     QCOMPARE(a3_s_o1->currentTime(), 250);
       
   285     QCOMPARE(sequence2->currentTime(), 0);
       
   286     QCOMPARE(a1_s_o2->currentTime(), 0);
       
   287     QCOMPARE(a1_s_o3->currentTime(), 0);
       
   288 
       
   289     // Current time = 1500
       
   290     group.setCurrentTime(1500);
       
   291     QCOMPARE(group.currentTime(), 1500);
       
   292     QCOMPARE(sequence->currentTime(), 1250);
       
   293     QCOMPARE(a1_s_o1->currentTime(), 250);
       
   294     QCOMPARE(a2_s_o1->currentTime(), 250);
       
   295     QCOMPARE(a2_s_o1->currentLoop(), 2);
       
   296     QCOMPARE(a3_s_o1->currentTime(), 250);
       
   297     QCOMPARE(sequence2->currentTime(), 250);
       
   298     QCOMPARE(a1_s_o2->currentTime(), 250);
       
   299     QCOMPARE(a1_s_o3->currentTime(), 0);
       
   300 
       
   301     // Current time = 1750
       
   302     group.setCurrentTime(1750);
       
   303     QCOMPARE(group.currentTime(), 1750);
       
   304     QCOMPARE(sequence->currentTime(), 1250);
       
   305     QCOMPARE(a1_s_o1->currentTime(), 250);
       
   306     QCOMPARE(a2_s_o1->currentTime(), 250);
       
   307     QCOMPARE(a2_s_o1->currentLoop(), 2);
       
   308     QCOMPARE(a3_s_o1->currentTime(), 250);
       
   309     QCOMPARE(sequence2->currentTime(), 500);
       
   310     QCOMPARE(a1_s_o2->currentTime(), 250);
       
   311     QCOMPARE(a1_s_o3->currentTime(), 250);
       
   312 
       
   313     // Current time = 2000
       
   314     group.setCurrentTime(2000);
       
   315     QCOMPARE(group.currentTime(), 1750);
       
   316     QCOMPARE(sequence->currentTime(), 1250);
       
   317     QCOMPARE(a1_s_o1->currentTime(), 250);
       
   318     QCOMPARE(a2_s_o1->currentTime(), 250);
       
   319     QCOMPARE(a2_s_o1->currentLoop(), 2);
       
   320     QCOMPARE(a3_s_o1->currentTime(), 250);
       
   321     QCOMPARE(sequence2->currentTime(), 500);
       
   322     QCOMPARE(a1_s_o2->currentTime(), 250);
       
   323     QCOMPARE(a1_s_o3->currentTime(), 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.currentTime(), 1);
       
   361     QCOMPARE(sequence->currentTime(), 1);
       
   362     QCOMPARE(a1_s_o1->currentTime(), 1);
       
   363     QCOMPARE(a1_s_o2->currentTime(), 0);
       
   364     QCOMPARE(notTimeDriven->currentTime(), 0);
       
   365     QCOMPARE(loopsForever->currentTime(), 0);
       
   366 
       
   367     // Current time = 250
       
   368     group.setCurrentTime(250);
       
   369     QCOMPARE(group.currentTime(), 250);
       
   370     QCOMPARE(sequence->currentTime(), 250);
       
   371     QCOMPARE(a1_s_o1->currentTime(), 250);
       
   372     QCOMPARE(a1_s_o2->currentTime(), 0);
       
   373     QCOMPARE(notTimeDriven->currentTime(), 0);
       
   374     QCOMPARE(loopsForever->currentTime(), 0);
       
   375 
       
   376     // Current time = 500
       
   377     group.setCurrentTime(500);
       
   378     QCOMPARE(group.currentTime(), 500);
       
   379     QCOMPARE(sequence->currentTime(), 500);
       
   380     QCOMPARE(a1_s_o1->currentTime(), 250);
       
   381     QCOMPARE(a1_s_o2->currentTime(), 250);
       
   382     QCOMPARE(notTimeDriven->currentTime(), 0);
       
   383     QCOMPARE(loopsForever->currentTime(), 0);
       
   384     QCOMPARE(group.currentAnimation(), notTimeDriven);
       
   385 
       
   386     // Current time = 505
       
   387     group.setCurrentTime(505);
       
   388     QCOMPARE(group.currentTime(), 505);
       
   389     QCOMPARE(sequence->currentTime(), 500);
       
   390     QCOMPARE(a1_s_o1->currentTime(), 250);
       
   391     QCOMPARE(a1_s_o2->currentTime(), 250);
       
   392     QCOMPARE(notTimeDriven->currentTime(), 5);
       
   393     QCOMPARE(loopsForever->currentTime(), 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.currentTime(), 750);
       
   404     QCOMPARE(sequence->currentTime(), 500);
       
   405     QCOMPARE(a1_s_o1->currentTime(), 250);
       
   406     QCOMPARE(a1_s_o2->currentTime(), 250);
       
   407     QCOMPARE(notTimeDriven->currentTime(), 250);
       
   408     QCOMPARE(loopsForever->currentTime(), 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.currentTime(), 800);
       
   419     QCOMPARE(group.currentAnimation(), loopsForever);
       
   420     QCOMPARE(sequence->currentTime(), 500);
       
   421     QCOMPARE(a1_s_o1->currentTime(), 250);
       
   422     QCOMPARE(a1_s_o2->currentTime(), 250);
       
   423     QCOMPARE(notTimeDriven->currentTime(), 250);
       
   424     QCOMPARE(loopsForever->currentTime(), 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.currentTime(), 1);
       
   470     QCOMPARE(sequence->currentTime(), 1);
       
   471     QCOMPARE(a1_s_o1->currentTime(), 1);
       
   472     QCOMPARE(a2_s_o1->currentTime(), 0);
       
   473     QCOMPARE(a3_s_o1->currentTime(), 0);
       
   474     QCOMPARE(sequence2->currentTime(), 0);
       
   475     QCOMPARE(a1_s_o2->currentTime(), 0);
       
   476     QCOMPARE(a1_s_o3->currentTime(), 0);
       
   477 
       
   478     // Current time = 1500
       
   479     group.setCurrentTime(1500);
       
   480     QCOMPARE(group.currentTime(), 1500);
       
   481     QCOMPARE(sequence->currentTime(), 1250);
       
   482     QCOMPARE(a1_s_o1->currentTime(), 250);
       
   483     QCOMPARE(a2_s_o1->currentTime(), 250);
       
   484     QCOMPARE(a2_s_o1->currentLoop(), 2);
       
   485     QCOMPARE(a3_s_o1->currentTime(), 250);
       
   486     QCOMPARE(sequence2->currentTime(), 250);
       
   487     QCOMPARE(a1_s_o2->currentTime(), 250);
       
   488     QCOMPARE(a1_s_o3->currentTime(), 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.currentTime(), 1750);
       
   503     QCOMPARE(sequence->currentTime(), 1250);
       
   504     QCOMPARE(a1_s_o1->currentTime(), 250);
       
   505     QCOMPARE(a2_s_o1->currentTime(), 250);
       
   506     QCOMPARE(a2_s_o1->currentLoop(), 2);
       
   507     QCOMPARE(a3_s_o1->currentTime(), 250);
       
   508     QCOMPARE(sequence2->currentTime(), 500);
       
   509     QCOMPARE(a1_s_o2->currentTime(), 250);
       
   510     QCOMPARE(a1_s_o3->currentTime(), 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.currentTime(), 1600);
       
   541     QCOMPARE(sequence->currentTime(), 1250);
       
   542     QCOMPARE(a1_s_o1->currentTime(), 250);
       
   543     QCOMPARE(a2_s_o1->currentTime(), 250);
       
   544     QCOMPARE(a2_s_o1->currentLoop(), 2);
       
   545     QCOMPARE(a3_s_o1->currentTime(), 250);
       
   546     QCOMPARE(sequence2->currentTime(), 350);
       
   547     QCOMPARE(a1_s_o2->currentTime(), 250);
       
   548     QCOMPARE(a1_s_o3->currentTime(), 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.currentTime(), 1);
       
   560     QCOMPARE(sequence->currentTime(), 1);
       
   561     QCOMPARE(a1_s_o1->currentTime(), 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->currentTime(), 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->currentTime(), 0);
       
   572     QCOMPARE(sequence2->currentTime(), 0);
       
   573     QCOMPARE(a1_s_o2->currentTime(), 0);
       
   574     QCOMPARE(a1_s_o3->currentTime(), 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.currentTime(), 1750);
       
   586     QCOMPARE(sequence->currentTime(), 1250);
       
   587     QCOMPARE(a1_s_o1->currentTime(), 250);
       
   588     QCOMPARE(a2_s_o1->currentTime(), 250);
       
   589     QCOMPARE(a2_s_o1->currentLoop(), 2);
       
   590     QCOMPARE(a3_s_o1->currentTime(), 250);
       
   591     QCOMPARE(sequence2->currentTime(), 500);
       
   592     QCOMPARE(a1_s_o2->currentTime(), 250);
       
   593     QCOMPARE(a1_s_o3->currentTime(), 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.value(1));
       
   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.currentTime(), 1751);
       
   676     QCOMPARE(sequence->currentTime(), 751);
       
   677     QCOMPARE(sequence->currentLoop(), 1);
       
   678     QCOMPARE(a1_s_o1->currentTime(), 250);
       
   679     QCOMPARE(a2_s_o1->currentTime(), 250);
       
   680     QCOMPARE(a2_s_o1->currentLoop(), 1);
       
   681     QCOMPARE(a3_s_o1->currentLoop(), 0);
       
   682     QCOMPARE(a3_s_o1->currentTime(), 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).at(1)),
       
   700              QAnimationGroup::Running);
       
   701     QCOMPARE(qVariantValue<QAbstractAnimation::State>(a1StateChangedSpy.at(1).at(1)),
       
   702              QAnimationGroup::Paused);
       
   703     QCOMPARE(qVariantValue<QAbstractAnimation::State>(a1StateChangedSpy.at(2).at(1)),
       
   704              QAnimationGroup::Stopped);
       
   705     QCOMPARE(qVariantValue<QAbstractAnimation::State>(a1StateChangedSpy.at(3).at(1)),
       
   706              QAnimationGroup::Running);
       
   707     QCOMPARE(qVariantValue<QAbstractAnimation::State>(a1StateChangedSpy.at(4).at(1)),
       
   708              QAnimationGroup::Stopped);
       
   709 
       
   710     QCOMPARE(qVariantValue<QAbstractAnimation::State>(seqStateChangedSpy.at(0).at(1)),
       
   711              QAnimationGroup::Running);
       
   712     QCOMPARE(qVariantValue<QAbstractAnimation::State>(seqStateChangedSpy.at(1).at(1)),
       
   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.currentTime() >= 1751);
       
   724     QVERIFY(sequence->currentTime() >= 751);
       
   725     QCOMPARE(sequence->currentLoop(), 1);
       
   726     QCOMPARE(a1_s_o1->currentTime(), 250);
       
   727     QCOMPARE(a2_s_o1->currentTime(), 250);
       
   728     QCOMPARE(a2_s_o1->currentLoop(), 1);
       
   729     QCOMPARE(a3_s_o1->currentLoop(), 0);
       
   730     QVERIFY(a3_s_o1->currentTime() >= 1);
       
   731 
       
   732     QCOMPARE(seqStateChangedSpy.count(), 3);    // Running,Paused,Running
       
   733     QCOMPARE(qVariantValue<QAbstractAnimation::State>(seqStateChangedSpy.at(2).at(1)),
       
   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.currentTime() >= 1751);
       
   745     QVERIFY(sequence->currentTime() >= 751);
       
   746     QCOMPARE(sequence->currentLoop(), 1);
       
   747     QCOMPARE(a1_s_o1->currentTime(), 250);
       
   748     QCOMPARE(a2_s_o1->currentTime(), 250);
       
   749     QCOMPARE(a2_s_o1->currentLoop(), 1);
       
   750     QCOMPARE(a3_s_o1->currentLoop(), 0);
       
   751     QVERIFY(a3_s_o1->currentTime() >= 1);
       
   752 
       
   753     QCOMPARE(seqStateChangedSpy.count(), 4);    // Running,Paused,Running,Paused
       
   754     QCOMPARE(qVariantValue<QAbstractAnimation::State>(seqStateChangedSpy.at(3).at(1)),
       
   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).at(1)),
       
   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).at(1)),
       
   801                  QAnimationGroup::Running);
       
   802         QCOMPARE(qVariantValue<QAbstractAnimation::State>(animsStateChanged[i]->at(1).at(1)),
       
   803                  QAnimationGroup::Stopped);
       
   804         QCOMPARE(qVariantValue<QAbstractAnimation::State>(animsStateChanged[i]->at(2).at(1)),
       
   805                  QAnimationGroup::Running);
       
   806         QCOMPARE(qVariantValue<QAbstractAnimation::State>(animsStateChanged[i]->at(3).at(1)),
       
   807                  QAnimationGroup::Stopped);
       
   808     }
       
   809 
       
   810     QCOMPARE(seqStateChangedSpy.count(), 2);
       
   811     QCOMPARE(qVariantValue<QAbstractAnimation::State>(seqStateChangedSpy.at(0).at(1)),
       
   812              QAnimationGroup::Running);
       
   813     QCOMPARE(qVariantValue<QAbstractAnimation::State>(seqStateChangedSpy.at(1).at(1)),
       
   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.currentTime(), 1750);
       
   859     QCOMPARE(sequence->currentTime(), 750);
       
   860     QCOMPARE(sequence->currentLoop(), 1);
       
   861     QCOMPARE(a1_s_o1->currentTime(), 250);
       
   862     QCOMPARE(a2_s_o1->currentTime(), 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->currentTime(), 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.currentTime(), 1);
       
   894     QCOMPARE(group.currentLoop(), 1);
       
   895     QCOMPARE(sequence->currentTime(), 1);
       
   896     QCOMPARE(sequence->currentLoop(), 0);
       
   897     QCOMPARE(a1_s_o1->currentTime(), 1);
       
   898     QCOMPARE(a2_s_o1->currentTime(), 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->currentTime(), 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     QEventLoop loop;
       
   933     QObject::connect(&group, SIGNAL(finished()), &loop, SLOT(quit()));
       
   934 
       
   935     QTime time;
       
   936     time.start();
       
   937     group.start();
       
   938     loop.exec();
       
   939 
       
   940     QVERIFY(time.elapsed() >= 375);
       
   941     QVERIFY(time.elapsed() < 1000);
       
   942 }
       
   943 
       
   944 void tst_QSequentialAnimationGroup::clearGroup()
       
   945 {
       
   946     QSequentialAnimationGroup group;
       
   947 	
       
   948 	static const int animationCount = 20;
       
   949 
       
   950     for (int i = 0; i < animationCount/2; ++i) {
       
   951         QSequentialAnimationGroup *subGroup = new QSequentialAnimationGroup(&group);
       
   952         group.addPause(100);
       
   953         subGroup->addPause(10);
       
   954     }
       
   955 
       
   956     QCOMPARE(group.animationCount(), animationCount);
       
   957 
       
   958     QPointer<QAbstractAnimation> children[animationCount];
       
   959     for (int i = 0; i < animationCount; ++i) {
       
   960         QVERIFY(group.animationAt(i) != 0);
       
   961         children[i] = group.animationAt(i);
       
   962     }
       
   963 
       
   964     group.clearAnimations();
       
   965     QCOMPARE(group.animationCount(), 0);
       
   966     QCOMPARE(group.currentTime(), 0);
       
   967     for (int i = 0; i < animationCount; ++i)
       
   968         QVERIFY(children[i].isNull());
       
   969 }
       
   970 
       
   971 void tst_QSequentialAnimationGroup::groupWithZeroDurationAnimations()
       
   972 {
       
   973     QObject o;
       
   974     QObject o2;
       
   975 
       
   976     o.setProperty("myProperty", 42);
       
   977     o.setProperty("myOtherProperty", 13);
       
   978     o2.setProperty("myProperty", 42);
       
   979     o2.setProperty("myOtherProperty", 13);
       
   980 
       
   981     QSequentialAnimationGroup group;
       
   982 
       
   983     QVariantAnimation *a1 = new QPropertyAnimation(&o, "myProperty");
       
   984     a1->setDuration(0);
       
   985     a1->setEndValue(43);
       
   986     group.addAnimation(a1);
       
   987 
       
   988     //this should just run fine and change nothing
       
   989     group.setCurrentTime(0);
       
   990     QCOMPARE(group.currentAnimation(), static_cast<QAbstractAnimation*>(a1));
       
   991 
       
   992     QVariantAnimation *a2 = new QPropertyAnimation(&o2, "myOtherProperty");
       
   993     a2->setDuration(500);
       
   994     a2->setEndValue(31);
       
   995     group.addAnimation(a2);
       
   996 
       
   997     QVariantAnimation *a3 = new QPropertyAnimation(&o, "myProperty");
       
   998     a3->setDuration(0);
       
   999     a3->setEndValue(44);
       
  1000     group.addAnimation(a3);
       
  1001 
       
  1002     QVariantAnimation *a4 = new QPropertyAnimation(&o, "myOtherProperty");
       
  1003     a4->setDuration(250);
       
  1004     a4->setEndValue(75);
       
  1005     group.addAnimation(a4);
       
  1006 
       
  1007     QVariantAnimation *a5 = new QPropertyAnimation(&o2, "myProperty");
       
  1008     a5->setDuration(0);
       
  1009     a5->setEndValue(12);
       
  1010     group.addAnimation(a5);
       
  1011 
       
  1012     QCOMPARE(o.property("myProperty").toInt(), 42);
       
  1013     QCOMPARE(o.property("myOtherProperty").toInt(), 13);
       
  1014     QCOMPARE(o2.property("myProperty").toInt(), 42);
       
  1015     QCOMPARE(o2.property("myOtherProperty").toInt(), 13);
       
  1016 
       
  1017 
       
  1018     group.start();
       
  1019 
       
  1020     QCOMPARE(o.property("myProperty").toInt(), 43);
       
  1021     QCOMPARE(o.property("myOtherProperty").toInt(), 13);
       
  1022     QCOMPARE(o2.property("myProperty").toInt(), 42);
       
  1023     QCOMPARE(o2.property("myOtherProperty").toInt(), 13);
       
  1024 
       
  1025     QTest::qWait(100);
       
  1026 
       
  1027     int o2val = o2.property("myOtherProperty").toInt();
       
  1028     QVERIFY(o2val > 13);
       
  1029     QVERIFY(o2val < 31);
       
  1030     QCOMPARE(o.property("myProperty").toInt(), 43);
       
  1031     QCOMPARE(o.property("myOtherProperty").toInt(), 13);
       
  1032 
       
  1033     QTest::qWait(500);
       
  1034 
       
  1035     QCOMPARE(o.property("myProperty").toInt(), 44);
       
  1036     QCOMPARE(o2.property("myProperty").toInt(), 42);
       
  1037     QCOMPARE(o2.property("myOtherProperty").toInt(), 31);
       
  1038     QCOMPARE(a1->state(), QAnimationGroup::Stopped);
       
  1039     QCOMPARE(a2->state(), QAnimationGroup::Stopped);
       
  1040     QCOMPARE(a3->state(), QAnimationGroup::Stopped);
       
  1041     QCOMPARE(a4->state(), QAnimationGroup::Running);
       
  1042     QCOMPARE(a5->state(), QAnimationGroup::Stopped);
       
  1043     QCOMPARE(group.state(), QAnimationGroup::Running);
       
  1044     QTest::qWait(500);
       
  1045 
       
  1046     QTRY_COMPARE(group.state(), QAnimationGroup::Stopped);
       
  1047     QCOMPARE(o.property("myProperty").toInt(), 44);
       
  1048     QCOMPARE(o.property("myOtherProperty").toInt(), 75);
       
  1049     QCOMPARE(o2.property("myProperty").toInt(), 12);
       
  1050     QCOMPARE(o2.property("myOtherProperty").toInt(), 31);
       
  1051     QCOMPARE(a1->state(), QAnimationGroup::Stopped);
       
  1052     QCOMPARE(a2->state(), QAnimationGroup::Stopped);
       
  1053     QCOMPARE(a3->state(), QAnimationGroup::Stopped);
       
  1054     QCOMPARE(a4->state(), QAnimationGroup::Stopped);
       
  1055     QCOMPARE(a5->state(), QAnimationGroup::Stopped);
       
  1056 }
       
  1057 
       
  1058 void tst_QSequentialAnimationGroup::propagateGroupUpdateToChildren()
       
  1059 {
       
  1060     // this test verifies if group state changes are updating its children correctly
       
  1061     QSequentialAnimationGroup group;
       
  1062 
       
  1063     QObject o;
       
  1064     o.setProperty("ole", 42);
       
  1065     QCOMPARE(o.property("ole").toInt(), 42);
       
  1066 
       
  1067     QPropertyAnimation anim1(&o, "ole");
       
  1068     anim1.setEndValue(43);
       
  1069     anim1.setDuration(100);
       
  1070     QVERIFY(!anim1.currentValue().isValid());
       
  1071     QCOMPARE(anim1.currentValue().toInt(), 0);
       
  1072     QCOMPARE(o.property("ole").toInt(), 42);
       
  1073 
       
  1074     TestAnimation anim2;
       
  1075     anim2.setStartValue(0);
       
  1076     anim2.setEndValue(100);
       
  1077     anim2.setDuration(200);
       
  1078 
       
  1079     QVERIFY(anim2.currentValue().isValid());
       
  1080     QCOMPARE(anim2.currentValue().toInt(), 0);
       
  1081 
       
  1082     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
  1083     QCOMPARE(anim1.state(), QAnimationGroup::Stopped);
       
  1084     QCOMPARE(anim2.state(), QAnimationGroup::Stopped);
       
  1085 
       
  1086     group.addAnimation(&anim1);
       
  1087     group.addAnimation(&anim2);
       
  1088 
       
  1089     group.start();
       
  1090 
       
  1091     QCOMPARE(group.state(), QAnimationGroup::Running);
       
  1092     QCOMPARE(anim1.state(), QAnimationGroup::Running);
       
  1093     QCOMPARE(anim2.state(), QAnimationGroup::Stopped);
       
  1094 
       
  1095     group.pause();
       
  1096 
       
  1097     QCOMPARE(group.state(), QAnimationGroup::Paused);
       
  1098     QCOMPARE(anim1.state(), QAnimationGroup::Paused);
       
  1099     QCOMPARE(anim2.state(), QAnimationGroup::Stopped);
       
  1100 
       
  1101     group.stop();
       
  1102 
       
  1103     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
  1104     QCOMPARE(anim1.state(), QAnimationGroup::Stopped);
       
  1105     QCOMPARE(anim2.state(), QAnimationGroup::Stopped);
       
  1106 }
       
  1107 
       
  1108 void tst_QSequentialAnimationGroup::updateChildrenWithRunningGroup()
       
  1109 {
       
  1110     // assert that its possible to modify a child's state directly while their group is running
       
  1111     QSequentialAnimationGroup group;
       
  1112 
       
  1113     TestAnimation anim;
       
  1114     anim.setStartValue(0);
       
  1115     anim.setEndValue(100);
       
  1116     anim.setDuration(200);
       
  1117 
       
  1118     QSignalSpy groupStateChangedSpy(&group, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
       
  1119     QSignalSpy childStateChangedSpy(&anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
       
  1120 
       
  1121     QCOMPARE(groupStateChangedSpy.count(), 0);
       
  1122     QCOMPARE(childStateChangedSpy.count(), 0);
       
  1123     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
  1124     QCOMPARE(anim.state(), QAnimationGroup::Stopped);
       
  1125 
       
  1126     group.addAnimation(&anim);
       
  1127 
       
  1128     group.start();
       
  1129 
       
  1130     QCOMPARE(group.state(), QAnimationGroup::Running);
       
  1131     QCOMPARE(anim.state(), QAnimationGroup::Running);
       
  1132 
       
  1133     QCOMPARE(groupStateChangedSpy.count(), 1);
       
  1134     QCOMPARE(childStateChangedSpy.count(), 1);
       
  1135 
       
  1136     QCOMPARE(qVariantValue<QAbstractAnimation::State>(groupStateChangedSpy.at(0).at(1)),
       
  1137              QAnimationGroup::Running);
       
  1138     QCOMPARE(qVariantValue<QAbstractAnimation::State>(childStateChangedSpy.at(0).at(1)),
       
  1139              QAnimationGroup::Running);
       
  1140 
       
  1141     // starting directly a running child will not have any effect
       
  1142     anim.start();
       
  1143 
       
  1144     QCOMPARE(groupStateChangedSpy.count(), 1);
       
  1145     QCOMPARE(childStateChangedSpy.count(), 1);
       
  1146 
       
  1147     anim.pause();
       
  1148 
       
  1149     QCOMPARE(group.state(), QAnimationGroup::Running);
       
  1150     QCOMPARE(anim.state(), QAnimationGroup::Paused);
       
  1151 
       
  1152     // in the animation stops directly, the group will still be running
       
  1153     anim.stop();
       
  1154 
       
  1155     QCOMPARE(group.state(), QAnimationGroup::Running);
       
  1156     QCOMPARE(anim.state(), QAnimationGroup::Stopped);
       
  1157 }
       
  1158 
       
  1159 void tst_QSequentialAnimationGroup::deleteChildrenWithRunningGroup()
       
  1160 {
       
  1161     // test if children can be activated when their group is stopped
       
  1162     QSequentialAnimationGroup group;
       
  1163 
       
  1164     QVariantAnimation *anim1 = new TestAnimation;
       
  1165     anim1->setStartValue(0);
       
  1166     anim1->setEndValue(100);
       
  1167     anim1->setDuration(200);
       
  1168     group.addAnimation(anim1);
       
  1169 
       
  1170     QCOMPARE(group.duration(), anim1->duration());
       
  1171 
       
  1172     group.start();
       
  1173     QCOMPARE(group.state(), QAnimationGroup::Running);
       
  1174     QCOMPARE(anim1->state(), QAnimationGroup::Running);
       
  1175 
       
  1176     QTest::qWait(100);
       
  1177     QVERIFY(group.currentTime() > 0);
       
  1178 
       
  1179     delete anim1;
       
  1180     QCOMPARE(group.animationCount(), 0);
       
  1181     QCOMPARE(group.duration(), 0);
       
  1182     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
  1183     QCOMPARE(group.currentTime(), 0); //that's the invariant
       
  1184 }
       
  1185 
       
  1186 void tst_QSequentialAnimationGroup::startChildrenWithStoppedGroup()
       
  1187 {
       
  1188     // test if children can be activated when their group is stopped
       
  1189     QSequentialAnimationGroup group;
       
  1190 
       
  1191     TestAnimation anim1;
       
  1192     anim1.setStartValue(0);
       
  1193     anim1.setEndValue(100);
       
  1194     anim1.setDuration(200);
       
  1195 
       
  1196     TestAnimation anim2;
       
  1197     anim2.setStartValue(0);
       
  1198     anim2.setEndValue(100);
       
  1199     anim2.setDuration(200);
       
  1200 
       
  1201     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
  1202     QCOMPARE(anim1.state(), QAnimationGroup::Stopped);
       
  1203     QCOMPARE(anim2.state(), QAnimationGroup::Stopped);
       
  1204 
       
  1205     group.addAnimation(&anim1);
       
  1206     group.addAnimation(&anim2);
       
  1207 
       
  1208     group.stop();
       
  1209 
       
  1210     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
  1211     QCOMPARE(anim1.state(), QAnimationGroup::Stopped);
       
  1212     QCOMPARE(anim2.state(), QAnimationGroup::Stopped);
       
  1213 
       
  1214     anim1.start();
       
  1215     anim2.start();
       
  1216     anim2.pause();
       
  1217 
       
  1218     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
  1219     QCOMPARE(anim1.state(), QAnimationGroup::Running);
       
  1220     QCOMPARE(anim2.state(), QAnimationGroup::Paused);
       
  1221 }
       
  1222 
       
  1223 void tst_QSequentialAnimationGroup::stopGroupWithRunningChild()
       
  1224 {
       
  1225     // children that started independently will not be affected by a group stop
       
  1226     QSequentialAnimationGroup group;
       
  1227 
       
  1228     TestAnimation anim1;
       
  1229     anim1.setStartValue(0);
       
  1230     anim1.setEndValue(100);
       
  1231     anim1.setDuration(200);
       
  1232 
       
  1233     TestAnimation anim2;
       
  1234     anim2.setStartValue(0);
       
  1235     anim2.setEndValue(100);
       
  1236     anim2.setDuration(200);
       
  1237 
       
  1238     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
  1239     QCOMPARE(anim1.state(), QAnimationGroup::Stopped);
       
  1240     QCOMPARE(anim2.state(), QAnimationGroup::Stopped);
       
  1241 
       
  1242     group.addAnimation(&anim1);
       
  1243     group.addAnimation(&anim2);
       
  1244 
       
  1245     anim1.start();
       
  1246     anim2.start();
       
  1247     anim2.pause();
       
  1248 
       
  1249     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
  1250     QCOMPARE(anim1.state(), QAnimationGroup::Running);
       
  1251     QCOMPARE(anim2.state(), QAnimationGroup::Paused);
       
  1252 
       
  1253     group.stop();
       
  1254 
       
  1255     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
  1256     QCOMPARE(anim1.state(), QAnimationGroup::Running);
       
  1257     QCOMPARE(anim2.state(), QAnimationGroup::Paused);
       
  1258 
       
  1259     anim1.stop();
       
  1260     anim2.stop();
       
  1261 
       
  1262     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
  1263     QCOMPARE(anim1.state(), QAnimationGroup::Stopped);
       
  1264     QCOMPARE(anim2.state(), QAnimationGroup::Stopped);
       
  1265 }
       
  1266 
       
  1267 void tst_QSequentialAnimationGroup::startGroupWithRunningChild()
       
  1268 {
       
  1269     // as the group has precedence over its children, starting a group will restart all the children
       
  1270     QSequentialAnimationGroup group;
       
  1271 
       
  1272     TestAnimation *anim1 = new TestAnimation();
       
  1273     anim1->setStartValue(0);
       
  1274     anim1->setEndValue(100);
       
  1275     anim1->setDuration(200);
       
  1276 
       
  1277     TestAnimation *anim2 = new TestAnimation();
       
  1278     anim2->setStartValue(0);
       
  1279     anim2->setEndValue(100);
       
  1280     anim2->setDuration(200);
       
  1281 
       
  1282     QSignalSpy stateChangedSpy1(anim1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
       
  1283     QSignalSpy stateChangedSpy2(anim2, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
       
  1284 
       
  1285     QCOMPARE(stateChangedSpy1.count(), 0);
       
  1286     QCOMPARE(stateChangedSpy2.count(), 0);
       
  1287     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
  1288     QCOMPARE(anim1->state(), QAnimationGroup::Stopped);
       
  1289     QCOMPARE(anim2->state(), QAnimationGroup::Stopped);
       
  1290 
       
  1291     group.addAnimation(anim1);
       
  1292     group.addAnimation(anim2);
       
  1293 
       
  1294     anim1->start();
       
  1295     anim2->start();
       
  1296     anim2->pause();
       
  1297 
       
  1298     QVERIFY(compareStates(stateChangedSpy1, (StateList() << QAbstractAnimation::Running)));
       
  1299 
       
  1300     QVERIFY(compareStates(stateChangedSpy2, (StateList() << QAbstractAnimation::Running
       
  1301                                                          << QAbstractAnimation::Paused)));
       
  1302 
       
  1303     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
  1304     QCOMPARE(anim1->state(), QAnimationGroup::Running);
       
  1305     QCOMPARE(anim2->state(), QAnimationGroup::Paused);
       
  1306 
       
  1307     group.start();
       
  1308 
       
  1309     QVERIFY(compareStates(stateChangedSpy1, (StateList() << QAbstractAnimation::Running
       
  1310                                                          << QAbstractAnimation::Stopped
       
  1311                                                          << QAbstractAnimation::Running)));
       
  1312     QVERIFY(compareStates(stateChangedSpy2, (StateList() << QAbstractAnimation::Running
       
  1313                                                          << QAbstractAnimation::Paused)));
       
  1314 
       
  1315     QCOMPARE(group.state(), QAnimationGroup::Running);
       
  1316     QCOMPARE(anim1->state(), QAnimationGroup::Running);
       
  1317     QCOMPARE(anim2->state(), QAnimationGroup::Paused);
       
  1318 
       
  1319     QTest::qWait(300);
       
  1320 
       
  1321     QCOMPARE(group.state(), QAnimationGroup::Running);
       
  1322     QCOMPARE(anim1->state(), QAnimationGroup::Stopped);
       
  1323     QCOMPARE(anim2->state(), QAnimationGroup::Running);
       
  1324 
       
  1325     QCOMPARE(stateChangedSpy2.count(), 4);
       
  1326     QCOMPARE(qVariantValue<QAbstractAnimation::State>(stateChangedSpy2.at(2).at(1)),
       
  1327              QAnimationGroup::Stopped);
       
  1328     QCOMPARE(qVariantValue<QAbstractAnimation::State>(stateChangedSpy2.at(3).at(1)),
       
  1329              QAnimationGroup::Running);
       
  1330 
       
  1331     group.stop();
       
  1332 
       
  1333     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
  1334     QCOMPARE(anim1->state(), QAnimationGroup::Stopped);
       
  1335     QCOMPARE(anim2->state(), QAnimationGroup::Stopped);
       
  1336 }
       
  1337 
       
  1338 void tst_QSequentialAnimationGroup::zeroDurationAnimation()
       
  1339 {
       
  1340     QSequentialAnimationGroup group;
       
  1341 
       
  1342     TestAnimation *anim1 = new TestAnimation();
       
  1343     anim1->setStartValue(0);
       
  1344     anim1->setEndValue(100);
       
  1345     anim1->setDuration(0);
       
  1346 
       
  1347     TestAnimation *anim2 = new TestAnimation();
       
  1348     anim2->setStartValue(0);
       
  1349     anim2->setEndValue(100);
       
  1350     anim2->setDuration(100);
       
  1351 
       
  1352     DummyPropertyAnimation *anim3 = new DummyPropertyAnimation;
       
  1353     anim3->setEndValue(100);
       
  1354     anim3->setDuration(0);
       
  1355 
       
  1356     QSignalSpy stateChangedSpy(anim1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
       
  1357 
       
  1358     group.addAnimation(anim1);
       
  1359     group.addAnimation(anim2);
       
  1360     group.addAnimation(anim3);
       
  1361     group.setLoopCount(2);
       
  1362     group.start();
       
  1363 
       
  1364     QCOMPARE(stateChangedSpy.count(), 2);
       
  1365     QCOMPARE(qVariantValue<QAbstractAnimation::State>(stateChangedSpy.at(0).at(1)),
       
  1366              QAnimationGroup::Running);
       
  1367     QCOMPARE(qVariantValue<QAbstractAnimation::State>(stateChangedSpy.at(1).at(1)),
       
  1368              QAnimationGroup::Stopped);
       
  1369 
       
  1370     QCOMPARE(anim1->state(), QAnimationGroup::Stopped);
       
  1371     QCOMPARE(anim2->state(), QAnimationGroup::Running);
       
  1372     QCOMPARE(group.state(), QAnimationGroup::Running);
       
  1373 
       
  1374     //now let's try to seek to the next loop
       
  1375     group.setCurrentTime(group.duration() + 1);
       
  1376     QCOMPARE(anim1->state(), QAnimationGroup::Stopped);
       
  1377     QCOMPARE(anim2->state(), QAnimationGroup::Running);
       
  1378     QCOMPARE(anim3->state(), QAnimationGroup::Stopped);
       
  1379     QCOMPARE(group.state(), QAnimationGroup::Running);
       
  1380     QCOMPARE(anim3->o.value(), 100); //anim3 should have been run
       
  1381 }
       
  1382 
       
  1383 void tst_QSequentialAnimationGroup::stopUncontrolledAnimations()
       
  1384 {
       
  1385     QSequentialAnimationGroup group;
       
  1386 
       
  1387     AnimationObject o1;
       
  1388     UncontrolledAnimation notTimeDriven(&o1);
       
  1389     QCOMPARE(notTimeDriven.totalDuration(), -1);
       
  1390 
       
  1391     TestAnimation loopsForever;
       
  1392     loopsForever.setStartValue(0);
       
  1393     loopsForever.setEndValue(100);
       
  1394     loopsForever.setDuration(100);
       
  1395     loopsForever.setLoopCount(-1);
       
  1396 
       
  1397     group.addAnimation(&notTimeDriven);
       
  1398     group.addAnimation(&loopsForever);
       
  1399 
       
  1400     group.start();
       
  1401 
       
  1402     QCOMPARE(group.state(), QAnimationGroup::Running);
       
  1403     QCOMPARE(notTimeDriven.state(), QAnimationGroup::Running);
       
  1404     QCOMPARE(loopsForever.state(), QAnimationGroup::Stopped);
       
  1405 
       
  1406     notTimeDriven.stop();
       
  1407 
       
  1408     QCOMPARE(group.state(), QAnimationGroup::Running);
       
  1409     QCOMPARE(notTimeDriven.state(), QAnimationGroup::Stopped);
       
  1410     QCOMPARE(loopsForever.state(), QAnimationGroup::Running);
       
  1411 
       
  1412     loopsForever.stop();
       
  1413 
       
  1414     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
  1415     QCOMPARE(notTimeDriven.state(), QAnimationGroup::Stopped);
       
  1416     QCOMPARE(loopsForever.state(), QAnimationGroup::Stopped);
       
  1417 }
       
  1418 
       
  1419 void tst_QSequentialAnimationGroup::finishWithUncontrolledAnimation()
       
  1420 {
       
  1421     AnimationObject o1;
       
  1422 
       
  1423     //1st case:
       
  1424     //first we test a group with one uncontrolled animation
       
  1425     QSequentialAnimationGroup group;
       
  1426     UncontrolledAnimation notTimeDriven(&o1, &group);
       
  1427     QSignalSpy spy(&group, SIGNAL(finished()));
       
  1428 
       
  1429     group.start();
       
  1430     QCOMPARE(group.state(), QAnimationGroup::Running);
       
  1431     QCOMPARE(notTimeDriven.state(), QAnimationGroup::Running);
       
  1432     QCOMPARE(group.currentTime(), 0);
       
  1433     QCOMPARE(notTimeDriven.currentTime(), 0);
       
  1434 
       
  1435     QTest::qWait(300); //wait for the end of notTimeDriven
       
  1436     QCOMPARE(notTimeDriven.state(), QAnimationGroup::Stopped);
       
  1437     const int actualDuration = notTimeDriven.currentTime();
       
  1438     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
  1439     QCOMPARE(group.currentTime(), actualDuration);
       
  1440     QCOMPARE(spy.count(), 1);
       
  1441 
       
  1442     //2nd case:
       
  1443     // lets make sure the seeking will work again
       
  1444     spy.clear();
       
  1445     DummyPropertyAnimation anim(&group);
       
  1446     QSignalSpy animStateChangedSpy(&anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
       
  1447 
       
  1448     group.setCurrentTime(300);
       
  1449     QCOMPARE(group.state(), QAnimationGroup::Stopped);
       
  1450     QCOMPARE(notTimeDriven.currentTime(), actualDuration);
       
  1451     QCOMPARE(group.currentAnimation(), static_cast<QAbstractAnimation*>(&anim));
       
  1452 
       
  1453     //3rd case:
       
  1454     //now let's add a perfectly defined animation at the end
       
  1455     QCOMPARE(animStateChangedSpy.count(), 0);
       
  1456     group.start();
       
  1457     QCOMPARE(group.state(), QAnimationGroup::Running);
       
  1458     QCOMPARE(notTimeDriven.state(), QAnimationGroup::Running);
       
  1459     QCOMPARE(group.currentTime(), 0);
       
  1460     QCOMPARE(notTimeDriven.currentTime(), 0);
       
  1461 
       
  1462     QCOMPARE(animStateChangedSpy.count(), 0);
       
  1463 
       
  1464     QTest::qWait(300); //wait for the end of notTimeDriven
       
  1465     QCOMPARE(notTimeDriven.state(), QAnimationGroup::Stopped);
       
  1466     QCOMPARE(group.state(), QAnimationGroup::Running);
       
  1467     QCOMPARE(anim.state(), QAnimationGroup::Running);
       
  1468     QCOMPARE(group.currentAnimation(), static_cast<QAbstractAnimation*>(&anim));
       
  1469     QCOMPARE(animStateChangedSpy.count(), 1);
       
  1470     QTest::qWait(300); //wait for the end of anim
       
  1471 
       
  1472     QCOMPARE(anim.state(), QAnimationGroup::Stopped);
       
  1473     QCOMPARE(anim.currentTime(), anim.duration());
       
  1474 
       
  1475     //we should simply be at the end
       
  1476     QCOMPARE(spy.count(), 1);
       
  1477     QCOMPARE(animStateChangedSpy.count(), 2);
       
  1478     QCOMPARE(group.currentTime(), notTimeDriven.currentTime() + anim.currentTime());
       
  1479 }
       
  1480 
       
  1481 void tst_QSequentialAnimationGroup::addRemoveAnimation()
       
  1482 {
       
  1483     //this test is specific to the sequential animation group
       
  1484     QSequentialAnimationGroup group;
       
  1485 
       
  1486     QCOMPARE(group.duration(), 0);
       
  1487     QCOMPARE(group.currentTime(), 0);
       
  1488     QAbstractAnimation *anim1 = new QPropertyAnimation;
       
  1489     group.addAnimation(anim1);
       
  1490     QCOMPARE(group.duration(), 250);
       
  1491     QCOMPARE(group.currentTime(), 0);
       
  1492     QCOMPARE(group.currentAnimation(), anim1);
       
  1493 
       
  1494     //let's append an animation
       
  1495     QAbstractAnimation *anim2 = new QPropertyAnimation;
       
  1496     group.addAnimation(anim2);
       
  1497     QCOMPARE(group.duration(), 500);
       
  1498     QCOMPARE(group.currentTime(), 0);
       
  1499     QCOMPARE(group.currentAnimation(), anim1);
       
  1500 
       
  1501     //let's prepend an animation
       
  1502     QAbstractAnimation *anim0 = new QPropertyAnimation;
       
  1503     group.insertAnimationAt(0, anim0);
       
  1504     QCOMPARE(group.duration(), 750);
       
  1505     QCOMPARE(group.currentTime(), 0);
       
  1506     QCOMPARE(group.currentAnimation(), anim0); //anim0 has become the new currentAnimation
       
  1507 
       
  1508     group.setCurrentTime(300); //anim0 | anim1 | anim2
       
  1509     QCOMPARE(group.currentTime(), 300);
       
  1510     QCOMPARE(group.currentAnimation(), anim1);
       
  1511     QCOMPARE(anim1->currentTime(), 50);
       
  1512 
       
  1513     group.removeAnimation(anim0); //anim1 | anim2
       
  1514     QCOMPARE(group.currentTime(), 50);
       
  1515     QCOMPARE(group.currentAnimation(), anim1);
       
  1516     QCOMPARE(anim1->currentTime(), 50);
       
  1517 
       
  1518     group.setCurrentTime(0);
       
  1519     group.insertAnimationAt(0, anim0); //anim0 | anim1 | anim2
       
  1520     group.setCurrentTime(300);
       
  1521     QCOMPARE(group.currentTime(), 300);
       
  1522     QCOMPARE(group.currentAnimation(), anim1);
       
  1523     QCOMPARE(anim1->currentTime(), 50);
       
  1524 
       
  1525     group.removeAnimation(anim1); //anim0 | anim2
       
  1526     QCOMPARE(group.currentTime(), 250);
       
  1527     QCOMPARE(group.currentAnimation(), anim2);
       
  1528     QCOMPARE(anim0->currentTime(), 250);
       
  1529 }
       
  1530 
       
  1531 void tst_QSequentialAnimationGroup::currentAnimation()
       
  1532 {
       
  1533     QSequentialAnimationGroup group;
       
  1534     QVERIFY(group.currentAnimation() == 0);
       
  1535 
       
  1536     QPropertyAnimation anim;
       
  1537     anim.setDuration(0);
       
  1538     group.addAnimation(&anim);
       
  1539     QCOMPARE(group.currentAnimation(), static_cast<QAbstractAnimation*>(&anim));
       
  1540 }
       
  1541 
       
  1542 void tst_QSequentialAnimationGroup::currentAnimationWithZeroDuration()
       
  1543 {
       
  1544     QSequentialAnimationGroup group;
       
  1545     QVERIFY(group.currentAnimation() == 0);
       
  1546 
       
  1547     QPropertyAnimation zero1;
       
  1548     zero1.setDuration(0);
       
  1549     QPropertyAnimation zero2;
       
  1550     zero2.setDuration(0);
       
  1551 
       
  1552     QPropertyAnimation anim;
       
  1553 
       
  1554     QPropertyAnimation zero3;
       
  1555     zero3.setDuration(0);
       
  1556     QPropertyAnimation zero4;
       
  1557     zero4.setDuration(0);
       
  1558 
       
  1559 
       
  1560     group.addAnimation(&zero1);
       
  1561     group.addAnimation(&zero2);
       
  1562     group.addAnimation(&anim);
       
  1563     group.addAnimation(&zero3);
       
  1564     group.addAnimation(&zero4);
       
  1565 
       
  1566     QCOMPARE(group.currentAnimation(), static_cast<QAbstractAnimation*>(&zero1));
       
  1567 
       
  1568     group.setCurrentTime(0);
       
  1569     QCOMPARE(group.currentAnimation(), static_cast<QAbstractAnimation*>(&anim));
       
  1570 
       
  1571     group.setCurrentTime(group.duration());
       
  1572     QCOMPARE(group.currentAnimation(), static_cast<QAbstractAnimation*>(&zero4));
       
  1573 
       
  1574     group.setDirection(QAbstractAnimation::Backward);
       
  1575 
       
  1576     group.setCurrentTime(0);
       
  1577     QCOMPARE(group.currentAnimation(), static_cast<QAbstractAnimation*>(&zero1));
       
  1578 
       
  1579     group.setCurrentTime(group.duration());
       
  1580     QCOMPARE(group.currentAnimation(), static_cast<QAbstractAnimation*>(&anim));
       
  1581 }
       
  1582 
       
  1583 void tst_QSequentialAnimationGroup::insertAnimation()
       
  1584 {
       
  1585     QSequentialAnimationGroup group;
       
  1586     group.setLoopCount(2);
       
  1587     QPropertyAnimation *anim = new DummyPropertyAnimation(&group);
       
  1588     QCOMPARE(group.duration(), anim->duration());
       
  1589     group.setCurrentTime(300);
       
  1590     QCOMPARE(group.currentLoop(), 1);
       
  1591 
       
  1592     //this will crash if the sequential group calls duration on the created animation
       
  1593     new QPropertyAnimation(&group);
       
  1594 }
       
  1595 
       
  1596 
       
  1597 class SequentialAnimationGroup : public QSequentialAnimationGroup
       
  1598 {
       
  1599     Q_OBJECT
       
  1600 public slots:
       
  1601     void clearAnimations()
       
  1602     {
       
  1603         QSequentialAnimationGroup::clearAnimations();
       
  1604     }
       
  1605 
       
  1606     void refill()
       
  1607     {
       
  1608         stop();
       
  1609         clearAnimations();
       
  1610         new DummyPropertyAnimation(this);
       
  1611         start();
       
  1612     }
       
  1613 
       
  1614 };
       
  1615 
       
  1616 
       
  1617 void tst_QSequentialAnimationGroup::clearAnimations()
       
  1618 {
       
  1619     SequentialAnimationGroup group;
       
  1620     QPointer<QAbstractAnimation> anim1 = new DummyPropertyAnimation(&group);
       
  1621     group.connect(anim1, SIGNAL(finished()), SLOT(clearAnimations()));
       
  1622     new DummyPropertyAnimation(&group);
       
  1623     QCOMPARE(group.animationCount(), 2);
       
  1624 
       
  1625     group.start();
       
  1626     QTest::qWait(anim1->duration() + 100);
       
  1627     QCOMPARE(group.animationCount(), 0);
       
  1628     QCOMPARE(group.state(), QAbstractAnimation::Stopped);
       
  1629     QCOMPARE(group.currentTime(), 0);
       
  1630 
       
  1631     anim1 = new DummyPropertyAnimation(&group);
       
  1632     group.connect(anim1, SIGNAL(finished()), SLOT(refill()));
       
  1633     group.start();
       
  1634     QTest::qWait(anim1->duration() + 100);
       
  1635     QVERIFY(anim1 == 0); //anim1 should have been deleted
       
  1636     QCOMPARE(group.state(), QAbstractAnimation::Running);
       
  1637 }
       
  1638 
       
  1639 void tst_QSequentialAnimationGroup::pauseResume()
       
  1640 {
       
  1641     QObject dummy;
       
  1642     dummy.setProperty("foo", 0);
       
  1643     QParallelAnimationGroup group;
       
  1644     QPropertyAnimation *anim = new QPropertyAnimation(&dummy, "foo", &group);
       
  1645     anim->setDuration(250);
       
  1646     anim->setEndValue(250);
       
  1647     QSignalSpy spy(anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
       
  1648     QCOMPARE(group.duration(), 250);
       
  1649     group.start();
       
  1650     QTest::qWait(100);
       
  1651     QCOMPARE(group.state(), QAnimationGroup::Running);
       
  1652     QCOMPARE(anim->state(), QAnimationGroup::Running);
       
  1653     QCOMPARE(spy.count(), 1);
       
  1654     spy.clear();
       
  1655     const int currentTime = group.currentTime();
       
  1656     QCOMPARE(anim->currentTime(), currentTime);
       
  1657 
       
  1658     group.pause();
       
  1659     QCOMPARE(group.state(), QAnimationGroup::Paused);
       
  1660     QCOMPARE(group.currentTime(), currentTime);
       
  1661     QCOMPARE(anim->state(), QAnimationGroup::Paused);
       
  1662     QCOMPARE(anim->currentTime(), currentTime);
       
  1663     QCOMPARE(spy.count(), 1);
       
  1664     spy.clear();
       
  1665 
       
  1666     group.resume();
       
  1667     QCOMPARE(group.state(), QAnimationGroup::Running);
       
  1668     QCOMPARE(group.currentTime(), currentTime);
       
  1669     QCOMPARE(anim->state(), QAnimationGroup::Running);
       
  1670     QCOMPARE(anim->currentTime(), currentTime);
       
  1671     QCOMPARE(spy.count(), 1);
       
  1672 }
       
  1673 
       
  1674 QTEST_MAIN(tst_QSequentialAnimationGroup)
       
  1675 #include "tst_qsequentialanimationgroup.moc"