Merge branch 'master' of git://gitorious.org/qt/qtdeclarative into merge-master
[profile/ivi/qtdeclarative.git] / tests / auto / quick / qquickflickable / tst_qquickflickable.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
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.
16 **
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.
20 **
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.
28 **
29 ** Other Usage
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.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 #include <qtest.h>
42 #include <QtTest/QSignalSpy>
43 #include <QtQml/qqmlengine.h>
44 #include <QtQml/qqmlcomponent.h>
45 #include <QtQuick/qquickview.h>
46 #include <private/qquickflickable_p.h>
47 #include <private/qquickflickable_p_p.h>
48 #include <private/qqmlvaluetype_p.h>
49 #include <math.h>
50 #include "../../shared/util.h"
51 #include "../shared/viewtestutil.h"
52 #include "../shared/visualtestutil.h"
53
54 using namespace QQuickViewTestUtil;
55 using namespace QQuickVisualTestUtil;
56
57 class tst_qquickflickable : public QQmlDataTest
58 {
59     Q_OBJECT
60 public:
61
62 private slots:
63     void create();
64     void horizontalViewportSize();
65     void verticalViewportSize();
66     void properties();
67     void boundsBehavior();
68     void maximumFlickVelocity();
69     void flickDeceleration();
70     void pressDelay();
71     void nestedPressDelay();
72     void flickableDirection();
73     void resizeContent();
74     void returnToBounds();
75     void wheel();
76     void movingAndDragging();
77     void disabled();
78     void flickVelocity();
79     void margins();
80
81 private:
82     QQmlEngine engine;
83 };
84
85 void tst_qquickflickable::create()
86 {
87     QQmlEngine engine;
88     QQmlComponent c(&engine, testFileUrl("flickable01.qml"));
89     QQuickFlickable *obj = qobject_cast<QQuickFlickable*>(c.create());
90
91     QVERIFY(obj != 0);
92     QCOMPARE(obj->isAtXBeginning(), true);
93     QCOMPARE(obj->isAtXEnd(), false);
94     QCOMPARE(obj->isAtYBeginning(), true);
95     QCOMPARE(obj->isAtYEnd(), false);
96     QCOMPARE(obj->contentX(), 0.);
97     QCOMPARE(obj->contentY(), 0.);
98
99     QCOMPARE(obj->horizontalVelocity(), 0.);
100     QCOMPARE(obj->verticalVelocity(), 0.);
101
102     QCOMPARE(obj->isInteractive(), true);
103     QCOMPARE(obj->boundsBehavior(), QQuickFlickable::DragAndOvershootBounds);
104     QCOMPARE(obj->pressDelay(), 0);
105     QCOMPARE(obj->maximumFlickVelocity(), 2500.);
106
107     delete obj;
108 }
109
110 void tst_qquickflickable::horizontalViewportSize()
111 {
112     QQmlEngine engine;
113     QQmlComponent c(&engine, testFileUrl("flickable02.qml"));
114     QQuickFlickable *obj = qobject_cast<QQuickFlickable*>(c.create());
115
116     QVERIFY(obj != 0);
117     QCOMPARE(obj->contentWidth(), 800.);
118     QCOMPARE(obj->contentHeight(), 300.);
119     QCOMPARE(obj->isAtXBeginning(), true);
120     QCOMPARE(obj->isAtXEnd(), false);
121     QCOMPARE(obj->isAtYBeginning(), true);
122     QCOMPARE(obj->isAtYEnd(), false);
123
124     delete obj;
125 }
126
127 void tst_qquickflickable::verticalViewportSize()
128 {
129     QQmlEngine engine;
130     QQmlComponent c(&engine, testFileUrl("flickable03.qml"));
131     QQuickFlickable *obj = qobject_cast<QQuickFlickable*>(c.create());
132
133     QVERIFY(obj != 0);
134     QCOMPARE(obj->contentWidth(), 200.);
135     QCOMPARE(obj->contentHeight(), 6000.);
136     QCOMPARE(obj->isAtXBeginning(), true);
137     QCOMPARE(obj->isAtXEnd(), false);
138     QCOMPARE(obj->isAtYBeginning(), true);
139     QCOMPARE(obj->isAtYEnd(), false);
140
141     delete obj;
142 }
143
144 void tst_qquickflickable::properties()
145 {
146     QQmlEngine engine;
147     QQmlComponent c(&engine, testFileUrl("flickable04.qml"));
148     QQuickFlickable *obj = qobject_cast<QQuickFlickable*>(c.create());
149
150     QVERIFY(obj != 0);
151     QCOMPARE(obj->isInteractive(), false);
152     QCOMPARE(obj->boundsBehavior(), QQuickFlickable::StopAtBounds);
153     QCOMPARE(obj->pressDelay(), 200);
154     QCOMPARE(obj->maximumFlickVelocity(), 2000.);
155
156     QVERIFY(obj->property("ok").toBool() == false);
157     QMetaObject::invokeMethod(obj, "check");
158     QVERIFY(obj->property("ok").toBool() == true);
159
160     delete obj;
161 }
162
163 void tst_qquickflickable::boundsBehavior()
164 {
165     QQmlComponent component(&engine);
166     component.setData("import QtQuick 2.0; Flickable { boundsBehavior: Flickable.StopAtBounds }", QUrl::fromLocalFile(""));
167     QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(component.create());
168     QSignalSpy spy(flickable, SIGNAL(boundsBehaviorChanged()));
169
170     QVERIFY(flickable);
171     QVERIFY(flickable->boundsBehavior() == QQuickFlickable::StopAtBounds);
172
173     flickable->setBoundsBehavior(QQuickFlickable::DragAndOvershootBounds);
174     QVERIFY(flickable->boundsBehavior() == QQuickFlickable::DragAndOvershootBounds);
175     QCOMPARE(spy.count(),1);
176     flickable->setBoundsBehavior(QQuickFlickable::DragAndOvershootBounds);
177     QCOMPARE(spy.count(),1);
178
179     flickable->setBoundsBehavior(QQuickFlickable::DragOverBounds);
180     QVERIFY(flickable->boundsBehavior() == QQuickFlickable::DragOverBounds);
181     QCOMPARE(spy.count(),2);
182     flickable->setBoundsBehavior(QQuickFlickable::DragOverBounds);
183     QCOMPARE(spy.count(),2);
184
185     flickable->setBoundsBehavior(QQuickFlickable::StopAtBounds);
186     QVERIFY(flickable->boundsBehavior() == QQuickFlickable::StopAtBounds);
187     QCOMPARE(spy.count(),3);
188     flickable->setBoundsBehavior(QQuickFlickable::StopAtBounds);
189     QCOMPARE(spy.count(),3);
190 }
191
192 void tst_qquickflickable::maximumFlickVelocity()
193 {
194     QQmlComponent component(&engine);
195     component.setData("import QtQuick 2.0; Flickable { maximumFlickVelocity: 1.0; }", QUrl::fromLocalFile(""));
196     QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(component.create());
197     QSignalSpy spy(flickable, SIGNAL(maximumFlickVelocityChanged()));
198
199     QVERIFY(flickable);
200     QCOMPARE(flickable->maximumFlickVelocity(), 1.0);
201
202     flickable->setMaximumFlickVelocity(2.0);
203     QCOMPARE(flickable->maximumFlickVelocity(), 2.0);
204     QCOMPARE(spy.count(),1);
205     flickable->setMaximumFlickVelocity(2.0);
206     QCOMPARE(spy.count(),1);
207 }
208
209 void tst_qquickflickable::flickDeceleration()
210 {
211     QQmlComponent component(&engine);
212     component.setData("import QtQuick 2.0; Flickable { flickDeceleration: 1.0; }", QUrl::fromLocalFile(""));
213     QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(component.create());
214     QSignalSpy spy(flickable, SIGNAL(flickDecelerationChanged()));
215
216     QVERIFY(flickable);
217     QCOMPARE(flickable->flickDeceleration(), 1.0);
218
219     flickable->setFlickDeceleration(2.0);
220     QCOMPARE(flickable->flickDeceleration(), 2.0);
221     QCOMPARE(spy.count(),1);
222     flickable->setFlickDeceleration(2.0);
223     QCOMPARE(spy.count(),1);
224 }
225
226 void tst_qquickflickable::pressDelay()
227 {
228     QQmlComponent component(&engine);
229     component.setData("import QtQuick 2.0; Flickable { pressDelay: 100; }", QUrl::fromLocalFile(""));
230     QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(component.create());
231     QSignalSpy spy(flickable, SIGNAL(pressDelayChanged()));
232
233     QVERIFY(flickable);
234     QCOMPARE(flickable->pressDelay(), 100);
235
236     flickable->setPressDelay(200);
237     QCOMPARE(flickable->pressDelay(), 200);
238     QCOMPARE(spy.count(),1);
239     flickable->setPressDelay(200);
240     QCOMPARE(spy.count(),1);
241 }
242
243 // QTBUG-17361
244 void tst_qquickflickable::nestedPressDelay()
245 {
246     QQuickView *canvas = new QQuickView;
247     canvas->setSource(testFileUrl("nestedPressDelay.qml"));
248     canvas->show();
249     canvas->requestActivateWindow();
250     QVERIFY(canvas->rootObject() != 0);
251
252     QQuickFlickable *outer = qobject_cast<QQuickFlickable*>(canvas->rootObject());
253     QVERIFY(outer != 0);
254
255     QQuickFlickable *inner = canvas->rootObject()->findChild<QQuickFlickable*>("innerFlickable");
256     QVERIFY(inner != 0);
257
258     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(150, 150));
259     // the MouseArea is not pressed immediately
260     QVERIFY(outer->property("pressed").toBool() == false);
261
262     // The outer pressDelay will prevail (50ms, vs. 10sec)
263     // QTRY_VERIFY() has 5sec timeout, so will timeout well within 10sec.
264     QTRY_VERIFY(outer->property("pressed").toBool() == true);
265
266     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(150, 150));
267
268     delete canvas;
269 }
270
271 void tst_qquickflickable::flickableDirection()
272 {
273     QQmlComponent component(&engine);
274     component.setData("import QtQuick 2.0; Flickable { flickableDirection: Flickable.VerticalFlick; }", QUrl::fromLocalFile(""));
275     QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(component.create());
276     QSignalSpy spy(flickable, SIGNAL(flickableDirectionChanged()));
277
278     QVERIFY(flickable);
279     QCOMPARE(flickable->flickableDirection(), QQuickFlickable::VerticalFlick);
280
281     flickable->setFlickableDirection(QQuickFlickable::HorizontalAndVerticalFlick);
282     QCOMPARE(flickable->flickableDirection(), QQuickFlickable::HorizontalAndVerticalFlick);
283     QCOMPARE(spy.count(),1);
284
285     flickable->setFlickableDirection(QQuickFlickable::AutoFlickDirection);
286     QCOMPARE(flickable->flickableDirection(), QQuickFlickable::AutoFlickDirection);
287     QCOMPARE(spy.count(),2);
288
289     flickable->setFlickableDirection(QQuickFlickable::HorizontalFlick);
290     QCOMPARE(flickable->flickableDirection(), QQuickFlickable::HorizontalFlick);
291     QCOMPARE(spy.count(),3);
292
293     flickable->setFlickableDirection(QQuickFlickable::HorizontalFlick);
294     QCOMPARE(flickable->flickableDirection(), QQuickFlickable::HorizontalFlick);
295     QCOMPARE(spy.count(),3);
296 }
297
298 // QtQuick 1.1
299 void tst_qquickflickable::resizeContent()
300 {
301     QQmlEngine engine;
302     QQmlComponent c(&engine, testFileUrl("resize.qml"));
303     QQuickItem *root = qobject_cast<QQuickItem*>(c.create());
304     QQuickFlickable *obj = findItem<QQuickFlickable>(root, "flick");
305
306     QVERIFY(obj != 0);
307     QCOMPARE(obj->contentX(), 0.);
308     QCOMPARE(obj->contentY(), 0.);
309     QCOMPARE(obj->contentWidth(), 300.);
310     QCOMPARE(obj->contentHeight(), 300.);
311
312     QMetaObject::invokeMethod(root, "resizeContent");
313
314     QCOMPARE(obj->contentX(), 100.);
315     QCOMPARE(obj->contentY(), 100.);
316     QCOMPARE(obj->contentWidth(), 600.);
317     QCOMPARE(obj->contentHeight(), 600.);
318
319     delete root;
320 }
321
322 // QtQuick 1.1
323 void tst_qquickflickable::returnToBounds()
324 {
325     QQmlEngine engine;
326     QQmlComponent c(&engine, testFileUrl("resize.qml"));
327     QQuickItem *root = qobject_cast<QQuickItem*>(c.create());
328     QQuickFlickable *obj = findItem<QQuickFlickable>(root, "flick");
329
330     QVERIFY(obj != 0);
331     QCOMPARE(obj->contentX(), 0.);
332     QCOMPARE(obj->contentY(), 0.);
333     QCOMPARE(obj->contentWidth(), 300.);
334     QCOMPARE(obj->contentHeight(), 300.);
335
336     obj->setContentX(100);
337     obj->setContentY(400);
338     QTRY_COMPARE(obj->contentX(), 100.);
339     QTRY_COMPARE(obj->contentY(), 400.);
340
341     QMetaObject::invokeMethod(root, "returnToBounds");
342
343     QTRY_COMPARE(obj->contentX(), 0.);
344     QTRY_COMPARE(obj->contentY(), 0.);
345
346     delete root;
347 }
348
349 void tst_qquickflickable::wheel()
350 {
351     QQuickView *canvas = new QQuickView;
352     canvas->setSource(testFileUrl("wheel.qml"));
353     canvas->show();
354     canvas->requestActivateWindow();
355     QVERIFY(canvas->rootObject() != 0);
356
357     QQuickFlickable *flick = canvas->rootObject()->findChild<QQuickFlickable*>("flick");
358     QVERIFY(flick != 0);
359
360     {
361         QWheelEvent event(QPoint(200, 200), -120, Qt::NoButton, Qt::NoModifier, Qt::Vertical);
362         event.setAccepted(false);
363         QGuiApplication::sendEvent(canvas, &event);
364     }
365
366     QTRY_VERIFY(flick->contentY() > 0);
367     QVERIFY(flick->contentX() == 0);
368
369     flick->setContentY(0);
370     QVERIFY(flick->contentY() == 0);
371
372     {
373         QWheelEvent event(QPoint(200, 200), -120, Qt::NoButton, Qt::NoModifier, Qt::Horizontal);
374         event.setAccepted(false);
375         QGuiApplication::sendEvent(canvas, &event);
376     }
377
378     QTRY_VERIFY(flick->contentX() > 0);
379     QVERIFY(flick->contentY() == 0);
380
381     delete canvas;
382 }
383
384 void tst_qquickflickable::movingAndDragging()
385 {
386     QQuickView *canvas = new QQuickView;
387     canvas->setSource(testFileUrl("flickable03.qml"));
388     canvas->show();
389     canvas->requestActivateWindow();
390     QTest::qWaitForWindowShown(canvas);
391     QVERIFY(canvas->rootObject() != 0);
392
393     QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(canvas->rootObject());
394     QVERIFY(flickable != 0);
395
396     QSignalSpy vDragSpy(flickable, SIGNAL(draggingVerticallyChanged()));
397     QSignalSpy hDragSpy(flickable, SIGNAL(draggingHorizontallyChanged()));
398     QSignalSpy dragSpy(flickable, SIGNAL(draggingChanged()));
399     QSignalSpy vMoveSpy(flickable, SIGNAL(movingVerticallyChanged()));
400     QSignalSpy hMoveSpy(flickable, SIGNAL(movingHorizontallyChanged()));
401     QSignalSpy moveSpy(flickable, SIGNAL(movingChanged()));
402     QSignalSpy dragStartSpy(flickable, SIGNAL(dragStarted()));
403     QSignalSpy dragEndSpy(flickable, SIGNAL(dragEnded()));
404
405     //Vertical
406     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50, 90));
407
408     QTest::mouseMove(canvas, QPoint(50, 80));
409     QTest::mouseMove(canvas, QPoint(50, 70));
410     QTest::mouseMove(canvas, QPoint(50, 60));
411
412     QMouseEvent moveEvent(QEvent::MouseMove, QPoint(50, 80), Qt::LeftButton, Qt::LeftButton, 0);
413
414     QVERIFY(!flickable->isDraggingHorizontally());
415     QVERIFY(flickable->isDraggingVertically());
416     QVERIFY(flickable->isDragging());
417     QCOMPARE(vDragSpy.count(), 1);
418     QCOMPARE(dragSpy.count(), 1);
419     QCOMPARE(hDragSpy.count(), 0);
420     QCOMPARE(dragStartSpy.count(), 1);
421     QCOMPARE(dragEndSpy.count(), 0);
422
423     QVERIFY(!flickable->isMovingHorizontally());
424     QVERIFY(flickable->isMovingVertically());
425     QVERIFY(flickable->isMoving());
426     QCOMPARE(vMoveSpy.count(), 1);
427     QCOMPARE(moveSpy.count(), 1);
428     QCOMPARE(hMoveSpy.count(), 0);
429
430     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50, 60));
431
432     QTRY_VERIFY(!flickable->isDraggingVertically());
433     QVERIFY(!flickable->isDragging());
434     QCOMPARE(vDragSpy.count(), 2);
435     QCOMPARE(dragSpy.count(), 2);
436     QCOMPARE(hDragSpy.count(), 0);
437     QCOMPARE(dragStartSpy.count(), 1);
438     QCOMPARE(dragEndSpy.count(), 1);
439
440     // wait for any motion to end
441     QTRY_VERIFY(flickable->isMoving() == false);
442
443     //Horizontal
444     vDragSpy.clear();
445     hDragSpy.clear();
446     dragSpy.clear();
447     vMoveSpy.clear();
448     hMoveSpy.clear();
449     moveSpy.clear();
450     dragStartSpy.clear();
451     dragEndSpy.clear();
452
453     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(90, 50));
454
455     QTest::mouseMove(canvas, QPoint(80, 50));
456     QTest::mouseMove(canvas, QPoint(70, 50));
457     QTest::mouseMove(canvas, QPoint(60, 50));
458
459     QVERIFY(!flickable->isDraggingVertically());
460     QVERIFY(flickable->isDraggingHorizontally());
461     QVERIFY(flickable->isDragging());
462     QCOMPARE(vDragSpy.count(), 0);
463     QCOMPARE(dragSpy.count(), 1);
464     QCOMPARE(hDragSpy.count(), 1);
465     QCOMPARE(dragStartSpy.count(), 1);
466     QCOMPARE(dragEndSpy.count(), 0);
467
468     QVERIFY(!flickable->isMovingVertically());
469     QVERIFY(flickable->isMovingHorizontally());
470     QVERIFY(flickable->isMoving());
471     QCOMPARE(vMoveSpy.count(), 0);
472     QCOMPARE(moveSpy.count(), 1);
473     QCOMPARE(hMoveSpy.count(), 1);
474
475     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(60, 50));
476
477     QTRY_VERIFY(!flickable->isDraggingHorizontally());
478     QVERIFY(!flickable->isDragging());
479     QCOMPARE(vDragSpy.count(), 0);
480     QCOMPARE(dragSpy.count(), 2);
481     QCOMPARE(hDragSpy.count(), 2);
482     QCOMPARE(dragStartSpy.count(), 1);
483     QCOMPARE(dragEndSpy.count(), 1);
484     // Don't test moving because a flick could occur
485
486 #ifdef Q_OS_MAC
487     QSKIP("Producing flicks on Mac CI impossible due to timing problems");
488 #endif
489
490     QTRY_VERIFY(!flickable->isMoving());
491
492     vMoveSpy.clear();
493     hMoveSpy.clear();
494     moveSpy.clear();
495     QSignalSpy vFlickSpy(flickable, SIGNAL(flickingVerticallyChanged()));
496     QSignalSpy hFlickSpy(flickable, SIGNAL(flickingHorizontallyChanged()));
497     QSignalSpy flickSpy(flickable, SIGNAL(flickingChanged()));
498
499     // flick then press while it is still moving
500     // flicking == false, moving == true;
501     flick(canvas, QPoint(20,190), QPoint(20, 50), 200);
502     QVERIFY(flickable->verticalVelocity() > 0.0);
503     QVERIFY(flickable->isFlicking());
504     QVERIFY(flickable->isFlickingVertically());
505     QVERIFY(!flickable->isFlickingHorizontally());
506     QVERIFY(flickable->isMoving());
507     QVERIFY(flickable->isMovingVertically());
508     QVERIFY(!flickable->isMovingHorizontally());
509     QCOMPARE(vMoveSpy.count(), 1);
510     QCOMPARE(hMoveSpy.count(), 0);
511     QCOMPARE(moveSpy.count(), 1);
512     QCOMPARE(vFlickSpy.count(), 1);
513     QCOMPARE(hFlickSpy.count(), 0);
514     QCOMPARE(flickSpy.count(), 1);
515
516     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(20, 50));
517     QTRY_VERIFY(!flickable->isFlicking());
518     QVERIFY(!flickable->isFlickingVertically());
519     QVERIFY(flickable->isMoving());
520     QVERIFY(flickable->isMovingVertically());
521
522     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(20,50));
523     QVERIFY(!flickable->isFlicking());
524     QVERIFY(!flickable->isFlickingVertically());
525     QTRY_VERIFY(!flickable->isMoving());
526     QVERIFY(!flickable->isMovingVertically());
527
528     delete canvas;
529 }
530
531 void tst_qquickflickable::disabled()
532 {
533     QQuickView *canvas = new QQuickView;
534     canvas->setSource(testFileUrl("disabled.qml"));
535     canvas->show();
536     canvas->requestActivateWindow();
537     QVERIFY(canvas->rootObject() != 0);
538
539     QQuickFlickable *flick = canvas->rootObject()->findChild<QQuickFlickable*>("flickable");
540     QVERIFY(flick != 0);
541
542     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50, 90));
543
544     QTest::mouseMove(canvas, QPoint(50, 80));
545     QTest::mouseMove(canvas, QPoint(50, 70));
546     QTest::mouseMove(canvas, QPoint(50, 60));
547
548     QVERIFY(flick->isMoving() == false);
549
550     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50, 60));
551
552     // verify that mouse clicks on other elements still work (QTBUG-20584)
553     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50, 10));
554     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50, 10));
555
556     QTRY_VERIFY(canvas->rootObject()->property("clicked").toBool() == true);
557 }
558
559 void tst_qquickflickable::flickVelocity()
560 {
561 #ifdef Q_OS_MAC
562     QSKIP("Producing flicks on Mac CI impossible due to timing problems");
563 #endif
564
565     QQuickView *canvas = new QQuickView;
566     canvas->setSource(testFileUrl("flickable03.qml"));
567     canvas->show();
568     canvas->requestActivateWindow();
569     QVERIFY(canvas->rootObject() != 0);
570
571     QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(canvas->rootObject());
572     QVERIFY(flickable != 0);
573
574     // flick up
575     flick(canvas, QPoint(20,190), QPoint(20, 50), 200);
576     QVERIFY(flickable->verticalVelocity() > 0.0);
577     QTRY_VERIFY(flickable->verticalVelocity() == 0.0);
578
579     // flick down
580     flick(canvas, QPoint(20,10), QPoint(20, 140), 200);
581     QVERIFY(flickable->verticalVelocity() < 0.0);
582     QTRY_VERIFY(flickable->verticalVelocity() == 0.0);
583
584     // Flick multiple times and verify that flick acceleration is applied.
585     QQuickFlickablePrivate *fp = QQuickFlickablePrivate::get(flickable);
586     bool boosted = false;
587     for (int i = 0; i < 6; ++i) {
588         flick(canvas, QPoint(20,390), QPoint(20, 50), 200);
589         boosted |= fp->flickBoost > 1.0;
590     }
591     QVERIFY(boosted);
592
593     // Flick in opposite direction -> boost cancelled.
594     flick(canvas, QPoint(20,10), QPoint(20, 340), 200);
595     QTRY_VERIFY(flickable->verticalVelocity() < 0.0);
596     QVERIFY(fp->flickBoost == 1.0);
597
598     delete canvas;
599 }
600
601 void tst_qquickflickable::margins()
602 {
603     QQmlEngine engine;
604     QQmlComponent c(&engine, testFileUrl("margins.qml"));
605     QQuickItem *root = qobject_cast<QQuickItem*>(c.create());
606     QQuickFlickable *obj = qobject_cast<QQuickFlickable*>(root);
607     QVERIFY(obj != 0);
608
609     // starting state
610     QCOMPARE(obj->contentX(), -40.);
611     QCOMPARE(obj->contentY(), -20.);
612     QCOMPARE(obj->contentWidth(), 1600.);
613     QCOMPARE(obj->contentHeight(), 600.);
614     QCOMPARE(obj->xOrigin(), 0.);
615     QCOMPARE(obj->yOrigin(), 0.);
616
617     // Reduce left margin
618     obj->setLeftMargin(30);
619     QTRY_COMPARE(obj->contentX(), -30.);
620
621     // Reduce top margin
622     obj->setTopMargin(20);
623     QTRY_COMPARE(obj->contentY(), -20.);
624
625     // position to the far right, including margin
626     obj->setContentX(1600 + 50 - obj->width());
627     obj->returnToBounds();
628     QTest::qWait(200);
629     QCOMPARE(obj->contentX(), 1600. + 50. - obj->width());
630
631     // position beyond the far right, including margin
632     obj->setContentX(1600 + 50 - obj->width() + 1.);
633     obj->returnToBounds();
634     QTRY_COMPARE(obj->contentX(), 1600. + 50. - obj->width());
635
636     // Reduce right margin
637     obj->setRightMargin(40);
638     QTRY_COMPARE(obj->contentX(), 1600. + 40. - obj->width());
639     QCOMPARE(obj->contentWidth(), 1600.);
640
641     // position to the far bottom, including margin
642     obj->setContentY(600 + 30 - obj->height());
643     obj->returnToBounds();
644     QTest::qWait(200);
645     QCOMPARE(obj->contentY(), 600. + 30. - obj->height());
646
647     // position beyond the far bottom, including margin
648     obj->setContentY(600 + 30 - obj->height() + 1.);
649     obj->returnToBounds();
650     QTRY_COMPARE(obj->contentY(), 600. + 30. - obj->height());
651
652     // Reduce bottom margin
653     obj->setBottomMargin(20);
654     QTRY_COMPARE(obj->contentY(), 600. + 20. - obj->height());
655     QCOMPARE(obj->contentHeight(), 600.);
656
657     delete root;
658 }
659
660 QTEST_MAIN(tst_qquickflickable)
661
662 #include "tst_qquickflickable.moc"