tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp
changeset 30 5dc02b23752f
child 33 3e2da88830cd
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp	Tue Jul 06 15:10:48 2010 +0300
@@ -0,0 +1,1090 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <qtest.h>
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <QtDeclarative/qdeclarativecomponent.h>
+#include <private/qdeclarativeanchors_p_p.h>
+#include <private/qdeclarativerectangle_p.h>
+#include <private/qdeclarativeimage_p.h>
+#include <private/qdeclarativetext_p.h>
+#include <private/qdeclarativepropertychanges_p.h>
+#include <private/qdeclarativestategroup_p.h>
+#include <private/qdeclarativeitem_p.h>
+
+
+class MyRect : public QDeclarativeRectangle
+{
+   Q_OBJECT
+   Q_PROPERTY(int propertyWithNotify READ propertyWithNotify WRITE setPropertyWithNotify NOTIFY oddlyNamedNotifySignal)
+public:
+    MyRect() {}
+
+    void doSomething() { emit didSomething(); }
+    
+    int propertyWithNotify() const { return m_prop; }
+    void setPropertyWithNotify(int i) { m_prop = i; emit oddlyNamedNotifySignal(); }
+Q_SIGNALS:
+    void didSomething();
+    void oddlyNamedNotifySignal();
+
+private:
+    int m_prop;
+};
+
+
+class tst_qdeclarativestates : public QObject
+{
+    Q_OBJECT
+public:
+    tst_qdeclarativestates() {}
+
+private:
+    static QByteArray fullDataPath(const QString &path);
+
+private slots:
+    void initTestCase();
+
+    void basicChanges();
+    void basicExtension();
+    void basicBinding();
+    void signalOverride();
+    void signalOverrideCrash();
+    void signalOverrideCrash2();
+    void parentChange();
+    void parentChangeErrors();
+    void anchorChanges();
+    void anchorChanges2();
+    void anchorChanges3();
+    void anchorChanges4();
+    void anchorChanges5();
+    void anchorChangesCrash();
+    void script();
+    void restoreEntryValues();
+    void explicitChanges();
+    void propertyErrors();
+    void incorrectRestoreBug();
+    void autoStateAtStartupRestoreBug();
+    void deletingChange();
+    void deletingState();
+    void tempState();
+    void illegalTempState();
+    void nonExistantProperty();
+    void reset();
+    void illegalObjectCreation();
+    void whenOrdering();
+    void urlResolution();
+    void unnamedWhen();
+};
+
+void tst_qdeclarativestates::initTestCase()
+{
+    qmlRegisterType<MyRect>("Qt.test", 1, 0, "MyRectangle");
+}
+
+QByteArray tst_qdeclarativestates::fullDataPath(const QString &path)
+{
+    return QUrl::fromLocalFile(SRCDIR + path).toString().toUtf8();    
+}
+
+void tst_qdeclarativestates::basicChanges()
+{
+    QDeclarativeEngine engine;
+
+    {
+        QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicChanges.qml");
+        QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create());
+        QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
+        QVERIFY(rect != 0);
+
+        QCOMPARE(rect->color(),QColor("red"));
+
+        rectPrivate->setState("blue");
+        QCOMPARE(rect->color(),QColor("blue"));
+
+        rectPrivate->setState("");
+        QCOMPARE(rect->color(),QColor("red"));
+    }
+
+    {
+        QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicChanges2.qml");
+        QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create());
+        QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
+        QVERIFY(rect != 0);
+
+        QCOMPARE(rect->color(),QColor("red"));
+
+        rectPrivate->setState("blue");
+        QCOMPARE(rect->color(),QColor("blue"));
+
+        rectPrivate->setState("green");
+        QCOMPARE(rect->color(),QColor("green"));
+
+        rectPrivate->setState("");
+        QCOMPARE(rect->color(),QColor("red"));
+
+        rectPrivate->setState("green");
+        QCOMPARE(rect->color(),QColor("green"));
+    }
+
+    {
+        QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicChanges3.qml");
+        QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create());
+        QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
+        QVERIFY(rect != 0);
+
+        QCOMPARE(rect->color(),QColor("red"));
+        QCOMPARE(rect->border()->width(),1);
+
+        rectPrivate->setState("blue");
+        QCOMPARE(rect->color(),QColor("blue"));
+        QCOMPARE(rect->border()->width(),1);
+
+        rectPrivate->setState("bordered");
+        QCOMPARE(rect->color(),QColor("red"));
+        QCOMPARE(rect->border()->width(),2);
+
+        rectPrivate->setState("");
+        QCOMPARE(rect->color(),QColor("red"));
+        QCOMPARE(rect->border()->width(),1);
+        //### we should be checking that this is an implicit rather than explicit 1 (which currently fails)
+
+        rectPrivate->setState("bordered");
+        QCOMPARE(rect->color(),QColor("red"));
+        QCOMPARE(rect->border()->width(),2);
+
+        rectPrivate->setState("blue");
+        QCOMPARE(rect->color(),QColor("blue"));
+        QCOMPARE(rect->border()->width(),1);
+
+    }
+
+    {
+        // Test basicChanges4.qml can magically connect to propertyWithNotify's notify
+        // signal using 'onPropertyWithNotifyChanged' even though the signal name is
+        // actually 'oddlyNamedNotifySignal'
+
+        QDeclarativeComponent component(&engine, SRCDIR "/data/basicChanges4.qml");
+        QVERIFY(component.isReady());
+
+        MyRect *rect = qobject_cast<MyRect*>(component.create());
+        QVERIFY(rect != 0);
+
+        QMetaProperty prop = rect->metaObject()->property(rect->metaObject()->indexOfProperty("propertyWithNotify"));
+        QVERIFY(prop.hasNotifySignal());
+        QString notifySignal = QByteArray(prop.notifySignal().signature());
+        QVERIFY(!notifySignal.startsWith("propertyWithNotifyChanged("));
+
+        QCOMPARE(rect->color(), QColor(Qt::red));
+
+        rect->setPropertyWithNotify(100);
+        QCOMPARE(rect->color(), QColor(Qt::blue));
+    }
+}
+
+void tst_qdeclarativestates::basicExtension()
+{
+    QDeclarativeEngine engine;
+
+    {
+        QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicExtension.qml");
+        QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create());
+        QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
+        QVERIFY(rect != 0);
+
+        QCOMPARE(rect->color(),QColor("red"));
+        QCOMPARE(rect->border()->width(),1);
+
+        rectPrivate->setState("blue");
+        QCOMPARE(rect->color(),QColor("blue"));
+        QCOMPARE(rect->border()->width(),1);
+
+        rectPrivate->setState("bordered");
+        QCOMPARE(rect->color(),QColor("blue"));
+        QCOMPARE(rect->border()->width(),2);
+
+        rectPrivate->setState("blue");
+        QCOMPARE(rect->color(),QColor("blue"));
+        QCOMPARE(rect->border()->width(),1);
+
+        rectPrivate->setState("");
+        QCOMPARE(rect->color(),QColor("red"));
+        QCOMPARE(rect->border()->width(),1);
+
+        rectPrivate->setState("bordered");
+        QCOMPARE(rect->color(),QColor("blue"));
+        QCOMPARE(rect->border()->width(),2);
+
+        rectPrivate->setState("");
+        QCOMPARE(rect->color(),QColor("red"));
+        QCOMPARE(rect->border()->width(),1);
+    }
+
+    {
+        QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/fakeExtension.qml");
+        QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create());
+        QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
+        QVERIFY(rect != 0);
+
+        QCOMPARE(rect->color(),QColor("red"));
+
+        rectPrivate->setState("blue");
+        QCOMPARE(rect->color(),QColor("blue"));
+
+        rectPrivate->setState("green");
+        QCOMPARE(rect->color(),QColor("green"));
+
+        rectPrivate->setState("blue");
+        QCOMPARE(rect->color(),QColor("blue"));
+
+        rectPrivate->setState("green");
+        QCOMPARE(rect->color(),QColor("green"));
+
+        rectPrivate->setState("");
+        QCOMPARE(rect->color(),QColor("red"));
+
+        rectPrivate->setState("green");
+        QCOMPARE(rect->color(),QColor("green"));
+    }
+}
+
+void tst_qdeclarativestates::basicBinding()
+{
+    QDeclarativeEngine engine;
+
+    {
+        QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicBinding.qml");
+        QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create());
+        QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
+        QVERIFY(rect != 0);
+
+        QCOMPARE(rect->color(),QColor("red"));
+
+        rectPrivate->setState("blue");
+        QCOMPARE(rect->color(),QColor("blue"));
+
+        rectPrivate->setState("");
+        QCOMPARE(rect->color(),QColor("red"));
+
+        rectPrivate->setState("blue");
+        QCOMPARE(rect->color(),QColor("blue"));
+        rect->setProperty("sourceColor", QColor("green"));
+        QCOMPARE(rect->color(),QColor("green"));
+
+        rectPrivate->setState("");
+        QCOMPARE(rect->color(),QColor("red"));
+        rect->setProperty("sourceColor", QColor("yellow"));
+        QCOMPARE(rect->color(),QColor("red"));
+
+        rectPrivate->setState("blue");
+        QCOMPARE(rect->color(),QColor("yellow"));
+    }
+
+    {
+        QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicBinding2.qml");
+        QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create());
+        QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
+        QVERIFY(rect != 0);
+
+        QCOMPARE(rect->color(),QColor("red"));
+
+        rectPrivate->setState("blue");
+        QCOMPARE(rect->color(),QColor("blue"));
+
+        rectPrivate->setState("");
+        QCOMPARE(rect->color(),QColor("red"));
+
+        rectPrivate->setState("blue");
+        QCOMPARE(rect->color(),QColor("blue"));
+        rect->setProperty("sourceColor", QColor("green"));
+        QCOMPARE(rect->color(),QColor("blue"));
+
+        rectPrivate->setState("");
+        QCOMPARE(rect->color(),QColor("green"));
+        rect->setProperty("sourceColor", QColor("yellow"));
+        QCOMPARE(rect->color(),QColor("yellow"));
+
+        rectPrivate->setState("blue");
+        QCOMPARE(rect->color(),QColor("blue"));
+
+        rectPrivate->setState("");
+        QCOMPARE(rect->color(),QColor("yellow"));
+    }
+
+    {
+        QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicBinding3.qml");
+        QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create());
+        QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
+        QVERIFY(rect != 0);
+
+        QCOMPARE(rect->color(),QColor("red"));
+        rect->setProperty("sourceColor", QColor("green"));
+        QCOMPARE(rect->color(),QColor("green"));
+
+        rectPrivate->setState("blue");
+        QCOMPARE(rect->color(),QColor("blue"));
+        rect->setProperty("sourceColor", QColor("red"));
+        QCOMPARE(rect->color(),QColor("blue"));
+        rect->setProperty("sourceColor2", QColor("yellow"));
+        QCOMPARE(rect->color(),QColor("yellow"));
+
+        rectPrivate->setState("");
+        QCOMPARE(rect->color(),QColor("red"));
+        rect->setProperty("sourceColor2", QColor("green"));
+        QCOMPARE(rect->color(),QColor("red"));
+        rect->setProperty("sourceColor", QColor("yellow"));
+        QCOMPARE(rect->color(),QColor("yellow"));
+    }
+
+    {
+        QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicBinding4.qml");
+        QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create());
+        QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
+        QVERIFY(rect != 0);
+
+        QCOMPARE(rect->color(),QColor("red"));
+
+        rectPrivate->setState("blue");
+        QCOMPARE(rect->color(),QColor("blue"));
+        rect->setProperty("sourceColor", QColor("yellow"));
+        QCOMPARE(rect->color(),QColor("yellow"));
+
+        rectPrivate->setState("green");
+        QCOMPARE(rect->color(),QColor("green"));
+        rect->setProperty("sourceColor", QColor("purple"));
+        QCOMPARE(rect->color(),QColor("green"));
+
+        rectPrivate->setState("blue");
+        QCOMPARE(rect->color(),QColor("purple"));
+
+        rectPrivate->setState("green");
+        QCOMPARE(rect->color(),QColor("green"));
+
+        rectPrivate->setState("");
+        QCOMPARE(rect->color(),QColor("red"));
+    }
+}
+
+void tst_qdeclarativestates::signalOverride()
+{
+    QDeclarativeEngine engine;
+
+    {
+        QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/signalOverride.qml");
+        MyRect *rect = qobject_cast<MyRect*>(rectComponent.create());
+        QVERIFY(rect != 0);
+
+        QCOMPARE(rect->color(),QColor("red"));
+        rect->doSomething();
+        QCOMPARE(rect->color(),QColor("blue"));
+
+        QDeclarativeItemPrivate::get(rect)->setState("green");
+        rect->doSomething();
+        QCOMPARE(rect->color(),QColor("green"));
+    }
+
+    {
+        QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/signalOverride2.qml");
+        MyRect *rect = qobject_cast<MyRect*>(rectComponent.create());
+        QVERIFY(rect != 0);
+
+        QCOMPARE(rect->color(),QColor("white"));
+        rect->doSomething();
+        QCOMPARE(rect->color(),QColor("blue"));
+
+        QDeclarativeRectangle *innerRect = qobject_cast<QDeclarativeRectangle*>(rect->findChild<QDeclarativeRectangle*>("extendedRect"));
+        QDeclarativeItemPrivate::get(innerRect)->setState("green");
+        rect->doSomething();
+        QCOMPARE(rect->color(),QColor("blue"));
+        QCOMPARE(innerRect->color(),QColor("green"));
+        QCOMPARE(innerRect->property("extendedColor").value<QColor>(),QColor("green"));
+    }
+}
+
+void tst_qdeclarativestates::signalOverrideCrash()
+{
+    QDeclarativeEngine engine;
+
+    QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/signalOverrideCrash.qml");
+    MyRect *rect = qobject_cast<MyRect*>(rectComponent.create());
+    QVERIFY(rect != 0);
+
+    QDeclarativeItemPrivate::get(rect)->setState("overridden");
+    rect->doSomething();
+}
+
+void tst_qdeclarativestates::signalOverrideCrash2()
+{
+    QDeclarativeEngine engine;
+
+    QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/signalOverrideCrash2.qml");
+    QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create());
+    QVERIFY(rect != 0);
+
+    QDeclarativeItemPrivate::get(rect)->setState("state1");
+    QDeclarativeItemPrivate::get(rect)->setState("state2");
+    QDeclarativeItemPrivate::get(rect)->setState("state1");
+
+    delete rect;
+}
+
+void tst_qdeclarativestates::parentChange()
+{
+    QDeclarativeEngine engine;
+
+    {
+        QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/parentChange1.qml");
+        QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create());
+        QVERIFY(rect != 0);
+
+        QDeclarativeRectangle *innerRect = qobject_cast<QDeclarativeRectangle*>(rect->findChild<QDeclarativeRectangle*>("MyRect"));
+        QVERIFY(innerRect != 0);
+
+        QDeclarativeListReference list(rect, "states");
+        QDeclarativeState *state = qobject_cast<QDeclarativeState*>(list.at(0));
+        QVERIFY(state != 0);
+
+        qmlExecuteDeferred(state);
+        QDeclarativeParentChange *pChange = qobject_cast<QDeclarativeParentChange*>(state->operationAt(0));
+        QVERIFY(pChange != 0);
+        QDeclarativeItem *nParent = qobject_cast<QDeclarativeItem*>(rect->findChild<QDeclarativeItem*>("NewParent"));
+        QVERIFY(nParent != 0);
+
+        QCOMPARE(pChange->parent(), nParent);
+
+        QDeclarativeItemPrivate::get(rect)->setState("reparented");
+        QCOMPARE(innerRect->rotation(), qreal(0));
+        QCOMPARE(innerRect->scale(), qreal(1));
+        QCOMPARE(innerRect->x(), qreal(-133));
+        QCOMPARE(innerRect->y(), qreal(-300));
+    }
+
+    {
+        QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/parentChange2.qml");
+        QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create());
+        QVERIFY(rect != 0);
+        QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
+        QDeclarativeRectangle *innerRect = qobject_cast<QDeclarativeRectangle*>(rect->findChild<QDeclarativeRectangle*>("MyRect"));
+        QVERIFY(innerRect != 0);
+
+        rectPrivate->setState("reparented");
+        QCOMPARE(innerRect->rotation(), qreal(15));
+        QCOMPARE(innerRect->scale(), qreal(.5));
+        QCOMPARE(QString("%1").arg(innerRect->x()), QString("%1").arg(-19.9075));
+        QCOMPARE(QString("%1").arg(innerRect->y()), QString("%1").arg(-8.73433));
+    }
+
+    {
+        QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/parentChange3.qml");
+        QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create());
+        QVERIFY(rect != 0);
+        QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
+        QDeclarativeRectangle *innerRect = qobject_cast<QDeclarativeRectangle*>(rect->findChild<QDeclarativeRectangle*>("MyRect"));
+        QVERIFY(innerRect != 0);
+
+        rectPrivate->setState("reparented");
+        QCOMPARE(innerRect->rotation(), qreal(-37));
+        QCOMPARE(innerRect->scale(), qreal(.25));
+        QCOMPARE(QString("%1").arg(innerRect->x()), QString("%1").arg(-217.305));
+        QCOMPARE(QString("%1").arg(innerRect->y()), QString("%1").arg(-164.413));
+
+        rectPrivate->setState("");
+        QCOMPARE(innerRect->rotation(), qreal(0));
+        QCOMPARE(innerRect->scale(), qreal(1));
+        QCOMPARE(innerRect->x(), qreal(5));
+        //do a non-qFuzzyCompare fuzzy compare
+        QVERIFY(innerRect->y() < qreal(0.00001) && innerRect->y() > qreal(-0.00001));
+    }
+}
+
+void tst_qdeclarativestates::parentChangeErrors()
+{
+    QDeclarativeEngine engine;
+
+    {
+        QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/parentChange4.qml");
+        QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create());
+        QVERIFY(rect != 0);
+
+        QDeclarativeRectangle *innerRect = qobject_cast<QDeclarativeRectangle*>(rect->findChild<QDeclarativeRectangle*>("MyRect"));
+        QVERIFY(innerRect != 0);
+
+        QTest::ignoreMessage(QtWarningMsg, fullDataPath("/data/parentChange4.qml") + ":25:9: QML ParentChange: Unable to preserve appearance under non-uniform scale");
+        QDeclarativeItemPrivate::get(rect)->setState("reparented");
+        QCOMPARE(innerRect->rotation(), qreal(0));
+        QCOMPARE(innerRect->scale(), qreal(1));
+        QCOMPARE(innerRect->x(), qreal(5));
+        QCOMPARE(innerRect->y(), qreal(5));
+    }
+
+    {
+        QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/parentChange5.qml");
+        QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create());
+        QVERIFY(rect != 0);
+
+        QDeclarativeRectangle *innerRect = qobject_cast<QDeclarativeRectangle*>(rect->findChild<QDeclarativeRectangle*>("MyRect"));
+        QVERIFY(innerRect != 0);
+
+        QTest::ignoreMessage(QtWarningMsg, fullDataPath("/data/parentChange5.qml") + ":25:9: QML ParentChange: Unable to preserve appearance under complex transform");
+        QDeclarativeItemPrivate::get(rect)->setState("reparented");
+        QCOMPARE(innerRect->rotation(), qreal(0));
+        QCOMPARE(innerRect->scale(), qreal(1));
+        QCOMPARE(innerRect->x(), qreal(5));
+        QCOMPARE(innerRect->y(), qreal(5));
+    }
+}
+
+void tst_qdeclarativestates::anchorChanges()
+{
+    QDeclarativeEngine engine;
+
+    QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChanges1.qml");
+    QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create());
+    QVERIFY(rect != 0);
+    QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
+
+    QDeclarativeRectangle *innerRect = qobject_cast<QDeclarativeRectangle*>(rect->findChild<QDeclarativeRectangle*>("MyRect"));
+    QVERIFY(innerRect != 0);
+
+    QDeclarativeListReference list(rect, "states");
+    QDeclarativeState *state = qobject_cast<QDeclarativeState*>(list.at(0));
+    QVERIFY(state != 0);
+
+    qmlExecuteDeferred(state);
+    QDeclarativeAnchorChanges *aChanges = qobject_cast<QDeclarativeAnchorChanges*>(state->operationAt(0));
+    QVERIFY(aChanges != 0);
+
+    rectPrivate->setState("right");
+    QCOMPARE(innerRect->x(), qreal(150));
+    QCOMPARE(aChanges->object(), qobject_cast<QDeclarativeItem*>(innerRect));
+    QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->left().anchorLine, QDeclarativeAnchorLine::Invalid);  //### was reset (how do we distinguish from not set at all)
+    QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->right().item, rectPrivate->right().item);
+    QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->right().anchorLine, rectPrivate->right().anchorLine);
+
+    rectPrivate->setState("");
+    QCOMPARE(innerRect->x(), qreal(5));
+
+    delete rect;
+}
+
+void tst_qdeclarativestates::anchorChanges2()
+{
+    QDeclarativeEngine engine;
+
+    QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChanges2.qml");
+    QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create());
+    QVERIFY(rect != 0);
+    QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
+
+    QDeclarativeRectangle *innerRect = qobject_cast<QDeclarativeRectangle*>(rect->findChild<QDeclarativeRectangle*>("MyRect"));
+    QVERIFY(innerRect != 0);
+
+    rectPrivate->setState("right");
+    QCOMPARE(innerRect->x(), qreal(150));
+
+    rectPrivate->setState("");
+    QCOMPARE(innerRect->x(), qreal(5));
+
+    delete rect;
+}
+
+void tst_qdeclarativestates::anchorChanges3()
+{
+    QDeclarativeEngine engine;
+
+    QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChanges3.qml");
+    QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create());
+    QVERIFY(rect != 0);
+    QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
+
+    QDeclarativeRectangle *innerRect = qobject_cast<QDeclarativeRectangle*>(rect->findChild<QDeclarativeRectangle*>("MyRect"));
+    QVERIFY(innerRect != 0);
+
+    QDeclarativeItem *leftGuideline = qobject_cast<QDeclarativeItem*>(rect->findChild<QDeclarativeItem*>("LeftGuideline"));
+    QVERIFY(leftGuideline != 0);
+
+    QDeclarativeItem *bottomGuideline = qobject_cast<QDeclarativeItem*>(rect->findChild<QDeclarativeItem*>("BottomGuideline"));
+    QVERIFY(bottomGuideline != 0);
+
+    QDeclarativeListReference list(rect, "states");
+    QDeclarativeState *state = qobject_cast<QDeclarativeState*>(list.at(0));
+    QVERIFY(state != 0);
+
+    qmlExecuteDeferred(state);
+    QDeclarativeAnchorChanges *aChanges = qobject_cast<QDeclarativeAnchorChanges*>(state->operationAt(0));
+    QVERIFY(aChanges != 0);
+
+    rectPrivate->setState("reanchored");
+    QCOMPARE(aChanges->object(), qobject_cast<QDeclarativeItem*>(innerRect));
+    QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->left().item, QDeclarativeItemPrivate::get(leftGuideline)->left().item);
+    QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->left().anchorLine, QDeclarativeItemPrivate::get(leftGuideline)->left().anchorLine);
+    QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->right().item, rectPrivate->right().item);
+    QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->right().anchorLine, rectPrivate->right().anchorLine);
+    QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->top().item, rectPrivate->top().item);
+    QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->top().anchorLine, rectPrivate->top().anchorLine);
+    QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->bottom().item, QDeclarativeItemPrivate::get(bottomGuideline)->bottom().item);
+    QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->bottom().anchorLine, QDeclarativeItemPrivate::get(bottomGuideline)->bottom().anchorLine);
+
+    QCOMPARE(innerRect->x(), qreal(10));
+    QCOMPARE(innerRect->y(), qreal(0));
+    QCOMPARE(innerRect->width(), qreal(190));
+    QCOMPARE(innerRect->height(), qreal(150));
+
+    rectPrivate->setState("");
+    QCOMPARE(innerRect->x(), qreal(0));
+    QCOMPARE(innerRect->y(), qreal(10));
+    QCOMPARE(innerRect->width(), qreal(150));
+    QCOMPARE(innerRect->height(), qreal(190));
+
+    delete rect;
+}
+
+void tst_qdeclarativestates::anchorChanges4()
+{
+    QDeclarativeEngine engine;
+
+    QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChanges4.qml");
+    QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create());
+    QVERIFY(rect != 0);
+
+    QDeclarativeRectangle *innerRect = qobject_cast<QDeclarativeRectangle*>(rect->findChild<QDeclarativeRectangle*>("MyRect"));
+    QVERIFY(innerRect != 0);
+
+    QDeclarativeItem *leftGuideline = qobject_cast<QDeclarativeItem*>(rect->findChild<QDeclarativeItem*>("LeftGuideline"));
+    QVERIFY(leftGuideline != 0);
+
+    QDeclarativeItem *bottomGuideline = qobject_cast<QDeclarativeItem*>(rect->findChild<QDeclarativeItem*>("BottomGuideline"));
+    QVERIFY(bottomGuideline != 0);
+
+    QDeclarativeListReference list(rect, "states");
+    QDeclarativeState *state = qobject_cast<QDeclarativeState*>(list.at(0));
+    QVERIFY(state != 0);
+
+    qmlExecuteDeferred(state);
+    QDeclarativeAnchorChanges *aChanges = qobject_cast<QDeclarativeAnchorChanges*>(state->operationAt(0));
+    QVERIFY(aChanges != 0);
+
+    QDeclarativeItemPrivate::get(rect)->setState("reanchored");
+    QCOMPARE(aChanges->object(), qobject_cast<QDeclarativeItem*>(innerRect));
+    QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->horizontalCenter().item, QDeclarativeItemPrivate::get(bottomGuideline)->horizontalCenter().item);
+    QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->horizontalCenter().anchorLine, QDeclarativeItemPrivate::get(bottomGuideline)->horizontalCenter().anchorLine);
+    QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->verticalCenter().item, QDeclarativeItemPrivate::get(leftGuideline)->verticalCenter().item);
+    QCOMPARE(QDeclarativeItemPrivate::get(aChanges->object())->anchors()->verticalCenter().anchorLine, QDeclarativeItemPrivate::get(leftGuideline)->verticalCenter().anchorLine);
+
+    delete rect;
+}
+
+void tst_qdeclarativestates::anchorChanges5()
+{
+    QDeclarativeEngine engine;
+
+    QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChanges5.qml");
+    QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create());
+    QVERIFY(rect != 0);
+
+    QDeclarativeRectangle *innerRect = qobject_cast<QDeclarativeRectangle*>(rect->findChild<QDeclarativeRectangle*>("MyRect"));
+    QVERIFY(innerRect != 0);
+
+    QDeclarativeItem *leftGuideline = qobject_cast<QDeclarativeItem*>(rect->findChild<QDeclarativeItem*>("LeftGuideline"));
+    QVERIFY(leftGuideline != 0);
+
+    QDeclarativeItem *bottomGuideline = qobject_cast<QDeclarativeItem*>(rect->findChild<QDeclarativeItem*>("BottomGuideline"));
+    QVERIFY(bottomGuideline != 0);
+
+    QDeclarativeListReference list(rect, "states");
+    QDeclarativeState *state = qobject_cast<QDeclarativeState*>(list.at(0));
+    QVERIFY(state != 0);
+
+    qmlExecuteDeferred(state);
+    QDeclarativeAnchorChanges *aChanges = qobject_cast<QDeclarativeAnchorChanges*>(state->operationAt(0));
+    QVERIFY(aChanges != 0);
+
+    QDeclarativeItemPrivate::get(rect)->setState("reanchored");
+    QCOMPARE(aChanges->object(), qobject_cast<QDeclarativeItem*>(innerRect));
+    //QCOMPARE(aChanges->anchors()->horizontalCenter().item, bottomGuideline->horizontalCenter().item);
+    //QCOMPARE(aChanges->anchors()->horizontalCenter().anchorLine, bottomGuideline->horizontalCenter().anchorLine);
+    //QCOMPARE(aChanges->anchors()->baseline().item, leftGuideline->baseline().item);
+    //QCOMPARE(aChanges->anchors()->baseline().anchorLine, leftGuideline->baseline().anchorLine);
+
+    delete rect;
+}
+
+//QTBUG-9609
+void tst_qdeclarativestates::anchorChangesCrash()
+{
+    QDeclarativeEngine engine;
+
+    QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChangesCrash.qml");
+    QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create());
+    QVERIFY(rect != 0);
+
+    QDeclarativeItemPrivate::get(rect)->setState("reanchored");
+
+    delete rect;
+}
+
+void tst_qdeclarativestates::script()
+{
+    QDeclarativeEngine engine;
+
+    {
+        QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/script.qml");
+        QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create());
+        QVERIFY(rect != 0);
+        QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
+        QCOMPARE(rect->color(),QColor("red"));
+
+        rectPrivate->setState("blue");
+        QCOMPARE(rect->color(),QColor("blue"));
+
+        rectPrivate->setState("");
+        QCOMPARE(rect->color(),QColor("blue")); // a script isn't reverted
+    }
+}
+
+void tst_qdeclarativestates::restoreEntryValues()
+{
+    QDeclarativeEngine engine;
+
+    QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/restoreEntryValues.qml");
+    QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create());
+    QVERIFY(rect != 0);
+    QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
+    QCOMPARE(rect->color(),QColor("red"));
+
+    rectPrivate->setState("blue");
+    QCOMPARE(rect->color(),QColor("blue"));
+
+    rectPrivate->setState("");
+    QCOMPARE(rect->color(),QColor("blue"));
+}
+
+void tst_qdeclarativestates::explicitChanges()
+{
+    QDeclarativeEngine engine;
+
+    QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/explicit.qml");
+    QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create());
+    QVERIFY(rect != 0);
+    QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
+    QDeclarativeListReference list(rect, "states");
+    QDeclarativeState *state = qobject_cast<QDeclarativeState*>(list.at(0));
+    QVERIFY(state != 0);
+
+    qmlExecuteDeferred(state);
+    QDeclarativePropertyChanges *changes = qobject_cast<QDeclarativePropertyChanges*>(rect->findChild<QDeclarativePropertyChanges*>("changes"));
+    QVERIFY(changes != 0);
+    QVERIFY(changes->isExplicit());
+
+    QCOMPARE(rect->color(),QColor("red"));
+
+    rectPrivate->setState("blue");
+    QCOMPARE(rect->color(),QColor("blue"));
+
+    rect->setProperty("sourceColor", QColor("green"));
+    QCOMPARE(rect->color(),QColor("blue"));
+
+    rectPrivate->setState("");
+    QCOMPARE(rect->color(),QColor("red"));
+    rect->setProperty("sourceColor", QColor("yellow"));
+    QCOMPARE(rect->color(),QColor("red"));
+
+    rectPrivate->setState("blue");
+    QCOMPARE(rect->color(),QColor("yellow"));
+}
+
+void tst_qdeclarativestates::propertyErrors()
+{
+    QDeclarativeEngine engine;
+    QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/propertyErrors.qml");
+    QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create());
+    QVERIFY(rect != 0);
+
+    QCOMPARE(rect->color(),QColor("red"));
+
+    QTest::ignoreMessage(QtWarningMsg, fullDataPath("/data/propertyErrors.qml") + ":8:9: QML PropertyChanges: Cannot assign to non-existent property \"colr\"");
+    QTest::ignoreMessage(QtWarningMsg, fullDataPath("/data/propertyErrors.qml") + ":8:9: QML PropertyChanges: Cannot assign to read-only property \"wantsFocus\"");
+    QDeclarativeItemPrivate::get(rect)->setState("blue");
+}
+
+void tst_qdeclarativestates::incorrectRestoreBug()
+{
+    QDeclarativeEngine engine;
+
+    QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicChanges.qml");
+    QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create());
+    QVERIFY(rect != 0);
+    QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
+    QCOMPARE(rect->color(),QColor("red"));
+
+    rectPrivate->setState("blue");
+    QCOMPARE(rect->color(),QColor("blue"));
+
+    rectPrivate->setState("");
+    QCOMPARE(rect->color(),QColor("red"));
+
+    // make sure if we change the base state value, we then restore to it correctly
+    rect->setColor(QColor("green"));
+
+    rectPrivate->setState("blue");
+    QCOMPARE(rect->color(),QColor("blue"));
+
+    rectPrivate->setState("");
+    QCOMPARE(rect->color(),QColor("green"));
+}
+
+void tst_qdeclarativestates::autoStateAtStartupRestoreBug()
+{
+    QDeclarativeEngine engine;
+
+    QDeclarativeComponent component(&engine, SRCDIR "/data/autoStateAtStartupRestoreBug.qml");
+    QObject *obj = component.create();
+
+    QVERIFY(obj != 0);
+    QCOMPARE(obj->property("test").toInt(), 3);
+
+    obj->setProperty("input", 2);
+
+    QCOMPARE(obj->property("test").toInt(), 9);
+
+    delete obj;
+}
+
+void tst_qdeclarativestates::deletingChange()
+{
+    QDeclarativeEngine engine;
+
+    QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/deleting.qml");
+    QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create());
+    QVERIFY(rect != 0);
+    QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
+    rectPrivate->setState("blue");
+    QCOMPARE(rect->color(),QColor("blue"));
+    QCOMPARE(rect->radius(),qreal(5));
+
+    rectPrivate->setState("");
+    QCOMPARE(rect->color(),QColor("red"));
+    QCOMPARE(rect->radius(),qreal(0));
+
+    QDeclarativePropertyChanges *pc = rect->findChild<QDeclarativePropertyChanges*>("pc1");
+    QVERIFY(pc != 0);
+    delete pc;
+
+    QDeclarativeState *state = rect->findChild<QDeclarativeState*>();
+    QVERIFY(state != 0);
+    qmlExecuteDeferred(state);
+    QCOMPARE(state->operationCount(), 1);
+
+    rectPrivate->setState("blue");
+    QCOMPARE(rect->color(),QColor("red"));
+    QCOMPARE(rect->radius(),qreal(5));
+
+    delete rect;
+}
+
+void tst_qdeclarativestates::deletingState()
+{
+    QDeclarativeEngine engine;
+
+    QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/deletingState.qml");
+    QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create());
+    QVERIFY(rect != 0);
+
+    QDeclarativeStateGroup *sg = rect->findChild<QDeclarativeStateGroup*>();
+    QVERIFY(sg != 0);
+    QVERIFY(sg->findState("blue") != 0);
+
+    sg->setState("blue");
+    QCOMPARE(rect->color(),QColor("blue"));
+
+    sg->setState("");
+    QCOMPARE(rect->color(),QColor("red"));
+
+    QDeclarativeState *state = rect->findChild<QDeclarativeState*>();
+    QVERIFY(state != 0);
+    delete state;
+
+    QVERIFY(sg->findState("blue") == 0);
+
+    //### should we warn that state doesn't exist
+    sg->setState("blue");
+    QCOMPARE(rect->color(),QColor("red"));
+
+    delete rect;
+}
+
+void tst_qdeclarativestates::tempState()
+{
+    QDeclarativeEngine engine;
+
+    QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/legalTempState.qml");
+    QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create());
+    QVERIFY(rect != 0);
+    QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
+    QTest::ignoreMessage(QtDebugMsg, "entering placed");
+    QTest::ignoreMessage(QtDebugMsg, "entering idle");
+    rectPrivate->setState("placed");
+    QCOMPARE(rectPrivate->state(), QLatin1String("idle"));
+}
+
+void tst_qdeclarativestates::illegalTempState()
+{
+    QDeclarativeEngine engine;
+
+    QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/illegalTempState.qml");
+    QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create());
+    QVERIFY(rect != 0);
+    QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
+    QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML StateGroup: Can't apply a state change as part of a state definition.");
+    rectPrivate->setState("placed");
+    QCOMPARE(rectPrivate->state(), QLatin1String("placed"));
+}
+
+void tst_qdeclarativestates::nonExistantProperty()
+{
+    QDeclarativeEngine engine;
+
+    QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/nonExistantProp.qml");
+    QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create());
+    QVERIFY(rect != 0);
+    QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
+    QTest::ignoreMessage(QtWarningMsg, fullDataPath("/data/nonExistantProp.qml") + ":9:9: QML PropertyChanges: Cannot assign to non-existent property \"colr\"");
+    rectPrivate->setState("blue");
+    QCOMPARE(rectPrivate->state(), QLatin1String("blue"));
+}
+
+void tst_qdeclarativestates::reset()
+{
+    QDeclarativeEngine engine;
+
+    QDeclarativeComponent c(&engine, SRCDIR "/data/reset.qml");
+    QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(c.create());
+    QVERIFY(rect != 0);
+
+    QDeclarativeText *text = rect->findChild<QDeclarativeText*>();
+    QVERIFY(text != 0);
+    QCOMPARE(text->width(), qreal(40.));
+    QVERIFY(text->width() < text->height());
+
+    QDeclarativeItemPrivate::get(rect)->setState("state1");
+
+    QVERIFY(text->width() > 41);
+    QVERIFY(text->width() > text->height());
+}
+
+void tst_qdeclarativestates::illegalObjectCreation()
+{
+    QDeclarativeEngine engine;
+
+    QDeclarativeComponent component(&engine, SRCDIR "/data/illegalObj.qml");
+    QList<QDeclarativeError> errors = component.errors();
+    QVERIFY(errors.count() == 1);
+    const QDeclarativeError &error = errors.at(0);
+    QCOMPARE(error.line(), 9);
+    QCOMPARE(error.column(), 23);
+    QCOMPARE(error.description().toUtf8().constData(), "PropertyChanges does not support creating state-specific objects.");
+}
+
+void tst_qdeclarativestates::whenOrdering()
+{
+    QDeclarativeEngine engine;
+
+    QDeclarativeComponent c(&engine, SRCDIR "/data/whenOrdering.qml");
+    QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(c.create());
+    QVERIFY(rect != 0);
+    QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
+
+    QCOMPARE(rectPrivate->state(), QLatin1String(""));
+    rect->setProperty("condition2", true);
+    QCOMPARE(rectPrivate->state(), QLatin1String("state2"));
+    rect->setProperty("condition1", true);
+    QCOMPARE(rectPrivate->state(), QLatin1String("state1"));
+    rect->setProperty("condition2", false);
+    QCOMPARE(rectPrivate->state(), QLatin1String("state1"));
+    rect->setProperty("condition2", true);
+    QCOMPARE(rectPrivate->state(), QLatin1String("state1"));
+    rect->setProperty("condition1", false);
+    rect->setProperty("condition2", false);
+    QCOMPARE(rectPrivate->state(), QLatin1String(""));
+}
+
+void tst_qdeclarativestates::urlResolution()
+{
+    QDeclarativeEngine engine;
+
+    QDeclarativeComponent c(&engine, SRCDIR "/data/urlResolution.qml");
+    QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(c.create());
+    QVERIFY(rect != 0);
+
+    QDeclarativeItem *myType = rect->findChild<QDeclarativeItem*>("MyType");
+    QDeclarativeImage *image1 = rect->findChild<QDeclarativeImage*>("image1");
+    QDeclarativeImage *image2 = rect->findChild<QDeclarativeImage*>("image2");
+    QDeclarativeImage *image3 = rect->findChild<QDeclarativeImage*>("image3");
+    QVERIFY(myType != 0 && image1 != 0 && image2 != 0 && image3 != 0);
+
+    QDeclarativeItemPrivate::get(myType)->setState("SetImageState");
+    QUrl resolved = QUrl::fromLocalFile(SRCDIR "/data/Implementation/images/qt-logo.png");
+    QCOMPARE(image1->source(), resolved);
+    QCOMPARE(image2->source(), resolved);
+    QCOMPARE(image3->source(), resolved);
+}
+
+void tst_qdeclarativestates::unnamedWhen()
+{
+    QDeclarativeEngine engine;
+
+    QDeclarativeComponent c(&engine, SRCDIR "/data/unnamedWhen.qml");
+    QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(c.create());
+    QVERIFY(rect != 0);
+    QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
+
+    QCOMPARE(rectPrivate->state(), QLatin1String(""));
+    QCOMPARE(rect->property("stateString").toString(), QLatin1String(""));
+    rect->setProperty("triggerState", true);
+    QCOMPARE(rectPrivate->state(), QLatin1String("anonymousState1"));
+    QCOMPARE(rect->property("stateString").toString(), QLatin1String("inState"));
+    rect->setProperty("triggerState", false);
+    QCOMPARE(rectPrivate->state(), QLatin1String(""));
+    QCOMPARE(rect->property("stateString").toString(), QLatin1String(""));
+}
+
+QTEST_MAIN(tst_qdeclarativestates)
+
+#include "tst_qdeclarativestates.moc"