5fa0c7f665e9b0603f329555dc33a534889e60ab
[profile/ivi/qtdeclarative.git] / tests / auto / qtquick2 / qquickpositioners / tst_qquickpositioners.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: http://www.qt-project.org/
6 **
7 ** This file is part of the test suite of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 #include <QtTest/QtTest>
42 #include <private/qlistmodelinterface_p.h>
43 #include <QtQuick/qquickview.h>
44 #include <qdeclarativeengine.h>
45 #include <QtQuick/private/qquickrectangle_p.h>
46 #include <QtQuick/private/qquickpositioners_p.h>
47 #include <QtQuick/private/qdeclarativetransition_p.h>
48 #include <private/qquickitem_p.h>
49 #include <qdeclarativeexpression.h>
50 #include "../../shared/util.h"
51
52 class tst_qquickpositioners : public QDeclarativeDataTest
53 {
54     Q_OBJECT
55 public:
56     tst_qquickpositioners();
57
58 private slots:
59     void test_horizontal();
60     void test_horizontal_rtl();
61     void test_horizontal_spacing();
62     void test_horizontal_spacing_rightToLeft();
63     void test_horizontal_animated();
64     void test_horizontal_animated_rightToLeft();
65     void test_horizontal_animated_disabled();
66     void test_vertical();
67     void test_vertical_spacing();
68     void test_vertical_animated();
69     void test_grid();
70     void test_grid_topToBottom();
71     void test_grid_rightToLeft();
72     void test_grid_spacing();
73     void test_grid_row_column_spacing();
74     void test_grid_animated();
75     void test_grid_animated_rightToLeft();
76     void test_grid_zero_columns();
77     void test_propertychanges();
78     void test_repeater();
79     void test_flow();
80     void test_flow_rightToLeft();
81     void test_flow_topToBottom();
82     void test_flow_resize();
83     void test_flow_resize_rightToLeft();
84     void test_flow_implicit_resize();
85     void test_conflictinganchors();
86     void test_mirroring();
87     void test_allInvisible();
88     void test_attachedproperties();
89     void test_attachedproperties_data();
90     void test_attachedproperties_dynamic();
91
92 private:
93     QQuickView *createView(const QString &filename, bool wait=true);
94 };
95
96 tst_qquickpositioners::tst_qquickpositioners()
97 {
98 }
99
100 void tst_qquickpositioners::test_horizontal()
101 {
102     QQuickView *canvas = createView(testFile("horizontal.qml"));
103
104     canvas->rootObject()->setProperty("testRightToLeft", false);
105
106     QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
107     QVERIFY(one != 0);
108
109     QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
110     QVERIFY(two != 0);
111
112     QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
113     QVERIFY(three != 0);
114
115     QCOMPARE(one->x(), 0.0);
116     QCOMPARE(one->y(), 0.0);
117     QCOMPARE(two->x(), 50.0);
118     QCOMPARE(two->y(), 0.0);
119     QCOMPARE(three->x(), 70.0);
120     QCOMPARE(three->y(), 0.0);
121
122     QQuickItem *row = canvas->rootObject()->findChild<QQuickItem*>("row");
123     QCOMPARE(row->width(), 110.0);
124     QCOMPARE(row->height(), 50.0);
125
126     delete canvas;
127 }
128
129 void tst_qquickpositioners::test_horizontal_rtl()
130 {
131     QQuickView *canvas = createView(testFile("horizontal.qml"));
132
133     canvas->rootObject()->setProperty("testRightToLeft", true);
134
135     QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
136     QVERIFY(one != 0);
137
138     QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
139     QVERIFY(two != 0);
140
141     QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
142     QVERIFY(three != 0);
143
144     QCOMPARE(one->x(), 60.0);
145     QCOMPARE(one->y(), 0.0);
146     QCOMPARE(two->x(), 40.0);
147     QCOMPARE(two->y(), 0.0);
148     QCOMPARE(three->x(), 0.0);
149     QCOMPARE(three->y(), 0.0);
150
151     QQuickItem *row = canvas->rootObject()->findChild<QQuickItem*>("row");
152     QCOMPARE(row->width(), 110.0);
153     QCOMPARE(row->height(), 50.0);
154
155     // Change the width of the row and check that items stay to the right
156     row->setWidth(200);
157     QTRY_COMPARE(one->x(), 150.0);
158     QCOMPARE(one->y(), 0.0);
159     QCOMPARE(two->x(), 130.0);
160     QCOMPARE(two->y(), 0.0);
161     QCOMPARE(three->x(), 90.0);
162     QCOMPARE(three->y(), 0.0);
163
164     delete canvas;
165 }
166
167 void tst_qquickpositioners::test_horizontal_spacing()
168 {
169     QQuickView *canvas = createView(testFile("horizontal-spacing.qml"));
170
171     canvas->rootObject()->setProperty("testRightToLeft", false);
172
173     QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
174     QVERIFY(one != 0);
175
176     QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
177     QVERIFY(two != 0);
178
179     QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
180     QVERIFY(three != 0);
181
182     QCOMPARE(one->x(), 0.0);
183     QCOMPARE(one->y(), 0.0);
184     QCOMPARE(two->x(), 60.0);
185     QCOMPARE(two->y(), 0.0);
186     QCOMPARE(three->x(), 90.0);
187     QCOMPARE(three->y(), 0.0);
188
189     QQuickItem *row = canvas->rootObject()->findChild<QQuickItem*>("row");
190     QCOMPARE(row->width(), 130.0);
191     QCOMPARE(row->height(), 50.0);
192
193     delete canvas;
194 }
195
196 void tst_qquickpositioners::test_horizontal_spacing_rightToLeft()
197 {
198     QQuickView *canvas = createView(testFile("horizontal-spacing.qml"));
199
200     canvas->rootObject()->setProperty("testRightToLeft", true);
201
202     QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
203     QVERIFY(one != 0);
204
205     QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
206     QVERIFY(two != 0);
207
208     QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
209     QVERIFY(three != 0);
210
211     QCOMPARE(one->x(), 80.0);
212     QCOMPARE(one->y(), 0.0);
213     QCOMPARE(two->x(), 50.0);
214     QCOMPARE(two->y(), 0.0);
215     QCOMPARE(three->x(), 00.0);
216     QCOMPARE(three->y(), 0.0);
217
218     QQuickItem *row = canvas->rootObject()->findChild<QQuickItem*>("row");
219     QCOMPARE(row->width(), 130.0);
220     QCOMPARE(row->height(), 50.0);
221
222     delete canvas;
223 }
224
225 void tst_qquickpositioners::test_horizontal_animated()
226 {
227     QQuickView *canvas = createView(testFile("horizontal-animated.qml"), false);
228
229     canvas->rootObject()->setProperty("testRightToLeft", false);
230
231     QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
232     QVERIFY(one != 0);
233
234     QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
235     QVERIFY(two != 0);
236
237     QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
238     QVERIFY(three != 0);
239
240     //Note that they animate in
241     QCOMPARE(one->x(), -100.0);
242     QCOMPARE(two->x(), -100.0);
243     QCOMPARE(three->x(), -100.0);
244
245     QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
246
247     QQuickItem *row = canvas->rootObject()->findChild<QQuickItem*>("row");
248     QVERIFY(row);
249     QCOMPARE(row->width(), 100.0);
250     QCOMPARE(row->height(), 50.0);
251
252     //QTRY_COMPARE used instead of waiting for the expected time of animation completion
253     //Note that this means the duration of the animation is NOT tested
254
255     QTRY_COMPARE(one->x(), 0.0);
256     QTRY_COMPARE(one->y(), 0.0);
257     QTRY_COMPARE(two->isVisible(), false);
258     QTRY_COMPARE(two->x(), -100.0);//Not 'in' yet
259     QTRY_COMPARE(two->y(), 0.0);
260     QTRY_COMPARE(three->x(), 50.0);
261     QTRY_COMPARE(three->y(), 0.0);
262
263     //Add 'two'
264     two->setVisible(true);
265     QTRY_COMPARE(two->isVisible(), true);
266     QTRY_COMPARE(row->width(), 150.0);
267     QTRY_COMPARE(row->height(), 50.0);
268
269     QTest::qWait(0);//Let the animation start
270     QVERIFY(two->x() >= -100.0 && two->x() < 50.0);
271     QVERIFY(three->x() >= 50.0 && three->x() < 100.0);
272
273     QTRY_COMPARE(two->x(), 50.0);
274     QTRY_COMPARE(three->x(), 100.0);
275
276     delete canvas;
277 }
278
279 void tst_qquickpositioners::test_horizontal_animated_rightToLeft()
280 {
281     QQuickView *canvas = createView(testFile("horizontal-animated.qml"), false);
282
283     canvas->rootObject()->setProperty("testRightToLeft", true);
284
285     QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
286     QVERIFY(one != 0);
287
288     QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
289     QVERIFY(two != 0);
290
291     QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
292     QVERIFY(three != 0);
293
294     //Note that they animate in
295     QCOMPARE(one->x(), -100.0);
296     QCOMPARE(two->x(), -100.0);
297     QCOMPARE(three->x(), -100.0);
298
299     QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
300
301     QQuickItem *row = canvas->rootObject()->findChild<QQuickItem*>("row");
302     QVERIFY(row);
303     QCOMPARE(row->width(), 100.0);
304     QCOMPARE(row->height(), 50.0);
305
306     //QTRY_COMPARE used instead of waiting for the expected time of animation completion
307     //Note that this means the duration of the animation is NOT tested
308
309     QTRY_COMPARE(one->x(), 50.0);
310     QTRY_COMPARE(one->y(), 0.0);
311     QTRY_COMPARE(two->isVisible(), false);
312     QTRY_COMPARE(two->x(), -100.0);//Not 'in' yet
313     QTRY_COMPARE(two->y(), 0.0);
314     QTRY_COMPARE(three->x(), 0.0);
315     QTRY_COMPARE(three->y(), 0.0);
316
317     //Add 'two'
318     two->setVisible(true);
319     QTRY_COMPARE(two->isVisible(), true);
320
321     // New size should propagate after visible change
322     QTRY_COMPARE(row->width(), 150.0);
323     QTRY_COMPARE(row->height(), 50.0);
324
325     QTest::qWait(0);//Let the animation start
326     QVERIFY(one->x() >= 50.0 && one->x() < 100);
327     QVERIFY(two->x() >= -100.0 && two->x() < 50.0);
328
329     QTRY_COMPARE(one->x(), 100.0);
330     QTRY_COMPARE(two->x(), 50.0);
331
332     delete canvas;
333 }
334
335 void tst_qquickpositioners::test_horizontal_animated_disabled()
336 {
337     QQuickView *canvas = createView(testFile("horizontal-animated-disabled.qml"));
338
339     QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
340     QVERIFY(one != 0);
341
342     QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
343     QVERIFY(two != 0);
344
345     QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
346     QVERIFY(three != 0);
347
348     QQuickItem *row = canvas->rootObject()->findChild<QQuickItem*>("row");
349     QVERIFY(row);
350
351     qApp->processEvents();
352
353     QCOMPARE(one->x(), 0.0);
354     QCOMPARE(one->y(), 0.0);
355     QCOMPARE(two->isVisible(), false);
356     QCOMPARE(two->x(), -100.0);//Not 'in' yet
357     QCOMPARE(two->y(), 0.0);
358     QCOMPARE(three->x(), 50.0);
359     QCOMPARE(three->y(), 0.0);
360
361     //Add 'two'
362     two->setVisible(true);
363     QCOMPARE(two->isVisible(), true);
364     QTRY_COMPARE(row->width(), 150.0);
365     QTRY_COMPARE(row->height(), 50.0);
366
367     QTRY_COMPARE(two->x(), 50.0);
368     QTRY_COMPARE(three->x(), 100.0);
369
370     delete canvas;
371 }
372
373 void tst_qquickpositioners::test_vertical()
374 {
375     QQuickView *canvas = createView(testFile("vertical.qml"));
376
377     QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
378     QVERIFY(one != 0);
379
380     QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
381     QVERIFY(two != 0);
382
383     QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
384     QVERIFY(three != 0);
385
386     QCOMPARE(one->x(), 0.0);
387     QCOMPARE(one->y(), 0.0);
388     QCOMPARE(two->x(), 0.0);
389     QCOMPARE(two->y(), 50.0);
390     QCOMPARE(three->x(), 0.0);
391     QCOMPARE(three->y(), 60.0);
392
393     QQuickItem *column = canvas->rootObject()->findChild<QQuickItem*>("column");
394     QVERIFY(column);
395     QCOMPARE(column->height(), 80.0);
396     QCOMPARE(column->width(), 50.0);
397
398     delete canvas;
399 }
400
401 void tst_qquickpositioners::test_vertical_spacing()
402 {
403     QQuickView *canvas = createView(testFile("vertical-spacing.qml"));
404
405     QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
406     QVERIFY(one != 0);
407
408     QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
409     QVERIFY(two != 0);
410
411     QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
412     QVERIFY(three != 0);
413
414     QCOMPARE(one->x(), 0.0);
415     QCOMPARE(one->y(), 0.0);
416     QCOMPARE(two->x(), 0.0);
417     QCOMPARE(two->y(), 60.0);
418     QCOMPARE(three->x(), 0.0);
419     QCOMPARE(three->y(), 80.0);
420
421     QQuickItem *column = canvas->rootObject()->findChild<QQuickItem*>("column");
422     QCOMPARE(column->height(), 100.0);
423     QCOMPARE(column->width(), 50.0);
424
425     delete canvas;
426 }
427
428 void tst_qquickpositioners::test_vertical_animated()
429 {
430     QQuickView *canvas = createView(testFile("vertical-animated.qml"), false);
431
432     //Note that they animate in
433     QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
434     QVERIFY(one != 0);
435     QCOMPARE(one->y(), -100.0);
436
437     QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
438     QVERIFY(two != 0);
439     QCOMPARE(two->y(), -100.0);
440
441     QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
442     QVERIFY(three != 0);
443     QCOMPARE(three->y(), -100.0);
444
445     QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
446
447     QQuickItem *column = canvas->rootObject()->findChild<QQuickItem*>("column");
448     QVERIFY(column);
449     QCOMPARE(column->height(), 100.0);
450     QCOMPARE(column->width(), 50.0);
451
452     //QTRY_COMPARE used instead of waiting for the expected time of animation completion
453     //Note that this means the duration of the animation is NOT tested
454
455     QTRY_COMPARE(one->y(), 0.0);
456     QTRY_COMPARE(one->x(), 0.0);
457     QTRY_COMPARE(two->isVisible(), false);
458     QTRY_COMPARE(two->y(), -100.0);//Not 'in' yet
459     QTRY_COMPARE(two->x(), 0.0);
460     QTRY_COMPARE(three->y(), 50.0);
461     QTRY_COMPARE(three->x(), 0.0);
462
463     //Add 'two'
464     two->setVisible(true);
465     QTRY_COMPARE(two->isVisible(), true);
466     QTRY_COMPARE(column->height(), 150.0);
467     QTRY_COMPARE(column->width(), 50.0);
468     QTest::qWait(0);//Let the animation start
469     QVERIFY(two->y() >= -100.0 && two->y() < 50.0);
470     QVERIFY(three->y() >= 50.0 && three->y() < 100.0);
471
472     QTRY_COMPARE(two->y(), 50.0);
473     QTRY_COMPARE(three->y(), 100.0);
474
475     delete canvas;
476 }
477
478 void tst_qquickpositioners::test_grid()
479 {
480     QQuickView *canvas = createView(testFile("gridtest.qml"));
481
482     QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
483     QVERIFY(one != 0);
484     QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
485     QVERIFY(two != 0);
486     QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
487     QVERIFY(three != 0);
488     QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
489     QVERIFY(four != 0);
490     QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
491     QVERIFY(five != 0);
492
493     QCOMPARE(one->x(), 0.0);
494     QCOMPARE(one->y(), 0.0);
495     QCOMPARE(two->x(), 50.0);
496     QCOMPARE(two->y(), 0.0);
497     QCOMPARE(three->x(), 70.0);
498     QCOMPARE(three->y(), 0.0);
499     QCOMPARE(four->x(), 0.0);
500     QCOMPARE(four->y(), 50.0);
501     QCOMPARE(five->x(), 50.0);
502     QCOMPARE(five->y(), 50.0);
503
504     QQuickGrid *grid = canvas->rootObject()->findChild<QQuickGrid*>("grid");
505     QCOMPARE(grid->flow(), QQuickGrid::LeftToRight);
506     QCOMPARE(grid->width(), 100.0);
507     QCOMPARE(grid->height(), 100.0);
508
509     delete canvas;
510 }
511
512 void tst_qquickpositioners::test_grid_topToBottom()
513 {
514     QQuickView *canvas = createView(testFile("grid-toptobottom.qml"));
515
516     QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
517     QVERIFY(one != 0);
518     QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
519     QVERIFY(two != 0);
520     QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
521     QVERIFY(three != 0);
522     QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
523     QVERIFY(four != 0);
524     QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
525     QVERIFY(five != 0);
526
527     QCOMPARE(one->x(), 0.0);
528     QCOMPARE(one->y(), 0.0);
529     QCOMPARE(two->x(), 0.0);
530     QCOMPARE(two->y(), 50.0);
531     QCOMPARE(three->x(), 0.0);
532     QCOMPARE(three->y(), 100.0);
533     QCOMPARE(four->x(), 50.0);
534     QCOMPARE(four->y(), 0.0);
535     QCOMPARE(five->x(), 50.0);
536     QCOMPARE(five->y(), 50.0);
537
538     QQuickGrid *grid = canvas->rootObject()->findChild<QQuickGrid*>("grid");
539     QCOMPARE(grid->flow(), QQuickGrid::TopToBottom);
540     QCOMPARE(grid->width(), 100.0);
541     QCOMPARE(grid->height(), 120.0);
542
543     delete canvas;
544 }
545
546 void tst_qquickpositioners::test_grid_rightToLeft()
547 {
548     QQuickView *canvas = createView(testFile("gridtest.qml"));
549
550     canvas->rootObject()->setProperty("testRightToLeft", true);
551
552     QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
553     QVERIFY(one != 0);
554     QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
555     QVERIFY(two != 0);
556     QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
557     QVERIFY(three != 0);
558     QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
559     QVERIFY(four != 0);
560     QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
561     QVERIFY(five != 0);
562
563     QCOMPARE(one->x(), 50.0);
564     QCOMPARE(one->y(), 0.0);
565     QCOMPARE(two->x(), 30.0);
566     QCOMPARE(two->y(), 0.0);
567     QCOMPARE(three->x(), 0.0);
568     QCOMPARE(three->y(), 0.0);
569     QCOMPARE(four->x(), 50.0);
570     QCOMPARE(four->y(), 50.0);
571     QCOMPARE(five->x(), 40.0);
572     QCOMPARE(five->y(), 50.0);
573
574     QQuickGrid *grid = canvas->rootObject()->findChild<QQuickGrid*>("grid");
575     QCOMPARE(grid->layoutDirection(), Qt::RightToLeft);
576     QCOMPARE(grid->width(), 100.0);
577     QCOMPARE(grid->height(), 100.0);
578
579     // Change the width of the grid and check that items stay to the right
580     grid->setWidth(200);
581     QTRY_COMPARE(one->x(), 150.0);
582     QCOMPARE(one->y(), 0.0);
583     QCOMPARE(two->x(), 130.0);
584     QCOMPARE(two->y(), 0.0);
585     QCOMPARE(three->x(), 100.0);
586     QCOMPARE(three->y(), 0.0);
587     QCOMPARE(four->x(), 150.0);
588     QCOMPARE(four->y(), 50.0);
589     QCOMPARE(five->x(), 140.0);
590     QCOMPARE(five->y(), 50.0);
591
592     delete canvas;
593 }
594
595 void tst_qquickpositioners::test_grid_spacing()
596 {
597     QQuickView *canvas = createView(testFile("grid-spacing.qml"));
598
599     QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
600     QVERIFY(one != 0);
601     QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
602     QVERIFY(two != 0);
603     QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
604     QVERIFY(three != 0);
605     QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
606     QVERIFY(four != 0);
607     QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
608     QVERIFY(five != 0);
609
610     QCOMPARE(one->x(), 0.0);
611     QCOMPARE(one->y(), 0.0);
612     QCOMPARE(two->x(), 54.0);
613     QCOMPARE(two->y(), 0.0);
614     QCOMPARE(three->x(), 78.0);
615     QCOMPARE(three->y(), 0.0);
616     QCOMPARE(four->x(), 0.0);
617     QCOMPARE(four->y(), 54.0);
618     QCOMPARE(five->x(), 54.0);
619     QCOMPARE(five->y(), 54.0);
620
621     QQuickItem *grid = canvas->rootObject()->findChild<QQuickItem*>("grid");
622     QCOMPARE(grid->width(), 128.0);
623     QCOMPARE(grid->height(), 104.0);
624
625     delete canvas;
626 }
627
628 void tst_qquickpositioners::test_grid_row_column_spacing()
629 {
630     QQuickView *canvas = createView(testFile("grid-row-column-spacing.qml"));
631
632     QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
633     QVERIFY(one != 0);
634     QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
635     QVERIFY(two != 0);
636     QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
637     QVERIFY(three != 0);
638     QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
639     QVERIFY(four != 0);
640     QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
641     QVERIFY(five != 0);
642
643     QCOMPARE(one->x(), 0.0);
644     QCOMPARE(one->y(), 0.0);
645     QCOMPARE(two->x(), 61.0);
646     QCOMPARE(two->y(), 0.0);
647     QCOMPARE(three->x(), 92.0);
648     QCOMPARE(three->y(), 0.0);
649     QCOMPARE(four->x(), 0.0);
650     QCOMPARE(four->y(), 57.0);
651     QCOMPARE(five->x(), 61.0);
652     QCOMPARE(five->y(), 57.0);
653
654     QQuickItem *grid = canvas->rootObject()->findChild<QQuickItem*>("grid");
655     QCOMPARE(grid->width(), 142.0);
656     QCOMPARE(grid->height(), 107.0);
657
658     delete canvas;
659 }
660
661 void tst_qquickpositioners::test_grid_animated()
662 {
663     QQuickView *canvas = createView(testFile("grid-animated.qml"), false);
664
665     canvas->rootObject()->setProperty("testRightToLeft", false);
666
667     //Note that all animate in
668     QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
669     QVERIFY(one != 0);
670     QCOMPARE(one->x(), -100.0);
671     QCOMPARE(one->y(), -100.0);
672
673     QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
674     QVERIFY(two != 0);
675     QCOMPARE(two->x(), -100.0);
676     QCOMPARE(two->y(), -100.0);
677
678     QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
679     QVERIFY(three != 0);
680     QCOMPARE(three->x(), -100.0);
681     QCOMPARE(three->y(), -100.0);
682
683     QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
684     QVERIFY(four != 0);
685     QCOMPARE(four->x(), -100.0);
686     QCOMPARE(four->y(), -100.0);
687
688     QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
689     QVERIFY(five != 0);
690     QCOMPARE(five->x(), -100.0);
691     QCOMPARE(five->y(), -100.0);
692
693     QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
694
695     QQuickItem *grid = canvas->rootObject()->findChild<QQuickItem*>("grid");
696     QVERIFY(grid);
697     QCOMPARE(grid->width(), 150.0);
698     QCOMPARE(grid->height(), 100.0);
699
700     //QTRY_COMPARE used instead of waiting for the expected time of animation completion
701     //Note that this means the duration of the animation is NOT tested
702
703     QTRY_COMPARE(one->y(), 0.0);
704     QTRY_COMPARE(one->x(), 0.0);
705     QTRY_COMPARE(two->isVisible(), false);
706     QTRY_COMPARE(two->y(), -100.0);
707     QTRY_COMPARE(two->x(), -100.0);
708     QTRY_COMPARE(three->y(), 0.0);
709     QTRY_COMPARE(three->x(), 50.0);
710     QTRY_COMPARE(four->y(), 0.0);
711     QTRY_COMPARE(four->x(), 100.0);
712     QTRY_COMPARE(five->y(), 50.0);
713     QTRY_COMPARE(five->x(), 0.0);
714
715     //Add 'two'
716     two->setVisible(true);
717     QCOMPARE(two->isVisible(), true);
718     QCOMPARE(grid->width(), 150.0);
719     QCOMPARE(grid->height(), 100.0);
720     QTest::qWait(0);//Let the animation start
721     QCOMPARE(two->x(), -100.0);
722     QCOMPARE(two->y(), -100.0);
723     QCOMPARE(one->x(), 0.0);
724     QCOMPARE(one->y(), 0.0);
725     QCOMPARE(three->x(), 50.0);
726     QCOMPARE(three->y(), 0.0);
727     QCOMPARE(four->x(), 100.0);
728     QCOMPARE(four->y(), 0.0);
729     QCOMPARE(five->x(), 0.0);
730     QCOMPARE(five->y(), 50.0);
731     //Let the animation complete
732     QTRY_COMPARE(two->x(), 50.0);
733     QTRY_COMPARE(two->y(), 0.0);
734     QTRY_COMPARE(one->x(), 0.0);
735     QTRY_COMPARE(one->y(), 0.0);
736     QTRY_COMPARE(three->x(), 100.0);
737     QTRY_COMPARE(three->y(), 0.0);
738     QTRY_COMPARE(four->x(), 0.0);
739     QTRY_COMPARE(four->y(), 50.0);
740     QTRY_COMPARE(five->x(), 50.0);
741     QTRY_COMPARE(five->y(), 50.0);
742
743     delete canvas;
744 }
745
746 void tst_qquickpositioners::test_grid_animated_rightToLeft()
747 {
748     QQuickView *canvas = createView(testFile("grid-animated.qml"), false);
749
750     canvas->rootObject()->setProperty("testRightToLeft", true);
751
752     //Note that all animate in
753     QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
754     QVERIFY(one != 0);
755     QCOMPARE(one->x(), -100.0);
756     QCOMPARE(one->y(), -100.0);
757
758     QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
759     QVERIFY(two != 0);
760     QCOMPARE(two->x(), -100.0);
761     QCOMPARE(two->y(), -100.0);
762
763     QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
764     QVERIFY(three != 0);
765     QCOMPARE(three->x(), -100.0);
766     QCOMPARE(three->y(), -100.0);
767
768     QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
769     QVERIFY(four != 0);
770     QCOMPARE(four->x(), -100.0);
771     QCOMPARE(four->y(), -100.0);
772
773     QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
774     QVERIFY(five != 0);
775     QCOMPARE(five->x(), -100.0);
776     QCOMPARE(five->y(), -100.0);
777
778     QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
779
780     QQuickItem *grid = canvas->rootObject()->findChild<QQuickItem*>("grid");
781     QVERIFY(grid);
782     QCOMPARE(grid->width(), 150.0);
783     QCOMPARE(grid->height(), 100.0);
784
785     //QTRY_COMPARE used instead of waiting for the expected time of animation completion
786     //Note that this means the duration of the animation is NOT tested
787
788     QTRY_COMPARE(one->y(), 0.0);
789     QTRY_COMPARE(one->x(), 100.0);
790     QTRY_COMPARE(two->isVisible(), false);
791     QTRY_COMPARE(two->y(), -100.0);
792     QTRY_COMPARE(two->x(), -100.0);
793     QTRY_COMPARE(three->y(), 0.0);
794     QTRY_COMPARE(three->x(), 50.0);
795     QTRY_COMPARE(four->y(), 0.0);
796     QTRY_COMPARE(four->x(), 0.0);
797     QTRY_COMPARE(five->y(), 50.0);
798     QTRY_COMPARE(five->x(), 100.0);
799
800     //Add 'two'
801     two->setVisible(true);
802     QCOMPARE(two->isVisible(), true);
803     QCOMPARE(grid->width(), 150.0);
804     QCOMPARE(grid->height(), 100.0);
805     QTest::qWait(0);//Let the animation start
806     QCOMPARE(two->x(), -100.0);
807     QCOMPARE(two->y(), -100.0);
808     QCOMPARE(one->x(), 100.0);
809     QCOMPARE(one->y(), 0.0);
810     QCOMPARE(three->x(), 50.0);
811     QCOMPARE(three->y(), 0.0);
812     QCOMPARE(four->x(), 0.0);
813     QCOMPARE(four->y(), 0.0);
814     QCOMPARE(five->x(), 100.0);
815     QCOMPARE(five->y(), 50.0);
816     //Let the animation complete
817     QTRY_COMPARE(two->x(), 50.0);
818     QTRY_COMPARE(two->y(), 0.0);
819     QTRY_COMPARE(one->x(), 100.0);
820     QTRY_COMPARE(one->y(), 0.0);
821     QTRY_COMPARE(three->x(), 0.0);
822     QTRY_COMPARE(three->y(), 0.0);
823     QTRY_COMPARE(four->x(), 100.0);
824     QTRY_COMPARE(four->y(), 50.0);
825     QTRY_COMPARE(five->x(), 50.0);
826     QTRY_COMPARE(five->y(), 50.0);
827
828     delete canvas;
829 }
830
831 void tst_qquickpositioners::test_grid_zero_columns()
832 {
833     QQuickView *canvas = createView(testFile("gridzerocolumns.qml"));
834
835     QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
836     QVERIFY(one != 0);
837     QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
838     QVERIFY(two != 0);
839     QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
840     QVERIFY(three != 0);
841     QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
842     QVERIFY(four != 0);
843     QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
844     QVERIFY(five != 0);
845
846     QCOMPARE(one->x(), 0.0);
847     QCOMPARE(one->y(), 0.0);
848     QCOMPARE(two->x(), 50.0);
849     QCOMPARE(two->y(), 0.0);
850     QCOMPARE(three->x(), 70.0);
851     QCOMPARE(three->y(), 0.0);
852     QCOMPARE(four->x(), 120.0);
853     QCOMPARE(four->y(), 0.0);
854     QCOMPARE(five->x(), 0.0);
855     QCOMPARE(five->y(), 50.0);
856
857     QQuickItem *grid = canvas->rootObject()->findChild<QQuickItem*>("grid");
858     QCOMPARE(grid->width(), 170.0);
859     QCOMPARE(grid->height(), 60.0);
860
861     delete canvas;
862 }
863
864 void tst_qquickpositioners::test_propertychanges()
865 {
866     QQuickView *canvas = createView(testFile("propertychangestest.qml"));
867
868     QQuickGrid *grid = qobject_cast<QQuickGrid*>(canvas->rootObject());
869     QVERIFY(grid != 0);
870     QDeclarativeTransition *rowTransition = canvas->rootObject()->findChild<QDeclarativeTransition*>("rowTransition");
871     QDeclarativeTransition *columnTransition = canvas->rootObject()->findChild<QDeclarativeTransition*>("columnTransition");
872
873     QSignalSpy addSpy(grid, SIGNAL(addChanged()));
874     QSignalSpy moveSpy(grid, SIGNAL(moveChanged()));
875     QSignalSpy columnsSpy(grid, SIGNAL(columnsChanged()));
876     QSignalSpy rowsSpy(grid, SIGNAL(rowsChanged()));
877
878     QVERIFY(grid);
879     QVERIFY(rowTransition);
880     QVERIFY(columnTransition);
881     QCOMPARE(grid->add(), columnTransition);
882     QCOMPARE(grid->move(), columnTransition);
883     QCOMPARE(grid->columns(), 4);
884     QCOMPARE(grid->rows(), -1);
885
886     grid->setAdd(rowTransition);
887     grid->setMove(rowTransition);
888     QCOMPARE(grid->add(), rowTransition);
889     QCOMPARE(grid->move(), rowTransition);
890     QCOMPARE(addSpy.count(),1);
891     QCOMPARE(moveSpy.count(),1);
892
893     grid->setAdd(rowTransition);
894     grid->setMove(rowTransition);
895     QCOMPARE(addSpy.count(),1);
896     QCOMPARE(moveSpy.count(),1);
897
898     grid->setAdd(0);
899     grid->setMove(0);
900     QCOMPARE(addSpy.count(),2);
901     QCOMPARE(moveSpy.count(),2);
902
903     grid->setColumns(-1);
904     grid->setRows(3);
905     QCOMPARE(grid->columns(), -1);
906     QCOMPARE(grid->rows(), 3);
907     QCOMPARE(columnsSpy.count(),1);
908     QCOMPARE(rowsSpy.count(),1);
909
910     grid->setColumns(-1);
911     grid->setRows(3);
912     QCOMPARE(columnsSpy.count(),1);
913     QCOMPARE(rowsSpy.count(),1);
914
915     grid->setColumns(2);
916     grid->setRows(2);
917     QCOMPARE(columnsSpy.count(),2);
918     QCOMPARE(rowsSpy.count(),2);
919
920     delete canvas;
921 }
922
923 void tst_qquickpositioners::test_repeater()
924 {
925     QQuickView *canvas = createView(testFile("repeatertest.qml"));
926
927     QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
928     QVERIFY(one != 0);
929
930     QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
931     QVERIFY(two != 0);
932
933     QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
934     QVERIFY(three != 0);
935
936     QCOMPARE(one->x(), 0.0);
937     QCOMPARE(one->y(), 0.0);
938     QCOMPARE(two->x(), 50.0);
939     QCOMPARE(two->y(), 0.0);
940     QCOMPARE(three->x(), 100.0);
941     QCOMPARE(three->y(), 0.0);
942
943     delete canvas;
944 }
945
946 void tst_qquickpositioners::test_flow()
947 {
948     QQuickView *canvas = createView(testFile("flowtest.qml"));
949
950     canvas->rootObject()->setProperty("testRightToLeft", false);
951
952     QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
953     QVERIFY(one != 0);
954     QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
955     QVERIFY(two != 0);
956     QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
957     QVERIFY(three != 0);
958     QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
959     QVERIFY(four != 0);
960     QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
961     QVERIFY(five != 0);
962
963     QCOMPARE(one->x(), 0.0);
964     QCOMPARE(one->y(), 0.0);
965     QCOMPARE(two->x(), 50.0);
966     QCOMPARE(two->y(), 0.0);
967     QCOMPARE(three->x(), 0.0);
968     QCOMPARE(three->y(), 50.0);
969     QCOMPARE(four->x(), 0.0);
970     QCOMPARE(four->y(), 70.0);
971     QCOMPARE(five->x(), 50.0);
972     QCOMPARE(five->y(), 70.0);
973
974     QQuickItem *flow = canvas->rootObject()->findChild<QQuickItem*>("flow");
975     QVERIFY(flow);
976     QCOMPARE(flow->width(), 90.0);
977     QCOMPARE(flow->height(), 120.0);
978
979     delete canvas;
980 }
981
982 void tst_qquickpositioners::test_flow_rightToLeft()
983 {
984     QQuickView *canvas = createView(testFile("flowtest.qml"));
985
986     canvas->rootObject()->setProperty("testRightToLeft", true);
987
988     QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
989     QVERIFY(one != 0);
990     QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
991     QVERIFY(two != 0);
992     QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
993     QVERIFY(three != 0);
994     QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
995     QVERIFY(four != 0);
996     QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
997     QVERIFY(five != 0);
998
999     QCOMPARE(one->x(), 40.0);
1000     QCOMPARE(one->y(), 0.0);
1001     QCOMPARE(two->x(), 20.0);
1002     QCOMPARE(two->y(), 0.0);
1003     QCOMPARE(three->x(), 40.0);
1004     QCOMPARE(three->y(), 50.0);
1005     QCOMPARE(four->x(), 40.0);
1006     QCOMPARE(four->y(), 70.0);
1007     QCOMPARE(five->x(), 30.0);
1008     QCOMPARE(five->y(), 70.0);
1009
1010     QQuickItem *flow = canvas->rootObject()->findChild<QQuickItem*>("flow");
1011     QVERIFY(flow);
1012     QCOMPARE(flow->width(), 90.0);
1013     QCOMPARE(flow->height(), 120.0);
1014
1015     delete canvas;
1016 }
1017
1018 void tst_qquickpositioners::test_flow_topToBottom()
1019 {
1020     QQuickView *canvas = createView(testFile("flowtest-toptobottom.qml"));
1021
1022     canvas->rootObject()->setProperty("testRightToLeft", false);
1023
1024     QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
1025     QVERIFY(one != 0);
1026     QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
1027     QVERIFY(two != 0);
1028     QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
1029     QVERIFY(three != 0);
1030     QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
1031     QVERIFY(four != 0);
1032     QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
1033     QVERIFY(five != 0);
1034
1035     QCOMPARE(one->x(), 0.0);
1036     QCOMPARE(one->y(), 0.0);
1037     QCOMPARE(two->x(), 50.0);
1038     QCOMPARE(two->y(), 0.0);
1039     QCOMPARE(three->x(), 50.0);
1040     QCOMPARE(three->y(), 50.0);
1041     QCOMPARE(four->x(), 100.0);
1042     QCOMPARE(four->y(), 00.0);
1043     QCOMPARE(five->x(), 100.0);
1044     QCOMPARE(five->y(), 50.0);
1045
1046     QQuickItem *flow = canvas->rootObject()->findChild<QQuickItem*>("flow");
1047     QVERIFY(flow);
1048     QCOMPARE(flow->height(), 90.0);
1049     QCOMPARE(flow->width(), 150.0);
1050
1051     canvas->rootObject()->setProperty("testRightToLeft", true);
1052
1053     QVERIFY(flow);
1054     QCOMPARE(flow->height(), 90.0);
1055     QCOMPARE(flow->width(), 150.0);
1056
1057     QCOMPARE(one->x(), 100.0);
1058     QCOMPARE(one->y(), 0.0);
1059     QCOMPARE(two->x(), 80.0);
1060     QCOMPARE(two->y(), 0.0);
1061     QCOMPARE(three->x(), 50.0);
1062     QCOMPARE(three->y(), 50.0);
1063     QCOMPARE(four->x(), 0.0);
1064     QCOMPARE(four->y(), 0.0);
1065     QCOMPARE(five->x(), 40.0);
1066     QCOMPARE(five->y(), 50.0);
1067
1068     delete canvas;
1069 }
1070
1071 void tst_qquickpositioners::test_flow_resize()
1072 {
1073     QQuickView *canvas = createView(testFile("flowtest.qml"));
1074
1075     QQuickItem *root = qobject_cast<QQuickItem*>(canvas->rootObject());
1076     QVERIFY(root);
1077     root->setWidth(125);
1078     root->setProperty("testRightToLeft", false);
1079
1080     QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
1081     QVERIFY(one != 0);
1082     QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
1083     QVERIFY(two != 0);
1084     QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
1085     QVERIFY(three != 0);
1086     QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
1087     QVERIFY(four != 0);
1088     QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
1089     QVERIFY(five != 0);
1090
1091     QTRY_COMPARE(one->x(), 0.0);
1092     QTRY_COMPARE(one->y(), 0.0);
1093     QTRY_COMPARE(two->x(), 50.0);
1094     QTRY_COMPARE(two->y(), 0.0);
1095     QTRY_COMPARE(three->x(), 70.0);
1096     QTRY_COMPARE(three->y(), 0.0);
1097     QTRY_COMPARE(four->x(), 0.0);
1098     QTRY_COMPARE(four->y(), 50.0);
1099     QTRY_COMPARE(five->x(), 50.0);
1100     QTRY_COMPARE(five->y(), 50.0);
1101
1102     delete canvas;
1103 }
1104
1105 void tst_qquickpositioners::test_flow_resize_rightToLeft()
1106 {
1107     QQuickView *canvas = createView(testFile("flowtest.qml"));
1108
1109     QQuickItem *root = qobject_cast<QQuickItem*>(canvas->rootObject());
1110     QVERIFY(root);
1111     root->setWidth(125);
1112     root->setProperty("testRightToLeft", true);
1113
1114     QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
1115     QTRY_VERIFY(one != 0);
1116     QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
1117     QVERIFY(two != 0);
1118     QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
1119     QVERIFY(three != 0);
1120     QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
1121     QVERIFY(four != 0);
1122     QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
1123     QVERIFY(five != 0);
1124
1125     QCOMPARE(one->x(), 75.0);
1126     QCOMPARE(one->y(), 0.0);
1127     QCOMPARE(two->x(), 55.0);
1128     QCOMPARE(two->y(), 0.0);
1129     QCOMPARE(three->x(), 5.0);
1130     QCOMPARE(three->y(), 0.0);
1131     QCOMPARE(four->x(), 75.0);
1132     QCOMPARE(four->y(), 50.0);
1133     QCOMPARE(five->x(), 65.0);
1134     QCOMPARE(five->y(), 50.0);
1135
1136     delete canvas;
1137 }
1138
1139 void tst_qquickpositioners::test_flow_implicit_resize()
1140 {
1141     QQuickView *canvas = createView(testFile("flow-testimplicitsize.qml"));
1142     QVERIFY(canvas->rootObject() != 0);
1143
1144     QQuickFlow *flow = canvas->rootObject()->findChild<QQuickFlow*>("flow");
1145     QVERIFY(flow != 0);
1146
1147     QCOMPARE(flow->width(), 100.0);
1148     QCOMPARE(flow->height(), 120.0);
1149
1150     canvas->rootObject()->setProperty("flowLayout", 0);
1151     QCOMPARE(flow->flow(), QQuickFlow::LeftToRight);
1152     QCOMPARE(flow->width(), 220.0);
1153     QCOMPARE(flow->height(), 50.0);
1154
1155     canvas->rootObject()->setProperty("flowLayout", 1);
1156     QCOMPARE(flow->flow(), QQuickFlow::TopToBottom);
1157     QCOMPARE(flow->width(), 100.0);
1158     QCOMPARE(flow->height(), 120.0);
1159
1160     canvas->rootObject()->setProperty("flowLayout", 2);
1161     QCOMPARE(flow->layoutDirection(), Qt::RightToLeft);
1162     QCOMPARE(flow->width(), 220.0);
1163     QCOMPARE(flow->height(), 50.0);
1164
1165     delete canvas;
1166 }
1167
1168 QString warningMessage;
1169
1170 void interceptWarnings(QtMsgType type, const char *msg)
1171 {
1172     Q_UNUSED( type );
1173     warningMessage = msg;
1174 }
1175
1176 void tst_qquickpositioners::test_conflictinganchors()
1177 {
1178     QtMsgHandler oldMsgHandler = qInstallMsgHandler(interceptWarnings);
1179     QDeclarativeEngine engine;
1180     QDeclarativeComponent component(&engine);
1181
1182     component.setData("import QtQuick 2.0\nColumn { Item {} }", QUrl::fromLocalFile(""));
1183     QQuickItem *item = qobject_cast<QQuickItem*>(component.create());
1184     QVERIFY(item);
1185     QVERIFY(warningMessage.isEmpty());
1186     delete item;
1187
1188     component.setData("import QtQuick 2.0\nRow { Item {} }", QUrl::fromLocalFile(""));
1189     item = qobject_cast<QQuickItem*>(component.create());
1190     QVERIFY(item);
1191     QVERIFY(warningMessage.isEmpty());
1192     delete item;
1193
1194     component.setData("import QtQuick 2.0\nGrid { Item {} }", QUrl::fromLocalFile(""));
1195     item = qobject_cast<QQuickItem*>(component.create());
1196     QVERIFY(item);
1197     QVERIFY(warningMessage.isEmpty());
1198     delete item;
1199
1200     component.setData("import QtQuick 2.0\nFlow { Item {} }", QUrl::fromLocalFile(""));
1201     item = qobject_cast<QQuickItem*>(component.create());
1202     QVERIFY(item);
1203     QVERIFY(warningMessage.isEmpty());
1204     delete item;
1205
1206     component.setData("import QtQuick 2.0\nColumn { Item { anchors.top: parent.top } }", QUrl::fromLocalFile(""));
1207     item = qobject_cast<QQuickItem*>(component.create());
1208     QVERIFY(item);
1209     QCOMPARE(warningMessage, QString("file::2:1: QML Column: Cannot specify top, bottom, verticalCenter, fill or centerIn anchors for items inside Column. Column will not function."));
1210     warningMessage.clear();
1211     delete item;
1212
1213     component.setData("import QtQuick 2.0\nColumn { Item { anchors.centerIn: parent } }", QUrl::fromLocalFile(""));
1214     item = qobject_cast<QQuickItem*>(component.create());
1215     QVERIFY(item);
1216     QCOMPARE(warningMessage, QString("file::2:1: QML Column: Cannot specify top, bottom, verticalCenter, fill or centerIn anchors for items inside Column. Column will not function."));
1217     warningMessage.clear();
1218     delete item;
1219
1220     component.setData("import QtQuick 2.0\nColumn { Item { anchors.left: parent.left } }", QUrl::fromLocalFile(""));
1221     item = qobject_cast<QQuickItem*>(component.create());
1222     QVERIFY(item);
1223     QVERIFY(warningMessage.isEmpty());
1224     warningMessage.clear();
1225     delete item;
1226
1227     component.setData("import QtQuick 2.0\nRow { Item { anchors.left: parent.left } }", QUrl::fromLocalFile(""));
1228     item = qobject_cast<QQuickItem*>(component.create());
1229     QVERIFY(item);
1230     QCOMPARE(warningMessage, QString("file::2:1: QML Row: Cannot specify left, right, horizontalCenter, fill or centerIn anchors for items inside Row. Row will not function."));
1231     warningMessage.clear();
1232     delete item;
1233
1234     component.setData("import QtQuick 2.0\nRow { Item { anchors.fill: parent } }", QUrl::fromLocalFile(""));
1235     item = qobject_cast<QQuickItem*>(component.create());
1236     QVERIFY(item);
1237     QCOMPARE(warningMessage, QString("file::2:1: QML Row: Cannot specify left, right, horizontalCenter, fill or centerIn anchors for items inside Row. Row will not function."));
1238     warningMessage.clear();
1239     delete item;
1240
1241     component.setData("import QtQuick 2.0\nRow { Item { anchors.top: parent.top } }", QUrl::fromLocalFile(""));
1242     item = qobject_cast<QQuickItem*>(component.create());
1243     QVERIFY(item);
1244     QVERIFY(warningMessage.isEmpty());
1245     warningMessage.clear();
1246     delete item;
1247
1248     component.setData("import QtQuick 2.0\nGrid { Item { anchors.horizontalCenter: parent.horizontalCenter } }", QUrl::fromLocalFile(""));
1249     item = qobject_cast<QQuickItem*>(component.create());
1250     QVERIFY(item);
1251     QCOMPARE(warningMessage, QString("file::2:1: QML Grid: Cannot specify anchors for items inside Grid. Grid will not function."));
1252     warningMessage.clear();
1253     delete item;
1254
1255     component.setData("import QtQuick 2.0\nGrid { Item { anchors.centerIn: parent } }", QUrl::fromLocalFile(""));
1256     item = qobject_cast<QQuickItem*>(component.create());
1257     QVERIFY(item);
1258     QCOMPARE(warningMessage, QString("file::2:1: QML Grid: Cannot specify anchors for items inside Grid. Grid will not function."));
1259     warningMessage.clear();
1260     delete item;
1261
1262     component.setData("import QtQuick 2.0\nFlow { Item { anchors.verticalCenter: parent.verticalCenter } }", QUrl::fromLocalFile(""));
1263     item = qobject_cast<QQuickItem*>(component.create());
1264     QVERIFY(item);
1265     QCOMPARE(warningMessage, QString("file::2:1: QML Flow: Cannot specify anchors for items inside Flow. Flow will not function."));
1266     delete item;
1267
1268     component.setData("import QtQuick 2.0\nFlow { Item { anchors.fill: parent } }", QUrl::fromLocalFile(""));
1269     item = qobject_cast<QQuickItem*>(component.create());
1270     QVERIFY(item);
1271     QCOMPARE(warningMessage, QString("file::2:1: QML Flow: Cannot specify anchors for items inside Flow. Flow will not function."));
1272     qInstallMsgHandler(oldMsgHandler);
1273     delete item;
1274 }
1275
1276 void tst_qquickpositioners::test_mirroring()
1277 {
1278     QList<QString> qmlFiles;
1279     qmlFiles << "horizontal.qml" << "gridtest.qml" << "flowtest.qml";
1280     QList<QString> objectNames;
1281     objectNames << "one" << "two" << "three" << "four" << "five";
1282
1283     foreach (const QString qmlFile, qmlFiles) {
1284         QQuickView *canvasA = createView(testFile(qmlFile));
1285         QQuickItem *rootA = qobject_cast<QQuickItem*>(canvasA->rootObject());
1286
1287         QQuickView *canvasB = createView(testFile(qmlFile));
1288         QQuickItem *rootB = qobject_cast<QQuickItem*>(canvasB->rootObject());
1289
1290         rootA->setProperty("testRightToLeft", true); // layoutDirection: Qt.RightToLeft
1291
1292         // LTR != RTL
1293         foreach (const QString objectName, objectNames) {
1294             // horizontal.qml only has three items
1295             if (qmlFile == QString("horizontal.qml") && objectName == QString("four"))
1296                 break;
1297             QQuickItem *itemA = rootA->findChild<QQuickItem*>(objectName);
1298             QQuickItem *itemB = rootB->findChild<QQuickItem*>(objectName);
1299             QTRY_VERIFY(itemA->x() != itemB->x());
1300         }
1301
1302         QDeclarativeProperty enabledProp(rootB, "LayoutMirroring.enabled", qmlContext(rootB));
1303         enabledProp.write(true);
1304         QDeclarativeProperty inheritProp(rootB, "LayoutMirroring.childrenInherit", qmlContext(rootB));
1305         inheritProp.write(true);
1306
1307         // RTL == mirror
1308         foreach (const QString objectName, objectNames) {
1309             // horizontal.qml only has three items
1310             if (qmlFile == QString("horizontal.qml") && objectName == QString("four"))
1311                 break;
1312             QQuickItem *itemA = rootA->findChild<QQuickItem*>(objectName);
1313             QQuickItem *itemB = rootB->findChild<QQuickItem*>(objectName);
1314             QTRY_COMPARE(itemA->x(), itemB->x());
1315         }
1316
1317         rootA->setProperty("testRightToLeft", false); // layoutDirection: Qt.LeftToRight
1318         rootB->setProperty("testRightToLeft", true); // layoutDirection: Qt.RightToLeft
1319
1320         // LTR == RTL + mirror
1321         foreach (const QString objectName, objectNames) {
1322             // horizontal.qml only has three items
1323             if (qmlFile == QString("horizontal.qml") && objectName == QString("four"))
1324                 break;
1325             QQuickItem *itemA = rootA->findChild<QQuickItem*>(objectName);
1326             QQuickItem *itemB = rootB->findChild<QQuickItem*>(objectName);
1327             QTRY_COMPARE(itemA->x(), itemB->x());
1328         }
1329         delete canvasA;
1330         delete canvasB;
1331     }
1332 }
1333
1334 void tst_qquickpositioners::test_allInvisible()
1335 {
1336     //QTBUG-19361
1337     QQuickView *canvas = createView(testFile("allInvisible.qml"));
1338
1339     QQuickItem *root = qobject_cast<QQuickItem*>(canvas->rootObject());
1340     QVERIFY(root);
1341
1342     QQuickRow *row = canvas->rootObject()->findChild<QQuickRow*>("row");
1343     QVERIFY(row != 0);
1344     QVERIFY(row->width() == 0);
1345     QVERIFY(row->height() == 0);
1346     QQuickColumn *column = canvas->rootObject()->findChild<QQuickColumn*>("column");
1347     QVERIFY(column != 0);
1348     QVERIFY(column->width() == 0);
1349     QVERIFY(column->height() == 0);
1350 }
1351
1352 void tst_qquickpositioners::test_attachedproperties()
1353 {
1354     QFETCH(QString, filename);
1355
1356     QQuickView *canvas = createView(filename);
1357     QVERIFY(canvas->rootObject() != 0);
1358
1359     QQuickRectangle *greenRect = canvas->rootObject()->findChild<QQuickRectangle *>("greenRect");
1360     QVERIFY(greenRect != 0);
1361
1362     int posIndex = greenRect->property("posIndex").toInt();
1363     QVERIFY(posIndex == 0);
1364     bool isFirst = greenRect->property("isFirstItem").toBool();
1365     QVERIFY(isFirst == true);
1366     bool isLast = greenRect->property("isLastItem").toBool();
1367     QVERIFY(isLast == false);
1368
1369     QQuickRectangle *yellowRect = canvas->rootObject()->findChild<QQuickRectangle *>("yellowRect");
1370     QVERIFY(yellowRect != 0);
1371
1372     posIndex = yellowRect->property("posIndex").toInt();
1373     QVERIFY(posIndex == -1);
1374     isFirst = yellowRect->property("isFirstItem").toBool();
1375     QVERIFY(isFirst == false);
1376     isLast = yellowRect->property("isLastItem").toBool();
1377     QVERIFY(isLast == false);
1378
1379     yellowRect->metaObject()->invokeMethod(yellowRect, "onDemandPositioner");
1380
1381     posIndex = yellowRect->property("posIndex").toInt();
1382     QVERIFY(posIndex == 1);
1383     isFirst = yellowRect->property("isFirstItem").toBool();
1384     QVERIFY(isFirst == false);
1385     isLast = yellowRect->property("isLastItem").toBool();
1386     QVERIFY(isLast == true);
1387
1388     delete canvas;
1389 }
1390
1391 void tst_qquickpositioners::test_attachedproperties_data()
1392 {
1393     QTest::addColumn<QString>("filename");
1394
1395     QTest::newRow("column") << testFile("attachedproperties-column.qml");
1396     QTest::newRow("row") << testFile("attachedproperties-row.qml");
1397     QTest::newRow("grid") << testFile("attachedproperties-grid.qml");
1398     QTest::newRow("flow") << testFile("attachedproperties-flow.qml");
1399 }
1400
1401 void tst_qquickpositioners::test_attachedproperties_dynamic()
1402 {
1403     QQuickView *canvas = createView(testFile("attachedproperties-dynamic.qml"));
1404     QVERIFY(canvas->rootObject() != 0);
1405
1406     QQuickRow *row = canvas->rootObject()->findChild<QQuickRow *>("pos");
1407     QVERIFY(row != 0);
1408
1409     QQuickRectangle *rect0 = canvas->rootObject()->findChild<QQuickRectangle *>("rect0");
1410     QVERIFY(rect0 != 0);
1411
1412     int posIndex = rect0->property("index").toInt();
1413     QVERIFY(posIndex == 0);
1414     bool isFirst = rect0->property("firstItem").toBool();
1415     QVERIFY(isFirst == true);
1416     bool isLast = rect0->property("lastItem").toBool();
1417     QVERIFY(isLast == false);
1418
1419     QQuickRectangle *rect1 = canvas->rootObject()->findChild<QQuickRectangle *>("rect1");
1420     QVERIFY(rect1 != 0);
1421
1422     posIndex = rect1->property("index").toInt();
1423     QVERIFY(posIndex == 1);
1424     isFirst = rect1->property("firstItem").toBool();
1425     QVERIFY(isFirst == false);
1426     isLast = rect1->property("lastItem").toBool();
1427     QVERIFY(isLast == true);
1428
1429     row->metaObject()->invokeMethod(row, "createSubRect");
1430
1431     QTRY_VERIFY(rect1->property("index").toInt() == 1);
1432     QTRY_VERIFY(rect1->property("firstItem").toBool() == false);
1433     QTRY_VERIFY(rect1->property("lastItem").toBool() == false);
1434
1435     QQuickRectangle *rect2 = canvas->rootObject()->findChild<QQuickRectangle *>("rect2");
1436     QVERIFY(rect2 != 0);
1437
1438     posIndex = rect2->property("index").toInt();
1439     QVERIFY(posIndex == 2);
1440     isFirst = rect2->property("firstItem").toBool();
1441     QVERIFY(isFirst == false);
1442     isLast = rect2->property("lastItem").toBool();
1443     QVERIFY(isLast == true);
1444
1445     row->metaObject()->invokeMethod(row, "destroySubRect");
1446
1447     QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
1448     QCoreApplication::processEvents();
1449
1450     QTRY_VERIFY(rect1->property("index").toInt() == 1);
1451     QTRY_VERIFY(rect1->property("firstItem").toBool() == false);
1452     QTRY_VERIFY(rect1->property("lastItem").toBool() == true);
1453
1454     delete canvas;
1455 }
1456
1457 QQuickView *tst_qquickpositioners::createView(const QString &filename, bool wait)
1458 {
1459     QQuickView *canvas = new QQuickView(0);
1460
1461     canvas->setSource(QUrl::fromLocalFile(filename));
1462     canvas->show();
1463     if (wait)
1464         QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
1465
1466     return canvas;
1467 }
1468
1469
1470 QTEST_MAIN(tst_qquickpositioners)
1471
1472 #include "tst_qquickpositioners.moc"