1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the test suite of the Qt Toolkit.
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.
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.
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.
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.
40 ****************************************************************************/
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>
53 // In Symbian OS test data is located in applications private dir
57 class MyAttached : public QObject
60 Q_PROPERTY(int foo READ foo WRITE setFoo)
62 MyAttached(QObject *parent) : QObject(parent), m_foo(13) {}
64 int foo() const { return m_foo; }
65 void setFoo(int f) { m_foo = f; }
71 class MyRect : public QDeclarative1Rectangle
74 Q_PROPERTY(int propertyWithNotify READ propertyWithNotify WRITE setPropertyWithNotify NOTIFY oddlyNamedNotifySignal)
78 void doSomething() { emit didSomething(); }
80 int propertyWithNotify() const { return m_prop; }
81 void setPropertyWithNotify(int i) { m_prop = i; emit oddlyNamedNotifySignal(); }
83 static MyAttached *qmlAttachedProperties(QObject *o) {
84 return new MyAttached(o);
88 void oddlyNamedNotifySignal();
94 QML_DECLARE_TYPE(MyRect)
95 QML_DECLARE_TYPEINFO(MyRect, QML_HAS_ATTACHED_PROPERTIES)
97 class tst_qdeclarativestates : public QObject
101 tst_qdeclarativestates() {}
104 static QByteArray fullDataPath(const QString &path);
110 void attachedPropertyChanges();
111 void basicExtension();
113 void signalOverride();
114 void signalOverrideCrash();
115 void signalOverrideCrash2();
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();
130 void restoreEntryValues();
131 void explicitChanges();
132 void propertyErrors();
133 void incorrectRestoreBug();
134 void autoStateAtStartupRestoreBug();
135 void deletingChange();
136 void deletingState();
138 void illegalTempState();
139 void nonExistantProperty();
141 void illegalObjectCreation();
143 void urlResolution();
147 void editProperties();
151 void tst_qdeclarativestates::initTestCase()
153 qmlRegisterType<MyRect>("Qt.test", 1, 0, "MyRectangle");
156 QByteArray tst_qdeclarativestates::fullDataPath(const QString &path)
158 return QUrl::fromLocalFile(SRCDIR + path).toString().toUtf8();
161 void tst_qdeclarativestates::basicChanges()
163 QDeclarativeEngine engine;
166 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicChanges.qml");
167 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
168 QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
171 QCOMPARE(rect->color(),QColor("red"));
173 rectPrivate->setState("blue");
174 QCOMPARE(rect->color(),QColor("blue"));
176 rectPrivate->setState("");
177 QCOMPARE(rect->color(),QColor("red"));
181 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicChanges2.qml");
182 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
183 QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
186 QCOMPARE(rect->color(),QColor("red"));
188 rectPrivate->setState("blue");
189 QCOMPARE(rect->color(),QColor("blue"));
191 rectPrivate->setState("green");
192 QCOMPARE(rect->color(),QColor("green"));
194 rectPrivate->setState("");
195 QCOMPARE(rect->color(),QColor("red"));
197 rectPrivate->setState("green");
198 QCOMPARE(rect->color(),QColor("green"));
202 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicChanges3.qml");
203 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
204 QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
207 QCOMPARE(rect->color(),QColor("red"));
208 QCOMPARE(rect->border()->width(),1);
210 rectPrivate->setState("blue");
211 QCOMPARE(rect->color(),QColor("blue"));
212 QCOMPARE(rect->border()->width(),1);
214 rectPrivate->setState("bordered");
215 QCOMPARE(rect->color(),QColor("red"));
216 QCOMPARE(rect->border()->width(),2);
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)
223 rectPrivate->setState("bordered");
224 QCOMPARE(rect->color(),QColor("red"));
225 QCOMPARE(rect->border()->width(),2);
227 rectPrivate->setState("blue");
228 QCOMPARE(rect->color(),QColor("blue"));
229 QCOMPARE(rect->border()->width(),1);
234 // Test basicChanges4.qml can magically connect to propertyWithNotify's notify
235 // signal using 'onPropertyWithNotifyChanged' even though the signal name is
236 // actually 'oddlyNamedNotifySignal'
238 QDeclarativeComponent component(&engine, SRCDIR "/data/basicChanges4.qml");
239 QVERIFY(component.isReady());
241 MyRect *rect = qobject_cast<MyRect*>(component.create());
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("));
249 QCOMPARE(rect->color(), QColor(Qt::red));
251 rect->setPropertyWithNotify(100);
252 QCOMPARE(rect->color(), QColor(Qt::blue));
256 void tst_qdeclarativestates::attachedPropertyChanges()
258 QDeclarativeEngine engine;
260 QDeclarativeComponent component(&engine, SRCDIR "/data/attachedPropertyChanges.qml");
261 QVERIFY(component.isReady());
263 QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(component.create());
265 QCOMPARE(item->width(), 50.0);
267 // Ensure attached property has been changed
268 QObject *attObj = qmlAttachedPropertiesObject<MyRect>(item, false);
271 MyAttached *att = qobject_cast<MyAttached*>(attObj);
274 QCOMPARE(att->foo(), 1);
277 void tst_qdeclarativestates::basicExtension()
279 QDeclarativeEngine engine;
282 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicExtension.qml");
283 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
284 QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
287 QCOMPARE(rect->color(),QColor("red"));
288 QCOMPARE(rect->border()->width(),1);
290 rectPrivate->setState("blue");
291 QCOMPARE(rect->color(),QColor("blue"));
292 QCOMPARE(rect->border()->width(),1);
294 rectPrivate->setState("bordered");
295 QCOMPARE(rect->color(),QColor("blue"));
296 QCOMPARE(rect->border()->width(),2);
298 rectPrivate->setState("blue");
299 QCOMPARE(rect->color(),QColor("blue"));
300 QCOMPARE(rect->border()->width(),1);
302 rectPrivate->setState("");
303 QCOMPARE(rect->color(),QColor("red"));
304 QCOMPARE(rect->border()->width(),1);
306 rectPrivate->setState("bordered");
307 QCOMPARE(rect->color(),QColor("blue"));
308 QCOMPARE(rect->border()->width(),2);
310 rectPrivate->setState("");
311 QCOMPARE(rect->color(),QColor("red"));
312 QCOMPARE(rect->border()->width(),1);
316 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/fakeExtension.qml");
317 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
318 QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
321 QCOMPARE(rect->color(),QColor("red"));
323 rectPrivate->setState("blue");
324 QCOMPARE(rect->color(),QColor("blue"));
326 rectPrivate->setState("green");
327 QCOMPARE(rect->color(),QColor("green"));
329 rectPrivate->setState("blue");
330 QCOMPARE(rect->color(),QColor("blue"));
332 rectPrivate->setState("green");
333 QCOMPARE(rect->color(),QColor("green"));
335 rectPrivate->setState("");
336 QCOMPARE(rect->color(),QColor("red"));
338 rectPrivate->setState("green");
339 QCOMPARE(rect->color(),QColor("green"));
343 void tst_qdeclarativestates::basicBinding()
345 QDeclarativeEngine engine;
348 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicBinding.qml");
349 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
350 QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
353 QCOMPARE(rect->color(),QColor("red"));
355 rectPrivate->setState("blue");
356 QCOMPARE(rect->color(),QColor("blue"));
358 rectPrivate->setState("");
359 QCOMPARE(rect->color(),QColor("red"));
361 rectPrivate->setState("blue");
362 QCOMPARE(rect->color(),QColor("blue"));
363 rect->setProperty("sourceColor", QColor("green"));
364 QCOMPARE(rect->color(),QColor("green"));
366 rectPrivate->setState("");
367 QCOMPARE(rect->color(),QColor("red"));
368 rect->setProperty("sourceColor", QColor("yellow"));
369 QCOMPARE(rect->color(),QColor("red"));
371 rectPrivate->setState("blue");
372 QCOMPARE(rect->color(),QColor("yellow"));
376 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicBinding2.qml");
377 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
378 QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
381 QCOMPARE(rect->color(),QColor("red"));
383 rectPrivate->setState("blue");
384 QCOMPARE(rect->color(),QColor("blue"));
386 rectPrivate->setState("");
387 QCOMPARE(rect->color(),QColor("red"));
389 rectPrivate->setState("blue");
390 QCOMPARE(rect->color(),QColor("blue"));
391 rect->setProperty("sourceColor", QColor("green"));
392 QCOMPARE(rect->color(),QColor("blue"));
394 rectPrivate->setState("");
395 QCOMPARE(rect->color(),QColor("green"));
396 rect->setProperty("sourceColor", QColor("yellow"));
397 QCOMPARE(rect->color(),QColor("yellow"));
399 rectPrivate->setState("blue");
400 QCOMPARE(rect->color(),QColor("blue"));
402 rectPrivate->setState("");
403 QCOMPARE(rect->color(),QColor("yellow"));
407 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicBinding3.qml");
408 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
409 QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
412 QCOMPARE(rect->color(),QColor("red"));
413 rect->setProperty("sourceColor", QColor("green"));
414 QCOMPARE(rect->color(),QColor("green"));
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"));
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"));
432 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicBinding4.qml");
433 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
434 QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
437 QCOMPARE(rect->color(),QColor("red"));
439 rectPrivate->setState("blue");
440 QCOMPARE(rect->color(),QColor("blue"));
441 rect->setProperty("sourceColor", QColor("yellow"));
442 QCOMPARE(rect->color(),QColor("yellow"));
444 rectPrivate->setState("green");
445 QCOMPARE(rect->color(),QColor("green"));
446 rect->setProperty("sourceColor", QColor("purple"));
447 QCOMPARE(rect->color(),QColor("green"));
449 rectPrivate->setState("blue");
450 QCOMPARE(rect->color(),QColor("purple"));
452 rectPrivate->setState("green");
453 QCOMPARE(rect->color(),QColor("green"));
455 rectPrivate->setState("");
456 QCOMPARE(rect->color(),QColor("red"));
460 void tst_qdeclarativestates::signalOverride()
462 QDeclarativeEngine engine;
465 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/signalOverride.qml");
466 MyRect *rect = qobject_cast<MyRect*>(rectComponent.create());
469 QCOMPARE(rect->color(),QColor("red"));
471 QCOMPARE(rect->color(),QColor("blue"));
473 QDeclarativeItemPrivate::get(rect)->setState("green");
475 QCOMPARE(rect->color(),QColor("green"));
479 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/signalOverride2.qml");
480 MyRect *rect = qobject_cast<MyRect*>(rectComponent.create());
483 QCOMPARE(rect->color(),QColor("white"));
485 QCOMPARE(rect->color(),QColor("blue"));
487 QDeclarative1Rectangle *innerRect = qobject_cast<QDeclarative1Rectangle*>(rect->findChild<QDeclarative1Rectangle*>("extendedRect"));
488 QDeclarativeItemPrivate::get(innerRect)->setState("green");
490 QCOMPARE(rect->color(),QColor("blue"));
491 QCOMPARE(innerRect->color(),QColor("green"));
492 QCOMPARE(innerRect->property("extendedColor").value<QColor>(),QColor("green"));
496 void tst_qdeclarativestates::signalOverrideCrash()
498 QDeclarativeEngine engine;
500 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/signalOverrideCrash.qml");
501 MyRect *rect = qobject_cast<MyRect*>(rectComponent.create());
504 QDeclarativeItemPrivate::get(rect)->setState("overridden");
508 void tst_qdeclarativestates::signalOverrideCrash2()
510 QDeclarativeEngine engine;
512 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/signalOverrideCrash2.qml");
513 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
516 QDeclarativeItemPrivate::get(rect)->setState("state1");
517 QDeclarativeItemPrivate::get(rect)->setState("state2");
518 QDeclarativeItemPrivate::get(rect)->setState("state1");
523 void tst_qdeclarativestates::parentChange()
525 QDeclarativeEngine engine;
528 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/parentChange1.qml");
529 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
532 QDeclarative1Rectangle *innerRect = qobject_cast<QDeclarative1Rectangle*>(rect->findChild<QDeclarative1Rectangle*>("MyRect"));
533 QVERIFY(innerRect != 0);
535 QDeclarativeListReference list(rect, "states");
536 QDeclarative1State *state = qobject_cast<QDeclarative1State*>(list.at(0));
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);
545 QCOMPARE(pChange->parent(), nParent);
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));
555 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/parentChange2.qml");
556 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
558 QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
559 QDeclarative1Rectangle *innerRect = qobject_cast<QDeclarative1Rectangle*>(rect->findChild<QDeclarative1Rectangle*>("MyRect"));
560 QVERIFY(innerRect != 0);
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));
570 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/parentChange3.qml");
571 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
573 QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
574 QDeclarative1Rectangle *innerRect = qobject_cast<QDeclarative1Rectangle*>(rect->findChild<QDeclarative1Rectangle*>("MyRect"));
575 QVERIFY(innerRect != 0);
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));
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));
592 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/parentChange6.qml");
593 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
596 QDeclarative1Rectangle *innerRect = qobject_cast<QDeclarative1Rectangle*>(rect->findChild<QDeclarative1Rectangle*>("MyRect"));
597 QVERIFY(innerRect != 0);
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));
607 void tst_qdeclarativestates::parentChangeErrors()
609 QDeclarativeEngine engine;
612 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/parentChange4.qml");
613 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
616 QDeclarative1Rectangle *innerRect = qobject_cast<QDeclarative1Rectangle*>(rect->findChild<QDeclarative1Rectangle*>("MyRect"));
617 QVERIFY(innerRect != 0);
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));
628 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/parentChange5.qml");
629 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
632 QDeclarative1Rectangle *innerRect = qobject_cast<QDeclarative1Rectangle*>(rect->findChild<QDeclarative1Rectangle*>("MyRect"));
633 QVERIFY(innerRect != 0);
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));
644 void tst_qdeclarativestates::anchorChanges()
646 QDeclarativeEngine engine;
648 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChanges1.qml");
649 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
651 QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
653 QDeclarative1Rectangle *innerRect = qobject_cast<QDeclarative1Rectangle*>(rect->findChild<QDeclarative1Rectangle*>("MyRect"));
654 QVERIFY(innerRect != 0);
656 QDeclarativeListReference list(rect, "states");
657 QDeclarative1State *state = qobject_cast<QDeclarative1State*>(list.at(0));
660 qmlExecuteDeferred(state);
661 QDeclarative1AnchorChanges *aChanges = qobject_cast<QDeclarative1AnchorChanges*>(state->operationAt(0));
662 QVERIFY(aChanges != 0);
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);
671 rectPrivate->setState("");
672 QCOMPARE(innerRect->x(), qreal(5));
677 void tst_qdeclarativestates::anchorChanges2()
679 QDeclarativeEngine engine;
681 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChanges2.qml");
682 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
684 QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
686 QDeclarative1Rectangle *innerRect = qobject_cast<QDeclarative1Rectangle*>(rect->findChild<QDeclarative1Rectangle*>("MyRect"));
687 QVERIFY(innerRect != 0);
689 rectPrivate->setState("right");
690 QCOMPARE(innerRect->x(), qreal(150));
692 rectPrivate->setState("");
693 QCOMPARE(innerRect->x(), qreal(5));
698 void tst_qdeclarativestates::anchorChanges3()
700 QDeclarativeEngine engine;
702 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChanges3.qml");
703 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
705 QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
707 QDeclarative1Rectangle *innerRect = qobject_cast<QDeclarative1Rectangle*>(rect->findChild<QDeclarative1Rectangle*>("MyRect"));
708 QVERIFY(innerRect != 0);
710 QDeclarativeItem *leftGuideline = qobject_cast<QDeclarativeItem*>(rect->findChild<QDeclarativeItem*>("LeftGuideline"));
711 QVERIFY(leftGuideline != 0);
713 QDeclarativeItem *bottomGuideline = qobject_cast<QDeclarativeItem*>(rect->findChild<QDeclarativeItem*>("BottomGuideline"));
714 QVERIFY(bottomGuideline != 0);
716 QDeclarativeListReference list(rect, "states");
717 QDeclarative1State *state = qobject_cast<QDeclarative1State*>(list.at(0));
720 qmlExecuteDeferred(state);
721 QDeclarative1AnchorChanges *aChanges = qobject_cast<QDeclarative1AnchorChanges*>(state->operationAt(0));
722 QVERIFY(aChanges != 0);
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);
735 QCOMPARE(innerRect->x(), qreal(10));
736 QCOMPARE(innerRect->y(), qreal(0));
737 QCOMPARE(innerRect->width(), qreal(190));
738 QCOMPARE(innerRect->height(), qreal(150));
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));
749 void tst_qdeclarativestates::anchorChanges4()
751 QDeclarativeEngine engine;
753 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChanges4.qml");
754 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
757 QDeclarative1Rectangle *innerRect = qobject_cast<QDeclarative1Rectangle*>(rect->findChild<QDeclarative1Rectangle*>("MyRect"));
758 QVERIFY(innerRect != 0);
760 QDeclarativeItem *leftGuideline = qobject_cast<QDeclarativeItem*>(rect->findChild<QDeclarativeItem*>("LeftGuideline"));
761 QVERIFY(leftGuideline != 0);
763 QDeclarativeItem *bottomGuideline = qobject_cast<QDeclarativeItem*>(rect->findChild<QDeclarativeItem*>("BottomGuideline"));
764 QVERIFY(bottomGuideline != 0);
766 QDeclarativeListReference list(rect, "states");
767 QDeclarative1State *state = qobject_cast<QDeclarative1State*>(list.at(0));
770 qmlExecuteDeferred(state);
771 QDeclarative1AnchorChanges *aChanges = qobject_cast<QDeclarative1AnchorChanges*>(state->operationAt(0));
772 QVERIFY(aChanges != 0);
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);
784 void tst_qdeclarativestates::anchorChanges5()
786 QDeclarativeEngine engine;
788 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChanges5.qml");
789 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
792 QDeclarative1Rectangle *innerRect = qobject_cast<QDeclarative1Rectangle*>(rect->findChild<QDeclarative1Rectangle*>("MyRect"));
793 QVERIFY(innerRect != 0);
795 QDeclarativeItem *leftGuideline = qobject_cast<QDeclarativeItem*>(rect->findChild<QDeclarativeItem*>("LeftGuideline"));
796 QVERIFY(leftGuideline != 0);
798 QDeclarativeItem *bottomGuideline = qobject_cast<QDeclarativeItem*>(rect->findChild<QDeclarativeItem*>("BottomGuideline"));
799 QVERIFY(bottomGuideline != 0);
801 QDeclarativeListReference list(rect, "states");
802 QDeclarative1State *state = qobject_cast<QDeclarative1State*>(list.at(0));
805 qmlExecuteDeferred(state);
806 QDeclarative1AnchorChanges *aChanges = qobject_cast<QDeclarative1AnchorChanges*>(state->operationAt(0));
807 QVERIFY(aChanges != 0);
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);
819 void mirrorAnchors(QDeclarativeItem *item) {
820 QDeclarativeItemPrivate *itemPrivate = QDeclarativeItemPrivate::get(item);
821 itemPrivate->setLayoutMirror(true);
824 qreal offsetRTL(QDeclarativeItem *anchorItem, QDeclarativeItem *item) {
825 return anchorItem->width()+2*anchorItem->x()-item->width();
828 void tst_qdeclarativestates::anchorChangesRTL()
830 QDeclarativeEngine engine;
832 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChanges1.qml");
833 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
835 QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
837 QDeclarative1Rectangle *innerRect = qobject_cast<QDeclarative1Rectangle*>(rect->findChild<QDeclarative1Rectangle*>("MyRect"));
838 QVERIFY(innerRect != 0);
839 mirrorAnchors(innerRect);
841 QDeclarativeListReference list(rect, "states");
842 QDeclarative1State *state = qobject_cast<QDeclarative1State*>(list.at(0));
845 qmlExecuteDeferred(state);
846 QDeclarative1AnchorChanges *aChanges = qobject_cast<QDeclarative1AnchorChanges*>(state->operationAt(0));
847 QVERIFY(aChanges != 0);
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);
856 rectPrivate->setState("");
857 QCOMPARE(innerRect->x(), offsetRTL(rect, innerRect) -qreal(5));
862 void tst_qdeclarativestates::anchorChangesRTL2()
864 QDeclarativeEngine engine;
866 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChanges2.qml");
867 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
869 QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
871 QDeclarative1Rectangle *innerRect = qobject_cast<QDeclarative1Rectangle*>(rect->findChild<QDeclarative1Rectangle*>("MyRect"));
872 QVERIFY(innerRect != 0);
873 mirrorAnchors(innerRect);
875 rectPrivate->setState("right");
876 QCOMPARE(innerRect->x(), offsetRTL(rect, innerRect) - qreal(150));
878 rectPrivate->setState("");
879 QCOMPARE(innerRect->x(), offsetRTL(rect, innerRect) - qreal(5));
884 void tst_qdeclarativestates::anchorChangesRTL3()
886 QDeclarativeEngine engine;
888 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChanges3.qml");
889 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
891 QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
893 QDeclarative1Rectangle *innerRect = qobject_cast<QDeclarative1Rectangle*>(rect->findChild<QDeclarative1Rectangle*>("MyRect"));
894 QVERIFY(innerRect != 0);
895 mirrorAnchors(innerRect);
897 QDeclarativeItem *leftGuideline = qobject_cast<QDeclarativeItem*>(rect->findChild<QDeclarativeItem*>("LeftGuideline"));
898 QVERIFY(leftGuideline != 0);
900 QDeclarativeItem *bottomGuideline = qobject_cast<QDeclarativeItem*>(rect->findChild<QDeclarativeItem*>("BottomGuideline"));
901 QVERIFY(bottomGuideline != 0);
903 QDeclarativeListReference list(rect, "states");
904 QDeclarative1State *state = qobject_cast<QDeclarative1State*>(list.at(0));
907 qmlExecuteDeferred(state);
908 QDeclarative1AnchorChanges *aChanges = qobject_cast<QDeclarative1AnchorChanges*>(state->operationAt(0));
909 QVERIFY(aChanges != 0);
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);
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));
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));
939 void tst_qdeclarativestates::anchorChangesCrash()
941 QDeclarativeEngine engine;
943 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChangesCrash.qml");
944 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
947 QDeclarativeItemPrivate::get(rect)->setState("reanchored");
953 void tst_qdeclarativestates::anchorRewindBug()
955 QDeclarativeEngine engine;
957 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorRewindBug.qml");
958 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
961 QDeclarativeItem * column = rect->findChild<QDeclarativeItem*>("column");
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");
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);
975 QDeclarativeItemPrivate::get(rect)->setState("");
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);
987 void tst_qdeclarativestates::anchorRewindBug2()
989 QDeclarativeEngine engine;
991 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorRewindBug2.qml");
992 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
995 QDeclarative1Rectangle *mover = rect->findChild<QDeclarative1Rectangle*>("mover");
998 QCOMPARE(mover->y(), qreal(0.0));
999 QCOMPARE(mover->width(), qreal(50.0));
1001 QDeclarativeItemPrivate::get(rect)->setState("anchored");
1002 QCOMPARE(mover->y(), qreal(250.0));
1003 QCOMPARE(mover->width(), qreal(200.0));
1005 QDeclarativeItemPrivate::get(rect)->setState("");
1006 QCOMPARE(mover->y(), qreal(0.0));
1007 QCOMPARE(mover->width(), qreal(50.0));
1012 void tst_qdeclarativestates::script()
1014 QDeclarativeEngine engine;
1017 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/script.qml");
1018 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
1020 QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
1021 QCOMPARE(rect->color(),QColor("red"));
1023 rectPrivate->setState("blue");
1024 QCOMPARE(rect->color(),QColor("blue"));
1026 rectPrivate->setState("");
1027 QCOMPARE(rect->color(),QColor("blue")); // a script isn't reverted
1031 void tst_qdeclarativestates::restoreEntryValues()
1033 QDeclarativeEngine engine;
1035 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/restoreEntryValues.qml");
1036 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
1038 QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
1039 QCOMPARE(rect->color(),QColor("red"));
1041 rectPrivate->setState("blue");
1042 QCOMPARE(rect->color(),QColor("blue"));
1044 rectPrivate->setState("");
1045 QCOMPARE(rect->color(),QColor("blue"));
1048 void tst_qdeclarativestates::explicitChanges()
1050 QDeclarativeEngine engine;
1052 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/explicit.qml");
1053 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
1055 QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
1056 QDeclarativeListReference list(rect, "states");
1057 QDeclarative1State *state = qobject_cast<QDeclarative1State*>(list.at(0));
1058 QVERIFY(state != 0);
1060 qmlExecuteDeferred(state);
1061 QDeclarative1PropertyChanges *changes = qobject_cast<QDeclarative1PropertyChanges*>(rect->findChild<QDeclarative1PropertyChanges*>("changes"));
1062 QVERIFY(changes != 0);
1063 QVERIFY(changes->isExplicit());
1065 QCOMPARE(rect->color(),QColor("red"));
1067 rectPrivate->setState("blue");
1068 QCOMPARE(rect->color(),QColor("blue"));
1070 rect->setProperty("sourceColor", QColor("green"));
1071 QCOMPARE(rect->color(),QColor("blue"));
1073 rectPrivate->setState("");
1074 QCOMPARE(rect->color(),QColor("red"));
1075 rect->setProperty("sourceColor", QColor("yellow"));
1076 QCOMPARE(rect->color(),QColor("red"));
1078 rectPrivate->setState("blue");
1079 QCOMPARE(rect->color(),QColor("yellow"));
1082 void tst_qdeclarativestates::propertyErrors()
1084 QDeclarativeEngine engine;
1085 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/propertyErrors.qml");
1086 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
1089 QCOMPARE(rect->color(),QColor("red"));
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");
1096 void tst_qdeclarativestates::incorrectRestoreBug()
1098 QDeclarativeEngine engine;
1100 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicChanges.qml");
1101 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
1103 QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
1104 QCOMPARE(rect->color(),QColor("red"));
1106 rectPrivate->setState("blue");
1107 QCOMPARE(rect->color(),QColor("blue"));
1109 rectPrivate->setState("");
1110 QCOMPARE(rect->color(),QColor("red"));
1112 // make sure if we change the base state value, we then restore to it correctly
1113 rect->setColor(QColor("green"));
1115 rectPrivate->setState("blue");
1116 QCOMPARE(rect->color(),QColor("blue"));
1118 rectPrivate->setState("");
1119 QCOMPARE(rect->color(),QColor("green"));
1122 void tst_qdeclarativestates::autoStateAtStartupRestoreBug()
1124 QDeclarativeEngine engine;
1126 QDeclarativeComponent component(&engine, SRCDIR "/data/autoStateAtStartupRestoreBug.qml");
1127 QObject *obj = component.create();
1130 QCOMPARE(obj->property("test").toInt(), 3);
1132 obj->setProperty("input", 2);
1134 QCOMPARE(obj->property("test").toInt(), 9);
1139 void tst_qdeclarativestates::deletingChange()
1141 QDeclarativeEngine engine;
1143 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/deleting.qml");
1144 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
1146 QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
1147 rectPrivate->setState("blue");
1148 QCOMPARE(rect->color(),QColor("blue"));
1149 QCOMPARE(rect->radius(),qreal(5));
1151 rectPrivate->setState("");
1152 QCOMPARE(rect->color(),QColor("red"));
1153 QCOMPARE(rect->radius(),qreal(0));
1155 QDeclarative1PropertyChanges *pc = rect->findChild<QDeclarative1PropertyChanges*>("pc1");
1159 QDeclarative1State *state = rect->findChild<QDeclarative1State*>();
1160 QVERIFY(state != 0);
1161 qmlExecuteDeferred(state);
1162 QCOMPARE(state->operationCount(), 1);
1164 rectPrivate->setState("blue");
1165 QCOMPARE(rect->color(),QColor("red"));
1166 QCOMPARE(rect->radius(),qreal(5));
1171 void tst_qdeclarativestates::deletingState()
1173 QDeclarativeEngine engine;
1175 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/deletingState.qml");
1176 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
1179 QDeclarative1StateGroup *sg = rect->findChild<QDeclarative1StateGroup*>();
1181 QVERIFY(sg->findState("blue") != 0);
1183 sg->setState("blue");
1184 QCOMPARE(rect->color(),QColor("blue"));
1187 QCOMPARE(rect->color(),QColor("red"));
1189 QDeclarative1State *state = rect->findChild<QDeclarative1State*>();
1190 QVERIFY(state != 0);
1193 QVERIFY(sg->findState("blue") == 0);
1195 //### should we warn that state doesn't exist
1196 sg->setState("blue");
1197 QCOMPARE(rect->color(),QColor("red"));
1202 void tst_qdeclarativestates::tempState()
1204 QDeclarativeEngine engine;
1206 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/legalTempState.qml");
1207 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
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"));
1216 void tst_qdeclarativestates::illegalTempState()
1218 QDeclarativeEngine engine;
1220 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/illegalTempState.qml");
1221 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
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"));
1229 void tst_qdeclarativestates::nonExistantProperty()
1231 QDeclarativeEngine engine;
1233 QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/nonExistantProp.qml");
1234 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
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"));
1242 void tst_qdeclarativestates::reset()
1244 QDeclarativeEngine engine;
1246 QDeclarativeComponent c(&engine, SRCDIR "/data/reset.qml");
1247 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(c.create());
1250 QDeclarative1Image *image = rect->findChild<QDeclarative1Image*>();
1251 QVERIFY(image != 0);
1252 QCOMPARE(image->width(), qreal(40.));
1253 QCOMPARE(image->height(), qreal(20.));
1255 QDeclarativeItemPrivate::get(rect)->setState("state1");
1257 QCOMPARE(image->width(), 20.0);
1258 QCOMPARE(image->height(), qreal(20.));
1261 void tst_qdeclarativestates::illegalObjectCreation()
1263 QDeclarativeEngine engine;
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.");
1274 void tst_qdeclarativestates::whenOrdering()
1276 QDeclarativeEngine engine;
1278 QDeclarativeComponent c(&engine, SRCDIR "/data/whenOrdering.qml");
1279 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(c.create());
1281 QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
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(""));
1297 void tst_qdeclarativestates::urlResolution()
1299 QDeclarativeEngine engine;
1301 QDeclarativeComponent c(&engine, SRCDIR "/data/urlResolution.qml");
1302 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(c.create());
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);
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);
1318 void tst_qdeclarativestates::unnamedWhen()
1320 QDeclarativeEngine engine;
1322 QDeclarativeComponent c(&engine, SRCDIR "/data/unnamedWhen.qml");
1323 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(c.create());
1325 QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
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(""));
1337 void tst_qdeclarativestates::returnToBase()
1339 QDeclarativeEngine engine;
1341 QDeclarativeComponent c(&engine, SRCDIR "/data/returnToBase.qml");
1342 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(c.create());
1344 QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
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"));
1357 void tst_qdeclarativestates::extendsBug()
1359 QDeclarativeEngine engine;
1361 QDeclarativeComponent c(&engine, SRCDIR "/data/extendsBug.qml");
1362 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(c.create());
1364 QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
1365 QDeclarative1Rectangle *greenRect = rect->findChild<QDeclarative1Rectangle*>("greenRect");
1367 rectPrivate->setState("b");
1368 QCOMPARE(greenRect->x(), qreal(100));
1369 QCOMPARE(greenRect->y(), qreal(100));
1372 void tst_qdeclarativestates::editProperties()
1374 QDeclarativeEngine engine;
1376 QDeclarativeComponent c(&engine, SRCDIR "/data/editProperties.qml");
1377 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(c.create());
1380 QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
1382 QDeclarative1StateGroup *stateGroup = rectPrivate->_states();
1383 QVERIFY(stateGroup != 0);
1384 qmlExecuteDeferred(stateGroup);
1386 QDeclarative1State *blueState = stateGroup->findState("blue");
1387 QVERIFY(blueState != 0);
1388 qmlExecuteDeferred(blueState);
1390 QDeclarative1PropertyChanges *propertyChangesBlue = qobject_cast<QDeclarative1PropertyChanges*>(blueState->operationAt(0));
1391 QVERIFY(propertyChangesBlue != 0);
1393 QDeclarative1State *greenState = stateGroup->findState("green");
1394 QVERIFY(greenState != 0);
1395 qmlExecuteDeferred(greenState);
1397 QDeclarative1PropertyChanges *propertyChangesGreen = qobject_cast<QDeclarative1PropertyChanges*>(greenState->operationAt(0));
1398 QVERIFY(propertyChangesGreen != 0);
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));
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"));
1413 rectPrivate->setState("green");
1414 QCOMPARE(childRect->width(), qreal(200));
1415 QCOMPARE(childRect->height(), qreal(100));
1416 QVERIFY(greenState->bindingInRevertList(childRect, "width"));
1419 rectPrivate->setState("");
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());
1428 propertyChangesBlue->changeValue("width", 60);
1429 QCOMPARE(propertyChangesBlue->value("width").toInt(), 60);
1430 QCOMPARE(propertyChangesBlue->actions().length(), 2);
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);
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);
1445 QVERIFY(QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "width")));
1446 rectPrivate->setState("blue");
1447 QCOMPARE(childRect->width(), qreal(50));
1448 QCOMPARE(childRect->height(), qreal(40));
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")));
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));
1464 propertyChangesBlue->changeValue("width", 50);
1465 QCOMPARE(childRect->width(), qreal(50));
1467 rectPrivate->setState("");
1468 QCOMPARE(childRect->width(), qreal(402));
1469 QVERIFY(QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "width")));
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);
1480 propertyChangesGreen->removeProperty("height");
1481 QVERIFY(!QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "height")));
1482 QCOMPARE(childRect->height(), qreal(200));
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"));
1492 propertyChangesBlue->removeProperty("width");
1493 QCOMPARE(childRect->width(), qreal(402));
1495 rectPrivate->setState("blue");
1496 QCOMPARE(childRect->width(), qreal(402));
1497 QCOMPARE(childRect->height(), qreal(40));
1500 void tst_qdeclarativestates::QTBUG_14830()
1502 QDeclarativeEngine engine;
1504 QDeclarativeComponent c(&engine, SRCDIR "/data/QTBUG-14830.qml");
1505 QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(c.create());
1507 QDeclarativeItem *item = rect->findChild<QDeclarativeItem*>("area");
1509 QCOMPARE(item->width(), qreal(171));
1512 QTEST_MAIN(tst_qdeclarativestates)
1514 #include "tst_qdeclarativestates.moc"