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