1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the test suite of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
41 #include <QtTest/QtTest>
42 #include <QtDeclarative/qdeclarativeengine.h>
43 #include <QtDeclarative/qdeclarativecomponent.h>
44 #include <QtQuick/qquickview.h>
45 #include <QtDeclarative/private/qanimationgroupjob_p.h>
46 #include <QtQuick/private/qquickrectangle_p.h>
47 #include <QtQuick/private/qdeclarativeanimation_p.h>
48 #include <QtQuick/private/qdeclarativetransition_p.h>
49 #include <QtQuick/private/qquickanimation_p.h>
50 #include <QtQuick/private/qdeclarativepathinterpolator_p.h>
51 #include <QtQuick/private/qquickitem_p.h>
52 #include <QEasingCurve>
57 #include "../../shared/util.h"
59 class tst_qdeclarativeanimations : public QDeclarativeDataTest
63 tst_qdeclarativeanimations() {}
68 QDeclarativeEngine engine; // ensure types are registered
69 QDeclarativeDataTest::initTestCase();
72 void simpleProperty();
75 void simpleRotation();
79 void pathInterpolator();
80 void pathInterpolatorBackwardJump();
81 void pathWithNoStart();
82 void alwaysRunToEnd();
90 void propertiesTransition();
91 void pathTransition();
92 void disabledTransition();
93 void invalidDuration();
95 void propertyValueSourceDefaultStart();
97 void easingProperties();
99 void runningTrueBug();
100 void nonTransitionBug();
101 void registrationBug();
102 void doubleRegistrationBug();
103 void alwaysRunToEndRestartBug();
104 void transitionAssignmentBug();
105 void pauseBindingBug();
110 #define QTIMED_COMPARE(lhs, rhs) do { \
111 for (int ii = 0; ii < 5; ++ii) { \
116 QCOMPARE(lhs, rhs); \
119 void tst_qdeclarativeanimations::simpleProperty()
121 QQuickRectangle rect;
122 QDeclarativePropertyAnimation animation;
123 animation.setTargetObject(&rect);
124 animation.setProperty("x");
125 animation.setTo(200);
126 QVERIFY(animation.target() == &rect);
127 QVERIFY(animation.property() == "x");
128 QVERIFY(animation.to().toReal() == 200.0);
130 QVERIFY(animation.isRunning());
131 QTest::qWait(animation.duration());
132 QTIMED_COMPARE(rect.x(), 200.0);
134 rect.setPos(QPointF(0,0));
136 QVERIFY(animation.isRunning());
138 QVERIFY(animation.isPaused());
139 animation.setCurrentTime(125);
140 QVERIFY(animation.currentTime() == 125);
141 QCOMPARE(rect.x(),100.0);
144 void tst_qdeclarativeanimations::simpleNumber()
146 QQuickRectangle rect;
147 QDeclarativeNumberAnimation animation;
148 animation.setTargetObject(&rect);
149 animation.setProperty("x");
150 animation.setTo(200);
151 QVERIFY(animation.target() == &rect);
152 QVERIFY(animation.property() == "x");
153 QVERIFY(animation.to() == 200);
155 QVERIFY(animation.isRunning());
156 QTest::qWait(animation.duration());
157 QTIMED_COMPARE(rect.x(), qreal(200));
162 QVERIFY(animation.isRunning());
163 QVERIFY(animation.isPaused());
164 animation.setCurrentTime(125);
165 QVERIFY(animation.currentTime() == 125);
166 QCOMPARE(rect.x(), qreal(100));
169 void tst_qdeclarativeanimations::simpleColor()
171 QQuickRectangle rect;
172 QDeclarativeColorAnimation animation;
173 animation.setTargetObject(&rect);
174 animation.setProperty("color");
175 animation.setTo(QColor("red"));
176 QVERIFY(animation.target() == &rect);
177 QVERIFY(animation.property() == "color");
178 QVERIFY(animation.to() == QColor("red"));
180 QVERIFY(animation.isRunning());
181 QTest::qWait(animation.duration());
182 QTIMED_COMPARE(rect.color(), QColor("red"));
184 rect.setColor(QColor("blue"));
187 QVERIFY(animation.isRunning());
188 QVERIFY(animation.isPaused());
189 animation.setCurrentTime(125);
190 QVERIFY(animation.currentTime() == 125);
191 #if defined(UBUNTU_ONEIRIC) && defined(__x86_64__)
192 QEXPECT_FAIL("", "Fails on this platform - QTBUG-23385", Abort);
194 QCOMPARE(rect.color(), QColor::fromRgbF(0.498039, 0, 0.498039, 1));
196 rect.setColor(QColor("green"));
197 animation.setFrom(QColor("blue"));
198 QVERIFY(animation.from() == QColor("blue"));
200 QCOMPARE(rect.color(), QColor("blue"));
201 QVERIFY(animation.isRunning());
202 animation.setCurrentTime(125);
203 QCOMPARE(rect.color(), QColor::fromRgbF(0.498039, 0, 0.498039, 1));
206 void tst_qdeclarativeanimations::simpleRotation()
208 QQuickRectangle rect;
209 QDeclarativeRotationAnimation animation;
210 animation.setTargetObject(&rect);
211 animation.setProperty("rotation");
212 animation.setTo(270);
213 QVERIFY(animation.target() == &rect);
214 QVERIFY(animation.property() == "rotation");
215 QVERIFY(animation.to() == 270);
216 QVERIFY(animation.direction() == QDeclarativeRotationAnimation::Numerical);
218 QVERIFY(animation.isRunning());
219 QTest::qWait(animation.duration());
220 QTIMED_COMPARE(rect.rotation(), qreal(270));
225 QVERIFY(animation.isRunning());
226 QVERIFY(animation.isPaused());
227 animation.setCurrentTime(125);
228 QVERIFY(animation.currentTime() == 125);
229 QCOMPARE(rect.rotation(), qreal(135));
232 void tst_qdeclarativeanimations::simplePath()
235 QDeclarativeEngine engine;
236 QDeclarativeComponent c(&engine, testFileUrl("pathAnimation.qml"));
237 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
240 QQuickRectangle *redRect = rect->findChild<QQuickRectangle*>();
242 QQuickPathAnimation *pathAnim = rect->findChild<QQuickPathAnimation*>();
245 QCOMPARE(pathAnim->duration(), 100);
246 QCOMPARE(pathAnim->target(), redRect);
251 pathAnim->setCurrentTime(30);
252 QCOMPARE(redRect->x(), qreal(167));
253 QCOMPARE(redRect->y(), qreal(104));
255 pathAnim->setCurrentTime(100);
256 QCOMPARE(redRect->x(), qreal(300));
257 QCOMPARE(redRect->y(), qreal(300));
259 //verify animation runs to end
261 QCOMPARE(redRect->x(), qreal(50));
262 QCOMPARE(redRect->y(), qreal(50));
263 QTRY_COMPARE(redRect->x(), qreal(300));
264 QCOMPARE(redRect->y(), qreal(300));
266 pathAnim->setOrientation(QQuickPathAnimation::RightFirst);
267 QCOMPARE(pathAnim->orientation(), QQuickPathAnimation::RightFirst);
269 QTRY_VERIFY(redRect->rotation() != 0);
276 QDeclarativeEngine engine;
277 QDeclarativeComponent c(&engine, testFileUrl("pathAnimation2.qml"));
278 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
281 QQuickRectangle *redRect = rect->findChild<QQuickRectangle*>();
283 QQuickPathAnimation *pathAnim = rect->findChild<QQuickPathAnimation*>();
286 QCOMPARE(pathAnim->orientation(), QQuickPathAnimation::RightFirst);
287 QCOMPARE(pathAnim->endRotation(), qreal(0));
288 QCOMPARE(pathAnim->orientationEntryDuration(), 10);
289 QCOMPARE(pathAnim->orientationExitDuration(), 10);
293 QCOMPARE(redRect->x(), qreal(50));
294 QCOMPARE(redRect->y(), qreal(50));
295 QCOMPARE(redRect->rotation(), qreal(-360));
297 pathAnim->setCurrentTime(50);
298 QCOMPARE(redRect->x(), qreal(175));
299 QCOMPARE(redRect->y(), qreal(175));
300 QCOMPARE(redRect->rotation(), qreal(-315));
302 pathAnim->setCurrentTime(100);
303 QCOMPARE(redRect->x(), qreal(300));
304 QCOMPARE(redRect->y(), qreal(300));
305 QCOMPARE(redRect->rotation(), qreal(0));
311 void tst_qdeclarativeanimations::simpleAnchor()
313 QDeclarativeEngine engine;
314 QDeclarativeComponent c(&engine, testFileUrl("reanchor.qml"));
315 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
318 QQuickRectangle *greenRect = rect->findChild<QQuickRectangle*>();
321 QCOMPARE(rect->state(), QLatin1String("reanchored"));
322 QCOMPARE(greenRect->x(), qreal(10));
323 QCOMPARE(greenRect->y(), qreal(0));
324 QCOMPARE(greenRect->width(), qreal(190));
325 QCOMPARE(greenRect->height(), qreal(150));
329 //verify animation in progress
330 QTRY_VERIFY(greenRect->x() < 10 && greenRect->x() > 0);
331 QVERIFY(greenRect->y() > 0 && greenRect->y() < 10);
332 QVERIFY(greenRect->width() < 190 && greenRect->width() > 150);
333 QVERIFY(greenRect->height() > 150 && greenRect->height() < 190);
335 //verify end state ("")
336 QTRY_COMPARE(greenRect->x(), qreal(0));
337 QCOMPARE(greenRect->y(), qreal(10));
338 QCOMPARE(greenRect->width(), qreal(150));
339 QCOMPARE(greenRect->height(), qreal(190));
341 rect->setState("reanchored2");
343 //verify animation in progress
344 QTRY_VERIFY(greenRect->y() > 10 && greenRect->y() < 50);
345 QVERIFY(greenRect->height() > 125 && greenRect->height() < 190);
346 //NOTE: setting left/right anchors to undefined removes the anchors, but does not resize.
347 QCOMPARE(greenRect->x(), qreal(0));
348 QCOMPARE(greenRect->width(), qreal(150));
350 //verify end state ("reanchored2")
351 QTRY_COMPARE(greenRect->y(), qreal(50));
352 QCOMPARE(greenRect->height(), qreal(125));
353 QCOMPARE(greenRect->x(), qreal(0));
354 QCOMPARE(greenRect->width(), qreal(150));
356 rect->setState("reanchored");
358 //verify animation in progress
359 QTRY_VERIFY(greenRect->x() < 10 && greenRect->x() > 0);
360 QVERIFY(greenRect->y() > 0 && greenRect->y() < 50);
361 QVERIFY(greenRect->width() < 190 && greenRect->width() > 150);
362 QVERIFY(greenRect->height() > 125 && greenRect->height() < 150);
364 //verify end state ("reanchored")
365 QTRY_COMPARE(greenRect->x(), qreal(10));
366 QCOMPARE(greenRect->y(), qreal(0));
367 QCOMPARE(greenRect->width(), qreal(190));
368 QCOMPARE(greenRect->height(), qreal(150));
370 rect->setState("reanchored2");
372 //verify animation in progress
373 QTRY_VERIFY(greenRect->x() < 10 && greenRect->x() > 0);
374 QVERIFY(greenRect->y() > 0 && greenRect->y() < 50);
375 QVERIFY(greenRect->width() < 190 && greenRect->width() > 150);
376 QVERIFY(greenRect->height() > 125 && greenRect->height() < 150);
378 //verify end state ("reanchored2")
379 QTRY_COMPARE(greenRect->x(), qreal(0));
380 QCOMPARE(greenRect->y(), qreal(50));
381 QCOMPARE(greenRect->width(), qreal(150));
382 QCOMPARE(greenRect->height(), qreal(125));
387 void tst_qdeclarativeanimations::reparent()
389 QDeclarativeEngine engine;
390 QDeclarativeComponent c(&engine, testFileUrl("reparent.qml"));
391 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
394 QQuickRectangle *target = rect->findChild<QQuickRectangle*>("target");
397 QCOMPARE(target->parentItem(), rect);
398 QCOMPARE(target->x(), qreal(0));
399 QCOMPARE(target->y(), qreal(0));
400 QCOMPARE(target->width(), qreal(50));
401 QCOMPARE(target->height(), qreal(50));
402 QCOMPARE(target->rotation(), qreal(0));
403 QCOMPARE(target->scale(), qreal(1));
405 rect->setState("state1");
407 QQuickRectangle *viaParent = rect->findChild<QQuickRectangle*>("viaParent");
410 QQuickRectangle *newParent = rect->findChild<QQuickRectangle*>("newParent");
415 //animation in progress
416 QTRY_COMPARE(target->parentItem(), viaParent);
417 QVERIFY(target->x() > -100 && target->x() < 50);
418 QVERIFY(target->y() > -100 && target->y() < 50);
419 QVERIFY(target->width() > 50 && target->width() < 100);
420 QCOMPARE(target->height(), qreal(50));
421 QCOMPARE(target->rotation(), qreal(-45));
422 QCOMPARE(target->scale(), qreal(.5));
425 QTRY_COMPARE(target->parentItem(), newParent);
426 QCOMPARE(target->x(), qreal(50));
427 QCOMPARE(target->y(), qreal(50));
428 QCOMPARE(target->width(), qreal(100));
429 QCOMPARE(target->height(), qreal(50));
430 QCOMPARE(target->rotation(), qreal(0));
431 QCOMPARE(target->scale(), qreal(1));
436 void tst_qdeclarativeanimations::pathInterpolator()
438 QDeclarativeEngine engine;
439 QDeclarativeComponent c(&engine, testFileUrl("pathInterpolator.qml"));
440 QDeclarativePathInterpolator *interpolator = qobject_cast<QDeclarativePathInterpolator*>(c.create());
441 QVERIFY(interpolator);
443 QCOMPARE(interpolator->progress(), qreal(0));
444 QCOMPARE(interpolator->x(), qreal(50));
445 QCOMPARE(interpolator->y(), qreal(50));
446 QCOMPARE(interpolator->angle(), qreal(0));
448 interpolator->setProgress(.5);
449 QCOMPARE(interpolator->progress(), qreal(.5));
450 QCOMPARE(interpolator->x(), qreal(175));
451 QCOMPARE(interpolator->y(), qreal(175));
452 QCOMPARE(interpolator->angle(), qreal(90));
454 interpolator->setProgress(1);
455 QCOMPARE(interpolator->progress(), qreal(1));
456 QCOMPARE(interpolator->x(), qreal(300));
457 QCOMPARE(interpolator->y(), qreal(300));
458 QCOMPARE(interpolator->angle(), qreal(0));
461 void tst_qdeclarativeanimations::pathInterpolatorBackwardJump()
464 QDeclarativeEngine engine;
465 QDeclarativeComponent c(&engine, testFileUrl("pathInterpolatorBack.qml"));
466 QDeclarativePathInterpolator *interpolator = qobject_cast<QDeclarativePathInterpolator*>(c.create());
467 QVERIFY(interpolator);
469 QCOMPARE(interpolator->progress(), qreal(0));
470 QCOMPARE(interpolator->x(), qreal(50));
471 QCOMPARE(interpolator->y(), qreal(50));
472 QCOMPARE(interpolator->angle(), qreal(90));
474 interpolator->setProgress(.5);
475 QCOMPARE(interpolator->progress(), qreal(.5));
476 QCOMPARE(interpolator->x(), qreal(100));
477 QCOMPARE(interpolator->y(), qreal(75));
478 QCOMPARE(interpolator->angle(), qreal(270));
480 interpolator->setProgress(1);
481 QCOMPARE(interpolator->progress(), qreal(1));
482 QCOMPARE(interpolator->x(), qreal(200));
483 QCOMPARE(interpolator->y(), qreal(50));
484 QCOMPARE(interpolator->angle(), qreal(0));
486 //make sure we don't get caught in infinite loop here
487 interpolator->setProgress(0);
488 QCOMPARE(interpolator->progress(), qreal(0));
489 QCOMPARE(interpolator->x(), qreal(50));
490 QCOMPARE(interpolator->y(), qreal(50));
491 QCOMPARE(interpolator->angle(), qreal(90));
495 QDeclarativeEngine engine;
496 QDeclarativeComponent c(&engine, testFileUrl("pathInterpolatorBack2.qml"));
497 QDeclarativePathInterpolator *interpolator = qobject_cast<QDeclarativePathInterpolator*>(c.create());
498 QVERIFY(interpolator);
500 QCOMPARE(interpolator->progress(), qreal(0));
501 QCOMPARE(interpolator->x(), qreal(200));
502 QCOMPARE(interpolator->y(), qreal(280));
503 QCOMPARE(interpolator->angle(), qreal(180));
505 interpolator->setProgress(1);
506 QCOMPARE(interpolator->progress(), qreal(1));
507 QCOMPARE(interpolator->x(), qreal(0));
508 QCOMPARE(interpolator->y(), qreal(80));
509 QCOMPARE(interpolator->angle(), qreal(180));
511 //make sure we don't get caught in infinite loop here
512 interpolator->setProgress(0);
513 QCOMPARE(interpolator->progress(), qreal(0));
514 QCOMPARE(interpolator->x(), qreal(200));
515 QCOMPARE(interpolator->y(), qreal(280));
516 QCOMPARE(interpolator->angle(), qreal(180));
520 void tst_qdeclarativeanimations::pathWithNoStart()
522 QDeclarativeEngine engine;
523 QDeclarativeComponent c(&engine, testFileUrl("pathAnimationNoStart.qml"));
524 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
527 QQuickRectangle *redRect = rect->findChild<QQuickRectangle*>();
529 QQuickPathAnimation *pathAnim = rect->findChild<QQuickPathAnimation*>();
534 QCOMPARE(redRect->x(), qreal(50));
535 QCOMPARE(redRect->y(), qreal(50));
537 pathAnim->setCurrentTime(50);
538 QCOMPARE(redRect->x(), qreal(175));
539 QCOMPARE(redRect->y(), qreal(175));
541 pathAnim->setCurrentTime(100);
542 QCOMPARE(redRect->x(), qreal(300));
543 QCOMPARE(redRect->y(), qreal(300));
548 QCOMPARE(redRect->x(), qreal(100));
549 QCOMPARE(redRect->y(), qreal(100));
550 QTRY_COMPARE(redRect->x(), qreal(300));
551 QCOMPARE(redRect->y(), qreal(300));
554 void tst_qdeclarativeanimations::alwaysRunToEnd()
556 QQuickRectangle rect;
557 QDeclarativePropertyAnimation animation;
558 animation.setTargetObject(&rect);
559 animation.setProperty("x");
560 animation.setTo(200);
561 animation.setDuration(1000);
562 animation.setLoops(-1);
563 animation.setAlwaysRunToEnd(true);
564 QVERIFY(animation.loops() == -1);
565 QVERIFY(animation.alwaysRunToEnd() == true);
569 QVERIFY(rect.x() != qreal(200));
571 QTIMED_COMPARE(rect.x(), qreal(200));
574 void tst_qdeclarativeanimations::complete()
576 QQuickRectangle rect;
577 QDeclarativePropertyAnimation animation;
578 animation.setTargetObject(&rect);
579 animation.setProperty("x");
580 animation.setFrom(1);
581 animation.setTo(200);
582 animation.setDuration(500);
583 QVERIFY(animation.from() == 1);
587 QVERIFY(rect.x() != qreal(200));
590 QVERIFY(animation.isRunning());
591 animation.complete();
592 QCOMPARE(rect.x(), qreal(200));
595 void tst_qdeclarativeanimations::resume()
597 QQuickRectangle rect;
598 QDeclarativePropertyAnimation animation;
599 animation.setTargetObject(&rect);
600 animation.setProperty("x");
601 animation.setFrom(10);
602 animation.setTo(200);
603 animation.setDuration(1000);
604 QVERIFY(animation.from() == 10);
610 QVERIFY(x != qreal(200) && x != qreal(10));
611 QVERIFY(animation.isRunning());
612 QVERIFY(animation.isPaused());
615 QVERIFY(animation.isRunning());
616 QVERIFY(!animation.isPaused());
619 QVERIFY(rect.x() > x);
622 void tst_qdeclarativeanimations::dotProperty()
624 QQuickRectangle rect;
625 QDeclarativeNumberAnimation animation;
626 animation.setTargetObject(&rect);
627 animation.setProperty("border.width");
630 QTest::qWait(animation.duration()+50);
631 QTIMED_COMPARE(rect.border()->width(), 10.0);
633 rect.border()->setWidth(0);
636 animation.setCurrentTime(125);
637 QVERIFY(animation.currentTime() == 125);
638 QCOMPARE(rect.border()->width(), 5.0);
641 void tst_qdeclarativeanimations::badTypes()
645 QQuickView *view = new QQuickView;
646 view->setSource(testFileUrl("badtype1.qml"));
648 qApp->processEvents();
653 //make sure we get a compiler error
655 QDeclarativeEngine engine;
656 QDeclarativeComponent c(&engine, testFileUrl("badtype2.qml"));
657 QTest::ignoreMessage(QtWarningMsg, "QDeclarativeComponent: Component is not ready");
660 QVERIFY(c.errors().count() == 1);
661 QCOMPARE(c.errors().at(0).description(), QLatin1String("Invalid property assignment: number expected"));
664 //make sure we get a compiler error
666 QDeclarativeEngine engine;
667 QDeclarativeComponent c(&engine, testFileUrl("badtype3.qml"));
668 QTest::ignoreMessage(QtWarningMsg, "QDeclarativeComponent: Component is not ready");
671 QVERIFY(c.errors().count() == 1);
672 QCOMPARE(c.errors().at(0).description(), QLatin1String("Invalid property assignment: color expected"));
677 QDeclarativeEngine engine;
678 QDeclarativeComponent c(&engine, testFileUrl("badtype4.qml"));
679 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
682 QQuickItemPrivate::get(rect)->setState("state1");
683 QTest::qWait(1000 + 50);
684 QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("MyRect");
686 QCOMPARE(myRect->x(),qreal(200));
690 void tst_qdeclarativeanimations::badProperties()
692 //make sure we get a runtime error
694 QDeclarativeEngine engine;
696 QDeclarativeComponent c1(&engine, testFileUrl("badproperty1.qml"));
697 QByteArray message = testFileUrl("badproperty1.qml").toString().toUtf8() + ":18:9: QML ColorAnimation: Cannot animate non-existent property \"border.colr\"";
698 QTest::ignoreMessage(QtWarningMsg, message);
699 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c1.create());
702 QDeclarativeComponent c2(&engine, testFileUrl("badproperty2.qml"));
703 message = testFileUrl("badproperty2.qml").toString().toUtf8() + ":18:9: QML ColorAnimation: Cannot animate read-only property \"border\"";
704 QTest::ignoreMessage(QtWarningMsg, message);
705 rect = qobject_cast<QQuickRectangle*>(c2.create());
708 //### should we warn here are well?
709 //rect->setState("state1");
713 //test animating mixed types with property animation in a transition
714 //for example, int + real; color + real; etc
715 void tst_qdeclarativeanimations::mixedTypes()
717 //assumes border.width stays a real -- not real robust
719 QDeclarativeEngine engine;
720 QDeclarativeComponent c(&engine, testFileUrl("mixedtype1.qml"));
721 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
724 QQuickItemPrivate::get(rect)->setState("state1");
726 QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("MyRect");
729 //rather inexact -- is there a better way?
730 QVERIFY(myRect->x() > 100 && myRect->x() < 200);
731 QVERIFY(myRect->border()->width() > 1 && myRect->border()->width() < 10);
735 QDeclarativeEngine engine;
736 QDeclarativeComponent c(&engine, testFileUrl("mixedtype2.qml"));
737 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
740 QQuickItemPrivate::get(rect)->setState("state1");
742 QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("MyRect");
745 //rather inexact -- is there a better way?
746 QVERIFY(myRect->x() > 100 && myRect->x() < 200);
747 #if defined(UBUNTU_ONEIRIC) && defined(__x86_64__)
748 QEXPECT_FAIL("", "Fails on this platform - QTBUG-23385", Continue);
750 QVERIFY(myRect->color() != QColor("red") && myRect->color() != QColor("blue"));
754 void tst_qdeclarativeanimations::properties()
756 const int waitDuration = 300;
758 QDeclarativeEngine engine;
759 QDeclarativeComponent c(&engine, testFileUrl("properties.qml"));
760 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
763 QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
765 QTest::qWait(waitDuration);
766 QTIMED_COMPARE(myRect->x(),qreal(200));
770 QDeclarativeEngine engine;
771 QDeclarativeComponent c(&engine, testFileUrl("properties2.qml"));
772 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
775 QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
777 QTest::qWait(waitDuration);
778 QTIMED_COMPARE(myRect->x(),qreal(200));
782 QDeclarativeEngine engine;
783 QDeclarativeComponent c(&engine, testFileUrl("properties3.qml"));
784 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
787 QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
789 QTest::qWait(waitDuration);
790 QTIMED_COMPARE(myRect->x(),qreal(300));
794 QDeclarativeEngine engine;
795 QDeclarativeComponent c(&engine, testFileUrl("properties4.qml"));
796 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
799 QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
801 QTest::qWait(waitDuration);
802 QTIMED_COMPARE(myRect->y(),qreal(200));
803 QTIMED_COMPARE(myRect->x(),qreal(100));
807 QDeclarativeEngine engine;
808 QDeclarativeComponent c(&engine, testFileUrl("properties5.qml"));
809 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
812 QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
814 QTest::qWait(waitDuration);
815 QTIMED_COMPARE(myRect->x(),qreal(100));
816 QTIMED_COMPARE(myRect->y(),qreal(200));
820 void tst_qdeclarativeanimations::propertiesTransition()
822 const int waitDuration = 300;
824 QDeclarativeEngine engine;
825 QDeclarativeComponent c(&engine, testFileUrl("propertiesTransition.qml"));
826 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
829 QQuickItemPrivate::get(rect)->setState("moved");
830 QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
832 QTest::qWait(waitDuration);
833 QTIMED_COMPARE(myRect->x(),qreal(200));
837 QDeclarativeEngine engine;
838 QDeclarativeComponent c(&engine, testFileUrl("propertiesTransition2.qml"));
839 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
842 QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
844 QQuickItemPrivate::get(rect)->setState("moved");
845 QCOMPARE(myRect->x(),qreal(200));
846 QCOMPARE(myRect->y(),qreal(100));
847 QTest::qWait(waitDuration);
848 QTIMED_COMPARE(myRect->y(),qreal(200));
852 QDeclarativeEngine engine;
853 QDeclarativeComponent c(&engine, testFileUrl("propertiesTransition3.qml"));
854 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
857 QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
859 QQuickItemPrivate::get(rect)->setState("moved");
860 QCOMPARE(myRect->x(),qreal(200));
861 QCOMPARE(myRect->y(),qreal(100));
865 QDeclarativeEngine engine;
866 QDeclarativeComponent c(&engine, testFileUrl("propertiesTransition4.qml"));
867 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
870 QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
872 QQuickItemPrivate::get(rect)->setState("moved");
873 QCOMPARE(myRect->x(),qreal(100));
874 QTest::qWait(waitDuration);
875 QTIMED_COMPARE(myRect->x(),qreal(200));
879 QDeclarativeEngine engine;
880 QDeclarativeComponent c(&engine, testFileUrl("propertiesTransition5.qml"));
881 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
884 QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
886 QQuickItemPrivate::get(rect)->setState("moved");
887 QCOMPARE(myRect->x(),qreal(100));
888 QTest::qWait(waitDuration);
889 QTIMED_COMPARE(myRect->x(),qreal(200));
893 QDeclarativeEngine engine;
894 QDeclarativeComponent c(&engine, testFileUrl("propertiesTransition6.qml"));
895 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
898 QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
900 QQuickItemPrivate::get(rect)->setState("moved");
901 QCOMPARE(myRect->x(),qreal(100));
902 QTest::qWait(waitDuration);
903 QTIMED_COMPARE(myRect->x(),qreal(100));
907 QDeclarativeEngine engine;
908 QDeclarativeComponent c(&engine, testFileUrl("propertiesTransition7.qml"));
909 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
912 QQuickItemPrivate::get(rect)->setState("moved");
913 QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
915 QTest::qWait(waitDuration);
916 QTIMED_COMPARE(myRect->x(),qreal(200));
921 void tst_qdeclarativeanimations::pathTransition()
923 QDeclarativeEngine engine;
924 QDeclarativeComponent c(&engine, testFileUrl("pathTransition.qml"));
925 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
928 QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("redRect");
931 QQuickItemPrivate::get(rect)->setState("moved");
932 QTRY_VERIFY(myRect->x() < 500 && myRect->x() > 100 && myRect->y() > 50 && myRect->y() < 700 ); //animation started
933 QTRY_VERIFY(qFuzzyCompare(myRect->x(), qreal(100)) && qFuzzyCompare(myRect->y(), qreal(700)));
936 QQuickItemPrivate::get(rect)->setState("");
937 QTRY_VERIFY(myRect->x() < 500 && myRect->x() > 100 && myRect->y() > 50 && myRect->y() < 700 ); //animation started
938 QTRY_VERIFY(qFuzzyCompare(myRect->x(), qreal(500)) && qFuzzyCompare(myRect->y(), qreal(50)));
941 void tst_qdeclarativeanimations::disabledTransition()
943 QDeclarativeEngine engine;
944 QDeclarativeComponent c(&engine, testFileUrl("disabledTransition.qml"));
945 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
948 QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
951 QDeclarativeTransition *trans = rect->findChild<QDeclarativeTransition*>();
954 QCOMPARE(trans->enabled(), false);
956 QQuickItemPrivate::get(rect)->setState("moved");
957 QCOMPARE(myRect->x(),qreal(200));
959 trans->setEnabled(true);
961 QQuickItemPrivate::get(rect)->setState("");
962 QCOMPARE(myRect->x(),qreal(200));
964 QTIMED_COMPARE(myRect->x(),qreal(100));
967 void tst_qdeclarativeanimations::invalidDuration()
969 QDeclarativePropertyAnimation *animation = new QDeclarativePropertyAnimation;
970 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML PropertyAnimation: Cannot set a duration of < 0");
971 animation->setDuration(-1);
972 QCOMPARE(animation->duration(), 250);
974 QDeclarativePauseAnimation *pauseAnimation = new QDeclarativePauseAnimation;
975 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML PauseAnimation: Cannot set a duration of < 0");
976 pauseAnimation->setDuration(-1);
977 QCOMPARE(pauseAnimation->duration(), 250);
980 void tst_qdeclarativeanimations::attached()
982 QDeclarativeEngine engine;
984 QDeclarativeComponent c(&engine, testFileUrl("attached.qml"));
985 QTest::ignoreMessage(QtDebugMsg, "off");
986 QTest::ignoreMessage(QtDebugMsg, "on");
987 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
991 void tst_qdeclarativeanimations::propertyValueSourceDefaultStart()
994 QDeclarativeEngine engine;
996 QDeclarativeComponent c(&engine, testFileUrl("valuesource.qml"));
998 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
1001 QDeclarativeAbstractAnimation *myAnim = rect->findChild<QDeclarativeAbstractAnimation*>("MyAnim");
1003 QVERIFY(myAnim->isRunning());
1007 QDeclarativeEngine engine;
1009 QDeclarativeComponent c(&engine, testFileUrl("valuesource2.qml"));
1011 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
1014 QDeclarativeAbstractAnimation *myAnim = rect->findChild<QDeclarativeAbstractAnimation*>("MyAnim");
1016 QVERIFY(myAnim->isRunning() == false);
1020 QDeclarativeEngine engine;
1022 QDeclarativeComponent c(&engine, testFileUrl("dontAutoStart.qml"));
1024 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
1027 QDeclarativeAbstractAnimation *myAnim = rect->findChild<QDeclarativeAbstractAnimation*>("MyAnim");
1028 QVERIFY(myAnim && !myAnim->qtAnimation());
1029 //QVERIFY(myAnim->qtAnimation()->state() == QAbstractAnimationJob::Stopped);
1034 void tst_qdeclarativeanimations::dontStart()
1037 QDeclarativeEngine engine;
1039 QDeclarativeComponent c(&engine, testFileUrl("dontStart.qml"));
1041 QString warning = c.url().toString() + ":14:13: QML NumberAnimation: setRunning() cannot be used on non-root animation nodes.";
1042 QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
1043 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
1046 QDeclarativeAbstractAnimation *myAnim = rect->findChild<QDeclarativeAbstractAnimation*>("MyAnim");
1047 QVERIFY(myAnim && !myAnim->qtAnimation());
1048 //QVERIFY(myAnim->qtAnimation()->state() == QAbstractAnimationJob::Stopped);
1052 QDeclarativeEngine engine;
1054 QDeclarativeComponent c(&engine, testFileUrl("dontStart2.qml"));
1056 QString warning = c.url().toString() + ":15:17: QML NumberAnimation: setRunning() cannot be used on non-root animation nodes.";
1057 QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
1058 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
1061 QDeclarativeAbstractAnimation *myAnim = rect->findChild<QDeclarativeAbstractAnimation*>("MyAnim");
1062 QVERIFY(myAnim && !myAnim->qtAnimation());
1063 //QVERIFY(myAnim->qtAnimation()->state() == QAbstractAnimationJob::Stopped);
1067 void tst_qdeclarativeanimations::easingProperties()
1070 QDeclarativeEngine engine;
1071 QString componentStr = "import QtQuick 2.0\nNumberAnimation { easing.type: \"InOutQuad\" }";
1072 QDeclarativeComponent animationComponent(&engine);
1073 animationComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1074 QDeclarativePropertyAnimation *animObject = qobject_cast<QDeclarativePropertyAnimation*>(animationComponent.create());
1076 QVERIFY(animObject != 0);
1077 QCOMPARE(animObject->easing().type(), QEasingCurve::InOutQuad);
1081 QDeclarativeEngine engine;
1082 QString componentStr = "import QtQuick 2.0\nPropertyAnimation { easing.type: \"OutBounce\"; easing.amplitude: 5.0 }";
1083 QDeclarativeComponent animationComponent(&engine);
1084 animationComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1085 QDeclarativePropertyAnimation *animObject = qobject_cast<QDeclarativePropertyAnimation*>(animationComponent.create());
1087 QVERIFY(animObject != 0);
1088 QCOMPARE(animObject->easing().type(), QEasingCurve::OutBounce);
1089 QCOMPARE(animObject->easing().amplitude(), 5.0);
1093 QDeclarativeEngine engine;
1094 QString componentStr = "import QtQuick 2.0\nPropertyAnimation { easing.type: \"OutElastic\"; easing.amplitude: 5.0; easing.period: 3.0}";
1095 QDeclarativeComponent animationComponent(&engine);
1096 animationComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1097 QDeclarativePropertyAnimation *animObject = qobject_cast<QDeclarativePropertyAnimation*>(animationComponent.create());
1099 QVERIFY(animObject != 0);
1100 QCOMPARE(animObject->easing().type(), QEasingCurve::OutElastic);
1101 QCOMPARE(animObject->easing().amplitude(), 5.0);
1102 QCOMPARE(animObject->easing().period(), 3.0);
1106 QDeclarativeEngine engine;
1107 QString componentStr = "import QtQuick 2.0\nPropertyAnimation { easing.type: \"InOutBack\"; easing.overshoot: 2 }";
1108 QDeclarativeComponent animationComponent(&engine);
1109 animationComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1110 QDeclarativePropertyAnimation *animObject = qobject_cast<QDeclarativePropertyAnimation*>(animationComponent.create());
1112 QVERIFY(animObject != 0);
1113 QCOMPARE(animObject->easing().type(), QEasingCurve::InOutBack);
1114 QCOMPARE(animObject->easing().overshoot(), 2.0);
1118 QDeclarativeEngine engine;
1119 QString componentStr = "import QtQuick 2.0\nPropertyAnimation { easing.type: \"Bezier\"; easing.bezierCurve: [0.5, 0.2, 0.13, 0.65, 1.0, 1.0] }";
1120 QDeclarativeComponent animationComponent(&engine);
1121 animationComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1122 QDeclarativePropertyAnimation *animObject = qobject_cast<QDeclarativePropertyAnimation*>(animationComponent.create());
1124 QVERIFY(animObject != 0);
1125 QCOMPARE(animObject->easing().type(), QEasingCurve::BezierSpline);
1126 QList<QPointF> points = animObject->easing().cubicBezierSpline();
1127 QCOMPARE(points.count(), 3);
1128 QCOMPARE(points.at(0), QPointF(0.5, 0.2));
1129 QCOMPARE(points.at(1), QPointF(0.13, 0.65));
1130 QCOMPARE(points.at(2), QPointF(1.0, 1.0));
1134 void tst_qdeclarativeanimations::rotation()
1136 QDeclarativeEngine engine;
1137 QDeclarativeComponent c(&engine, testFileUrl("rotation.qml"));
1138 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
1141 QQuickRectangle *rr = rect->findChild<QQuickRectangle*>("rr");
1142 QQuickRectangle *rr2 = rect->findChild<QQuickRectangle*>("rr2");
1143 QQuickRectangle *rr3 = rect->findChild<QQuickRectangle*>("rr3");
1144 QQuickRectangle *rr4 = rect->findChild<QQuickRectangle*>("rr4");
1146 QQuickItemPrivate::get(rect)->setState("state1");
1148 qreal r1 = rr->rotation();
1149 qreal r2 = rr2->rotation();
1150 qreal r3 = rr3->rotation();
1151 qreal r4 = rr4->rotation();
1153 QVERIFY(r1 > qreal(0) && r1 < qreal(370));
1154 QVERIFY(r2 > qreal(0) && r2 < qreal(370));
1155 QVERIFY(r3 < qreal(0) && r3 > qreal(-350));
1156 QVERIFY(r4 > qreal(0) && r4 < qreal(10));
1161 QTIMED_COMPARE(rr->rotation() + rr2->rotation() + rr3->rotation() + rr4->rotation(), qreal(370*4));
1164 void tst_qdeclarativeanimations::runningTrueBug()
1166 //ensure we start correctly when "running: true" is explicitly set
1167 QDeclarativeEngine engine;
1168 QDeclarativeComponent c(&engine, testFileUrl("runningTrueBug.qml"));
1169 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
1172 QQuickRectangle *cloud = rect->findChild<QQuickRectangle*>("cloud");
1175 QVERIFY(cloud->x() > qreal(0));
1179 void tst_qdeclarativeanimations::nonTransitionBug()
1181 //tests that the animation values from the previous transition are properly cleared
1182 //in the case where an animation in the transition doesn't match anything (but previously did)
1183 QDeclarativeEngine engine;
1185 QDeclarativeComponent c(&engine, testFileUrl("nonTransitionBug.qml"));
1186 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
1188 QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
1189 QQuickRectangle *mover = rect->findChild<QQuickRectangle*>("mover");
1192 QCOMPARE(mover->x(), qreal(100));
1194 rectPrivate->setState("left");
1195 QTRY_COMPARE(mover->x(), qreal(0));
1198 QCOMPARE(mover->x(), qreal(100));
1200 //make sure we don't try to animate back to 0
1201 rectPrivate->setState("free");
1203 QCOMPARE(mover->x(), qreal(100));
1207 void tst_qdeclarativeanimations::registrationBug()
1209 QDeclarativeEngine engine;
1211 QDeclarativeComponent c(&engine, testFileUrl("registrationBug.qml"));
1212 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
1214 QTRY_COMPARE(rect->property("value"), QVariant(int(100)));
1217 void tst_qdeclarativeanimations::doubleRegistrationBug()
1219 QDeclarativeEngine engine;
1221 QDeclarativeComponent c(&engine, testFileUrl("doubleRegistrationBug.qml"));
1222 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
1225 QDeclarativeAbstractAnimation *anim = rect->findChild<QDeclarativeAbstractAnimation*>("animation");
1227 QTRY_COMPARE(anim->qtAnimation()->state(), QAbstractAnimationJob::Stopped);
1231 void tst_qdeclarativeanimations::alwaysRunToEndRestartBug()
1233 QQuickRectangle rect;
1234 QDeclarativePropertyAnimation animation;
1235 animation.setTargetObject(&rect);
1236 animation.setProperty("x");
1237 animation.setTo(200);
1238 animation.setDuration(1000);
1239 animation.setLoops(-1);
1240 animation.setAlwaysRunToEnd(true);
1241 QVERIFY(animation.loops() == -1);
1242 QVERIFY(animation.alwaysRunToEnd() == true);
1248 QVERIFY(rect.x() != qreal(200));
1250 QTIMED_COMPARE(rect.x(), qreal(200));
1251 QCOMPARE(static_cast<QDeclarativeAbstractAnimation*>(&animation)->qtAnimation()->state(), QAbstractAnimationJob::Stopped);
1255 void tst_qdeclarativeanimations::transitionAssignmentBug()
1257 QDeclarativeEngine engine;
1259 QDeclarativeComponent c(&engine, testFileUrl("transitionAssignmentBug.qml"));
1260 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
1263 QCOMPARE(rect->property("nullObject").toBool(), false);
1267 void tst_qdeclarativeanimations::pauseBindingBug()
1269 QDeclarativeEngine engine;
1271 QDeclarativeComponent c(&engine, testFileUrl("pauseBindingBug.qml"));
1272 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
1274 QDeclarativeAbstractAnimation *anim = rect->findChild<QDeclarativeAbstractAnimation*>("animation");
1275 QVERIFY(anim->qtAnimation()->state() == QAbstractAnimationJob::Paused);
1281 void tst_qdeclarativeanimations::pauseBug()
1283 QDeclarativeEngine engine;
1285 QDeclarativeComponent c(&engine, testFileUrl("pauseBug.qml"));
1286 QDeclarativeAbstractAnimation *anim = qobject_cast<QDeclarativeAbstractAnimation*>(c.create());
1288 QCOMPARE(anim->qtAnimation()->state(), QAbstractAnimationJob::Paused);
1289 QCOMPARE(anim->isPaused(), true);
1290 QCOMPARE(anim->isRunning(), true);
1296 void tst_qdeclarativeanimations::loopingBug()
1298 QDeclarativeEngine engine;
1300 QDeclarativeComponent c(&engine, testFileUrl("looping.qml"));
1301 QObject *obj = c.create();
1303 QDeclarativeAbstractAnimation *anim = obj->findChild<QDeclarativeAbstractAnimation*>();
1305 QCOMPARE(anim->qtAnimation()->totalDuration(), 300);
1306 QCOMPARE(anim->isRunning(), true);
1307 QTRY_COMPARE(static_cast<QAnimationGroupJob*>(anim->qtAnimation())->firstChild()->currentLoop(), 2);
1308 QTRY_COMPARE(anim->isRunning(), false);
1310 QQuickRectangle *rect = obj->findChild<QQuickRectangle*>();
1312 QCOMPARE(rect->rotation(), qreal(90));
1317 QTEST_MAIN(tst_qdeclarativeanimations)
1319 #include "tst_qdeclarativeanimations.moc"