8da3abf614fe878dd6b58a60dd20dda45d58a094
[profile/ivi/qtdeclarative.git] / tests / auto / qtquick1 / qdeclarativestates / tst_qdeclarativestates.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 <QtDeclarative/qdeclarativeengine.h>
43 #include <QtDeclarative/qdeclarativecomponent.h>
44 #include <QtQuick1/private/qdeclarativeanchors_p_p.h>
45 #include <QtQuick1/private/qdeclarativerectangle_p.h>
46 #include <QtQuick1/private/qdeclarativeimage_p.h>
47 #include <QtQuick1/private/qdeclarativepropertychanges_p.h>
48 #include <QtQuick1/private/qdeclarativestategroup_p.h>
49 #include <QtQuick1/private/qdeclarativeitem_p.h>
50 #include <private/qdeclarativeproperty_p.h>
51
52 #ifdef Q_OS_SYMBIAN
53 // In Symbian OS test data is located in applications private dir
54 #define SRCDIR "."
55 #endif
56
57 class MyAttached : public QObject
58 {
59     Q_OBJECT
60     Q_PROPERTY(int foo READ foo WRITE setFoo)
61 public:
62     MyAttached(QObject *parent) : QObject(parent), m_foo(13) {}
63
64     int foo() const { return m_foo; }
65     void setFoo(int f) { m_foo = f; }
66
67 private:
68     int m_foo;
69 };
70
71 class MyRect : public QDeclarative1Rectangle
72 {
73    Q_OBJECT
74    Q_PROPERTY(int propertyWithNotify READ propertyWithNotify WRITE setPropertyWithNotify NOTIFY oddlyNamedNotifySignal)
75 public:
76     MyRect() {}
77
78     void doSomething() { emit didSomething(); }
79     
80     int propertyWithNotify() const { return m_prop; }
81     void setPropertyWithNotify(int i) { m_prop = i; emit oddlyNamedNotifySignal(); }
82
83     static MyAttached *qmlAttachedProperties(QObject *o) {
84         return new MyAttached(o);
85     }
86 Q_SIGNALS:
87     void didSomething();
88     void oddlyNamedNotifySignal();
89
90 private:
91     int m_prop;
92 };
93
94 QML_DECLARE_TYPE(MyRect)
95 QML_DECLARE_TYPEINFO(MyRect, QML_HAS_ATTACHED_PROPERTIES)
96
97 class tst_qdeclarativestates : public QObject
98 {
99     Q_OBJECT
100 public:
101     tst_qdeclarativestates() {}
102
103 private:
104     static QByteArray fullDataPath(const QString &path);
105
106 private slots:
107     void initTestCase();
108
109     void basicChanges();
110     void attachedPropertyChanges();
111     void basicExtension();
112     void basicBinding();
113     void signalOverride();
114     void signalOverrideCrash();
115     void signalOverrideCrash2();
116     void parentChange();
117     void parentChangeErrors();
118     void anchorChanges();
119     void anchorChanges2();
120     void anchorChanges3();
121     void anchorChanges4();
122     void anchorChanges5();
123     void anchorChangesRTL();
124     void anchorChangesRTL2();
125     void anchorChangesRTL3();
126     void anchorChangesCrash();
127     void anchorRewindBug();
128     void anchorRewindBug2();
129     void script();
130     void restoreEntryValues();
131     void explicitChanges();
132     void propertyErrors();
133     void incorrectRestoreBug();
134     void autoStateAtStartupRestoreBug();
135     void deletingChange();
136     void deletingState();
137     void tempState();
138     void illegalTempState();
139     void nonExistantProperty();
140     void reset();
141     void illegalObjectCreation();
142     void whenOrdering();
143     void urlResolution();
144     void unnamedWhen();
145     void returnToBase();
146     void extendsBug();
147     void editProperties();
148     void QTBUG_14830();
149 };
150
151 void tst_qdeclarativestates::initTestCase()
152 {
153     qmlRegisterType<MyRect>("Qt.test", 1, 0, "MyRectangle");
154 }
155
156 QByteArray tst_qdeclarativestates::fullDataPath(const QString &path)
157 {
158     return QUrl::fromLocalFile(SRCDIR + path).toString().toUtf8();    
159 }
160
161 void tst_qdeclarativestates::basicChanges()
162 {
163     QDeclarativeEngine engine;
164
165     {
166         QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicChanges.qml");
167         QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
168         QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
169         QVERIFY(rect != 0);
170
171         QCOMPARE(rect->color(),QColor("red"));
172
173         rectPrivate->setState("blue");
174         QCOMPARE(rect->color(),QColor("blue"));
175
176         rectPrivate->setState("");
177         QCOMPARE(rect->color(),QColor("red"));
178     }
179
180     {
181         QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicChanges2.qml");
182         QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
183         QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
184         QVERIFY(rect != 0);
185
186         QCOMPARE(rect->color(),QColor("red"));
187
188         rectPrivate->setState("blue");
189         QCOMPARE(rect->color(),QColor("blue"));
190
191         rectPrivate->setState("green");
192         QCOMPARE(rect->color(),QColor("green"));
193
194         rectPrivate->setState("");
195         QCOMPARE(rect->color(),QColor("red"));
196
197         rectPrivate->setState("green");
198         QCOMPARE(rect->color(),QColor("green"));
199     }
200
201     {
202         QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicChanges3.qml");
203         QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
204         QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
205         QVERIFY(rect != 0);
206
207         QCOMPARE(rect->color(),QColor("red"));
208         QCOMPARE(rect->border()->width(),1);
209
210         rectPrivate->setState("blue");
211         QCOMPARE(rect->color(),QColor("blue"));
212         QCOMPARE(rect->border()->width(),1);
213
214         rectPrivate->setState("bordered");
215         QCOMPARE(rect->color(),QColor("red"));
216         QCOMPARE(rect->border()->width(),2);
217
218         rectPrivate->setState("");
219         QCOMPARE(rect->color(),QColor("red"));
220         QCOMPARE(rect->border()->width(),1);
221         //### we should be checking that this is an implicit rather than explicit 1 (which currently fails)
222
223         rectPrivate->setState("bordered");
224         QCOMPARE(rect->color(),QColor("red"));
225         QCOMPARE(rect->border()->width(),2);
226
227         rectPrivate->setState("blue");
228         QCOMPARE(rect->color(),QColor("blue"));
229         QCOMPARE(rect->border()->width(),1);
230
231     }
232
233     {
234         // Test basicChanges4.qml can magically connect to propertyWithNotify's notify
235         // signal using 'onPropertyWithNotifyChanged' even though the signal name is
236         // actually 'oddlyNamedNotifySignal'
237
238         QDeclarativeComponent component(&engine, SRCDIR "/data/basicChanges4.qml");
239         QVERIFY(component.isReady());
240
241         MyRect *rect = qobject_cast<MyRect*>(component.create());
242         QVERIFY(rect != 0);
243
244         QMetaProperty prop = rect->metaObject()->property(rect->metaObject()->indexOfProperty("propertyWithNotify"));
245         QVERIFY(prop.hasNotifySignal());
246         QString notifySignal = QByteArray(prop.notifySignal().signature());
247         QVERIFY(!notifySignal.startsWith("propertyWithNotifyChanged("));
248
249         QCOMPARE(rect->color(), QColor(Qt::red));
250
251         rect->setPropertyWithNotify(100);
252         QCOMPARE(rect->color(), QColor(Qt::blue));
253     }
254 }
255
256 void tst_qdeclarativestates::attachedPropertyChanges()
257 {
258     QDeclarativeEngine engine;
259
260     QDeclarativeComponent component(&engine, SRCDIR "/data/attachedPropertyChanges.qml");
261     QVERIFY(component.isReady());
262
263     QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(component.create());
264     QVERIFY(item != 0);
265     QCOMPARE(item->width(), 50.0);
266
267     // Ensure attached property has been changed
268     QObject *attObj = qmlAttachedPropertiesObject<MyRect>(item, false);
269     QVERIFY(attObj);
270
271     MyAttached *att = qobject_cast<MyAttached*>(attObj);
272     QVERIFY(att);
273
274     QCOMPARE(att->foo(), 1);
275 }
276
277 void tst_qdeclarativestates::basicExtension()
278 {
279     QDeclarativeEngine engine;
280
281     {
282         QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicExtension.qml");
283         QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
284         QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
285         QVERIFY(rect != 0);
286
287         QCOMPARE(rect->color(),QColor("red"));
288         QCOMPARE(rect->border()->width(),1);
289
290         rectPrivate->setState("blue");
291         QCOMPARE(rect->color(),QColor("blue"));
292         QCOMPARE(rect->border()->width(),1);
293
294         rectPrivate->setState("bordered");
295         QCOMPARE(rect->color(),QColor("blue"));
296         QCOMPARE(rect->border()->width(),2);
297
298         rectPrivate->setState("blue");
299         QCOMPARE(rect->color(),QColor("blue"));
300         QCOMPARE(rect->border()->width(),1);
301
302         rectPrivate->setState("");
303         QCOMPARE(rect->color(),QColor("red"));
304         QCOMPARE(rect->border()->width(),1);
305
306         rectPrivate->setState("bordered");
307         QCOMPARE(rect->color(),QColor("blue"));
308         QCOMPARE(rect->border()->width(),2);
309
310         rectPrivate->setState("");
311         QCOMPARE(rect->color(),QColor("red"));
312         QCOMPARE(rect->border()->width(),1);
313     }
314
315     {
316         QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/fakeExtension.qml");
317         QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
318         QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
319         QVERIFY(rect != 0);
320
321         QCOMPARE(rect->color(),QColor("red"));
322
323         rectPrivate->setState("blue");
324         QCOMPARE(rect->color(),QColor("blue"));
325
326         rectPrivate->setState("green");
327         QCOMPARE(rect->color(),QColor("green"));
328
329         rectPrivate->setState("blue");
330         QCOMPARE(rect->color(),QColor("blue"));
331
332         rectPrivate->setState("green");
333         QCOMPARE(rect->color(),QColor("green"));
334
335         rectPrivate->setState("");
336         QCOMPARE(rect->color(),QColor("red"));
337
338         rectPrivate->setState("green");
339         QCOMPARE(rect->color(),QColor("green"));
340     }
341 }
342
343 void tst_qdeclarativestates::basicBinding()
344 {
345     QDeclarativeEngine engine;
346
347     {
348         QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicBinding.qml");
349         QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
350         QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
351         QVERIFY(rect != 0);
352
353         QCOMPARE(rect->color(),QColor("red"));
354
355         rectPrivate->setState("blue");
356         QCOMPARE(rect->color(),QColor("blue"));
357
358         rectPrivate->setState("");
359         QCOMPARE(rect->color(),QColor("red"));
360
361         rectPrivate->setState("blue");
362         QCOMPARE(rect->color(),QColor("blue"));
363         rect->setProperty("sourceColor", QColor("green"));
364         QCOMPARE(rect->color(),QColor("green"));
365
366         rectPrivate->setState("");
367         QCOMPARE(rect->color(),QColor("red"));
368         rect->setProperty("sourceColor", QColor("yellow"));
369         QCOMPARE(rect->color(),QColor("red"));
370
371         rectPrivate->setState("blue");
372         QCOMPARE(rect->color(),QColor("yellow"));
373     }
374
375     {
376         QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicBinding2.qml");
377         QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
378         QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
379         QVERIFY(rect != 0);
380
381         QCOMPARE(rect->color(),QColor("red"));
382
383         rectPrivate->setState("blue");
384         QCOMPARE(rect->color(),QColor("blue"));
385
386         rectPrivate->setState("");
387         QCOMPARE(rect->color(),QColor("red"));
388
389         rectPrivate->setState("blue");
390         QCOMPARE(rect->color(),QColor("blue"));
391         rect->setProperty("sourceColor", QColor("green"));
392         QCOMPARE(rect->color(),QColor("blue"));
393
394         rectPrivate->setState("");
395         QCOMPARE(rect->color(),QColor("green"));
396         rect->setProperty("sourceColor", QColor("yellow"));
397         QCOMPARE(rect->color(),QColor("yellow"));
398
399         rectPrivate->setState("blue");
400         QCOMPARE(rect->color(),QColor("blue"));
401
402         rectPrivate->setState("");
403         QCOMPARE(rect->color(),QColor("yellow"));
404     }
405
406     {
407         QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicBinding3.qml");
408         QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
409         QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
410         QVERIFY(rect != 0);
411
412         QCOMPARE(rect->color(),QColor("red"));
413         rect->setProperty("sourceColor", QColor("green"));
414         QCOMPARE(rect->color(),QColor("green"));
415
416         rectPrivate->setState("blue");
417         QCOMPARE(rect->color(),QColor("blue"));
418         rect->setProperty("sourceColor", QColor("red"));
419         QCOMPARE(rect->color(),QColor("blue"));
420         rect->setProperty("sourceColor2", QColor("yellow"));
421         QCOMPARE(rect->color(),QColor("yellow"));
422
423         rectPrivate->setState("");
424         QCOMPARE(rect->color(),QColor("red"));
425         rect->setProperty("sourceColor2", QColor("green"));
426         QCOMPARE(rect->color(),QColor("red"));
427         rect->setProperty("sourceColor", QColor("yellow"));
428         QCOMPARE(rect->color(),QColor("yellow"));
429     }
430
431     {
432         QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicBinding4.qml");
433         QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
434         QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
435         QVERIFY(rect != 0);
436
437         QCOMPARE(rect->color(),QColor("red"));
438
439         rectPrivate->setState("blue");
440         QCOMPARE(rect->color(),QColor("blue"));
441         rect->setProperty("sourceColor", QColor("yellow"));
442         QCOMPARE(rect->color(),QColor("yellow"));
443
444         rectPrivate->setState("green");
445         QCOMPARE(rect->color(),QColor("green"));
446         rect->setProperty("sourceColor", QColor("purple"));
447         QCOMPARE(rect->color(),QColor("green"));
448
449         rectPrivate->setState("blue");
450         QCOMPARE(rect->color(),QColor("purple"));
451
452         rectPrivate->setState("green");
453         QCOMPARE(rect->color(),QColor("green"));
454
455         rectPrivate->setState("");
456         QCOMPARE(rect->color(),QColor("red"));
457     }
458 }
459
460 void tst_qdeclarativestates::signalOverride()
461 {
462     QDeclarativeEngine engine;
463
464     {
465         QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/signalOverride.qml");
466         MyRect *rect = qobject_cast<MyRect*>(rectComponent.create());
467         QVERIFY(rect != 0);
468
469         QCOMPARE(rect->color(),QColor("red"));
470         rect->doSomething();
471         QCOMPARE(rect->color(),QColor("blue"));
472
473         QDeclarativeItemPrivate::get(rect)->setState("green");
474         rect->doSomething();
475         QCOMPARE(rect->color(),QColor("green"));
476     }
477
478     {
479         QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/signalOverride2.qml");
480         MyRect *rect = qobject_cast<MyRect*>(rectComponent.create());
481         QVERIFY(rect != 0);
482
483         QCOMPARE(rect->color(),QColor("white"));
484         rect->doSomething();
485         QCOMPARE(rect->color(),QColor("blue"));
486
487         QDeclarative1Rectangle *innerRect = qobject_cast<QDeclarative1Rectangle*>(rect->findChild<QDeclarative1Rectangle*>("extendedRect"));
488         QDeclarativeItemPrivate::get(innerRect)->setState("green");
489         rect->doSomething();
490         QCOMPARE(rect->color(),QColor("blue"));
491         QCOMPARE(innerRect->color(),QColor("green"));
492         QCOMPARE(innerRect->property("extendedColor").value<QColor>(),QColor("green"));
493     }
494 }
495
496 void tst_qdeclarativestates::signalOverrideCrash()
497 {
498     QDeclarativeEngine engine;
499
500     QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/signalOverrideCrash.qml");
501     MyRect *rect = qobject_cast<MyRect*>(rectComponent.create());
502     QVERIFY(rect != 0);
503
504     QDeclarativeItemPrivate::get(rect)->setState("overridden");
505     rect->doSomething();
506 }
507
508 void tst_qdeclarativestates::signalOverrideCrash2()
509 {
510     QDeclarativeEngine engine;
511
512     QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/signalOverrideCrash2.qml");
513     QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
514     QVERIFY(rect != 0);
515
516     QDeclarativeItemPrivate::get(rect)->setState("state1");
517     QDeclarativeItemPrivate::get(rect)->setState("state2");
518     QDeclarativeItemPrivate::get(rect)->setState("state1");
519
520     delete rect;
521 }
522
523 void tst_qdeclarativestates::parentChange()
524 {
525     QDeclarativeEngine engine;
526
527     {
528         QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/parentChange1.qml");
529         QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
530         QVERIFY(rect != 0);
531
532         QDeclarative1Rectangle *innerRect = qobject_cast<QDeclarative1Rectangle*>(rect->findChild<QDeclarative1Rectangle*>("MyRect"));
533         QVERIFY(innerRect != 0);
534
535         QDeclarativeListReference list(rect, "states");
536         QDeclarative1State *state = qobject_cast<QDeclarative1State*>(list.at(0));
537         QVERIFY(state != 0);
538
539         qmlExecuteDeferred(state);
540         QDeclarative1ParentChange *pChange = qobject_cast<QDeclarative1ParentChange*>(state->operationAt(0));
541         QVERIFY(pChange != 0);
542         QDeclarativeItem *nParent = qobject_cast<QDeclarativeItem*>(rect->findChild<QDeclarativeItem*>("NewParent"));
543         QVERIFY(nParent != 0);
544
545         QCOMPARE(pChange->parent(), nParent);
546
547         QDeclarativeItemPrivate::get(rect)->setState("reparented");
548         QCOMPARE(innerRect->rotation(), qreal(0));
549         QCOMPARE(innerRect->scale(), qreal(1));
550         QCOMPARE(innerRect->x(), qreal(-133));
551         QCOMPARE(innerRect->y(), qreal(-300));
552     }
553
554     {
555         QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/parentChange2.qml");
556         QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
557         QVERIFY(rect != 0);
558         QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
559         QDeclarative1Rectangle *innerRect = qobject_cast<QDeclarative1Rectangle*>(rect->findChild<QDeclarative1Rectangle*>("MyRect"));
560         QVERIFY(innerRect != 0);
561
562         rectPrivate->setState("reparented");
563         QCOMPARE(innerRect->rotation(), qreal(15));
564         QCOMPARE(innerRect->scale(), qreal(.5));
565         QCOMPARE(QString("%1").arg(innerRect->x()), QString("%1").arg(-19.9075));
566         QCOMPARE(QString("%1").arg(innerRect->y()), QString("%1").arg(-8.73433));
567     }
568
569     {
570         QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/parentChange3.qml");
571         QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
572         QVERIFY(rect != 0);
573         QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
574         QDeclarative1Rectangle *innerRect = qobject_cast<QDeclarative1Rectangle*>(rect->findChild<QDeclarative1Rectangle*>("MyRect"));
575         QVERIFY(innerRect != 0);
576
577         rectPrivate->setState("reparented");
578         QCOMPARE(innerRect->rotation(), qreal(-37));
579         QCOMPARE(innerRect->scale(), qreal(.25));
580         QCOMPARE(QString("%1").arg(innerRect->x()), QString("%1").arg(-217.305));
581         QCOMPARE(QString("%1").arg(innerRect->y()), QString("%1").arg(-164.413));
582
583         rectPrivate->setState("");
584         QCOMPARE(innerRect->rotation(), qreal(0));
585         QCOMPARE(innerRect->scale(), qreal(1));
586         QCOMPARE(innerRect->x(), qreal(5));
587         //do a non-qFuzzyCompare fuzzy compare
588         QVERIFY(innerRect->y() < qreal(0.00001) && innerRect->y() > qreal(-0.00001));
589     }
590
591     {
592         QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/parentChange6.qml");
593         QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
594         QVERIFY(rect != 0);
595
596         QDeclarative1Rectangle *innerRect = qobject_cast<QDeclarative1Rectangle*>(rect->findChild<QDeclarative1Rectangle*>("MyRect"));
597         QVERIFY(innerRect != 0);
598
599         QDeclarativeItemPrivate::get(rect)->setState("reparented");
600         QCOMPARE(innerRect->rotation(), qreal(180));
601         QCOMPARE(innerRect->scale(), qreal(1));
602         QCOMPARE(innerRect->x(), qreal(-105));
603         QCOMPARE(innerRect->y(), qreal(-105));
604     }
605 }
606
607 void tst_qdeclarativestates::parentChangeErrors()
608 {
609     QDeclarativeEngine engine;
610
611     {
612         QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/parentChange4.qml");
613         QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
614         QVERIFY(rect != 0);
615
616         QDeclarative1Rectangle *innerRect = qobject_cast<QDeclarative1Rectangle*>(rect->findChild<QDeclarative1Rectangle*>("MyRect"));
617         QVERIFY(innerRect != 0);
618
619         QTest::ignoreMessage(QtWarningMsg, fullDataPath("/data/parentChange4.qml") + ":25:9: QML ParentChange: Unable to preserve appearance under non-uniform scale");
620         QDeclarativeItemPrivate::get(rect)->setState("reparented");
621         QCOMPARE(innerRect->rotation(), qreal(0));
622         QCOMPARE(innerRect->scale(), qreal(1));
623         QCOMPARE(innerRect->x(), qreal(5));
624         QCOMPARE(innerRect->y(), qreal(5));
625     }
626
627     {
628         QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/parentChange5.qml");
629         QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
630         QVERIFY(rect != 0);
631
632         QDeclarative1Rectangle *innerRect = qobject_cast<QDeclarative1Rectangle*>(rect->findChild<QDeclarative1Rectangle*>("MyRect"));
633         QVERIFY(innerRect != 0);
634
635         QTest::ignoreMessage(QtWarningMsg, fullDataPath("/data/parentChange5.qml") + ":25:9: QML ParentChange: Unable to preserve appearance under complex transform");
636         QDeclarativeItemPrivate::get(rect)->setState("reparented");
637         QCOMPARE(innerRect->rotation(), qreal(0));
638         QCOMPARE(innerRect->scale(), qreal(1));
639         QCOMPARE(innerRect->x(), qreal(5));
640         QCOMPARE(innerRect->y(), qreal(5));
641     }
642 }
643
644 void tst_qdeclarativestates::anchorChanges()
645 {
646     QDeclarativeEngine engine;
647
648     QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChanges1.qml");
649     QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
650     QVERIFY(rect != 0);
651     QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
652
653     QDeclarative1Rectangle *innerRect = qobject_cast<QDeclarative1Rectangle*>(rect->findChild<QDeclarative1Rectangle*>("MyRect"));
654     QVERIFY(innerRect != 0);
655
656     QDeclarativeListReference list(rect, "states");
657     QDeclarative1State *state = qobject_cast<QDeclarative1State*>(list.at(0));
658     QVERIFY(state != 0);
659
660     qmlExecuteDeferred(state);
661     QDeclarative1AnchorChanges *aChanges = qobject_cast<QDeclarative1AnchorChanges*>(state->operationAt(0));
662     QVERIFY(aChanges != 0);
663
664     rectPrivate->setState("right");
665     QCOMPARE(innerRect->x(), qreal(150));
666     QCOMPARE(aChanges->object(), qobject_cast<QDeclarativeItem*>(innerRect));
667     QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->left().anchorLine, QDeclarative1AnchorLine::Invalid);  //### was reset (how do we distinguish from not set at all)
668     QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->right().item, rectPrivate->right().item);
669     QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->right().anchorLine, rectPrivate->right().anchorLine);
670
671     rectPrivate->setState("");
672     QCOMPARE(innerRect->x(), qreal(5));
673
674     delete rect;
675 }
676
677 void tst_qdeclarativestates::anchorChanges2()
678 {
679     QDeclarativeEngine engine;
680
681     QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChanges2.qml");
682     QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
683     QVERIFY(rect != 0);
684     QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
685
686     QDeclarative1Rectangle *innerRect = qobject_cast<QDeclarative1Rectangle*>(rect->findChild<QDeclarative1Rectangle*>("MyRect"));
687     QVERIFY(innerRect != 0);
688
689     rectPrivate->setState("right");
690     QCOMPARE(innerRect->x(), qreal(150));
691
692     rectPrivate->setState("");
693     QCOMPARE(innerRect->x(), qreal(5));
694
695     delete rect;
696 }
697
698 void tst_qdeclarativestates::anchorChanges3()
699 {
700     QDeclarativeEngine engine;
701
702     QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChanges3.qml");
703     QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
704     QVERIFY(rect != 0);
705     QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
706
707     QDeclarative1Rectangle *innerRect = qobject_cast<QDeclarative1Rectangle*>(rect->findChild<QDeclarative1Rectangle*>("MyRect"));
708     QVERIFY(innerRect != 0);
709
710     QDeclarativeItem *leftGuideline = qobject_cast<QDeclarativeItem*>(rect->findChild<QDeclarativeItem*>("LeftGuideline"));
711     QVERIFY(leftGuideline != 0);
712
713     QDeclarativeItem *bottomGuideline = qobject_cast<QDeclarativeItem*>(rect->findChild<QDeclarativeItem*>("BottomGuideline"));
714     QVERIFY(bottomGuideline != 0);
715
716     QDeclarativeListReference list(rect, "states");
717     QDeclarative1State *state = qobject_cast<QDeclarative1State*>(list.at(0));
718     QVERIFY(state != 0);
719
720     qmlExecuteDeferred(state);
721     QDeclarative1AnchorChanges *aChanges = qobject_cast<QDeclarative1AnchorChanges*>(state->operationAt(0));
722     QVERIFY(aChanges != 0);
723
724     rectPrivate->setState("reanchored");
725     QCOMPARE(aChanges->object(), qobject_cast<QDeclarativeItem*>(innerRect));
726     QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->left().item, QDeclarativeItemPrivate::get(leftGuideline)->left().item);
727     QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->left().anchorLine, QDeclarativeItemPrivate::get(leftGuideline)->left().anchorLine);
728     QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->right().item, rectPrivate->right().item);
729     QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->right().anchorLine, rectPrivate->right().anchorLine);
730     QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->top().item, rectPrivate->top().item);
731     QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->top().anchorLine, rectPrivate->top().anchorLine);
732     QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->bottom().item, QDeclarativeItemPrivate::get(bottomGuideline)->bottom().item);
733     QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->bottom().anchorLine, QDeclarativeItemPrivate::get(bottomGuideline)->bottom().anchorLine);
734
735     QCOMPARE(innerRect->x(), qreal(10));
736     QCOMPARE(innerRect->y(), qreal(0));
737     QCOMPARE(innerRect->width(), qreal(190));
738     QCOMPARE(innerRect->height(), qreal(150));
739
740     rectPrivate->setState("");
741     QCOMPARE(innerRect->x(), qreal(0));
742     QCOMPARE(innerRect->y(), qreal(10));
743     QCOMPARE(innerRect->width(), qreal(150));
744     QCOMPARE(innerRect->height(), qreal(190));
745
746     delete rect;
747 }
748
749 void tst_qdeclarativestates::anchorChanges4()
750 {
751     QDeclarativeEngine engine;
752
753     QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChanges4.qml");
754     QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
755     QVERIFY(rect != 0);
756
757     QDeclarative1Rectangle *innerRect = qobject_cast<QDeclarative1Rectangle*>(rect->findChild<QDeclarative1Rectangle*>("MyRect"));
758     QVERIFY(innerRect != 0);
759
760     QDeclarativeItem *leftGuideline = qobject_cast<QDeclarativeItem*>(rect->findChild<QDeclarativeItem*>("LeftGuideline"));
761     QVERIFY(leftGuideline != 0);
762
763     QDeclarativeItem *bottomGuideline = qobject_cast<QDeclarativeItem*>(rect->findChild<QDeclarativeItem*>("BottomGuideline"));
764     QVERIFY(bottomGuideline != 0);
765
766     QDeclarativeListReference list(rect, "states");
767     QDeclarative1State *state = qobject_cast<QDeclarative1State*>(list.at(0));
768     QVERIFY(state != 0);
769
770     qmlExecuteDeferred(state);
771     QDeclarative1AnchorChanges *aChanges = qobject_cast<QDeclarative1AnchorChanges*>(state->operationAt(0));
772     QVERIFY(aChanges != 0);
773
774     QDeclarativeItemPrivate::get(rect)->setState("reanchored");
775     QCOMPARE(aChanges->object(), qobject_cast<QDeclarativeItem*>(innerRect));
776     QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->horizontalCenter().item, QDeclarativeItemPrivate::get(bottomGuideline)->horizontalCenter().item);
777     QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->horizontalCenter().anchorLine, QDeclarativeItemPrivate::get(bottomGuideline)->horizontalCenter().anchorLine);
778     QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->verticalCenter().item, QDeclarativeItemPrivate::get(leftGuideline)->verticalCenter().item);
779     QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->verticalCenter().anchorLine, QDeclarativeItemPrivate::get(leftGuideline)->verticalCenter().anchorLine);
780
781     delete rect;
782 }
783
784 void tst_qdeclarativestates::anchorChanges5()
785 {
786     QDeclarativeEngine engine;
787
788     QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChanges5.qml");
789     QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
790     QVERIFY(rect != 0);
791
792     QDeclarative1Rectangle *innerRect = qobject_cast<QDeclarative1Rectangle*>(rect->findChild<QDeclarative1Rectangle*>("MyRect"));
793     QVERIFY(innerRect != 0);
794
795     QDeclarativeItem *leftGuideline = qobject_cast<QDeclarativeItem*>(rect->findChild<QDeclarativeItem*>("LeftGuideline"));
796     QVERIFY(leftGuideline != 0);
797
798     QDeclarativeItem *bottomGuideline = qobject_cast<QDeclarativeItem*>(rect->findChild<QDeclarativeItem*>("BottomGuideline"));
799     QVERIFY(bottomGuideline != 0);
800
801     QDeclarativeListReference list(rect, "states");
802     QDeclarative1State *state = qobject_cast<QDeclarative1State*>(list.at(0));
803     QVERIFY(state != 0);
804
805     qmlExecuteDeferred(state);
806     QDeclarative1AnchorChanges *aChanges = qobject_cast<QDeclarative1AnchorChanges*>(state->operationAt(0));
807     QVERIFY(aChanges != 0);
808
809     QDeclarativeItemPrivate::get(rect)->setState("reanchored");
810     QCOMPARE(aChanges->object(), qobject_cast<QDeclarativeItem*>(innerRect));
811     //QCOMPARE(aChanges->anchors()->horizontalCenter().item, bottomGuideline->horizontalCenter().item);
812     //QCOMPARE(aChanges->anchors()->horizontalCenter().anchorLine, bottomGuideline->horizontalCenter().anchorLine);
813     //QCOMPARE(aChanges->anchors()->baseline().item, leftGuideline->baseline().item);
814     //QCOMPARE(aChanges->anchors()->baseline().anchorLine, leftGuideline->baseline().anchorLine);
815
816     delete rect;
817 }
818
819 void mirrorAnchors(QDeclarativeItem *item) {
820     QDeclarativeItemPrivate *itemPrivate = QDeclarativeItemPrivate::get(item);
821     itemPrivate->setLayoutMirror(true);
822 }
823
824 qreal offsetRTL(QDeclarativeItem *anchorItem, QDeclarativeItem *item) {
825     return anchorItem->width()+2*anchorItem->x()-item->width();
826 }
827
828 void tst_qdeclarativestates::anchorChangesRTL()
829 {
830     QDeclarativeEngine engine;
831
832     QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChanges1.qml");
833     QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
834     QVERIFY(rect != 0);
835     QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
836
837     QDeclarative1Rectangle *innerRect = qobject_cast<QDeclarative1Rectangle*>(rect->findChild<QDeclarative1Rectangle*>("MyRect"));
838     QVERIFY(innerRect != 0);
839     mirrorAnchors(innerRect);
840
841     QDeclarativeListReference list(rect, "states");
842     QDeclarative1State *state = qobject_cast<QDeclarative1State*>(list.at(0));
843     QVERIFY(state != 0);
844
845     qmlExecuteDeferred(state);
846     QDeclarative1AnchorChanges *aChanges = qobject_cast<QDeclarative1AnchorChanges*>(state->operationAt(0));
847     QVERIFY(aChanges != 0);
848
849     rectPrivate->setState("right");
850     QCOMPARE(innerRect->x(), offsetRTL(rect, innerRect) - qreal(150));
851     QCOMPARE(aChanges->object(), qobject_cast<QDeclarativeItem*>(innerRect));
852     QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->left().anchorLine, QDeclarative1AnchorLine::Invalid);  //### was reset (how do we distinguish from not set at all)
853     QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->right().item, rectPrivate->right().item);
854     QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->right().anchorLine, rectPrivate->right().anchorLine);
855
856     rectPrivate->setState("");
857     QCOMPARE(innerRect->x(), offsetRTL(rect, innerRect) -qreal(5));
858
859     delete rect;
860 }
861
862 void tst_qdeclarativestates::anchorChangesRTL2()
863 {
864     QDeclarativeEngine engine;
865
866     QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChanges2.qml");
867     QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
868     QVERIFY(rect != 0);
869     QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
870
871     QDeclarative1Rectangle *innerRect = qobject_cast<QDeclarative1Rectangle*>(rect->findChild<QDeclarative1Rectangle*>("MyRect"));
872     QVERIFY(innerRect != 0);
873     mirrorAnchors(innerRect);
874
875     rectPrivate->setState("right");
876     QCOMPARE(innerRect->x(), offsetRTL(rect, innerRect) - qreal(150));
877
878     rectPrivate->setState("");
879     QCOMPARE(innerRect->x(), offsetRTL(rect, innerRect) - qreal(5));
880
881     delete rect;
882 }
883
884 void tst_qdeclarativestates::anchorChangesRTL3()
885 {
886     QDeclarativeEngine engine;
887
888     QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChanges3.qml");
889     QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
890     QVERIFY(rect != 0);
891     QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
892
893     QDeclarative1Rectangle *innerRect = qobject_cast<QDeclarative1Rectangle*>(rect->findChild<QDeclarative1Rectangle*>("MyRect"));
894     QVERIFY(innerRect != 0);
895     mirrorAnchors(innerRect);
896
897     QDeclarativeItem *leftGuideline = qobject_cast<QDeclarativeItem*>(rect->findChild<QDeclarativeItem*>("LeftGuideline"));
898     QVERIFY(leftGuideline != 0);
899
900     QDeclarativeItem *bottomGuideline = qobject_cast<QDeclarativeItem*>(rect->findChild<QDeclarativeItem*>("BottomGuideline"));
901     QVERIFY(bottomGuideline != 0);
902
903     QDeclarativeListReference list(rect, "states");
904     QDeclarative1State *state = qobject_cast<QDeclarative1State*>(list.at(0));
905     QVERIFY(state != 0);
906
907     qmlExecuteDeferred(state);
908     QDeclarative1AnchorChanges *aChanges = qobject_cast<QDeclarative1AnchorChanges*>(state->operationAt(0));
909     QVERIFY(aChanges != 0);
910
911     rectPrivate->setState("reanchored");
912     QCOMPARE(aChanges->object(), qobject_cast<QDeclarativeItem*>(innerRect));
913     QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->left().item, QDeclarativeItemPrivate::get(leftGuideline)->left().item);
914     QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->left().anchorLine, QDeclarativeItemPrivate::get(leftGuideline)->left().anchorLine);
915     QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->right().item, rectPrivate->right().item);
916     QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->right().anchorLine, rectPrivate->right().anchorLine);
917     QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->top().item, rectPrivate->top().item);
918     QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->top().anchorLine, rectPrivate->top().anchorLine);
919     QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->bottom().item, QDeclarativeItemPrivate::get(bottomGuideline)->bottom().item);
920     QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->bottom().anchorLine, QDeclarativeItemPrivate::get(bottomGuideline)->bottom().anchorLine);
921
922     QCOMPARE(innerRect->x(), offsetRTL(leftGuideline, innerRect) - qreal(10));
923     QCOMPARE(innerRect->y(), qreal(0));
924     // between left side of parent and leftGuideline.x: 10, which has width 0
925     QCOMPARE(innerRect->width(), qreal(10));
926     QCOMPARE(innerRect->height(), qreal(150));
927
928     rectPrivate->setState("");
929     QCOMPARE(innerRect->x(), offsetRTL(rect, innerRect) - qreal(0));
930     QCOMPARE(innerRect->y(), qreal(10));
931     // between right side of parent and left side of rightGuideline.x: 150, which has width 0
932     QCOMPARE(innerRect->width(), qreal(50));
933     QCOMPARE(innerRect->height(), qreal(190));
934
935     delete rect;
936 }
937
938 //QTBUG-9609
939 void tst_qdeclarativestates::anchorChangesCrash()
940 {
941     QDeclarativeEngine engine;
942
943     QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChangesCrash.qml");
944     QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
945     QVERIFY(rect != 0);
946
947     QDeclarativeItemPrivate::get(rect)->setState("reanchored");
948
949     delete rect;
950 }
951
952 // QTBUG-12273
953 void tst_qdeclarativestates::anchorRewindBug()
954 {
955     QDeclarativeEngine engine;
956
957     QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorRewindBug.qml");
958     QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
959     QVERIFY(rect != 0);
960
961     QDeclarativeItem * column = rect->findChild<QDeclarativeItem*>("column");
962
963     QVERIFY(column != 0);
964     QVERIFY(!QDeclarativeItemPrivate::get(column)->heightValid);
965     QVERIFY(!QDeclarativeItemPrivate::get(column)->widthValid);
966     QCOMPARE(column->height(), 200.0);
967     QDeclarativeItemPrivate::get(rect)->setState("reanchored");
968
969     // column height and width should stay implicit
970     // and column's implicit resizing should still work
971     QVERIFY(!QDeclarativeItemPrivate::get(column)->heightValid);
972     QVERIFY(!QDeclarativeItemPrivate::get(column)->widthValid);
973     QCOMPARE(column->height(), 100.0);
974
975     QDeclarativeItemPrivate::get(rect)->setState("");
976
977     // column height and width should stay implicit
978     // and column's implicit resizing should still work
979     QVERIFY(!QDeclarativeItemPrivate::get(column)->heightValid);
980     QVERIFY(!QDeclarativeItemPrivate::get(column)->widthValid);
981     QCOMPARE(column->height(), 200.0);
982
983     delete rect;
984 }
985
986 // QTBUG-11834
987 void tst_qdeclarativestates::anchorRewindBug2()
988 {
989     QDeclarativeEngine engine;
990
991     QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorRewindBug2.qml");
992     QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
993     QVERIFY(rect != 0);
994
995     QDeclarative1Rectangle *mover = rect->findChild<QDeclarative1Rectangle*>("mover");
996
997     QVERIFY(mover != 0);
998     QCOMPARE(mover->y(), qreal(0.0));
999     QCOMPARE(mover->width(), qreal(50.0));
1000
1001     QDeclarativeItemPrivate::get(rect)->setState("anchored");
1002     QCOMPARE(mover->y(), qreal(250.0));
1003     QCOMPARE(mover->width(), qreal(200.0));
1004
1005     QDeclarativeItemPrivate::get(rect)->setState("");
1006     QCOMPARE(mover->y(), qreal(0.0));
1007     QCOMPARE(mover->width(), qreal(50.0));
1008
1009     delete rect;
1010 }
1011
1012 void tst_qdeclarativestates::script()
1013 {
1014     QDeclarativeEngine engine;
1015
1016     {
1017         QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/script.qml");
1018         QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
1019         QVERIFY(rect != 0);
1020         QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
1021         QCOMPARE(rect->color(),QColor("red"));
1022
1023         rectPrivate->setState("blue");
1024         QCOMPARE(rect->color(),QColor("blue"));
1025
1026         rectPrivate->setState("");
1027         QCOMPARE(rect->color(),QColor("blue")); // a script isn't reverted
1028     }
1029 }
1030
1031 void tst_qdeclarativestates::restoreEntryValues()
1032 {
1033     QDeclarativeEngine engine;
1034
1035     QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/restoreEntryValues.qml");
1036     QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
1037     QVERIFY(rect != 0);
1038     QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
1039     QCOMPARE(rect->color(),QColor("red"));
1040
1041     rectPrivate->setState("blue");
1042     QCOMPARE(rect->color(),QColor("blue"));
1043
1044     rectPrivate->setState("");
1045     QCOMPARE(rect->color(),QColor("blue"));
1046 }
1047
1048 void tst_qdeclarativestates::explicitChanges()
1049 {
1050     QDeclarativeEngine engine;
1051
1052     QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/explicit.qml");
1053     QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
1054     QVERIFY(rect != 0);
1055     QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
1056     QDeclarativeListReference list(rect, "states");
1057     QDeclarative1State *state = qobject_cast<QDeclarative1State*>(list.at(0));
1058     QVERIFY(state != 0);
1059
1060     qmlExecuteDeferred(state);
1061     QDeclarative1PropertyChanges *changes = qobject_cast<QDeclarative1PropertyChanges*>(rect->findChild<QDeclarative1PropertyChanges*>("changes"));
1062     QVERIFY(changes != 0);
1063     QVERIFY(changes->isExplicit());
1064
1065     QCOMPARE(rect->color(),QColor("red"));
1066
1067     rectPrivate->setState("blue");
1068     QCOMPARE(rect->color(),QColor("blue"));
1069
1070     rect->setProperty("sourceColor", QColor("green"));
1071     QCOMPARE(rect->color(),QColor("blue"));
1072
1073     rectPrivate->setState("");
1074     QCOMPARE(rect->color(),QColor("red"));
1075     rect->setProperty("sourceColor", QColor("yellow"));
1076     QCOMPARE(rect->color(),QColor("red"));
1077
1078     rectPrivate->setState("blue");
1079     QCOMPARE(rect->color(),QColor("yellow"));
1080 }
1081
1082 void tst_qdeclarativestates::propertyErrors()
1083 {
1084     QDeclarativeEngine engine;
1085     QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/propertyErrors.qml");
1086     QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
1087     QVERIFY(rect != 0);
1088
1089     QCOMPARE(rect->color(),QColor("red"));
1090
1091     QTest::ignoreMessage(QtWarningMsg, fullDataPath("/data/propertyErrors.qml") + ":8:9: QML PropertyChanges: Cannot assign to non-existent property \"colr\"");
1092     QTest::ignoreMessage(QtWarningMsg, fullDataPath("/data/propertyErrors.qml") + ":8:9: QML PropertyChanges: Cannot assign to read-only property \"activeFocus\"");
1093     QDeclarativeItemPrivate::get(rect)->setState("blue");
1094 }
1095
1096 void tst_qdeclarativestates::incorrectRestoreBug()
1097 {
1098     QDeclarativeEngine engine;
1099
1100     QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicChanges.qml");
1101     QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
1102     QVERIFY(rect != 0);
1103     QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
1104     QCOMPARE(rect->color(),QColor("red"));
1105
1106     rectPrivate->setState("blue");
1107     QCOMPARE(rect->color(),QColor("blue"));
1108
1109     rectPrivate->setState("");
1110     QCOMPARE(rect->color(),QColor("red"));
1111
1112     // make sure if we change the base state value, we then restore to it correctly
1113     rect->setColor(QColor("green"));
1114
1115     rectPrivate->setState("blue");
1116     QCOMPARE(rect->color(),QColor("blue"));
1117
1118     rectPrivate->setState("");
1119     QCOMPARE(rect->color(),QColor("green"));
1120 }
1121
1122 void tst_qdeclarativestates::autoStateAtStartupRestoreBug()
1123 {
1124     QDeclarativeEngine engine;
1125
1126     QDeclarativeComponent component(&engine, SRCDIR "/data/autoStateAtStartupRestoreBug.qml");
1127     QObject *obj = component.create();
1128
1129     QVERIFY(obj != 0);
1130     QCOMPARE(obj->property("test").toInt(), 3);
1131
1132     obj->setProperty("input", 2);
1133
1134     QCOMPARE(obj->property("test").toInt(), 9);
1135
1136     delete obj;
1137 }
1138
1139 void tst_qdeclarativestates::deletingChange()
1140 {
1141     QDeclarativeEngine engine;
1142
1143     QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/deleting.qml");
1144     QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
1145     QVERIFY(rect != 0);
1146     QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
1147     rectPrivate->setState("blue");
1148     QCOMPARE(rect->color(),QColor("blue"));
1149     QCOMPARE(rect->radius(),qreal(5));
1150
1151     rectPrivate->setState("");
1152     QCOMPARE(rect->color(),QColor("red"));
1153     QCOMPARE(rect->radius(),qreal(0));
1154
1155     QDeclarative1PropertyChanges *pc = rect->findChild<QDeclarative1PropertyChanges*>("pc1");
1156     QVERIFY(pc != 0);
1157     delete pc;
1158
1159     QDeclarative1State *state = rect->findChild<QDeclarative1State*>();
1160     QVERIFY(state != 0);
1161     qmlExecuteDeferred(state);
1162     QCOMPARE(state->operationCount(), 1);
1163
1164     rectPrivate->setState("blue");
1165     QCOMPARE(rect->color(),QColor("red"));
1166     QCOMPARE(rect->radius(),qreal(5));
1167
1168     delete rect;
1169 }
1170
1171 void tst_qdeclarativestates::deletingState()
1172 {
1173     QDeclarativeEngine engine;
1174
1175     QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/deletingState.qml");
1176     QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
1177     QVERIFY(rect != 0);
1178
1179     QDeclarative1StateGroup *sg = rect->findChild<QDeclarative1StateGroup*>();
1180     QVERIFY(sg != 0);
1181     QVERIFY(sg->findState("blue") != 0);
1182
1183     sg->setState("blue");
1184     QCOMPARE(rect->color(),QColor("blue"));
1185
1186     sg->setState("");
1187     QCOMPARE(rect->color(),QColor("red"));
1188
1189     QDeclarative1State *state = rect->findChild<QDeclarative1State*>();
1190     QVERIFY(state != 0);
1191     delete state;
1192
1193     QVERIFY(sg->findState("blue") == 0);
1194
1195     //### should we warn that state doesn't exist
1196     sg->setState("blue");
1197     QCOMPARE(rect->color(),QColor("red"));
1198
1199     delete rect;
1200 }
1201
1202 void tst_qdeclarativestates::tempState()
1203 {
1204     QDeclarativeEngine engine;
1205
1206     QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/legalTempState.qml");
1207     QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
1208     QVERIFY(rect != 0);
1209     QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
1210     QTest::ignoreMessage(QtDebugMsg, "entering placed");
1211     QTest::ignoreMessage(QtDebugMsg, "entering idle");
1212     rectPrivate->setState("placed");
1213     QCOMPARE(rectPrivate->state(), QLatin1String("idle"));
1214 }
1215
1216 void tst_qdeclarativestates::illegalTempState()
1217 {
1218     QDeclarativeEngine engine;
1219
1220     QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/illegalTempState.qml");
1221     QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
1222     QVERIFY(rect != 0);
1223     QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
1224     QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML StateGroup: Can't apply a state change as part of a state definition.");
1225     rectPrivate->setState("placed");
1226     QCOMPARE(rectPrivate->state(), QLatin1String("placed"));
1227 }
1228
1229 void tst_qdeclarativestates::nonExistantProperty()
1230 {
1231     QDeclarativeEngine engine;
1232
1233     QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/nonExistantProp.qml");
1234     QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
1235     QVERIFY(rect != 0);
1236     QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
1237     QTest::ignoreMessage(QtWarningMsg, fullDataPath("/data/nonExistantProp.qml") + ":9:9: QML PropertyChanges: Cannot assign to non-existent property \"colr\"");
1238     rectPrivate->setState("blue");
1239     QCOMPARE(rectPrivate->state(), QLatin1String("blue"));
1240 }
1241
1242 void tst_qdeclarativestates::reset()
1243 {
1244     QDeclarativeEngine engine;
1245
1246     QDeclarativeComponent c(&engine, SRCDIR "/data/reset.qml");
1247     QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(c.create());
1248     QVERIFY(rect != 0);
1249
1250     QDeclarative1Image *image = rect->findChild<QDeclarative1Image*>();
1251     QVERIFY(image != 0);
1252     QCOMPARE(image->width(), qreal(40.));
1253     QCOMPARE(image->height(), qreal(20.));
1254
1255     QDeclarativeItemPrivate::get(rect)->setState("state1");
1256
1257     QCOMPARE(image->width(), 20.0);
1258     QCOMPARE(image->height(), qreal(20.));
1259 }
1260
1261 void tst_qdeclarativestates::illegalObjectCreation()
1262 {
1263     QDeclarativeEngine engine;
1264
1265     QDeclarativeComponent component(&engine, SRCDIR "/data/illegalObj.qml");
1266     QList<QDeclarativeError> errors = component.errors();
1267     QVERIFY(errors.count() == 1);
1268     const QDeclarativeError &error = errors.at(0);
1269     QCOMPARE(error.line(), 9);
1270     QCOMPARE(error.column(), 23);
1271     QCOMPARE(error.description().toUtf8().constData(), "PropertyChanges does not support creating state-specific objects.");
1272 }
1273
1274 void tst_qdeclarativestates::whenOrdering()
1275 {
1276     QDeclarativeEngine engine;
1277
1278     QDeclarativeComponent c(&engine, SRCDIR "/data/whenOrdering.qml");
1279     QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(c.create());
1280     QVERIFY(rect != 0);
1281     QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
1282
1283     QCOMPARE(rectPrivate->state(), QLatin1String(""));
1284     rect->setProperty("condition2", true);
1285     QCOMPARE(rectPrivate->state(), QLatin1String("state2"));
1286     rect->setProperty("condition1", true);
1287     QCOMPARE(rectPrivate->state(), QLatin1String("state1"));
1288     rect->setProperty("condition2", false);
1289     QCOMPARE(rectPrivate->state(), QLatin1String("state1"));
1290     rect->setProperty("condition2", true);
1291     QCOMPARE(rectPrivate->state(), QLatin1String("state1"));
1292     rect->setProperty("condition1", false);
1293     rect->setProperty("condition2", false);
1294     QCOMPARE(rectPrivate->state(), QLatin1String(""));
1295 }
1296
1297 void tst_qdeclarativestates::urlResolution()
1298 {
1299     QDeclarativeEngine engine;
1300
1301     QDeclarativeComponent c(&engine, SRCDIR "/data/urlResolution.qml");
1302     QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(c.create());
1303     QVERIFY(rect != 0);
1304
1305     QDeclarativeItem *myType = rect->findChild<QDeclarativeItem*>("MyType");
1306     QDeclarative1Image *image1 = rect->findChild<QDeclarative1Image*>("image1");
1307     QDeclarative1Image *image2 = rect->findChild<QDeclarative1Image*>("image2");
1308     QDeclarative1Image *image3 = rect->findChild<QDeclarative1Image*>("image3");
1309     QVERIFY(myType != 0 && image1 != 0 && image2 != 0 && image3 != 0);
1310
1311     QDeclarativeItemPrivate::get(myType)->setState("SetImageState");
1312     QUrl resolved = QUrl::fromLocalFile(SRCDIR "/data/Implementation/images/qt-logo.png");
1313     QCOMPARE(image1->source(), resolved);
1314     QCOMPARE(image2->source(), resolved);
1315     QCOMPARE(image3->source(), resolved);
1316 }
1317
1318 void tst_qdeclarativestates::unnamedWhen()
1319 {
1320     QDeclarativeEngine engine;
1321
1322     QDeclarativeComponent c(&engine, SRCDIR "/data/unnamedWhen.qml");
1323     QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(c.create());
1324     QVERIFY(rect != 0);
1325     QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
1326
1327     QCOMPARE(rectPrivate->state(), QLatin1String(""));
1328     QCOMPARE(rect->property("stateString").toString(), QLatin1String(""));
1329     rect->setProperty("triggerState", true);
1330     QCOMPARE(rectPrivate->state(), QLatin1String("anonymousState1"));
1331     QCOMPARE(rect->property("stateString").toString(), QLatin1String("inState"));
1332     rect->setProperty("triggerState", false);
1333     QCOMPARE(rectPrivate->state(), QLatin1String(""));
1334     QCOMPARE(rect->property("stateString").toString(), QLatin1String(""));
1335 }
1336
1337 void tst_qdeclarativestates::returnToBase()
1338 {
1339     QDeclarativeEngine engine;
1340
1341     QDeclarativeComponent c(&engine, SRCDIR "/data/returnToBase.qml");
1342     QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(c.create());
1343     QVERIFY(rect != 0);
1344     QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
1345
1346     QCOMPARE(rectPrivate->state(), QLatin1String(""));
1347     QCOMPARE(rect->property("stateString").toString(), QLatin1String(""));
1348     rect->setProperty("triggerState", true);
1349     QCOMPARE(rectPrivate->state(), QLatin1String("anonymousState1"));
1350     QCOMPARE(rect->property("stateString").toString(), QLatin1String("inState"));
1351     rect->setProperty("triggerState", false);
1352     QCOMPARE(rectPrivate->state(), QLatin1String(""));
1353     QCOMPARE(rect->property("stateString").toString(), QLatin1String("originalState"));
1354 }
1355
1356 //QTBUG-12559
1357 void tst_qdeclarativestates::extendsBug()
1358 {
1359     QDeclarativeEngine engine;
1360
1361     QDeclarativeComponent c(&engine, SRCDIR "/data/extendsBug.qml");
1362     QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(c.create());
1363     QVERIFY(rect != 0);
1364     QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
1365     QDeclarative1Rectangle *greenRect = rect->findChild<QDeclarative1Rectangle*>("greenRect");
1366
1367     rectPrivate->setState("b");
1368     QCOMPARE(greenRect->x(), qreal(100));
1369     QCOMPARE(greenRect->y(), qreal(100));
1370 }
1371
1372 void tst_qdeclarativestates::editProperties()
1373 {
1374     QDeclarativeEngine engine;
1375
1376     QDeclarativeComponent c(&engine, SRCDIR "/data/editProperties.qml");
1377     QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(c.create());
1378     QVERIFY(rect != 0);
1379
1380     QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
1381
1382     QDeclarative1StateGroup *stateGroup = rectPrivate->_states();
1383     QVERIFY(stateGroup != 0);
1384     qmlExecuteDeferred(stateGroup);
1385
1386     QDeclarative1State *blueState = stateGroup->findState("blue");
1387     QVERIFY(blueState != 0);
1388     qmlExecuteDeferred(blueState);
1389
1390     QDeclarative1PropertyChanges *propertyChangesBlue = qobject_cast<QDeclarative1PropertyChanges*>(blueState->operationAt(0));
1391     QVERIFY(propertyChangesBlue != 0);
1392
1393     QDeclarative1State *greenState = stateGroup->findState("green");
1394     QVERIFY(greenState != 0);
1395     qmlExecuteDeferred(greenState);
1396
1397     QDeclarative1PropertyChanges *propertyChangesGreen = qobject_cast<QDeclarative1PropertyChanges*>(greenState->operationAt(0));
1398     QVERIFY(propertyChangesGreen != 0);
1399
1400     QDeclarative1Rectangle *childRect = rect->findChild<QDeclarative1Rectangle*>("rect2");
1401     QVERIFY(childRect != 0);
1402     QCOMPARE(childRect->width(), qreal(402));
1403     QVERIFY(QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "width")));
1404     QCOMPARE(childRect->height(), qreal(200));
1405
1406     rectPrivate->setState("blue");
1407     QCOMPARE(childRect->width(), qreal(50));
1408     QCOMPARE(childRect->height(), qreal(40));
1409     QVERIFY(!QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "width")));
1410     QVERIFY(blueState->bindingInRevertList(childRect, "width"));
1411
1412
1413     rectPrivate->setState("green");
1414     QCOMPARE(childRect->width(), qreal(200));
1415     QCOMPARE(childRect->height(), qreal(100));
1416     QVERIFY(greenState->bindingInRevertList(childRect, "width"));
1417
1418
1419     rectPrivate->setState("");
1420
1421
1422     QCOMPARE(propertyChangesBlue->actions().length(), 2);
1423     QVERIFY(propertyChangesBlue->containsValue("width"));
1424     QVERIFY(!propertyChangesBlue->containsProperty("x"));
1425     QCOMPARE(propertyChangesBlue->value("width").toInt(), 50);
1426     QVERIFY(!propertyChangesBlue->value("x").isValid());
1427
1428     propertyChangesBlue->changeValue("width", 60);
1429     QCOMPARE(propertyChangesBlue->value("width").toInt(), 60);
1430     QCOMPARE(propertyChangesBlue->actions().length(), 2);
1431
1432
1433     propertyChangesBlue->changeExpression("width", "myRectangle.width / 2");
1434     QVERIFY(!propertyChangesBlue->containsValue("width"));
1435     QVERIFY(propertyChangesBlue->containsExpression("width"));
1436     QCOMPARE(propertyChangesBlue->value("width").toInt(), 0);
1437     QCOMPARE(propertyChangesBlue->actions().length(), 2);
1438
1439     propertyChangesBlue->changeValue("width", 50);
1440     QVERIFY(propertyChangesBlue->containsValue("width"));
1441     QVERIFY(!propertyChangesBlue->containsExpression("width"));
1442     QCOMPARE(propertyChangesBlue->value("width").toInt(), 50);
1443     QCOMPARE(propertyChangesBlue->actions().length(), 2);
1444
1445     QVERIFY(QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "width")));
1446     rectPrivate->setState("blue");
1447     QCOMPARE(childRect->width(), qreal(50));
1448     QCOMPARE(childRect->height(), qreal(40));
1449
1450     propertyChangesBlue->changeValue("width", 60);
1451     QCOMPARE(propertyChangesBlue->value("width").toInt(), 60);
1452     QCOMPARE(propertyChangesBlue->actions().length(), 2);
1453     QCOMPARE(childRect->width(), qreal(60));
1454     QVERIFY(!QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "width")));
1455
1456     propertyChangesBlue->changeExpression("width", "myRectangle.width / 2");
1457     QVERIFY(!propertyChangesBlue->containsValue("width"));
1458     QVERIFY(propertyChangesBlue->containsExpression("width"));
1459     QCOMPARE(propertyChangesBlue->value("width").toInt(), 0);
1460     QCOMPARE(propertyChangesBlue->actions().length(), 2);
1461     QVERIFY(QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "width")));
1462     QCOMPARE(childRect->width(), qreal(200));
1463
1464     propertyChangesBlue->changeValue("width", 50);
1465     QCOMPARE(childRect->width(), qreal(50));
1466
1467     rectPrivate->setState("");
1468     QCOMPARE(childRect->width(), qreal(402));
1469     QVERIFY(QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "width")));
1470
1471     QCOMPARE(propertyChangesGreen->actions().length(), 2);
1472     rectPrivate->setState("green");
1473     QCOMPARE(childRect->width(), qreal(200));
1474     QCOMPARE(childRect->height(), qreal(100));
1475     QVERIFY(QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "width")));
1476     QVERIFY(greenState->bindingInRevertList(childRect, "width"));
1477     QCOMPARE(propertyChangesGreen->actions().length(), 2);
1478
1479
1480     propertyChangesGreen->removeProperty("height");
1481     QVERIFY(!QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "height")));
1482     QCOMPARE(childRect->height(), qreal(200));
1483
1484     QVERIFY(greenState->bindingInRevertList(childRect, "width"));
1485     QVERIFY(greenState->containsPropertyInRevertList(childRect, "width"));
1486     propertyChangesGreen->removeProperty("width");
1487     QVERIFY(QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "width")));
1488     QCOMPARE(childRect->width(), qreal(402));
1489     QVERIFY(!greenState->bindingInRevertList(childRect, "width"));
1490     QVERIFY(!greenState->containsPropertyInRevertList(childRect, "width"));
1491
1492     propertyChangesBlue->removeProperty("width");
1493     QCOMPARE(childRect->width(), qreal(402));
1494
1495     rectPrivate->setState("blue");
1496     QCOMPARE(childRect->width(), qreal(402));
1497     QCOMPARE(childRect->height(), qreal(40));
1498 }
1499
1500 void tst_qdeclarativestates::QTBUG_14830()
1501 {
1502     QDeclarativeEngine engine;
1503
1504     QDeclarativeComponent c(&engine, SRCDIR "/data/QTBUG-14830.qml");
1505     QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(c.create());
1506     QVERIFY(rect != 0);
1507     QDeclarativeItem *item = rect->findChild<QDeclarativeItem*>("area");
1508
1509     QCOMPARE(item->width(), qreal(171));
1510 }
1511
1512 QTEST_MAIN(tst_qdeclarativestates)
1513
1514 #include "tst_qdeclarativestates.moc"