Remove Symbian-specific code from tests.
[profile/ivi/qtdeclarative.git] / tests / auto / declarative / qsgitem2 / tst_qsgitem.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 <qtest.h>
42 #include <QtTest/QSignalSpy>
43 #include <QtDeclarative/qdeclarativeengine.h>
44 #include <QtDeclarative/qdeclarativecomponent.h>
45 #include <QtDeclarative/qdeclarativecontext.h>
46 #include <QtDeclarative/qsgview.h>
47 #include <private/qsgrectangle_p.h>
48 #include <private/qsgitem_p.h>
49 #include "../../../shared/util.h"
50
51 class tst_QSGItem : public QObject
52 {
53     Q_OBJECT
54 public:
55     tst_QSGItem();
56
57 private slots:
58     void initTestCase();
59     void keys();
60     void keysProcessingOrder();
61     void keyNavigation();
62     void keyNavigation_RightToLeft();
63     void keyNavigation_skipNotVisible();
64     void keyNavigation_implicitSetting();
65     void layoutMirroring();
66     void layoutMirroringIllegalParent();
67     void smooth();
68     void clip();
69     void mapCoordinates();
70     void mapCoordinates_data();
71     void propertyChanges();
72     void transforms();
73     void transforms_data();
74     void childrenRect();
75     void childrenRectBug();
76     void childrenRectBug2();
77     void childrenRectBug3();
78
79     void childrenProperty();
80     void resourcesProperty();
81
82     void transformCrash();
83     void implicitSize();
84     void qtbug_16871();
85 private:
86     QDeclarativeEngine engine;
87 };
88
89 template<typename T>
90 T *findItem(QSGItem *parent, const QString &objectName)
91 {
92     if (!parent)
93         return 0;
94
95     const QMetaObject &mo = T::staticMetaObject;
96     //qDebug() << parent->QSGItem::children().count() << "children";
97     for (int i = 0; i < parent->childItems().count(); ++i) {
98         QSGItem *item = qobject_cast<QSGItem*>(parent->childItems().at(i));
99         if(!item)
100             continue;
101         //qDebug() << "try" << item;
102         if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName))
103             return static_cast<T*>(item);
104         item = findItem<T>(item, objectName);
105         if (item)
106             return static_cast<T*>(item);
107     }
108
109     return 0;
110 }
111
112 class KeysTestObject : public QObject
113 {
114     Q_OBJECT
115
116     Q_PROPERTY(bool processLast READ processLast NOTIFY processLastChanged)
117
118 public:
119     KeysTestObject() : mKey(0), mModifiers(0), mForwardedKey(0), mLast(false) {}
120
121     void reset() {
122         mKey = 0;
123         mText = QString();
124         mModifiers = 0;
125         mForwardedKey = 0;
126     }
127
128     bool processLast() const { return mLast; }
129     void setProcessLast(bool b) {
130         if (b != mLast) {
131             mLast = b;
132             emit processLastChanged();
133         }
134     }
135
136 public slots:
137     void keyPress(int key, QString text, int modifiers) {
138         mKey = key;
139         mText = text;
140         mModifiers = modifiers;
141     }
142     void keyRelease(int key, QString text, int modifiers) {
143         mKey = key;
144         mText = text;
145         mModifiers = modifiers;
146     }
147     void forwardedKey(int key) {
148         mForwardedKey = key;
149     }
150
151 signals:
152     void processLastChanged();
153
154 public:
155     int mKey;
156     QString mText;
157     int mModifiers;
158     int mForwardedKey;
159     bool mLast;
160
161 private:
162 };
163
164 class KeyTestItem : public QSGItem
165 {
166     Q_OBJECT
167 public:
168     KeyTestItem(QSGItem *parent=0) : QSGItem(parent), mKey(0) {}
169
170 protected:
171     void keyPressEvent(QKeyEvent *e) {
172         mKey = e->key();
173
174         if (e->key() == Qt::Key_A)
175             e->accept();
176         else
177             e->ignore();
178     }
179
180     void keyReleaseEvent(QKeyEvent *e) {
181         if (e->key() == Qt::Key_B)
182             e->accept();
183         else
184             e->ignore();
185     }
186
187 public:
188     int mKey;
189 };
190
191 QML_DECLARE_TYPE(KeyTestItem);
192
193
194 tst_QSGItem::tst_QSGItem()
195 {
196 }
197
198 void tst_QSGItem::initTestCase()
199 {
200     qmlRegisterType<KeyTestItem>("Test",1,0,"KeyTestItem");
201 }
202
203 void tst_QSGItem::keys()
204 {
205     QSGView *canvas = new QSGView(0);
206     canvas->setFixedSize(240,320);
207
208     KeysTestObject *testObject = new KeysTestObject;
209     canvas->rootContext()->setContextProperty("keysTestObject", testObject);
210
211     canvas->rootContext()->setContextProperty("enableKeyHanding", QVariant(true));
212     canvas->rootContext()->setContextProperty("forwardeeVisible", QVariant(true));
213
214     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/keystest.qml"));
215     canvas->show();
216     qApp->processEvents();
217
218     QEvent wa(QEvent::WindowActivate);
219     QApplication::sendEvent(canvas, &wa);
220     QFocusEvent fe(QEvent::FocusIn);
221     QApplication::sendEvent(canvas, &fe);
222
223     QVERIFY(canvas->rootObject());
224     QCOMPARE(canvas->rootObject()->property("isEnabled").toBool(), true);
225
226     QKeyEvent key(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "A", false, 1);
227     QApplication::sendEvent(canvas, &key);
228     QCOMPARE(testObject->mKey, int(Qt::Key_A));
229     QCOMPARE(testObject->mForwardedKey, int(Qt::Key_A));
230     QCOMPARE(testObject->mText, QLatin1String("A"));
231     QVERIFY(testObject->mModifiers == Qt::NoModifier);
232     QVERIFY(!key.isAccepted());
233
234     testObject->reset();
235
236     key = QKeyEvent(QEvent::KeyRelease, Qt::Key_A, Qt::ShiftModifier, "A", false, 1);
237     QApplication::sendEvent(canvas, &key);
238     QCOMPARE(testObject->mKey, int(Qt::Key_A));
239     QCOMPARE(testObject->mForwardedKey, int(Qt::Key_A));
240     QCOMPARE(testObject->mText, QLatin1String("A"));
241     QVERIFY(testObject->mModifiers == Qt::ShiftModifier);
242     QVERIFY(key.isAccepted());
243
244     testObject->reset();
245
246     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier, "", false, 1);
247     QApplication::sendEvent(canvas, &key);
248     QCOMPARE(testObject->mKey, int(Qt::Key_Return));
249     QCOMPARE(testObject->mForwardedKey, int(Qt::Key_Return));
250     QCOMPARE(testObject->mText, QLatin1String("Return"));
251     QVERIFY(testObject->mModifiers == Qt::NoModifier);
252     QVERIFY(key.isAccepted());
253
254     testObject->reset();
255
256     key = QKeyEvent(QEvent::KeyPress, Qt::Key_0, Qt::NoModifier, "0", false, 1);
257     QApplication::sendEvent(canvas, &key);
258     QCOMPARE(testObject->mKey, int(Qt::Key_0));
259     QCOMPARE(testObject->mForwardedKey, int(Qt::Key_0));
260     QCOMPARE(testObject->mText, QLatin1String("0"));
261     QVERIFY(testObject->mModifiers == Qt::NoModifier);
262     QVERIFY(key.isAccepted());
263
264     testObject->reset();
265
266     key = QKeyEvent(QEvent::KeyPress, Qt::Key_9, Qt::NoModifier, "9", false, 1);
267     QApplication::sendEvent(canvas, &key);
268     QCOMPARE(testObject->mKey, int(Qt::Key_9));
269     QCOMPARE(testObject->mForwardedKey, int(Qt::Key_9));
270     QCOMPARE(testObject->mText, QLatin1String("9"));
271     QVERIFY(testObject->mModifiers == Qt::NoModifier);
272     QVERIFY(!key.isAccepted());
273
274     testObject->reset();
275
276     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1);
277     QApplication::sendEvent(canvas, &key);
278     QCOMPARE(testObject->mKey, int(Qt::Key_Tab));
279     QCOMPARE(testObject->mForwardedKey, int(Qt::Key_Tab));
280     QCOMPARE(testObject->mText, QLatin1String("Tab"));
281     QVERIFY(testObject->mModifiers == Qt::NoModifier);
282     QVERIFY(key.isAccepted());
283
284     testObject->reset();
285
286     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1);
287     QApplication::sendEvent(canvas, &key);
288     QCOMPARE(testObject->mKey, int(Qt::Key_Backtab));
289     QCOMPARE(testObject->mForwardedKey, int(Qt::Key_Backtab));
290     QCOMPARE(testObject->mText, QLatin1String("Backtab"));
291     QVERIFY(testObject->mModifiers == Qt::NoModifier);
292     QVERIFY(key.isAccepted());
293
294     testObject->reset();
295
296     canvas->rootContext()->setContextProperty("forwardeeVisible", QVariant(false));
297     key = QKeyEvent(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "A", false, 1);
298     QApplication::sendEvent(canvas, &key);
299     QCOMPARE(testObject->mKey, int(Qt::Key_A));
300     QCOMPARE(testObject->mForwardedKey, 0);
301     QCOMPARE(testObject->mText, QLatin1String("A"));
302     QVERIFY(testObject->mModifiers == Qt::NoModifier);
303     QVERIFY(!key.isAccepted());
304
305     testObject->reset();
306
307     canvas->rootContext()->setContextProperty("enableKeyHanding", QVariant(false));
308     QCOMPARE(canvas->rootObject()->property("isEnabled").toBool(), false);
309
310     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier, "", false, 1);
311     QApplication::sendEvent(canvas, &key);
312     QCOMPARE(testObject->mKey, 0);
313     QVERIFY(!key.isAccepted());
314
315     canvas->rootContext()->setContextProperty("enableKeyHanding", QVariant(true));
316     QCOMPARE(canvas->rootObject()->property("isEnabled").toBool(), true);
317
318     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier, "", false, 1);
319     QApplication::sendEvent(canvas, &key);
320     QCOMPARE(testObject->mKey, int(Qt::Key_Return));
321     QVERIFY(key.isAccepted());
322
323     delete canvas;
324     delete testObject;
325 }
326
327 void tst_QSGItem::keysProcessingOrder()
328 {
329     QSGView *canvas = new QSGView(0);
330     canvas->setFixedSize(240,320);
331
332     KeysTestObject *testObject = new KeysTestObject;
333     canvas->rootContext()->setContextProperty("keysTestObject", testObject);
334
335     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/keyspriority.qml"));
336     canvas->show();
337     qApp->processEvents();
338
339     KeyTestItem *testItem = qobject_cast<KeyTestItem*>(canvas->rootObject());
340     QVERIFY(testItem);
341
342     QEvent wa(QEvent::WindowActivate);
343     QApplication::sendEvent(canvas, &wa);
344     QFocusEvent fe(QEvent::FocusIn);
345     QApplication::sendEvent(canvas, &fe);
346
347     QKeyEvent key(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "A", false, 1);
348     QApplication::sendEvent(canvas, &key);
349     QCOMPARE(testObject->mKey, int(Qt::Key_A));
350     QCOMPARE(testObject->mText, QLatin1String("A"));
351     QVERIFY(testObject->mModifiers == Qt::NoModifier);
352     QVERIFY(key.isAccepted());
353
354     testObject->reset();
355
356     testObject->setProcessLast(true);
357
358     key = QKeyEvent(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "A", false, 1);
359     QApplication::sendEvent(canvas, &key);
360     QCOMPARE(testObject->mKey, 0);
361     QVERIFY(key.isAccepted());
362
363     testObject->reset();
364
365     key = QKeyEvent(QEvent::KeyPress, Qt::Key_B, Qt::NoModifier, "B", false, 1);
366     QApplication::sendEvent(canvas, &key);
367     QCOMPARE(testObject->mKey, int(Qt::Key_B));
368     QCOMPARE(testObject->mText, QLatin1String("B"));
369     QVERIFY(testObject->mModifiers == Qt::NoModifier);
370     QVERIFY(!key.isAccepted());
371
372     testObject->reset();
373
374     key = QKeyEvent(QEvent::KeyRelease, Qt::Key_B, Qt::NoModifier, "B", false, 1);
375     QApplication::sendEvent(canvas, &key);
376     QCOMPARE(testObject->mKey, 0);
377     QVERIFY(key.isAccepted());
378
379     delete canvas;
380     delete testObject;
381 }
382
383 QSGItemPrivate *childPrivate(QSGItem *rootItem, const char * itemString)
384 {
385     QSGItem *item = findItem<QSGItem>(rootItem, QString(QLatin1String(itemString)));
386     QSGItemPrivate* itemPrivate = QSGItemPrivate::get(item);
387     return itemPrivate;
388 }
389
390 QVariant childProperty(QSGItem *rootItem, const char * itemString, const char * property)
391 {
392     QSGItem *item = findItem<QSGItem>(rootItem, QString(QLatin1String(itemString)));
393     return item->property(property);
394 }
395
396 bool anchorsMirrored(QSGItem *rootItem, const char * itemString)
397 {
398     QSGItem *item = findItem<QSGItem>(rootItem, QString(QLatin1String(itemString)));
399     QSGItemPrivate* itemPrivate = QSGItemPrivate::get(item);
400     return itemPrivate->anchors()->mirrored();
401 }
402
403 void tst_QSGItem::layoutMirroring()
404 {
405     QSGView *canvas = new QSGView(0);
406     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/layoutmirroring.qml"));
407     canvas->show();
408
409     QSGItem *rootItem = qobject_cast<QSGItem*>(canvas->rootObject());
410     QVERIFY(rootItem);
411     QSGItemPrivate *rootPrivate = QSGItemPrivate::get(rootItem);
412     QVERIFY(rootPrivate);
413
414     QCOMPARE(childPrivate(rootItem, "mirrored1")->effectiveLayoutMirror, true);
415     QCOMPARE(childPrivate(rootItem, "mirrored2")->effectiveLayoutMirror, true);
416     QCOMPARE(childPrivate(rootItem, "notMirrored1")->effectiveLayoutMirror, false);
417     QCOMPARE(childPrivate(rootItem, "notMirrored2")->effectiveLayoutMirror, false);
418     QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->effectiveLayoutMirror, true);
419     QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->effectiveLayoutMirror, true);
420
421     QCOMPARE(anchorsMirrored(rootItem, "mirrored1"), true);
422     QCOMPARE(anchorsMirrored(rootItem, "mirrored2"), true);
423     QCOMPARE(anchorsMirrored(rootItem, "notMirrored1"), false);
424     QCOMPARE(anchorsMirrored(rootItem, "notMirrored2"), false);
425     QCOMPARE(anchorsMirrored(rootItem, "inheritedMirror1"), true);
426     QCOMPARE(anchorsMirrored(rootItem, "inheritedMirror2"), true);
427
428     QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritedLayoutMirror, true);
429     QCOMPARE(childPrivate(rootItem, "mirrored2")->inheritedLayoutMirror, false);
430     QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritedLayoutMirror, true);
431     QCOMPARE(childPrivate(rootItem, "notMirrored2")->inheritedLayoutMirror, false);
432     QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->inheritedLayoutMirror, true);
433     QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritedLayoutMirror, true);
434
435     QCOMPARE(childPrivate(rootItem, "mirrored1")->isMirrorImplicit, false);
436     QCOMPARE(childPrivate(rootItem, "mirrored2")->isMirrorImplicit, false);
437     QCOMPARE(childPrivate(rootItem, "notMirrored1")->isMirrorImplicit, false);
438     QCOMPARE(childPrivate(rootItem, "notMirrored2")->isMirrorImplicit, true);
439     QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->isMirrorImplicit, true);
440     QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->isMirrorImplicit, true);
441
442     QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritMirrorFromParent, true);
443     QCOMPARE(childPrivate(rootItem, "mirrored2")->inheritMirrorFromParent, false);
444     QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritMirrorFromParent, true);
445     QCOMPARE(childPrivate(rootItem, "notMirrored2")->inheritMirrorFromParent, false);
446     QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->inheritMirrorFromParent, true);
447     QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritMirrorFromParent, true);
448
449     QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritMirrorFromItem, true);
450     QCOMPARE(childPrivate(rootItem, "mirrored2")->inheritMirrorFromItem, false);
451     QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritMirrorFromItem, false);
452     QCOMPARE(childPrivate(rootItem, "notMirrored2")->inheritMirrorFromItem, false);
453     QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->inheritMirrorFromItem, false);
454     QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritMirrorFromItem, false);
455
456     // load dynamic content using Loader that needs to inherit mirroring
457     rootItem->setProperty("state", "newContent");
458     QCOMPARE(childPrivate(rootItem, "notMirrored3")->effectiveLayoutMirror, false);
459     QCOMPARE(childPrivate(rootItem, "inheritedMirror3")->effectiveLayoutMirror, true);
460
461     QCOMPARE(childPrivate(rootItem, "notMirrored3")->inheritedLayoutMirror, true);
462     QCOMPARE(childPrivate(rootItem, "inheritedMirror3")->inheritedLayoutMirror, true);
463
464     QCOMPARE(childPrivate(rootItem, "notMirrored3")->isMirrorImplicit, false);
465     QCOMPARE(childPrivate(rootItem, "inheritedMirror3")->isMirrorImplicit, true);
466
467     QCOMPARE(childPrivate(rootItem, "notMirrored3")->inheritMirrorFromParent, true);
468     QCOMPARE(childPrivate(rootItem, "inheritedMirror3")->inheritMirrorFromParent, true);
469
470     QCOMPARE(childPrivate(rootItem, "notMirrored3")->inheritMirrorFromItem, false);
471     QCOMPARE(childPrivate(rootItem, "notMirrored3")->inheritMirrorFromItem, false);
472
473     // disable inheritance
474     rootItem->setProperty("childrenInherit", false);
475
476     QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->effectiveLayoutMirror, false);
477     QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->effectiveLayoutMirror, false);
478     QCOMPARE(childPrivate(rootItem, "mirrored1")->effectiveLayoutMirror, true);
479     QCOMPARE(childPrivate(rootItem, "notMirrored1")->effectiveLayoutMirror, false);
480
481     QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->inheritedLayoutMirror, false);
482     QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritedLayoutMirror, false);
483     QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritedLayoutMirror, false);
484     QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritedLayoutMirror, false);
485
486     // re-enable inheritance
487     rootItem->setProperty("childrenInherit", true);
488
489     QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->effectiveLayoutMirror, true);
490     QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->effectiveLayoutMirror, true);
491     QCOMPARE(childPrivate(rootItem, "mirrored1")->effectiveLayoutMirror, true);
492     QCOMPARE(childPrivate(rootItem, "notMirrored1")->effectiveLayoutMirror, false);
493
494     QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->inheritedLayoutMirror, true);
495     QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritedLayoutMirror, true);
496     QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritedLayoutMirror, true);
497     QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritedLayoutMirror, true);
498     
499     //
500     // dynamic parenting
501     //
502     QSGItem *parentItem1 = new QSGItem();
503     QSGItemPrivate::get(parentItem1)->effectiveLayoutMirror = true; // LayoutMirroring.enabled: true
504     QSGItemPrivate::get(parentItem1)->isMirrorImplicit = false;
505     QSGItemPrivate::get(parentItem1)->inheritMirrorFromItem = true; // LayoutMirroring.childrenInherit: true
506     QSGItemPrivate::get(parentItem1)->resolveLayoutMirror();
507
508     // inherit in constructor
509     QSGItem *childItem1 = new QSGItem(parentItem1);
510     QCOMPARE(QSGItemPrivate::get(childItem1)->effectiveLayoutMirror, true);
511     QCOMPARE(QSGItemPrivate::get(childItem1)->inheritMirrorFromParent, true);
512
513     // inherit through a parent change
514     QSGItem *childItem2 = new QSGItem();
515     QCOMPARE(QSGItemPrivate::get(childItem2)->effectiveLayoutMirror, false);
516     QCOMPARE(QSGItemPrivate::get(childItem2)->inheritMirrorFromParent, false);
517     childItem2->setParentItem(parentItem1);
518     QCOMPARE(QSGItemPrivate::get(childItem2)->effectiveLayoutMirror, true);
519     QCOMPARE(QSGItemPrivate::get(childItem2)->inheritMirrorFromParent, true);
520
521     // stop inherting through a parent change
522     QSGItem *parentItem2 = new QSGItem();
523     QSGItemPrivate::get(parentItem2)->effectiveLayoutMirror = true; // LayoutMirroring.enabled: true
524     QSGItemPrivate::get(parentItem2)->resolveLayoutMirror();
525     childItem2->setParentItem(parentItem2);
526     QCOMPARE(QSGItemPrivate::get(childItem2)->effectiveLayoutMirror, false);
527     QCOMPARE(QSGItemPrivate::get(childItem2)->inheritMirrorFromParent, false);
528     
529     delete parentItem1;
530     delete parentItem2;
531 }
532
533 void tst_QSGItem::layoutMirroringIllegalParent()
534 {
535     QDeclarativeComponent component(&engine);
536     component.setData("import QtQuick 2.0; QtObject { LayoutMirroring.enabled: true; LayoutMirroring.childrenInherit: true }", QUrl::fromLocalFile(""));
537     QTest::ignoreMessage(QtWarningMsg, "file::1:21: QML QtObject: LayoutDirection attached property only works with Items");
538     QObject *object = component.create();
539     QVERIFY(object != 0);
540 }
541
542 void tst_QSGItem::keyNavigation()
543 {
544     QSGView *canvas = new QSGView(0);
545     canvas->setFixedSize(240,320);
546
547     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/keynavigationtest.qml"));
548     canvas->show();
549     qApp->processEvents();
550
551     QEvent wa(QEvent::WindowActivate);
552     QApplication::sendEvent(canvas, &wa);
553     QFocusEvent fe(QEvent::FocusIn);
554     QApplication::sendEvent(canvas, &fe);
555
556     QSGItem *item = findItem<QSGItem>(canvas->rootObject(), "item1");
557     QVERIFY(item);
558     QVERIFY(item->hasActiveFocus());
559
560     QVariant result;
561     QVERIFY(QMetaObject::invokeMethod(canvas->rootObject(), "verify",
562             Q_RETURN_ARG(QVariant, result)));
563     QVERIFY(result.toBool());
564
565     // right
566     QKeyEvent key(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1);
567     QApplication::sendEvent(canvas, &key);
568     QVERIFY(key.isAccepted());
569
570     item = findItem<QSGItem>(canvas->rootObject(), "item2");
571     QVERIFY(item);
572     QVERIFY(item->hasActiveFocus());
573
574     // down
575     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier, "", false, 1);
576     QApplication::sendEvent(canvas, &key);
577     QVERIFY(key.isAccepted());
578
579     item = findItem<QSGItem>(canvas->rootObject(), "item4");
580     QVERIFY(item);
581     QVERIFY(item->hasActiveFocus());
582
583     // left
584     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier, "", false, 1);
585     QApplication::sendEvent(canvas, &key);
586     QVERIFY(key.isAccepted());
587
588     item = findItem<QSGItem>(canvas->rootObject(), "item3");
589     QVERIFY(item);
590     QVERIFY(item->hasActiveFocus());
591
592     // up
593     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Up, Qt::NoModifier, "", false, 1);
594     QApplication::sendEvent(canvas, &key);
595     QVERIFY(key.isAccepted());
596
597     item = findItem<QSGItem>(canvas->rootObject(), "item1");
598     QVERIFY(item);
599     QVERIFY(item->hasActiveFocus());
600
601     // tab
602     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1);
603     QApplication::sendEvent(canvas, &key);
604     QVERIFY(key.isAccepted());
605
606     item = findItem<QSGItem>(canvas->rootObject(), "item2");
607     QVERIFY(item);
608     QVERIFY(item->hasActiveFocus());
609
610     // backtab
611     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1);
612     QApplication::sendEvent(canvas, &key);
613     QVERIFY(key.isAccepted());
614
615     item = findItem<QSGItem>(canvas->rootObject(), "item1");
616     QVERIFY(item);
617     QVERIFY(item->hasActiveFocus());
618
619     delete canvas;
620 }
621
622 void tst_QSGItem::keyNavigation_RightToLeft()
623 {
624     QSGView *canvas = new QSGView(0);
625     canvas->setFixedSize(240,320);
626
627     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/keynavigationtest.qml"));
628     canvas->show();
629     qApp->processEvents();
630
631     QSGItem *rootItem = qobject_cast<QSGItem*>(canvas->rootObject());
632     QVERIFY(rootItem);
633     QSGItemPrivate* rootItemPrivate = QSGItemPrivate::get(rootItem);
634
635     rootItemPrivate->effectiveLayoutMirror = true; // LayoutMirroring.mirror: true
636     rootItemPrivate->isMirrorImplicit = false;
637     rootItemPrivate->inheritMirrorFromItem = true; // LayoutMirroring.inherit: true
638     rootItemPrivate->resolveLayoutMirror();
639
640     QEvent wa(QEvent::WindowActivate);
641     QApplication::sendEvent(canvas, &wa);
642     QFocusEvent fe(QEvent::FocusIn);
643     QApplication::sendEvent(canvas, &fe);
644
645     QSGItem *item = findItem<QSGItem>(canvas->rootObject(), "item1");
646     QVERIFY(item);
647     QVERIFY(item->hasActiveFocus());
648
649     QVariant result;
650     QVERIFY(QMetaObject::invokeMethod(canvas->rootObject(), "verify",
651             Q_RETURN_ARG(QVariant, result)));
652     QVERIFY(result.toBool());
653
654     // right
655     QKeyEvent key(QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier, "", false, 1);
656     QApplication::sendEvent(canvas, &key);
657     QVERIFY(key.isAccepted());
658
659     item = findItem<QSGItem>(canvas->rootObject(), "item2");
660     QVERIFY(item);
661     QVERIFY(item->hasActiveFocus());
662
663     // left
664     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1);
665     QApplication::sendEvent(canvas, &key);
666     QVERIFY(key.isAccepted());
667
668     item = findItem<QSGItem>(canvas->rootObject(), "item1");
669     QVERIFY(item);
670     QVERIFY(item->hasActiveFocus());
671
672     delete canvas;
673 }
674
675 void tst_QSGItem::keyNavigation_skipNotVisible()
676 {
677     QSGView *canvas = new QSGView(0);
678     canvas->setFixedSize(240,320);
679
680     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/keynavigationtest.qml"));
681     canvas->show();
682     qApp->processEvents();
683
684     QEvent wa(QEvent::WindowActivate);
685     QApplication::sendEvent(canvas, &wa);
686     QFocusEvent fe(QEvent::FocusIn);
687     QApplication::sendEvent(canvas, &fe);
688
689     QSGItem *item = findItem<QSGItem>(canvas->rootObject(), "item1");
690     QVERIFY(item);
691     QVERIFY(item->hasActiveFocus());
692
693     // Set item 2 to not visible
694     item = findItem<QSGItem>(canvas->rootObject(), "item2");
695     QVERIFY(item);
696     item->setVisible(false);
697     QVERIFY(!item->isVisible());
698
699     // right
700     QKeyEvent key(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1);
701     QApplication::sendEvent(canvas, &key);
702     QVERIFY(key.isAccepted());
703
704     item = findItem<QSGItem>(canvas->rootObject(), "item1");
705     QVERIFY(item);
706     QVERIFY(item->hasActiveFocus());
707
708     // tab
709     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1);
710     QApplication::sendEvent(canvas, &key);
711     QVERIFY(key.isAccepted());
712
713     item = findItem<QSGItem>(canvas->rootObject(), "item3");
714     QVERIFY(item);
715     QVERIFY(item->hasActiveFocus());
716
717     // backtab
718     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1);
719     QApplication::sendEvent(canvas, &key);
720     QVERIFY(key.isAccepted());
721
722     item = findItem<QSGItem>(canvas->rootObject(), "item1");
723     QVERIFY(item);
724     QVERIFY(item->hasActiveFocus());
725
726     //Set item 3 to not visible
727     item = findItem<QSGItem>(canvas->rootObject(), "item3");
728     QVERIFY(item);
729     item->setVisible(false);
730     QVERIFY(!item->isVisible());
731
732     // tab
733     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1);
734     QApplication::sendEvent(canvas, &key);
735     QVERIFY(key.isAccepted());
736
737     item = findItem<QSGItem>(canvas->rootObject(), "item4");
738     QVERIFY(item);
739     QVERIFY(item->hasActiveFocus());
740
741     // backtab
742     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1);
743     QApplication::sendEvent(canvas, &key);
744     QVERIFY(key.isAccepted());
745
746     item = findItem<QSGItem>(canvas->rootObject(), "item1");
747     QVERIFY(item);
748     QVERIFY(item->hasActiveFocus());
749
750     delete canvas;
751 }
752
753 void tst_QSGItem::keyNavigation_implicitSetting()
754 {
755     QSGView *canvas = new QSGView(0);
756     canvas->setFixedSize(240,320);
757
758     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/keynavigationtest_implicit.qml"));
759     canvas->show();
760     qApp->processEvents();
761
762     QEvent wa(QEvent::WindowActivate);
763     QApplication::sendEvent(canvas, &wa);
764     QFocusEvent fe(QEvent::FocusIn);
765     QApplication::sendEvent(canvas, &fe);
766
767     QSGItem *item = findItem<QSGItem>(canvas->rootObject(), "item1");
768     QVERIFY(item);
769     QVERIFY(item->hasActiveFocus());
770
771     QVariant result;
772     QVERIFY(QMetaObject::invokeMethod(canvas->rootObject(), "verify",
773             Q_RETURN_ARG(QVariant, result)));
774     QVERIFY(result.toBool());
775
776     // right
777     QKeyEvent key(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1);
778     QApplication::sendEvent(canvas, &key);
779     QVERIFY(key.isAccepted());
780
781     item = findItem<QSGItem>(canvas->rootObject(), "item2");
782     QVERIFY(item);
783     QVERIFY(item->hasActiveFocus());
784
785     // back to item1
786     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier, "", false, 1);
787     QApplication::sendEvent(canvas, &key);
788     QVERIFY(key.isAccepted());
789
790     item = findItem<QSGItem>(canvas->rootObject(), "item1");
791     QVERIFY(item);
792     QVERIFY(item->hasActiveFocus());
793
794     // down
795     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier, "", false, 1);
796     QApplication::sendEvent(canvas, &key);
797     QVERIFY(key.isAccepted());
798
799     item = findItem<QSGItem>(canvas->rootObject(), "item3");
800     QVERIFY(item);
801     QVERIFY(item->hasActiveFocus());
802
803     // move to item4
804     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1);
805     QApplication::sendEvent(canvas, &key);
806     QVERIFY(key.isAccepted());
807
808     item = findItem<QSGItem>(canvas->rootObject(), "item4");
809     QVERIFY(item);
810     QVERIFY(item->hasActiveFocus());
811
812     // left
813     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier, "", false, 1);
814     QApplication::sendEvent(canvas, &key);
815     QVERIFY(key.isAccepted());
816
817     item = findItem<QSGItem>(canvas->rootObject(), "item3");
818     QVERIFY(item);
819     QVERIFY(item->hasActiveFocus());
820
821     // back to item4
822     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1);
823     QApplication::sendEvent(canvas, &key);
824     QVERIFY(key.isAccepted());
825
826     item = findItem<QSGItem>(canvas->rootObject(), "item4");
827     QVERIFY(item);
828     QVERIFY(item->hasActiveFocus());
829
830     // up
831     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Up, Qt::NoModifier, "", false, 1);
832     QApplication::sendEvent(canvas, &key);
833     QVERIFY(key.isAccepted());
834
835     item = findItem<QSGItem>(canvas->rootObject(), "item2");
836     QVERIFY(item);
837     QVERIFY(item->hasActiveFocus());
838
839     // back to item4
840     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier, "", false, 1);
841     QApplication::sendEvent(canvas, &key);
842     QVERIFY(key.isAccepted());
843
844     item = findItem<QSGItem>(canvas->rootObject(), "item4");
845     QVERIFY(item);
846     QVERIFY(item->hasActiveFocus());
847
848     // tab
849     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1);
850     QApplication::sendEvent(canvas, &key);
851     QVERIFY(key.isAccepted());
852
853     item = findItem<QSGItem>(canvas->rootObject(), "item1");
854     QVERIFY(item);
855     QVERIFY(item->hasActiveFocus());
856
857     // back to item4
858     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1);
859     QApplication::sendEvent(canvas, &key);
860     QVERIFY(key.isAccepted());
861
862     item = findItem<QSGItem>(canvas->rootObject(), "item4");
863     QVERIFY(item);
864     QVERIFY(item->hasActiveFocus());
865
866     // backtab
867     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1);
868     QApplication::sendEvent(canvas, &key);
869     QVERIFY(key.isAccepted());
870
871     item = findItem<QSGItem>(canvas->rootObject(), "item3");
872     QVERIFY(item);
873     QVERIFY(item->hasActiveFocus());
874
875     delete canvas;
876 }
877
878 void tst_QSGItem::smooth()
879 {
880     QDeclarativeComponent component(&engine);
881     component.setData("import QtQuick 2.0; Item { smooth: false; }", QUrl::fromLocalFile(""));
882     QSGItem *item = qobject_cast<QSGItem*>(component.create());
883     QSignalSpy spy(item, SIGNAL(smoothChanged(bool)));
884
885     QVERIFY(item);
886     QVERIFY(!item->smooth());
887
888     item->setSmooth(true);
889     QVERIFY(item->smooth());
890     QCOMPARE(spy.count(),1);
891     QList<QVariant> arguments = spy.first();
892     QVERIFY(arguments.count() == 1);
893     QVERIFY(arguments.at(0).toBool() == true);
894
895     item->setSmooth(true);
896     QCOMPARE(spy.count(),1);
897
898     item->setSmooth(false);
899     QVERIFY(!item->smooth());
900     QCOMPARE(spy.count(),2);
901     item->setSmooth(false);
902     QCOMPARE(spy.count(),2);
903
904     delete item;
905 }
906
907 void tst_QSGItem::clip()
908 {
909     QDeclarativeComponent component(&engine);
910     component.setData("import QtQuick 2.0\nItem { clip: false\n }", QUrl::fromLocalFile(""));
911     QSGItem *item = qobject_cast<QSGItem*>(component.create());
912     QSignalSpy spy(item, SIGNAL(clipChanged(bool)));
913
914     QVERIFY(item);
915     QVERIFY(!item->clip());
916
917     item->setClip(true);
918     QVERIFY(item->clip());
919
920     QList<QVariant> arguments = spy.first();
921     QVERIFY(arguments.count() == 1);
922     QVERIFY(arguments.at(0).toBool() == true);
923
924     QCOMPARE(spy.count(),1);
925     item->setClip(true);
926     QCOMPARE(spy.count(),1);
927
928     item->setClip(false);
929     QVERIFY(!item->clip());
930     QCOMPARE(spy.count(),2);
931     item->setClip(false);
932     QCOMPARE(spy.count(),2);
933
934     delete item;
935 }
936
937 void tst_QSGItem::mapCoordinates()
938 {
939     QFETCH(int, x);
940     QFETCH(int, y);
941
942     QSGView *canvas = new QSGView(0);
943     canvas->setFixedSize(300, 300);
944     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/mapCoordinates.qml"));
945     canvas->show();
946     qApp->processEvents();
947
948     QSGItem *root = qobject_cast<QSGItem*>(canvas->rootObject());
949     QVERIFY(root != 0);
950     QSGItem *a = findItem<QSGItem>(canvas->rootObject(), "itemA");
951     QVERIFY(a != 0);
952     QSGItem *b = findItem<QSGItem>(canvas->rootObject(), "itemB");
953     QVERIFY(b != 0);
954
955     QVariant result;
956
957     QVERIFY(QMetaObject::invokeMethod(root, "mapAToB",
958             Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
959     QCOMPARE(result.value<QPointF>(), qobject_cast<QSGItem*>(a)->mapToItem(b, QPointF(x, y)));
960
961     QVERIFY(QMetaObject::invokeMethod(root, "mapAFromB",
962             Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
963     QCOMPARE(result.value<QPointF>(), qobject_cast<QSGItem*>(a)->mapFromItem(b, QPointF(x, y)));
964
965     QVERIFY(QMetaObject::invokeMethod(root, "mapAToNull",
966             Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
967     QCOMPARE(result.value<QPointF>(), qobject_cast<QSGItem*>(a)->mapToScene(QPointF(x, y)));
968
969     QVERIFY(QMetaObject::invokeMethod(root, "mapAFromNull",
970             Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
971     QCOMPARE(result.value<QPointF>(), qobject_cast<QSGItem*>(a)->mapFromScene(QPointF(x, y)));
972
973     QString warning1 = QUrl::fromLocalFile(SRCDIR "/data/mapCoordinates.qml").toString() + ":7:5: QML Item: mapToItem() given argument \"1122\" which is neither null nor an Item";
974     QString warning2 = QUrl::fromLocalFile(SRCDIR "/data/mapCoordinates.qml").toString() + ":7:5: QML Item: mapFromItem() given argument \"1122\" which is neither null nor an Item";
975
976     QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
977     QVERIFY(QMetaObject::invokeMethod(root, "checkMapAToInvalid",
978             Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
979     QVERIFY(result.toBool());
980
981     QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
982     QVERIFY(QMetaObject::invokeMethod(root, "checkMapAFromInvalid",
983             Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
984     QVERIFY(result.toBool());
985
986     delete canvas;
987 }
988
989 void tst_QSGItem::mapCoordinates_data()
990 {
991     QTest::addColumn<int>("x");
992     QTest::addColumn<int>("y");
993
994     for (int i=-20; i<=20; i+=10)
995         QTest::newRow(QTest::toString(i)) << i << i;
996 }
997
998 void tst_QSGItem::transforms_data()
999 {
1000     QTest::addColumn<QByteArray>("qml");
1001     QTest::addColumn<QTransform>("transform");
1002     QTest::newRow("translate") << QByteArray("Translate { x: 10; y: 20 }")
1003         << QTransform(1,0,0,0,1,0,10,20,1);
1004     QTest::newRow("rotation") << QByteArray("Rotation { angle: 90 }")
1005         << QTransform(0,1,0,-1,0,0,0,0,1);
1006     QTest::newRow("scale") << QByteArray("Scale { xScale: 1.5; yScale: -2  }")
1007         << QTransform(1.5,0,0,0,-2,0,0,0,1);
1008     QTest::newRow("sequence") << QByteArray("[ Translate { x: 10; y: 20 }, Scale { xScale: 1.5; yScale: -2  } ]")
1009         << QTransform(1,0,0,0,1,0,10,20,1) * QTransform(1.5,0,0,0,-2,0,0,0,1);
1010 }
1011
1012 void tst_QSGItem::transforms()
1013 {
1014     QFETCH(QByteArray, qml);
1015     QFETCH(QTransform, transform);
1016     QDeclarativeComponent component(&engine);
1017     component.setData("import QtQuick 2.0\nItem { transform: "+qml+"}", QUrl::fromLocalFile(""));
1018     QSGItem *item = qobject_cast<QSGItem*>(component.create());
1019     QVERIFY(item);
1020     QCOMPARE(item->itemTransform(0,0), transform);
1021 }
1022
1023 void tst_QSGItem::childrenProperty()
1024 {
1025     QDeclarativeComponent component(&engine, SRCDIR "/data/childrenProperty.qml");
1026     
1027     QObject *o = component.create();
1028     QVERIFY(o != 0);
1029
1030     QCOMPARE(o->property("test1").toBool(), true);
1031     QCOMPARE(o->property("test2").toBool(), true);
1032     QCOMPARE(o->property("test3").toBool(), true);
1033     QCOMPARE(o->property("test4").toBool(), true);
1034     QCOMPARE(o->property("test5").toBool(), true);
1035     delete o;
1036 }
1037
1038 void tst_QSGItem::resourcesProperty()
1039 {
1040     QDeclarativeComponent component(&engine, SRCDIR "/data/resourcesProperty.qml");
1041     
1042     QObject *o = component.create();
1043     QVERIFY(o != 0);
1044
1045     QCOMPARE(o->property("test1").toBool(), true);
1046     QCOMPARE(o->property("test2").toBool(), true);
1047     QCOMPARE(o->property("test3").toBool(), true);
1048     QCOMPARE(o->property("test4").toBool(), true);
1049     QCOMPARE(o->property("test5").toBool(), true);
1050     delete o;
1051 }
1052
1053 void tst_QSGItem::propertyChanges()
1054 {
1055     QSGView *canvas = new QSGView(0);
1056     canvas->setFixedSize(240,320);
1057     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml"));
1058     canvas->show();
1059
1060     QApplication::setActiveWindow(canvas);
1061     QTest::qWaitForWindowShown(canvas);
1062     QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas));
1063
1064     QSGItem *item = findItem<QSGItem>(canvas->rootObject(), "item");
1065     QSGItem *parentItem = findItem<QSGItem>(canvas->rootObject(), "parentItem");
1066
1067     QVERIFY(item);
1068     QVERIFY(parentItem);
1069
1070     QSignalSpy parentSpy(item, SIGNAL(parentChanged(QSGItem *)));
1071     QSignalSpy widthSpy(item, SIGNAL(widthChanged()));
1072     QSignalSpy heightSpy(item, SIGNAL(heightChanged()));
1073     QSignalSpy baselineOffsetSpy(item, SIGNAL(baselineOffsetChanged(qreal)));
1074     QSignalSpy childrenRectSpy(parentItem, SIGNAL(childrenRectChanged(QRectF)));
1075     QSignalSpy focusSpy(item, SIGNAL(focusChanged(bool)));
1076     QSignalSpy wantsFocusSpy(parentItem, SIGNAL(activeFocusChanged(bool)));
1077     QSignalSpy childrenChangedSpy(parentItem, SIGNAL(childrenChanged()));
1078     QSignalSpy xSpy(item, SIGNAL(xChanged()));
1079     QSignalSpy ySpy(item, SIGNAL(yChanged()));
1080
1081     item->setParentItem(parentItem);
1082     item->setWidth(100.0);
1083     item->setHeight(200.0);
1084     item->setFocus(true);
1085     item->setBaselineOffset(10.0);
1086
1087     QCOMPARE(item->parentItem(), parentItem);
1088     QCOMPARE(parentSpy.count(),1);
1089     QList<QVariant> parentArguments = parentSpy.first();
1090     QVERIFY(parentArguments.count() == 1);
1091     QCOMPARE(item->parentItem(), qvariant_cast<QSGItem *>(parentArguments.at(0)));
1092     QCOMPARE(childrenChangedSpy.count(),1);
1093
1094     item->setParentItem(parentItem);
1095     QCOMPARE(childrenChangedSpy.count(),1);
1096
1097     QCOMPARE(item->width(), 100.0);
1098     QCOMPARE(widthSpy.count(),1);
1099
1100     QCOMPARE(item->height(), 200.0);
1101     QCOMPARE(heightSpy.count(),1);
1102
1103     QCOMPARE(item->baselineOffset(), 10.0);
1104     QCOMPARE(baselineOffsetSpy.count(),1);
1105     QList<QVariant> baselineOffsetArguments = baselineOffsetSpy.first();
1106     QVERIFY(baselineOffsetArguments.count() == 1);
1107     QCOMPARE(item->baselineOffset(), baselineOffsetArguments.at(0).toReal());
1108
1109     QCOMPARE(parentItem->childrenRect(), QRectF(0.0,0.0,100.0,200.0));
1110     QCOMPARE(childrenRectSpy.count(),2);
1111     QList<QVariant> childrenRectArguments = childrenRectSpy.at(1);
1112     QVERIFY(childrenRectArguments.count() == 1);
1113     QCOMPARE(parentItem->childrenRect(), childrenRectArguments.at(0).toRectF());
1114
1115     QCOMPARE(item->hasActiveFocus(), true);
1116     QCOMPARE(focusSpy.count(),1);
1117     QList<QVariant> focusArguments = focusSpy.first();
1118     QVERIFY(focusArguments.count() == 1);
1119     QCOMPARE(focusArguments.at(0).toBool(), true);
1120
1121     QCOMPARE(parentItem->hasActiveFocus(), false);
1122     QCOMPARE(parentItem->hasFocus(), false);
1123     QCOMPARE(wantsFocusSpy.count(),0);
1124
1125     item->setX(10.0);
1126     QCOMPARE(item->x(), 10.0);
1127     QCOMPARE(xSpy.count(), 1);
1128
1129     item->setY(10.0);
1130     QCOMPARE(item->y(), 10.0);
1131     QCOMPARE(ySpy.count(), 1);
1132
1133     delete canvas;
1134 }
1135
1136 void tst_QSGItem::childrenRect()
1137 {
1138     QSGView *canvas = new QSGView(0);
1139     canvas->setFixedSize(240,320);
1140     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/childrenRect.qml"));
1141     canvas->show();
1142
1143     QSGItem *o = canvas->rootObject();
1144     QSGItem *item = o->findChild<QSGItem*>("testItem");
1145     QCOMPARE(item->width(), qreal(0));
1146     QCOMPARE(item->height(), qreal(0));
1147
1148     o->setProperty("childCount", 1);
1149     QCOMPARE(item->width(), qreal(10));
1150     QCOMPARE(item->height(), qreal(20));
1151
1152     o->setProperty("childCount", 5);
1153     QCOMPARE(item->width(), qreal(50));
1154     QCOMPARE(item->height(), qreal(100));
1155
1156     o->setProperty("childCount", 0);
1157     QCOMPARE(item->width(), qreal(0));
1158     QCOMPARE(item->height(), qreal(0));
1159
1160     delete o;
1161     delete canvas;
1162 }
1163
1164 // QTBUG-11383
1165 void tst_QSGItem::childrenRectBug()
1166 {
1167     QSGView *canvas = new QSGView(0);
1168     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/childrenRectBug.qml"));
1169     canvas->show();
1170
1171     QSGItem *o = canvas->rootObject();
1172     QSGItem *item = o->findChild<QSGItem*>("theItem");
1173     QCOMPARE(item->width(), qreal(200));
1174     QCOMPARE(item->height(), qreal(100));
1175     QCOMPARE(item->x(), qreal(100));
1176
1177     delete canvas;
1178 }
1179
1180 // QTBUG-11465
1181 void tst_QSGItem::childrenRectBug2()
1182 {
1183     QSGView *canvas = new QSGView(0);
1184     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/childrenRectBug2.qml"));
1185     canvas->show();
1186
1187     QSGRectangle *rect = qobject_cast<QSGRectangle*>(canvas->rootObject());
1188     QVERIFY(rect);
1189     QSGItem *item = rect->findChild<QSGItem*>("theItem");
1190     QCOMPARE(item->width(), qreal(100));
1191     QCOMPARE(item->height(), qreal(110));
1192     QCOMPARE(item->x(), qreal(130));
1193
1194     QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
1195     rectPrivate->setState("row");
1196     QCOMPARE(item->width(), qreal(210));
1197     QCOMPARE(item->height(), qreal(50));
1198     QCOMPARE(item->x(), qreal(75));
1199
1200     delete canvas;
1201 }
1202
1203 // QTBUG-12722
1204 void tst_QSGItem::childrenRectBug3()
1205 {
1206     QSGView *canvas = new QSGView(0);
1207     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/childrenRectBug3.qml"));
1208     canvas->show();
1209
1210     //don't crash on delete
1211     delete canvas;
1212 }
1213
1214 // QTBUG-13893
1215 void tst_QSGItem::transformCrash()
1216 {
1217     QSGView *canvas = new QSGView(0);
1218     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/transformCrash.qml"));
1219     canvas->show();
1220
1221     delete canvas;
1222 }
1223
1224 void tst_QSGItem::implicitSize()
1225 {
1226     QSGView *canvas = new QSGView(0);
1227     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/implicitsize.qml"));
1228     canvas->show();
1229
1230     QSGItem *item = qobject_cast<QSGItem*>(canvas->rootObject());
1231     QVERIFY(item);
1232     QCOMPARE(item->width(), qreal(80));
1233     QCOMPARE(item->height(), qreal(60));
1234
1235     QCOMPARE(item->implicitWidth(), qreal(200));
1236     QCOMPARE(item->implicitHeight(), qreal(100));
1237
1238     QMetaObject::invokeMethod(item, "resetSize");
1239
1240     QCOMPARE(item->width(), qreal(200));
1241     QCOMPARE(item->height(), qreal(100));
1242
1243     QMetaObject::invokeMethod(item, "changeImplicit");
1244
1245     QCOMPARE(item->implicitWidth(), qreal(150));
1246     QCOMPARE(item->implicitHeight(), qreal(80));
1247     QCOMPARE(item->width(), qreal(150));
1248     QCOMPARE(item->height(), qreal(80));
1249
1250     delete canvas;
1251 }
1252
1253 void tst_QSGItem::qtbug_16871()
1254 {
1255     QDeclarativeComponent component(&engine, SRCDIR "/data/qtbug_16871.qml");
1256     QObject *o = component.create();
1257     QVERIFY(o != 0);
1258     delete o;
1259 }
1260
1261 QTEST_MAIN(tst_QSGItem)
1262
1263 #include "tst_qsgitem.moc"