1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the test suite of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
42 #include <QtTest/QSignalSpy>
43 #include <QtDeclarative/qdeclarativeengine.h>
44 #include <QtDeclarative/qdeclarativecomponent.h>
45 #include <QtDeclarative/qdeclarativeview.h>
46 #include <private/qdeclarativeflickable_p.h>
47 #include <private/qdeclarativevaluetype_p.h>
48 #include <QtGui/qgraphicswidget.h>
50 #include "../../../shared/util.h"
53 // In Symbian OS test data is located in applications private dir
57 class tst_qdeclarativeflickable : public QObject
61 tst_qdeclarativeflickable();
65 void horizontalViewportSize();
66 void verticalViewportSize();
68 void boundsBehavior();
69 void maximumFlickVelocity();
70 void flickDeceleration();
72 void disabledContent();
73 void nestedPressDelay();
74 void flickableDirection();
75 void qgraphicswidget();
77 void returnToBounds();
78 void testQtQuick11Attributes();
79 void testQtQuick11Attributes_data();
83 QDeclarativeEngine engine;
86 T *findItem(QGraphicsObject *parent, const QString &objectName);
89 tst_qdeclarativeflickable::tst_qdeclarativeflickable()
93 void tst_qdeclarativeflickable::create()
95 QDeclarativeEngine engine;
96 QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/flickable01.qml"));
97 QDeclarativeFlickable *obj = qobject_cast<QDeclarativeFlickable*>(c.create());
100 QCOMPARE(obj->isAtXBeginning(), true);
101 QCOMPARE(obj->isAtXEnd(), false);
102 QCOMPARE(obj->isAtYBeginning(), true);
103 QCOMPARE(obj->isAtYEnd(), false);
104 QCOMPARE(obj->contentX(), 0.);
105 QCOMPARE(obj->contentY(), 0.);
107 QCOMPARE(obj->horizontalVelocity(), 0.);
108 QCOMPARE(obj->verticalVelocity(), 0.);
110 QCOMPARE(obj->isInteractive(), true);
111 QCOMPARE(obj->boundsBehavior(), QDeclarativeFlickable::DragAndOvershootBounds);
112 QCOMPARE(obj->pressDelay(), 0);
113 QCOMPARE(obj->maximumFlickVelocity(), 2500.);
118 void tst_qdeclarativeflickable::horizontalViewportSize()
120 QDeclarativeEngine engine;
121 QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/flickable02.qml"));
122 QDeclarativeFlickable *obj = qobject_cast<QDeclarativeFlickable*>(c.create());
125 QCOMPARE(obj->contentWidth(), 800.);
126 QCOMPARE(obj->contentHeight(), 300.);
127 QCOMPARE(obj->isAtXBeginning(), true);
128 QCOMPARE(obj->isAtXEnd(), false);
129 QCOMPARE(obj->isAtYBeginning(), true);
130 QCOMPARE(obj->isAtYEnd(), false);
135 void tst_qdeclarativeflickable::verticalViewportSize()
137 QDeclarativeEngine engine;
138 QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/flickable03.qml"));
139 QDeclarativeFlickable *obj = qobject_cast<QDeclarativeFlickable*>(c.create());
142 QCOMPARE(obj->contentWidth(), 200.);
143 QCOMPARE(obj->contentHeight(), 1200.);
144 QCOMPARE(obj->isAtXBeginning(), true);
145 QCOMPARE(obj->isAtXEnd(), false);
146 QCOMPARE(obj->isAtYBeginning(), true);
147 QCOMPARE(obj->isAtYEnd(), false);
152 void tst_qdeclarativeflickable::properties()
154 QDeclarativeEngine engine;
155 QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/flickable04.qml"));
156 QDeclarativeFlickable *obj = qobject_cast<QDeclarativeFlickable*>(c.create());
159 QCOMPARE(obj->isInteractive(), false);
160 QCOMPARE(obj->boundsBehavior(), QDeclarativeFlickable::StopAtBounds);
161 QCOMPARE(obj->pressDelay(), 200);
162 QCOMPARE(obj->maximumFlickVelocity(), 2000.);
164 QVERIFY(obj->property("ok").toBool() == false);
165 QMetaObject::invokeMethod(obj, "check");
166 QVERIFY(obj->property("ok").toBool() == true);
171 void tst_qdeclarativeflickable::boundsBehavior()
173 QDeclarativeComponent component(&engine);
174 component.setData("import QtQuick 1.0; Flickable { boundsBehavior: Flickable.StopAtBounds }", QUrl::fromLocalFile(""));
175 QDeclarativeFlickable *flickable = qobject_cast<QDeclarativeFlickable*>(component.create());
176 QSignalSpy spy(flickable, SIGNAL(boundsBehaviorChanged()));
179 QVERIFY(flickable->boundsBehavior() == QDeclarativeFlickable::StopAtBounds);
181 flickable->setBoundsBehavior(QDeclarativeFlickable::DragAndOvershootBounds);
182 QVERIFY(flickable->boundsBehavior() == QDeclarativeFlickable::DragAndOvershootBounds);
183 QCOMPARE(spy.count(),1);
184 flickable->setBoundsBehavior(QDeclarativeFlickable::DragAndOvershootBounds);
185 QCOMPARE(spy.count(),1);
187 flickable->setBoundsBehavior(QDeclarativeFlickable::DragOverBounds);
188 QVERIFY(flickable->boundsBehavior() == QDeclarativeFlickable::DragOverBounds);
189 QCOMPARE(spy.count(),2);
190 flickable->setBoundsBehavior(QDeclarativeFlickable::DragOverBounds);
191 QCOMPARE(spy.count(),2);
193 flickable->setBoundsBehavior(QDeclarativeFlickable::StopAtBounds);
194 QVERIFY(flickable->boundsBehavior() == QDeclarativeFlickable::StopAtBounds);
195 QCOMPARE(spy.count(),3);
196 flickable->setBoundsBehavior(QDeclarativeFlickable::StopAtBounds);
197 QCOMPARE(spy.count(),3);
200 void tst_qdeclarativeflickable::maximumFlickVelocity()
202 QDeclarativeComponent component(&engine);
203 component.setData("import QtQuick 1.0; Flickable { maximumFlickVelocity: 1.0; }", QUrl::fromLocalFile(""));
204 QDeclarativeFlickable *flickable = qobject_cast<QDeclarativeFlickable*>(component.create());
205 QSignalSpy spy(flickable, SIGNAL(maximumFlickVelocityChanged()));
208 QCOMPARE(flickable->maximumFlickVelocity(), 1.0);
210 flickable->setMaximumFlickVelocity(2.0);
211 QCOMPARE(flickable->maximumFlickVelocity(), 2.0);
212 QCOMPARE(spy.count(),1);
213 flickable->setMaximumFlickVelocity(2.0);
214 QCOMPARE(spy.count(),1);
217 void tst_qdeclarativeflickable::flickDeceleration()
219 QDeclarativeComponent component(&engine);
220 component.setData("import QtQuick 1.0; Flickable { flickDeceleration: 1.0; }", QUrl::fromLocalFile(""));
221 QDeclarativeFlickable *flickable = qobject_cast<QDeclarativeFlickable*>(component.create());
222 QSignalSpy spy(flickable, SIGNAL(flickDecelerationChanged()));
225 QCOMPARE(flickable->flickDeceleration(), 1.0);
227 flickable->setFlickDeceleration(2.0);
228 QCOMPARE(flickable->flickDeceleration(), 2.0);
229 QCOMPARE(spy.count(),1);
230 flickable->setFlickDeceleration(2.0);
231 QCOMPARE(spy.count(),1);
234 void tst_qdeclarativeflickable::pressDelay()
236 QDeclarativeComponent component(&engine);
237 component.setData("import QtQuick 1.0; Flickable { pressDelay: 100; }", QUrl::fromLocalFile(""));
238 QDeclarativeFlickable *flickable = qobject_cast<QDeclarativeFlickable*>(component.create());
239 QSignalSpy spy(flickable, SIGNAL(pressDelayChanged()));
242 QCOMPARE(flickable->pressDelay(), 100);
244 flickable->setPressDelay(200);
245 QCOMPARE(flickable->pressDelay(), 200);
246 QCOMPARE(spy.count(),1);
247 flickable->setPressDelay(200);
248 QCOMPARE(spy.count(),1);
252 void tst_qdeclarativeflickable::disabledContent()
254 QDeclarativeView *canvas = new QDeclarativeView;
255 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/disabledcontent.qml"));
258 QVERIFY(canvas->rootObject() != 0);
260 QDeclarativeFlickable *flickable = qobject_cast<QDeclarativeFlickable*>(canvas->rootObject());
261 QVERIFY(flickable != 0);
263 QVERIFY(flickable->contentX() == 0);
264 QVERIFY(flickable->contentY() == 0);
266 QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(50, 50)));
268 QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(70,70)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
269 QApplication::sendEvent(canvas->viewport(), &mv);
272 QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(90,90)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
273 QApplication::sendEvent(canvas->viewport(), &mv);
276 QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(100,100)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
277 QApplication::sendEvent(canvas->viewport(), &mv);
280 QVERIFY(flickable->contentX() < 0);
281 QVERIFY(flickable->contentY() < 0);
283 QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(90, 90)));
290 void tst_qdeclarativeflickable::nestedPressDelay()
292 QDeclarativeView *canvas = new QDeclarativeView;
293 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/nestedPressDelay.qml"));
296 QVERIFY(canvas->rootObject() != 0);
298 QDeclarativeFlickable *outer = qobject_cast<QDeclarativeFlickable*>(canvas->rootObject());
301 QDeclarativeFlickable *inner = canvas->rootObject()->findChild<QDeclarativeFlickable*>("innerFlickable");
304 QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(150, 150)));
305 // the MouseArea is not pressed immediately
306 QVERIFY(outer->property("pressed").toBool() == false);
308 // The outer pressDelay will prevail (50ms, vs. 10sec)
309 // QTRY_VERIFY() has 5sec timeout, so will timeout well within 10sec.
310 QTRY_VERIFY(outer->property("pressed").toBool() == true);
312 QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(150, 150)));
317 void tst_qdeclarativeflickable::flickableDirection()
319 QDeclarativeComponent component(&engine);
320 component.setData("import QtQuick 1.0; Flickable { flickableDirection: Flickable.VerticalFlick; }", QUrl::fromLocalFile(""));
321 QDeclarativeFlickable *flickable = qobject_cast<QDeclarativeFlickable*>(component.create());
322 QSignalSpy spy(flickable, SIGNAL(flickableDirectionChanged()));
325 QCOMPARE(flickable->flickableDirection(), QDeclarativeFlickable::VerticalFlick);
327 flickable->setFlickableDirection(QDeclarativeFlickable::HorizontalAndVerticalFlick);
328 QCOMPARE(flickable->flickableDirection(), QDeclarativeFlickable::HorizontalAndVerticalFlick);
329 QCOMPARE(spy.count(),1);
331 flickable->setFlickableDirection(QDeclarativeFlickable::AutoFlickDirection);
332 QCOMPARE(flickable->flickableDirection(), QDeclarativeFlickable::AutoFlickDirection);
333 QCOMPARE(spy.count(),2);
335 flickable->setFlickableDirection(QDeclarativeFlickable::HorizontalFlick);
336 QCOMPARE(flickable->flickableDirection(), QDeclarativeFlickable::HorizontalFlick);
337 QCOMPARE(spy.count(),3);
339 flickable->setFlickableDirection(QDeclarativeFlickable::HorizontalFlick);
340 QCOMPARE(flickable->flickableDirection(), QDeclarativeFlickable::HorizontalFlick);
341 QCOMPARE(spy.count(),3);
344 void tst_qdeclarativeflickable::qgraphicswidget()
346 QDeclarativeEngine engine;
347 QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/flickableqgraphicswidget.qml"));
348 QDeclarativeFlickable *flickable = qobject_cast<QDeclarativeFlickable*>(c.create());
350 QVERIFY(flickable != 0);
351 QGraphicsWidget *widget = findItem<QGraphicsWidget>(flickable->contentItem(), "widget1");
356 void tst_qdeclarativeflickable::resizeContent()
358 QDeclarativeEngine engine;
359 QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/resize.qml"));
360 QDeclarativeItem *root = qobject_cast<QDeclarativeItem*>(c.create());
361 QDeclarativeFlickable *obj = findItem<QDeclarativeFlickable>(root, "flick");
364 QCOMPARE(obj->contentX(), 0.);
365 QCOMPARE(obj->contentY(), 0.);
366 QCOMPARE(obj->contentWidth(), 300.);
367 QCOMPARE(obj->contentHeight(), 300.);
369 QMetaObject::invokeMethod(root, "resizeContent");
371 QCOMPARE(obj->contentX(), 100.);
372 QCOMPARE(obj->contentY(), 100.);
373 QCOMPARE(obj->contentWidth(), 600.);
374 QCOMPARE(obj->contentHeight(), 600.);
380 void tst_qdeclarativeflickable::returnToBounds()
382 QDeclarativeEngine engine;
383 QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/resize.qml"));
384 QDeclarativeItem *root = qobject_cast<QDeclarativeItem*>(c.create());
385 QDeclarativeFlickable *obj = findItem<QDeclarativeFlickable>(root, "flick");
388 QCOMPARE(obj->contentX(), 0.);
389 QCOMPARE(obj->contentY(), 0.);
390 QCOMPARE(obj->contentWidth(), 300.);
391 QCOMPARE(obj->contentHeight(), 300.);
393 obj->setContentX(100);
394 obj->setContentY(400);
395 QTRY_COMPARE(obj->contentX(), 100.);
396 QTRY_COMPARE(obj->contentY(), 400.);
398 QMetaObject::invokeMethod(root, "returnToBounds");
400 QTRY_COMPARE(obj->contentX(), 0.);
401 QTRY_COMPARE(obj->contentY(), 0.);
406 void tst_qdeclarativeflickable::testQtQuick11Attributes()
408 QFETCH(QString, code);
409 QFETCH(QString, warning);
410 QFETCH(QString, error);
412 QDeclarativeEngine engine;
415 QDeclarativeComponent invalid(&engine);
416 invalid.setData("import QtQuick 1.0; Flickable { " + code.toUtf8() + " }", QUrl(""));
417 QTest::ignoreMessage(QtWarningMsg, warning.toUtf8());
418 obj = invalid.create();
419 QCOMPARE(invalid.errorString(), error);
422 QDeclarativeComponent valid(&engine);
423 valid.setData("import QtQuick 1.1; Flickable { " + code.toUtf8() + " }", QUrl(""));
424 obj = valid.create();
426 QVERIFY(valid.errorString().isEmpty());
430 void tst_qdeclarativeflickable::testQtQuick11Attributes_data()
432 QTest::addColumn<QString>("code");
433 QTest::addColumn<QString>("warning");
434 QTest::addColumn<QString>("error");
436 QTest::newRow("resizeContent") << "Component.onCompleted: resizeContent(100,100,Qt.point(50,50))"
437 << "<Unknown File>:1: ReferenceError: Can't find variable: resizeContent"
440 QTest::newRow("returnToBounds") << "Component.onCompleted: returnToBounds()"
441 << "<Unknown File>:1: ReferenceError: Can't find variable: returnToBounds"
446 void tst_qdeclarativeflickable::wheel()
448 QDeclarativeView *canvas = new QDeclarativeView;
449 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/wheel.qml"));
452 QVERIFY(canvas->rootObject() != 0);
454 QDeclarativeFlickable *flick = canvas->rootObject()->findChild<QDeclarativeFlickable*>("flick");
457 QGraphicsScene *scene = canvas->scene();
458 QGraphicsSceneWheelEvent event(QEvent::GraphicsSceneWheel);
459 event.setScenePos(QPointF(200, 200));
460 event.setDelta(-120);
461 event.setOrientation(Qt::Vertical);
462 event.setAccepted(false);
463 QApplication::sendEvent(scene, &event);
465 QTRY_VERIFY(flick->contentY() > 0);
466 QVERIFY(flick->contentX() == 0);
468 flick->setContentY(0);
469 QVERIFY(flick->contentY() == 0);
471 event.setScenePos(QPointF(200, 200));
472 event.setDelta(-120);
473 event.setOrientation(Qt::Horizontal);
474 event.setAccepted(false);
475 QApplication::sendEvent(scene, &event);
477 QTRY_VERIFY(flick->contentX() > 0);
478 QVERIFY(flick->contentY() == 0);
485 T *tst_qdeclarativeflickable::findItem(QGraphicsObject *parent, const QString &objectName)
487 const QMetaObject &mo = T::staticMetaObject;
488 //qDebug() << parent->childItems().count() << "children";
489 for (int i = 0; i < parent->childItems().count(); ++i) {
490 QGraphicsObject *item = qobject_cast<QGraphicsObject*>(parent->childItems().at(i));
493 //qDebug() << "try" << item;
494 if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
495 return static_cast<T*>(item);
497 item = findItem<T>(item, objectName);
499 return static_cast<T*>(item);
505 QTEST_MAIN(tst_qdeclarativeflickable)
507 #include "tst_qdeclarativeflickable.moc"