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