c078ed416c3926de30019c88dc6ee65dc039af65
[profile/ivi/qtdeclarative.git] / tests / auto / qtquick2 / qdeclarativeanimations / tst_qdeclarativeanimations.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 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 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 #include <QtTest/QtTest>
42 #include <QtDeclarative/qdeclarativeengine.h>
43 #include <QtDeclarative/qdeclarativecomponent.h>
44 #include <QtQuick/qquickview.h>
45 #include <QtQuick/private/qquickrectangle_p.h>
46 #include <QtQuick/private/qdeclarativeanimation_p.h>
47 #include <QtQuick/private/qdeclarativetransition_p.h>
48 #include <QtQuick/private/qquickanimation_p.h>
49 #include <QtQuick/private/qdeclarativepathinterpolator_p.h>
50 #include <QtQuick/private/qquickitem_p.h>
51 #include <QVariantAnimation>
52 #include <QEasingCurve>
53
54 #include <limits.h>
55 #include <math.h>
56
57 #include "../../shared/util.h"
58
59 class tst_qdeclarativeanimations : public QDeclarativeDataTest
60 {
61     Q_OBJECT
62 public:
63     tst_qdeclarativeanimations() {}
64
65 private slots:
66     void initTestCase()
67     {
68         QDeclarativeEngine engine;  // ensure types are registered
69         QDeclarativeDataTest::initTestCase();
70     }
71
72     void simpleProperty();
73     void simpleNumber();
74     void simpleColor();
75     void simpleRotation();
76     void simplePath();
77     void pathInterpolator();
78     void pathInterpolatorBackwardJump();
79     void pathWithNoStart();
80     void alwaysRunToEnd();
81     void complete();
82     void resume();
83     void dotProperty();
84     void badTypes();
85     void badProperties();
86     void mixedTypes();
87     void properties();
88     void propertiesTransition();
89     void pathTransition();
90     void disabledTransition();
91     void invalidDuration();
92     void attached();
93     void propertyValueSourceDefaultStart();
94     void dontStart();
95     void easingProperties();
96     void rotation();
97     void runningTrueBug();
98     void nonTransitionBug();
99     void registrationBug();
100     void doubleRegistrationBug();
101     void alwaysRunToEndRestartBug();
102     void transitionAssignmentBug();
103     void pauseBindingBug();
104     void pauseBug();
105 };
106
107 #define QTIMED_COMPARE(lhs, rhs) do { \
108     for (int ii = 0; ii < 5; ++ii) { \
109         if (lhs == rhs)  \
110             break; \
111         QTest::qWait(50); \
112     } \
113     QCOMPARE(lhs, rhs); \
114 } while (false)
115
116 void tst_qdeclarativeanimations::simpleProperty()
117 {
118     QQuickRectangle rect;
119     QDeclarativePropertyAnimation animation;
120     animation.setTarget(&rect);
121     animation.setProperty("x");
122     animation.setTo(200);
123     QVERIFY(animation.target() == &rect);
124     QVERIFY(animation.property() == "x");
125     QVERIFY(animation.to().toReal() == 200.0);
126     animation.start();
127     QVERIFY(animation.isRunning());
128     QTest::qWait(animation.duration());
129     QTIMED_COMPARE(rect.x(), 200.0);
130
131     rect.setPos(QPointF(0,0));
132     animation.start();
133     animation.pause();
134     QVERIFY(animation.isRunning());
135     QVERIFY(animation.isPaused());
136     animation.setCurrentTime(125);
137     QVERIFY(animation.currentTime() == 125);
138     QCOMPARE(rect.x(),100.0);
139 }
140
141 void tst_qdeclarativeanimations::simpleNumber()
142 {
143     QQuickRectangle rect;
144     QDeclarativeNumberAnimation animation;
145     animation.setTarget(&rect);
146     animation.setProperty("x");
147     animation.setTo(200);
148     QVERIFY(animation.target() == &rect);
149     QVERIFY(animation.property() == "x");
150     QVERIFY(animation.to() == 200);
151     animation.start();
152     QVERIFY(animation.isRunning());
153     QTest::qWait(animation.duration());
154     QTIMED_COMPARE(rect.x(), qreal(200));
155
156     rect.setX(0);
157     animation.start();
158     animation.pause();
159     QVERIFY(animation.isRunning());
160     QVERIFY(animation.isPaused());
161     animation.setCurrentTime(125);
162     QVERIFY(animation.currentTime() == 125);
163     QCOMPARE(rect.x(), qreal(100));
164 }
165
166 void tst_qdeclarativeanimations::simpleColor()
167 {
168     QQuickRectangle rect;
169     QDeclarativeColorAnimation animation;
170     animation.setTarget(&rect);
171     animation.setProperty("color");
172     animation.setTo(QColor("red"));
173     QVERIFY(animation.target() == &rect);
174     QVERIFY(animation.property() == "color");
175     QVERIFY(animation.to() == QColor("red"));
176     animation.start();
177     QVERIFY(animation.isRunning());
178     QTest::qWait(animation.duration());
179     QTIMED_COMPARE(rect.color(), QColor("red"));
180
181     rect.setColor(QColor("blue"));
182     animation.start();
183     animation.pause();
184     QVERIFY(animation.isRunning());
185     QVERIFY(animation.isPaused());
186     animation.setCurrentTime(125);
187     QVERIFY(animation.currentTime() == 125);
188 #if defined(UBUNTU_ONEIRIC) && defined(__x86_64__)
189     QEXPECT_FAIL("", "Fails on this platform - QTBUG-23385", Abort);
190 #endif
191     QCOMPARE(rect.color(), QColor::fromRgbF(0.498039, 0, 0.498039, 1));
192
193     rect.setColor(QColor("green"));
194     animation.setFrom(QColor("blue"));
195     QVERIFY(animation.from() == QColor("blue"));
196     animation.restart();
197     QCOMPARE(rect.color(), QColor("blue"));
198     QVERIFY(animation.isRunning());
199     animation.setCurrentTime(125);
200     QCOMPARE(rect.color(), QColor::fromRgbF(0.498039, 0, 0.498039, 1));
201 }
202
203 void tst_qdeclarativeanimations::simpleRotation()
204 {
205     QQuickRectangle rect;
206     QDeclarativeRotationAnimation animation;
207     animation.setTarget(&rect);
208     animation.setProperty("rotation");
209     animation.setTo(270);
210     QVERIFY(animation.target() == &rect);
211     QVERIFY(animation.property() == "rotation");
212     QVERIFY(animation.to() == 270);
213     QVERIFY(animation.direction() == QDeclarativeRotationAnimation::Numerical);
214     animation.start();
215     QVERIFY(animation.isRunning());
216     QTest::qWait(animation.duration());
217     QTIMED_COMPARE(rect.rotation(), qreal(270));
218
219     rect.setRotation(0);
220     animation.start();
221     animation.pause();
222     QVERIFY(animation.isRunning());
223     QVERIFY(animation.isPaused());
224     animation.setCurrentTime(125);
225     QVERIFY(animation.currentTime() == 125);
226     QCOMPARE(rect.rotation(), qreal(135));
227 }
228
229 void tst_qdeclarativeanimations::simplePath()
230 {
231     {
232         QDeclarativeEngine engine;
233         QDeclarativeComponent c(&engine, testFileUrl("pathAnimation.qml"));
234         QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
235         QVERIFY(rect);
236
237         QQuickRectangle *redRect = rect->findChild<QQuickRectangle*>();
238         QVERIFY(redRect);
239         QQuickPathAnimation *pathAnim = rect->findChild<QQuickPathAnimation*>();
240         QVERIFY(pathAnim);
241
242         pathAnim->start();
243         pathAnim->pause();
244
245         pathAnim->setCurrentTime(30);
246         QCOMPARE(redRect->x(), qreal(167));
247         QCOMPARE(redRect->y(), qreal(104));
248
249         pathAnim->setCurrentTime(100);
250         QCOMPARE(redRect->x(), qreal(300));
251         QCOMPARE(redRect->y(), qreal(300));
252
253         //verify animation runs to end
254         pathAnim->start();
255         QCOMPARE(redRect->x(), qreal(50));
256         QCOMPARE(redRect->y(), qreal(50));
257         QTRY_COMPARE(redRect->x(), qreal(300));
258         QCOMPARE(redRect->y(), qreal(300));
259
260         pathAnim->setOrientation(QQuickPathAnimation::RightFirst);
261         QCOMPARE(pathAnim->orientation(), QQuickPathAnimation::RightFirst);
262         pathAnim->start();
263         QTRY_VERIFY(redRect->rotation() != 0);
264         pathAnim->stop();
265     }
266
267     {
268         QDeclarativeEngine engine;
269         QDeclarativeComponent c(&engine, testFileUrl("pathAnimation2.qml"));
270         QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
271         QVERIFY(rect);
272
273         QQuickRectangle *redRect = rect->findChild<QQuickRectangle*>();
274         QVERIFY(redRect);
275         QQuickPathAnimation *pathAnim = rect->findChild<QQuickPathAnimation*>();
276         QVERIFY(pathAnim);
277
278         QCOMPARE(pathAnim->orientation(), QQuickPathAnimation::RightFirst);
279
280         pathAnim->start();
281         pathAnim->pause();
282         QCOMPARE(redRect->x(), qreal(50));
283         QCOMPARE(redRect->y(), qreal(50));
284         QCOMPARE(redRect->rotation(), qreal(-360));
285
286         pathAnim->setCurrentTime(50);
287         QCOMPARE(redRect->x(), qreal(175));
288         QCOMPARE(redRect->y(), qreal(175));
289         QCOMPARE(redRect->rotation(), qreal(-315));
290
291         pathAnim->setCurrentTime(100);
292         QCOMPARE(redRect->x(), qreal(300));
293         QCOMPARE(redRect->y(), qreal(300));
294         QCOMPARE(redRect->rotation(), qreal(0));
295     }
296 }
297
298 void tst_qdeclarativeanimations::pathInterpolator()
299 {
300     QDeclarativeEngine engine;
301     QDeclarativeComponent c(&engine, testFileUrl("pathInterpolator.qml"));
302     QDeclarativePathInterpolator *interpolator = qobject_cast<QDeclarativePathInterpolator*>(c.create());
303     QVERIFY(interpolator);
304
305     QCOMPARE(interpolator->progress(), qreal(0));
306     QCOMPARE(interpolator->x(), qreal(50));
307     QCOMPARE(interpolator->y(), qreal(50));
308     QCOMPARE(interpolator->angle(), qreal(0));
309
310     interpolator->setProgress(.5);
311     QCOMPARE(interpolator->progress(), qreal(.5));
312     QCOMPARE(interpolator->x(), qreal(175));
313     QCOMPARE(interpolator->y(), qreal(175));
314     QCOMPARE(interpolator->angle(), qreal(270));
315
316     interpolator->setProgress(1);
317     QCOMPARE(interpolator->progress(), qreal(1));
318     QCOMPARE(interpolator->x(), qreal(300));
319     QCOMPARE(interpolator->y(), qreal(300));
320     QCOMPARE(interpolator->angle(), qreal(0));
321 }
322
323 void tst_qdeclarativeanimations::pathInterpolatorBackwardJump()
324 {
325     QDeclarativeEngine engine;
326     QDeclarativeComponent c(&engine, testFileUrl("pathInterpolatorBack.qml"));
327     QDeclarativePathInterpolator *interpolator = qobject_cast<QDeclarativePathInterpolator*>(c.create());
328     QVERIFY(interpolator);
329
330     QCOMPARE(interpolator->progress(), qreal(0));
331     QCOMPARE(interpolator->x(), qreal(50));
332     QCOMPARE(interpolator->y(), qreal(50));
333     QCOMPARE(interpolator->angle(), qreal(270));
334
335     interpolator->setProgress(.5);
336     QCOMPARE(interpolator->progress(), qreal(.5));
337     QCOMPARE(interpolator->x(), qreal(100));
338     QCOMPARE(interpolator->y(), qreal(75));
339     QCOMPARE(interpolator->angle(), qreal(90));
340
341     interpolator->setProgress(1);
342     QCOMPARE(interpolator->progress(), qreal(1));
343     QCOMPARE(interpolator->x(), qreal(200));
344     QCOMPARE(interpolator->y(), qreal(50));
345     QCOMPARE(interpolator->angle(), qreal(0));
346
347     //make sure we don't get caught in infinite loop here
348     interpolator->setProgress(0);
349     QCOMPARE(interpolator->progress(), qreal(0));
350     QCOMPARE(interpolator->x(), qreal(50));
351     QCOMPARE(interpolator->y(), qreal(50));
352     QCOMPARE(interpolator->angle(), qreal(270));
353 }
354
355 void tst_qdeclarativeanimations::pathWithNoStart()
356 {
357     QDeclarativeEngine engine;
358     QDeclarativeComponent c(&engine, testFileUrl("pathAnimationNoStart.qml"));
359     QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
360     QVERIFY(rect);
361
362     QQuickRectangle *redRect = rect->findChild<QQuickRectangle*>();
363     QVERIFY(redRect);
364     QQuickPathAnimation *pathAnim = rect->findChild<QQuickPathAnimation*>();
365     QVERIFY(pathAnim);
366
367     pathAnim->start();
368     pathAnim->pause();
369     QCOMPARE(redRect->x(), qreal(50));
370     QCOMPARE(redRect->y(), qreal(50));
371
372     pathAnim->setCurrentTime(50);
373     QCOMPARE(redRect->x(), qreal(175));
374     QCOMPARE(redRect->y(), qreal(175));
375
376     pathAnim->setCurrentTime(100);
377     QCOMPARE(redRect->x(), qreal(300));
378     QCOMPARE(redRect->y(), qreal(300));
379
380     redRect->setX(100);
381     redRect->setY(100);
382     pathAnim->start();
383     QCOMPARE(redRect->x(), qreal(100));
384     QCOMPARE(redRect->y(), qreal(100));
385     QTRY_COMPARE(redRect->x(), qreal(300));
386     QCOMPARE(redRect->y(), qreal(300));
387 }
388
389 void tst_qdeclarativeanimations::alwaysRunToEnd()
390 {
391     QQuickRectangle rect;
392     QDeclarativePropertyAnimation animation;
393     animation.setTarget(&rect);
394     animation.setProperty("x");
395     animation.setTo(200);
396     animation.setDuration(1000);
397     animation.setLoops(-1);
398     animation.setAlwaysRunToEnd(true);
399     QVERIFY(animation.loops() == -1);
400     QVERIFY(animation.alwaysRunToEnd() == true);
401     animation.start();
402     QTest::qWait(1500);
403     animation.stop();
404     QVERIFY(rect.x() != qreal(200));
405     QTest::qWait(500);
406     QTIMED_COMPARE(rect.x(), qreal(200));
407 }
408
409 void tst_qdeclarativeanimations::complete()
410 {
411     QQuickRectangle rect;
412     QDeclarativePropertyAnimation animation;
413     animation.setTarget(&rect);
414     animation.setProperty("x");
415     animation.setFrom(1);
416     animation.setTo(200);
417     animation.setDuration(500);
418     QVERIFY(animation.from() == 1);
419     animation.start();
420     QTest::qWait(50);
421     animation.stop();
422     QVERIFY(rect.x() != qreal(200));
423     animation.start();
424     QTest::qWait(50);
425     QVERIFY(animation.isRunning());
426     animation.complete();
427     QCOMPARE(rect.x(), qreal(200));
428 }
429
430 void tst_qdeclarativeanimations::resume()
431 {
432     QQuickRectangle rect;
433     QDeclarativePropertyAnimation animation;
434     animation.setTarget(&rect);
435     animation.setProperty("x");
436     animation.setFrom(10);
437     animation.setTo(200);
438     animation.setDuration(1000);
439     QVERIFY(animation.from() == 10);
440
441     animation.start();
442     QTest::qWait(400);
443     animation.pause();
444     qreal x = rect.x();
445     QVERIFY(x != qreal(200) && x != qreal(10));
446     QVERIFY(animation.isRunning());
447     QVERIFY(animation.isPaused());
448
449     animation.resume();
450     QVERIFY(animation.isRunning());
451     QVERIFY(!animation.isPaused());
452     QTest::qWait(400);
453     animation.stop();
454     QVERIFY(rect.x() > x);
455 }
456
457 void tst_qdeclarativeanimations::dotProperty()
458 {
459     QQuickRectangle rect;
460     QDeclarativeNumberAnimation animation;
461     animation.setTarget(&rect);
462     animation.setProperty("border.width");
463     animation.setTo(10);
464     animation.start();
465     QTest::qWait(animation.duration()+50);
466     QTIMED_COMPARE(rect.border()->width(), 10.0);
467
468     rect.border()->setWidth(0);
469     animation.start();
470     animation.pause();
471     animation.setCurrentTime(125);
472     QVERIFY(animation.currentTime() == 125);
473     QCOMPARE(rect.border()->width(), 5.0);
474 }
475
476 void tst_qdeclarativeanimations::badTypes()
477 {
478     //don't crash
479     {
480         QQuickView *view = new QQuickView;
481         view->setSource(testFileUrl("badtype1.qml"));
482
483         qApp->processEvents();
484
485         delete view;
486     }
487
488     //make sure we get a compiler error
489     {
490         QDeclarativeEngine engine;
491         QDeclarativeComponent c(&engine, testFileUrl("badtype2.qml"));
492         QTest::ignoreMessage(QtWarningMsg, "QDeclarativeComponent: Component is not ready");
493         c.create();
494
495         QVERIFY(c.errors().count() == 1);
496         QCOMPARE(c.errors().at(0).description(), QLatin1String("Invalid property assignment: number expected"));
497     }
498
499     //make sure we get a compiler error
500     {
501         QDeclarativeEngine engine;
502         QDeclarativeComponent c(&engine, testFileUrl("badtype3.qml"));
503         QTest::ignoreMessage(QtWarningMsg, "QDeclarativeComponent: Component is not ready");
504         c.create();
505
506         QVERIFY(c.errors().count() == 1);
507         QCOMPARE(c.errors().at(0).description(), QLatin1String("Invalid property assignment: color expected"));
508     }
509
510     //don't crash
511     {
512         QDeclarativeEngine engine;
513         QDeclarativeComponent c(&engine, testFileUrl("badtype4.qml"));
514         QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
515         QVERIFY(rect);
516
517         QQuickItemPrivate::get(rect)->setState("state1");
518         QTest::qWait(1000 + 50);
519         QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("MyRect");
520         QVERIFY(myRect);
521         QCOMPARE(myRect->x(),qreal(200));
522     }
523 }
524
525 void tst_qdeclarativeanimations::badProperties()
526 {
527     //make sure we get a runtime error
528     {
529         QDeclarativeEngine engine;
530
531         QDeclarativeComponent c1(&engine, testFileUrl("badproperty1.qml"));
532         QByteArray message = testFileUrl("badproperty1.qml").toString().toUtf8() + ":18:9: QML ColorAnimation: Cannot animate non-existent property \"border.colr\"";
533         QTest::ignoreMessage(QtWarningMsg, message);
534         QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c1.create());
535         QVERIFY(rect);
536
537         QDeclarativeComponent c2(&engine, testFileUrl("badproperty2.qml"));
538         message = testFileUrl("badproperty2.qml").toString().toUtf8() + ":18:9: QML ColorAnimation: Cannot animate read-only property \"border\"";
539         QTest::ignoreMessage(QtWarningMsg, message);
540         rect = qobject_cast<QQuickRectangle*>(c2.create());
541         QVERIFY(rect);
542
543         //### should we warn here are well?
544         //rect->setState("state1");
545     }
546 }
547
548 //test animating mixed types with property animation in a transition
549 //for example, int + real; color + real; etc
550 void tst_qdeclarativeanimations::mixedTypes()
551 {
552     //assumes border.width stays a real -- not real robust
553     {
554         QDeclarativeEngine engine;
555         QDeclarativeComponent c(&engine, testFileUrl("mixedtype1.qml"));
556         QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
557         QVERIFY(rect);
558
559         QQuickItemPrivate::get(rect)->setState("state1");
560         QTest::qWait(500);
561         QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("MyRect");
562         QVERIFY(myRect);
563
564         //rather inexact -- is there a better way?
565         QVERIFY(myRect->x() > 100 && myRect->x() < 200);
566         QVERIFY(myRect->border()->width() > 1 && myRect->border()->width() < 10);
567     }
568
569     {
570         QDeclarativeEngine engine;
571         QDeclarativeComponent c(&engine, testFileUrl("mixedtype2.qml"));
572         QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
573         QVERIFY(rect);
574
575         QQuickItemPrivate::get(rect)->setState("state1");
576         QTest::qWait(500);
577         QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("MyRect");
578         QVERIFY(myRect);
579
580         //rather inexact -- is there a better way?
581         QVERIFY(myRect->x() > 100 && myRect->x() < 200);
582 #if defined(UBUNTU_ONEIRIC) && defined(__x86_64__)
583         QEXPECT_FAIL("", "Fails on this platform - QTBUG-23385", Continue);
584 #endif
585         QVERIFY(myRect->color() != QColor("red") && myRect->color() != QColor("blue"));
586     }
587 }
588
589 void tst_qdeclarativeanimations::properties()
590 {
591     const int waitDuration = 300;
592     {
593         QDeclarativeEngine engine;
594         QDeclarativeComponent c(&engine, testFileUrl("properties.qml"));
595         QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
596         QVERIFY(rect);
597
598         QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
599         QVERIFY(myRect);
600         QTest::qWait(waitDuration);
601         QTIMED_COMPARE(myRect->x(),qreal(200));
602     }
603
604     {
605         QDeclarativeEngine engine;
606         QDeclarativeComponent c(&engine, testFileUrl("properties2.qml"));
607         QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
608         QVERIFY(rect);
609
610         QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
611         QVERIFY(myRect);
612         QTest::qWait(waitDuration);
613         QTIMED_COMPARE(myRect->x(),qreal(200));
614     }
615
616     {
617         QDeclarativeEngine engine;
618         QDeclarativeComponent c(&engine, testFileUrl("properties3.qml"));
619         QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
620         QVERIFY(rect);
621
622         QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
623         QVERIFY(myRect);
624         QTest::qWait(waitDuration);
625         QTIMED_COMPARE(myRect->x(),qreal(300));
626     }
627
628     {
629         QDeclarativeEngine engine;
630         QDeclarativeComponent c(&engine, testFileUrl("properties4.qml"));
631         QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
632         QVERIFY(rect);
633
634         QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
635         QVERIFY(myRect);
636         QTest::qWait(waitDuration);
637         QTIMED_COMPARE(myRect->y(),qreal(200));
638         QTIMED_COMPARE(myRect->x(),qreal(100));
639     }
640
641     {
642         QDeclarativeEngine engine;
643         QDeclarativeComponent c(&engine, testFileUrl("properties5.qml"));
644         QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
645         QVERIFY(rect);
646
647         QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
648         QVERIFY(myRect);
649         QTest::qWait(waitDuration);
650         QTIMED_COMPARE(myRect->x(),qreal(100));
651         QTIMED_COMPARE(myRect->y(),qreal(200));
652     }
653 }
654
655 void tst_qdeclarativeanimations::propertiesTransition()
656 {
657     const int waitDuration = 300;
658     {
659         QDeclarativeEngine engine;
660         QDeclarativeComponent c(&engine, testFileUrl("propertiesTransition.qml"));
661         QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
662         QVERIFY(rect);
663
664         QQuickItemPrivate::get(rect)->setState("moved");
665         QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
666         QVERIFY(myRect);
667         QTest::qWait(waitDuration);
668         QTIMED_COMPARE(myRect->x(),qreal(200));
669     }
670
671     {
672         QDeclarativeEngine engine;
673         QDeclarativeComponent c(&engine, testFileUrl("propertiesTransition2.qml"));
674         QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
675         QVERIFY(rect);
676
677         QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
678         QVERIFY(myRect);
679         QQuickItemPrivate::get(rect)->setState("moved");
680         QCOMPARE(myRect->x(),qreal(200));
681         QCOMPARE(myRect->y(),qreal(100));
682         QTest::qWait(waitDuration);
683         QTIMED_COMPARE(myRect->y(),qreal(200));
684     }
685
686     {
687         QDeclarativeEngine engine;
688         QDeclarativeComponent c(&engine, testFileUrl("propertiesTransition3.qml"));
689         QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
690         QVERIFY(rect);
691
692         QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
693         QVERIFY(myRect);
694         QQuickItemPrivate::get(rect)->setState("moved");
695         QCOMPARE(myRect->x(),qreal(200));
696         QCOMPARE(myRect->y(),qreal(100));
697     }
698
699     {
700         QDeclarativeEngine engine;
701         QDeclarativeComponent c(&engine, testFileUrl("propertiesTransition4.qml"));
702         QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
703         QVERIFY(rect);
704
705         QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
706         QVERIFY(myRect);
707         QQuickItemPrivate::get(rect)->setState("moved");
708         QCOMPARE(myRect->x(),qreal(100));
709         QTest::qWait(waitDuration);
710         QTIMED_COMPARE(myRect->x(),qreal(200));
711     }
712
713     {
714         QDeclarativeEngine engine;
715         QDeclarativeComponent c(&engine, testFileUrl("propertiesTransition5.qml"));
716         QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
717         QVERIFY(rect);
718
719         QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
720         QVERIFY(myRect);
721         QQuickItemPrivate::get(rect)->setState("moved");
722         QCOMPARE(myRect->x(),qreal(100));
723         QTest::qWait(waitDuration);
724         QTIMED_COMPARE(myRect->x(),qreal(200));
725     }
726
727     /*{
728         QDeclarativeEngine engine;
729         QDeclarativeComponent c(&engine, testFileUrl("propertiesTransition6.qml"));
730         QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
731         QVERIFY(rect);
732
733         QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
734         QVERIFY(myRect);
735         QQuickItemPrivate::get(rect)->setState("moved");
736         QCOMPARE(myRect->x(),qreal(100));
737         QTest::qWait(waitDuration);
738         QTIMED_COMPARE(myRect->x(),qreal(100));
739     }*/
740
741     {
742         QDeclarativeEngine engine;
743         QDeclarativeComponent c(&engine, testFileUrl("propertiesTransition7.qml"));
744         QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
745         QVERIFY(rect);
746
747         QQuickItemPrivate::get(rect)->setState("moved");
748         QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
749         QVERIFY(myRect);
750         QTest::qWait(waitDuration);
751         QTIMED_COMPARE(myRect->x(),qreal(200));
752     }
753
754 }
755
756 void tst_qdeclarativeanimations::pathTransition()
757 {
758     QDeclarativeEngine engine;
759     QDeclarativeComponent c(&engine, testFileUrl("pathTransition.qml"));
760     QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
761     QVERIFY(rect);
762
763     QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("redRect");
764     QVERIFY(myRect);
765
766     QQuickItemPrivate::get(rect)->setState("moved");
767     QTRY_VERIFY(myRect->x() < 500 && myRect->x() > 100 && myRect->y() > 50 && myRect->y() < 700 );  //animation started
768     QTRY_VERIFY(qFuzzyCompare(myRect->x(), qreal(100)) && qFuzzyCompare(myRect->y(), qreal(700)));
769     QTest::qWait(100);
770
771     QQuickItemPrivate::get(rect)->setState("");
772     QTRY_VERIFY(myRect->x() < 500 && myRect->x() > 100 && myRect->y() > 50 && myRect->y() < 700 );  //animation started
773     QTRY_VERIFY(qFuzzyCompare(myRect->x(), qreal(500)) && qFuzzyCompare(myRect->y(), qreal(50)));
774 }
775
776 void tst_qdeclarativeanimations::disabledTransition()
777 {
778     QDeclarativeEngine engine;
779     QDeclarativeComponent c(&engine, testFileUrl("disabledTransition.qml"));
780     QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
781     QVERIFY(rect);
782
783     QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
784     QVERIFY(myRect);
785
786     QDeclarativeTransition *trans = rect->findChild<QDeclarativeTransition*>();
787     QVERIFY(trans);
788
789     QCOMPARE(trans->enabled(), false);
790
791     QQuickItemPrivate::get(rect)->setState("moved");
792     QCOMPARE(myRect->x(),qreal(200));
793
794     trans->setEnabled(true);
795
796     QQuickItemPrivate::get(rect)->setState("");
797     QCOMPARE(myRect->x(),qreal(200));
798     QTest::qWait(300);
799     QTIMED_COMPARE(myRect->x(),qreal(100));
800 }
801
802 void tst_qdeclarativeanimations::invalidDuration()
803 {
804     QDeclarativePropertyAnimation *animation = new QDeclarativePropertyAnimation;
805     QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML PropertyAnimation: Cannot set a duration of < 0");
806     animation->setDuration(-1);
807     QCOMPARE(animation->duration(), 250);
808
809     QDeclarativePauseAnimation *pauseAnimation = new QDeclarativePauseAnimation;
810     QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML PauseAnimation: Cannot set a duration of < 0");
811     pauseAnimation->setDuration(-1);
812     QCOMPARE(pauseAnimation->duration(), 250);
813 }
814
815 void tst_qdeclarativeanimations::attached()
816 {
817     QDeclarativeEngine engine;
818
819     QDeclarativeComponent c(&engine, testFileUrl("attached.qml"));
820     QTest::ignoreMessage(QtDebugMsg, "off");
821     QTest::ignoreMessage(QtDebugMsg, "on");
822     QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
823     QVERIFY(rect);
824 }
825
826 void tst_qdeclarativeanimations::propertyValueSourceDefaultStart()
827 {
828     {
829         QDeclarativeEngine engine;
830
831         QDeclarativeComponent c(&engine, testFileUrl("valuesource.qml"));
832
833         QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
834         QVERIFY(rect);
835
836         QDeclarativeAbstractAnimation *myAnim = rect->findChild<QDeclarativeAbstractAnimation*>("MyAnim");
837         QVERIFY(myAnim);
838         QVERIFY(myAnim->isRunning());
839     }
840
841     {
842         QDeclarativeEngine engine;
843
844         QDeclarativeComponent c(&engine, testFileUrl("valuesource2.qml"));
845
846         QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
847         QVERIFY(rect);
848
849         QDeclarativeAbstractAnimation *myAnim = rect->findChild<QDeclarativeAbstractAnimation*>("MyAnim");
850         QVERIFY(myAnim);
851         QVERIFY(myAnim->isRunning() == false);
852     }
853
854     {
855         QDeclarativeEngine engine;
856
857         QDeclarativeComponent c(&engine, testFileUrl("dontAutoStart.qml"));
858
859         QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
860         QVERIFY(rect);
861
862         QDeclarativeAbstractAnimation *myAnim = rect->findChild<QDeclarativeAbstractAnimation*>("MyAnim");
863         QVERIFY(myAnim && myAnim->qtAnimation());
864         QVERIFY(myAnim->qtAnimation()->state() == QAbstractAnimation::Stopped);
865     }
866 }
867
868
869 void tst_qdeclarativeanimations::dontStart()
870 {
871     {
872         QDeclarativeEngine engine;
873
874         QDeclarativeComponent c(&engine, testFileUrl("dontStart.qml"));
875
876         QString warning = c.url().toString() + ":14:13: QML NumberAnimation: setRunning() cannot be used on non-root animation nodes.";
877         QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
878         QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
879         QVERIFY(rect);
880
881         QDeclarativeAbstractAnimation *myAnim = rect->findChild<QDeclarativeAbstractAnimation*>("MyAnim");
882         QVERIFY(myAnim && myAnim->qtAnimation());
883         QVERIFY(myAnim->qtAnimation()->state() == QAbstractAnimation::Stopped);
884     }
885
886     {
887         QDeclarativeEngine engine;
888
889         QDeclarativeComponent c(&engine, testFileUrl("dontStart2.qml"));
890
891         QString warning = c.url().toString() + ":15:17: QML NumberAnimation: setRunning() cannot be used on non-root animation nodes.";
892         QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
893         QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
894         QVERIFY(rect);
895
896         QDeclarativeAbstractAnimation *myAnim = rect->findChild<QDeclarativeAbstractAnimation*>("MyAnim");
897         QVERIFY(myAnim && myAnim->qtAnimation());
898         QVERIFY(myAnim->qtAnimation()->state() == QAbstractAnimation::Stopped);
899     }
900 }
901
902 void tst_qdeclarativeanimations::easingProperties()
903 {
904     {
905         QDeclarativeEngine engine;
906         QString componentStr = "import QtQuick 2.0\nNumberAnimation { easing.type: \"InOutQuad\" }";
907         QDeclarativeComponent animationComponent(&engine);
908         animationComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
909         QDeclarativePropertyAnimation *animObject = qobject_cast<QDeclarativePropertyAnimation*>(animationComponent.create());
910
911         QVERIFY(animObject != 0);
912         QCOMPARE(animObject->easing().type(), QEasingCurve::InOutQuad);
913     }
914
915     {
916         QDeclarativeEngine engine;
917         QString componentStr = "import QtQuick 2.0\nPropertyAnimation { easing.type: \"OutBounce\"; easing.amplitude: 5.0 }";
918         QDeclarativeComponent animationComponent(&engine);
919         animationComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
920         QDeclarativePropertyAnimation *animObject = qobject_cast<QDeclarativePropertyAnimation*>(animationComponent.create());
921
922         QVERIFY(animObject != 0);
923         QCOMPARE(animObject->easing().type(), QEasingCurve::OutBounce);
924         QCOMPARE(animObject->easing().amplitude(), 5.0);
925     }
926
927     {
928         QDeclarativeEngine engine;
929         QString componentStr = "import QtQuick 2.0\nPropertyAnimation { easing.type: \"OutElastic\"; easing.amplitude: 5.0; easing.period: 3.0}";
930         QDeclarativeComponent animationComponent(&engine);
931         animationComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
932         QDeclarativePropertyAnimation *animObject = qobject_cast<QDeclarativePropertyAnimation*>(animationComponent.create());
933
934         QVERIFY(animObject != 0);
935         QCOMPARE(animObject->easing().type(), QEasingCurve::OutElastic);
936         QCOMPARE(animObject->easing().amplitude(), 5.0);
937         QCOMPARE(animObject->easing().period(), 3.0);
938     }
939
940     {
941         QDeclarativeEngine engine;
942         QString componentStr = "import QtQuick 2.0\nPropertyAnimation { easing.type: \"InOutBack\"; easing.overshoot: 2 }";
943         QDeclarativeComponent animationComponent(&engine);
944         animationComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
945         QDeclarativePropertyAnimation *animObject = qobject_cast<QDeclarativePropertyAnimation*>(animationComponent.create());
946
947         QVERIFY(animObject != 0);
948         QCOMPARE(animObject->easing().type(), QEasingCurve::InOutBack);
949         QCOMPARE(animObject->easing().overshoot(), 2.0);
950     }
951
952     {
953         QDeclarativeEngine engine;
954         QString componentStr = "import QtQuick 2.0\nPropertyAnimation { easing.type: \"Bezier\"; easing.bezierCurve: [0.5, 0.2, 0.13, 0.65, 1.0, 1.0] }";
955         QDeclarativeComponent animationComponent(&engine);
956         animationComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
957         QDeclarativePropertyAnimation *animObject = qobject_cast<QDeclarativePropertyAnimation*>(animationComponent.create());
958
959         QVERIFY(animObject != 0);
960         QCOMPARE(animObject->easing().type(), QEasingCurve::BezierSpline);
961         QList<QPointF> points = animObject->easing().cubicBezierSpline();
962         QCOMPARE(points.count(), 3);
963         QCOMPARE(points.at(0), QPointF(0.5, 0.2));
964         QCOMPARE(points.at(1), QPointF(0.13, 0.65));
965         QCOMPARE(points.at(2), QPointF(1.0, 1.0));
966     }
967 }
968
969 void tst_qdeclarativeanimations::rotation()
970 {
971     QDeclarativeEngine engine;
972     QDeclarativeComponent c(&engine, testFileUrl("rotation.qml"));
973     QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
974     QVERIFY(rect);
975
976     QQuickRectangle *rr = rect->findChild<QQuickRectangle*>("rr");
977     QQuickRectangle *rr2 = rect->findChild<QQuickRectangle*>("rr2");
978     QQuickRectangle *rr3 = rect->findChild<QQuickRectangle*>("rr3");
979     QQuickRectangle *rr4 = rect->findChild<QQuickRectangle*>("rr4");
980
981     QQuickItemPrivate::get(rect)->setState("state1");
982     QTest::qWait(800);
983     qreal r1 = rr->rotation();
984     qreal r2 = rr2->rotation();
985     qreal r3 = rr3->rotation();
986     qreal r4 = rr4->rotation();
987
988     QVERIFY(r1 > qreal(0) && r1 < qreal(370));
989     QVERIFY(r2 > qreal(0) && r2 < qreal(370));
990     QVERIFY(r3 < qreal(0) && r3 > qreal(-350));
991     QVERIFY(r4 > qreal(0) && r4 < qreal(10));
992     QCOMPARE(r1,r2);
993     QVERIFY(r4 < r2);
994
995     QTest::qWait(800);
996     QTIMED_COMPARE(rr->rotation() + rr2->rotation() + rr3->rotation() + rr4->rotation(), qreal(370*4));
997 }
998
999 void tst_qdeclarativeanimations::runningTrueBug()
1000 {
1001     //ensure we start correctly when "running: true" is explicitly set
1002     QDeclarativeEngine engine;
1003     QDeclarativeComponent c(&engine, testFileUrl("runningTrueBug.qml"));
1004     QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
1005     QVERIFY(rect);
1006
1007     QQuickRectangle *cloud = rect->findChild<QQuickRectangle*>("cloud");
1008     QVERIFY(cloud);
1009     QTest::qWait(1000);
1010     QVERIFY(cloud->x() > qreal(0));
1011 }
1012
1013 //QTBUG-12805
1014 void tst_qdeclarativeanimations::nonTransitionBug()
1015 {
1016     //tests that the animation values from the previous transition are properly cleared
1017     //in the case where an animation in the transition doesn't match anything (but previously did)
1018     QDeclarativeEngine engine;
1019
1020     QDeclarativeComponent c(&engine, testFileUrl("nonTransitionBug.qml"));
1021     QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
1022     QVERIFY(rect != 0);
1023     QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
1024     QQuickRectangle *mover = rect->findChild<QQuickRectangle*>("mover");
1025
1026     mover->setX(100);
1027     QCOMPARE(mover->x(), qreal(100));
1028
1029     rectPrivate->setState("left");
1030     QTRY_COMPARE(mover->x(), qreal(0));
1031
1032     mover->setX(100);
1033     QCOMPARE(mover->x(), qreal(100));
1034
1035     //make sure we don't try to animate back to 0
1036     rectPrivate->setState("free");
1037     QTest::qWait(300);
1038     QCOMPARE(mover->x(), qreal(100));
1039 }
1040
1041 //QTBUG-14042
1042 void tst_qdeclarativeanimations::registrationBug()
1043 {
1044     QDeclarativeEngine engine;
1045
1046     QDeclarativeComponent c(&engine, testFileUrl("registrationBug.qml"));
1047     QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
1048     QVERIFY(rect != 0);
1049     QTRY_COMPARE(rect->property("value"), QVariant(int(100)));
1050 }
1051
1052 void tst_qdeclarativeanimations::doubleRegistrationBug()
1053 {
1054     QDeclarativeEngine engine;
1055
1056     QDeclarativeComponent c(&engine, testFileUrl("doubleRegistrationBug.qml"));
1057     QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
1058     QVERIFY(rect != 0);
1059
1060     QDeclarativeAbstractAnimation *anim = rect->findChild<QDeclarativeAbstractAnimation*>("animation");
1061     QVERIFY(anim != 0);
1062     QTRY_COMPARE(anim->qtAnimation()->state(), QAbstractAnimation::Stopped);
1063 }
1064
1065 //QTBUG-16736
1066 void tst_qdeclarativeanimations::alwaysRunToEndRestartBug()
1067 {
1068     QQuickRectangle rect;
1069     QDeclarativePropertyAnimation animation;
1070     animation.setTarget(&rect);
1071     animation.setProperty("x");
1072     animation.setTo(200);
1073     animation.setDuration(1000);
1074     animation.setLoops(-1);
1075     animation.setAlwaysRunToEnd(true);
1076     QVERIFY(animation.loops() == -1);
1077     QVERIFY(animation.alwaysRunToEnd() == true);
1078     animation.start();
1079     animation.stop();
1080     animation.start();
1081     animation.stop();
1082     QTest::qWait(500);
1083     QVERIFY(rect.x() != qreal(200));
1084     QTest::qWait(800);
1085     QTIMED_COMPARE(rect.x(), qreal(200));
1086     QCOMPARE(static_cast<QDeclarativeAbstractAnimation*>(&animation)->qtAnimation()->state(), QAbstractAnimation::Stopped);
1087 }
1088
1089 //QTBUG-20227
1090 void tst_qdeclarativeanimations::transitionAssignmentBug()
1091 {
1092     QDeclarativeEngine engine;
1093
1094     QDeclarativeComponent c(&engine, testFileUrl("transitionAssignmentBug.qml"));
1095     QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
1096     QVERIFY(rect != 0);
1097
1098     QCOMPARE(rect->property("nullObject").toBool(), false);
1099 }
1100
1101 //QTBUG-19080
1102 void tst_qdeclarativeanimations::pauseBindingBug()
1103 {
1104     QDeclarativeEngine engine;
1105
1106     QDeclarativeComponent c(&engine, testFileUrl("pauseBindingBug.qml"));
1107     QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
1108     QVERIFY(rect != 0);
1109     QDeclarativeAbstractAnimation *anim = rect->findChild<QDeclarativeAbstractAnimation*>("animation");
1110     QVERIFY(anim->qtAnimation()->state() == QAbstractAnimation::Paused);
1111
1112     delete rect;
1113 }
1114
1115 //QTBUG-13598
1116 void tst_qdeclarativeanimations::pauseBug()
1117 {
1118     QDeclarativeEngine engine;
1119
1120     QDeclarativeComponent c(&engine, testFileUrl("pauseBug.qml"));
1121     QDeclarativeAbstractAnimation *anim = qobject_cast<QDeclarativeAbstractAnimation*>(c.create());
1122     QVERIFY(anim != 0);
1123     QCOMPARE(anim->qtAnimation()->state(), QAbstractAnimation::Paused);
1124     QCOMPARE(anim->isPaused(), true);
1125     QCOMPARE(anim->isRunning(), true);
1126
1127     delete anim;
1128 }
1129
1130 QTEST_MAIN(tst_qdeclarativeanimations)
1131
1132 #include "tst_qdeclarativeanimations.moc"