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