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 <qsignalspy.h>
43 #include <QtDeclarative/qdeclarativeengine.h>
44 #include <QtDeclarative/qdeclarativecomponent.h>
45 #include <QtQuick/qquickview.h>
46 #include <QtQuick/private/qquickrectangle_p.h>
47 #include <QtQuick/private/qquicktext_p.h>
48 #include <QtQuick/private/qdeclarativebehavior_p.h>
49 #include <QtQuick/private/qdeclarativeanimation_p.h>
50 #include <private/qquickitem_p.h>
51 #include "../../shared/util.h"
53 class tst_qdeclarativebehaviors : public QDeclarativeDataTest
57 tst_qdeclarativebehaviors() {}
60 void init() { qApp->processEvents(); } //work around animation timer bug (QTBUG-22865)
61 void simpleBehavior();
62 void scriptTriggered();
66 void parentBehavior();
67 void replaceBinding();
68 //void transitionOverrides();
72 void explicitSelection();
73 void nonSelectingBehavior();
74 void reassignedAnimation();
78 void groupedPropertyCrash();
81 void delayedRegistration();
82 void startOnCompleted();
85 void tst_qdeclarativebehaviors::simpleBehavior()
87 QDeclarativeEngine engine;
88 QDeclarativeComponent c(&engine, testFileUrl("simple.qml"));
89 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
91 QTRY_VERIFY(qobject_cast<QDeclarativeBehavior*>(rect->findChild<QDeclarativeBehavior*>("MyBehavior"))->animation());
93 QQuickItemPrivate::get(rect)->setState("moved");
94 QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->x() > 0);
95 QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->x() < 200);
96 //i.e. the behavior has been triggered
101 void tst_qdeclarativebehaviors::scriptTriggered()
103 QDeclarativeEngine engine;
104 QDeclarativeComponent c(&engine, testFileUrl("scripttrigger.qml"));
105 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
108 rect->setColor(QColor("red"));
109 QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->x() > 0);
110 QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->x() < 200);
111 //i.e. the behavior has been triggered
116 void tst_qdeclarativebehaviors::cppTriggered()
118 QDeclarativeEngine engine;
119 QDeclarativeComponent c(&engine, testFileUrl("cpptrigger.qml"));
120 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
123 QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"));
124 QTRY_VERIFY(innerRect);
126 innerRect->setProperty("x", 200);
127 QTRY_VERIFY(innerRect->x() > 0);
128 QTRY_VERIFY(innerRect->x() < 200); //i.e. the behavior has been triggered
133 void tst_qdeclarativebehaviors::loop()
135 QDeclarativeEngine engine;
136 QDeclarativeComponent c(&engine, testFileUrl("loop.qml"));
137 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
141 QQuickItemPrivate::get(rect)->setState("moved");
146 void tst_qdeclarativebehaviors::colorBehavior()
148 QDeclarativeEngine engine;
149 QDeclarativeComponent c(&engine, testFileUrl("color.qml"));
150 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
153 QQuickItemPrivate::get(rect)->setState("red");
154 QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->color() != QColor("red"));
155 QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->color() != QColor("green"));
156 //i.e. the behavior has been triggered
161 void tst_qdeclarativebehaviors::parentBehavior()
163 QDeclarativeEngine engine;
164 QDeclarativeComponent c(&engine, testFileUrl("parent.qml"));
165 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
168 QQuickItemPrivate::get(rect)->setState("reparented");
169 QTRY_VERIFY(rect->findChild<QQuickRectangle*>("MyRect")->parentItem() != rect->findChild<QQuickItem*>("NewParent"));
170 QTRY_VERIFY(rect->findChild<QQuickRectangle*>("MyRect")->parentItem() == rect->findChild<QQuickItem*>("NewParent"));
175 void tst_qdeclarativebehaviors::replaceBinding()
177 QDeclarativeEngine engine;
178 QDeclarativeComponent c(&engine, testFileUrl("binding.qml"));
179 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
182 QQuickItemPrivate::get(rect)->setState("moved");
183 QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"));
184 QTRY_VERIFY(innerRect);
185 QTRY_VERIFY(innerRect->x() > 0);
186 QTRY_VERIFY(innerRect->x() < 200);
187 //i.e. the behavior has been triggered
188 QTRY_COMPARE(innerRect->x(), (qreal)200);
189 rect->setProperty("basex", 10);
190 QTRY_COMPARE(innerRect->x(), (qreal)200);
191 rect->setProperty("movedx", 210);
192 QTRY_COMPARE(innerRect->x(), (qreal)210);
194 QQuickItemPrivate::get(rect)->setState("");
195 QTRY_VERIFY(innerRect->x() > 10);
196 QTRY_VERIFY(innerRect->x() < 210); //i.e. the behavior has been triggered
197 QTRY_COMPARE(innerRect->x(), (qreal)10);
198 rect->setProperty("movedx", 200);
199 QTRY_COMPARE(innerRect->x(), (qreal)10);
200 rect->setProperty("basex", 20);
201 QTRY_COMPARE(innerRect->x(), (qreal)20);
206 void tst_qdeclarativebehaviors::group()
208 /* XXX TODO Create a test element for this case.
210 QDeclarativeEngine engine;
211 QDeclarativeComponent c(&engine, testFileUrl("groupProperty.qml")));
212 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
213 qDebug() << c.errorString();
216 QQuickItemPrivate::get(rect)->setState("moved");
218 QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->x() > 0);
219 QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->x() < 200);
220 //i.e. the behavior has been triggered
227 QDeclarativeEngine engine;
228 QDeclarativeComponent c(&engine, testFileUrl("groupProperty2.qml"));
229 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
232 QQuickItemPrivate::get(rect)->setState("moved");
233 QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->border()->width() > 0);
234 QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->border()->width() < 4);
235 //i.e. the behavior has been triggered
241 void tst_qdeclarativebehaviors::valueType()
243 QDeclarativeEngine engine;
244 QDeclarativeComponent c(&engine, testFileUrl("valueType.qml"));
245 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
249 QCOMPARE(rect->color(), QColor::fromRgb(255,0,255));
254 void tst_qdeclarativebehaviors::emptyBehavior()
256 QDeclarativeEngine engine;
257 QDeclarativeComponent c(&engine, testFileUrl("empty.qml"));
258 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
261 QQuickItemPrivate::get(rect)->setState("moved");
262 qreal x = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->x();
263 QCOMPARE(x, qreal(200)); //should change immediately
268 void tst_qdeclarativebehaviors::explicitSelection()
270 QDeclarativeEngine engine;
271 QDeclarativeComponent c(&engine, testFileUrl("explicit.qml"));
272 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
275 QQuickItemPrivate::get(rect)->setState("moved");
276 QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->x() > 0);
277 QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->x() < 200);
278 //i.e. the behavior has been triggered
283 void tst_qdeclarativebehaviors::nonSelectingBehavior()
285 QDeclarativeEngine engine;
286 QDeclarativeComponent c(&engine, testFileUrl("nonSelecting2.qml"));
287 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
290 QQuickItemPrivate::get(rect)->setState("moved");
291 qreal x = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->x();
292 QCOMPARE(x, qreal(200)); //should change immediately
297 void tst_qdeclarativebehaviors::reassignedAnimation()
299 QDeclarativeEngine engine;
300 QDeclarativeComponent c(&engine, testFileUrl("reassignedAnimation.qml"));
301 QString warning = testFileUrl("reassignedAnimation.qml").toString() + ":9:9: QML Behavior: Cannot change the animation assigned to a Behavior.";
302 QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
303 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
305 QCOMPARE(qobject_cast<QDeclarativeNumberAnimation*>(
306 rect->findChild<QDeclarativeBehavior*>("MyBehavior")->animation())->duration(), 200);
311 void tst_qdeclarativebehaviors::disabled()
313 QDeclarativeEngine engine;
314 QDeclarativeComponent c(&engine, testFileUrl("disabled.qml"));
315 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
317 QCOMPARE(rect->findChild<QDeclarativeBehavior*>("MyBehavior")->enabled(), false);
319 QQuickItemPrivate::get(rect)->setState("moved");
320 qreal x = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->x();
321 QCOMPARE(x, qreal(200)); //should change immediately
326 void tst_qdeclarativebehaviors::dontStart()
328 QDeclarativeEngine engine;
330 QDeclarativeComponent c(&engine, testFileUrl("dontStart.qml"));
332 QString warning = c.url().toString() + ":13:13: QML NumberAnimation: setRunning() cannot be used on non-root animation nodes.";
333 QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
334 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
337 QDeclarativeAbstractAnimation *myAnim = rect->findChild<QDeclarativeAbstractAnimation*>("MyAnim");
338 QVERIFY(myAnim && myAnim->qtAnimation());
339 QVERIFY(myAnim->qtAnimation()->state() == QAbstractAnimation::Stopped);
344 void tst_qdeclarativebehaviors::startup()
347 QDeclarativeEngine engine;
348 QDeclarativeComponent c(&engine, testFileUrl("startup.qml"));
349 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
352 QQuickRectangle *innerRect = rect->findChild<QQuickRectangle*>("innerRect");
355 QCOMPARE(innerRect->x(), qreal(100)); //should be set immediately
361 QDeclarativeEngine engine;
362 QDeclarativeComponent c(&engine, testFileUrl("startup2.qml"));
363 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
366 QQuickRectangle *innerRect = rect->findChild<QQuickRectangle*>("innerRect");
369 QQuickText *text = rect->findChild<QQuickText*>();
372 QCOMPARE(innerRect->x(), text->width()); //should be set immediately
379 void tst_qdeclarativebehaviors::groupedPropertyCrash()
381 QDeclarativeEngine engine;
382 QDeclarativeComponent c(&engine, testFileUrl("groupedPropertyCrash.qml"));
383 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
384 QVERIFY(rect); //don't crash
390 void tst_qdeclarativebehaviors::runningTrue()
392 QDeclarativeEngine engine;
393 QDeclarativeComponent c(&engine, testFileUrl("runningTrue.qml"));
394 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
397 QDeclarativeAbstractAnimation *animation = rect->findChild<QDeclarativeAbstractAnimation*>("rotAnim");
400 QSignalSpy runningSpy(animation, SIGNAL(runningChanged(bool)));
401 rect->setProperty("myValue", 180);
402 QTRY_VERIFY(runningSpy.count() > 0);
408 void tst_qdeclarativebehaviors::sameValue()
410 QDeclarativeEngine engine;
411 QDeclarativeComponent c(&engine, testFileUrl("qtbug12295.qml"));
412 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
415 QQuickRectangle *target = rect->findChild<QQuickRectangle*>("myRect");
419 QCOMPARE(target->x(), qreal(100));
421 target->setProperty("x", 0);
422 QTRY_VERIFY(target->x() != qreal(0) && target->x() != qreal(100));
423 QTRY_VERIFY(target->x() == qreal(0)); //make sure Behavior has finished.
426 QCOMPARE(target->x(), qreal(100));
428 //this is the main point of the test -- the behavior needs to be triggered again
429 //even though we set 0 twice in a row.
430 target->setProperty("x", 0);
431 QTRY_VERIFY(target->x() != qreal(0) && target->x() != qreal(100));
437 void tst_qdeclarativebehaviors::delayedRegistration()
439 QDeclarativeEngine engine;
441 QDeclarativeComponent c(&engine, testFileUrl("delayedRegistration.qml"));
442 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
445 QQuickItem *innerRect = rect->property("myItem").value<QQuickItem*>();
446 QVERIFY(innerRect != 0);
448 QCOMPARE(innerRect->property("x").toInt(), int(0));
450 QTRY_COMPARE(innerRect->property("x").toInt(), int(100));
454 void tst_qdeclarativebehaviors::startOnCompleted()
456 QDeclarativeEngine engine;
458 QDeclarativeComponent c(&engine, testFileUrl("startOnCompleted.qml"));
459 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
462 QQuickItem *innerRect = rect->findChild<QQuickRectangle*>();
463 QVERIFY(innerRect != 0);
465 QCOMPARE(innerRect->property("x").toInt(), int(0));
467 QTRY_COMPARE(innerRect->property("x").toInt(), int(100));
472 QTEST_MAIN(tst_qdeclarativebehaviors)
474 #include "tst_qdeclarativebehaviors.moc"