QDeclarativeIncubator autotests
authorAaron Kennedy <aaron.kennedy@nokia.com>
Tue, 4 Oct 2011 00:42:37 +0000 (10:42 +1000)
committerQt by Nokia <qt-info@nokia.com>
Tue, 4 Oct 2011 06:11:12 +0000 (08:11 +0200)
Change-Id: Ib1b70903c5aa82fc1112c17db1b676b4740ea685
Task-number: QTBUG-21151
Reviewed-on: http://codereview.qt-project.org/5940
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Martin Jones <martin.jones@nokia.com>
src/declarative/qml/qdeclarativeincubator.cpp
tests/auto/declarative/qdeclarativeincubator/data/forceCompletion.qml [new file with mode: 0644]
tests/auto/declarative/qdeclarativeincubator/data/noIncubationController.qml [new file with mode: 0644]
tests/auto/declarative/qdeclarativeincubator/data/setInitialState.qml [new file with mode: 0644]
tests/auto/declarative/qdeclarativeincubator/tst_qdeclarativeincubator.cpp

index b6eb4e4..ff0712d 100644 (file)
@@ -56,6 +56,9 @@ void QDeclarativeEnginePrivate::incubate(QDeclarativeIncubator &i, QDeclarativeC
 
     QDeclarativeIncubator::IncubationMode mode = i.incubationMode();
 
+    if (!incubationController)
+        mode = QDeclarativeIncubator::Synchronous;
+
     if (mode == QDeclarativeIncubator::AsynchronousIfNested) {
         mode = QDeclarativeIncubator::Synchronous;
 
@@ -77,11 +80,12 @@ void QDeclarativeEnginePrivate::incubate(QDeclarativeIncubator &i, QDeclarativeC
         }
     }
 
+    inProgressCreations++;
+
     if (mode == QDeclarativeIncubator::Synchronous) {
         QDeclarativeVME::Interrupt i;
         p->incubate(i);
     } else {
-        inProgressCreations++;
         incubatorList.insert(p);
         incubatorCount++;
 
@@ -132,11 +136,13 @@ void QDeclarativeIncubatorPrivate::clear()
         QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(component->engine);
         component->release();
         component = 0;
-
         enginePriv->incubatorCount--;
         QDeclarativeIncubationController *controller = enginePriv->incubationController;
         if (controller)
             controller->incubatingObjectCountChanged(enginePriv->incubatorCount);
+    } else if (component) {
+        component->release();
+        component = 0;
     }
 
     if (nextWaitingFor.isInList()) {
@@ -476,6 +482,12 @@ void QDeclarativeIncubator::clear()
     if (s == Null)
         return;
 
+    QDeclarativeEnginePrivate *enginePriv = 0;
+    if (s == Loading) {
+        Q_ASSERT(d->component);
+        enginePriv = QDeclarativeEnginePrivate::get(d->component->engine);
+    }
+
     d->clear();
 
     d->vme.reset();
@@ -489,6 +501,19 @@ void QDeclarativeIncubator::clear()
     d->errors.clear();
     d->progress = QDeclarativeIncubatorPrivate::Execute;
     d->result = 0;
+
+    if (s == Loading) {
+        Q_ASSERT(enginePriv);
+
+        enginePriv->inProgressCreations--;
+        if (0 == enginePriv->inProgressCreations) {
+            while (enginePriv->erroredBindings) {
+                enginePriv->warning(enginePriv->erroredBindings->error);
+                enginePriv->erroredBindings->removeError();
+            }
+        }
+    }
+
 }
 
 /*!
diff --git a/tests/auto/declarative/qdeclarativeincubator/data/forceCompletion.qml b/tests/auto/declarative/qdeclarativeincubator/data/forceCompletion.qml
new file mode 100644 (file)
index 0000000..9b76701
--- /dev/null
@@ -0,0 +1,9 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+Item {
+    property int testValue: 3499
+    SelfRegistering {
+        property int testValue2: 19
+    }
+}
diff --git a/tests/auto/declarative/qdeclarativeincubator/data/noIncubationController.qml b/tests/auto/declarative/qdeclarativeincubator/data/noIncubationController.qml
new file mode 100644 (file)
index 0000000..7d93e85
--- /dev/null
@@ -0,0 +1,5 @@
+import QtQuick 2.0
+
+QtObject {
+    property int testValue: 1913
+}
diff --git a/tests/auto/declarative/qdeclarativeincubator/data/setInitialState.qml b/tests/auto/declarative/qdeclarativeincubator/data/setInitialState.qml
new file mode 100644 (file)
index 0000000..0fd61ab
--- /dev/null
@@ -0,0 +1,17 @@
+import QtQuick 2.0
+
+QtObject {
+    property int test1: (testData1 * 32 + 99) / testData2
+    property int test2: myValueFunction()
+
+    property bool myValueFunctionCalled: false
+
+    property int testData1: 19
+    property int testData2: 13
+
+    function myValueFunction() {
+        myValueFunctionCalled = true;
+        return 13;
+    }
+}
+
index 25e6c6e..e7fc777 100644 (file)
@@ -47,6 +47,7 @@
 #include <QPointer>
 #include <QFileInfo>
 #include <QDeclarativeEngine>
+#include <QDeclarativeProperty>
 #include <QDeclarativeComponent>
 #include <QDeclarativeIncubator>
 
@@ -73,6 +74,9 @@ private slots:
     void incubationMode();
     void objectDeleted();
     void clear();
+    void noIncubationController();
+    void forceCompletion();
+    void setInitialState();
 
 private:
     QDeclarativeIncubationController controller;
@@ -234,6 +238,163 @@ void tst_qdeclarativeincubator::clear()
     // XXX Clear in error state
 }
 
+void tst_qdeclarativeincubator::noIncubationController()
+{
+    // All incubators should behave synchronously when there is no controller
+
+    QDeclarativeEngine engine;
+    QDeclarativeComponent component(&engine, TEST_FILE("noIncubationController.qml"));
+
+    QVERIFY(component.isReady());
+
+    {
+    QDeclarativeIncubator incubator(QDeclarativeIncubator::Asynchronous);
+    component.create(incubator);
+    QVERIFY(incubator.isReady());
+    QVERIFY(incubator.object());
+    QCOMPARE(incubator.object()->property("testValue").toInt(), 1913);
+    delete incubator.object();
+    }
+
+    {
+    QDeclarativeIncubator incubator(QDeclarativeIncubator::AsynchronousIfNested);
+    component.create(incubator);
+    QVERIFY(incubator.isReady());
+    QVERIFY(incubator.object());
+    QCOMPARE(incubator.object()->property("testValue").toInt(), 1913);
+    delete incubator.object();
+    }
+
+    {
+    QDeclarativeIncubator incubator(QDeclarativeIncubator::Synchronous);
+    component.create(incubator);
+    QVERIFY(incubator.isReady());
+    QVERIFY(incubator.object());
+    QCOMPARE(incubator.object()->property("testValue").toInt(), 1913);
+    delete incubator.object();
+    }
+}
+
+void tst_qdeclarativeincubator::forceCompletion()
+{
+    QDeclarativeComponent component(&engine, TEST_FILE("forceCompletion.qml"));
+    QVERIFY(component.isReady());
+
+    {
+    // forceCompletion on a null incubator does nothing
+    QDeclarativeIncubator incubator;
+    QVERIFY(incubator.isNull());
+    incubator.forceCompletion();
+    QVERIFY(incubator.isNull());
+    }
+
+    {
+    // forceCompletion immediately after creating an asynchronous object completes it
+    QDeclarativeIncubator incubator;
+    QVERIFY(incubator.isNull());
+    component.create(incubator);
+    QVERIFY(incubator.isLoading());
+
+    incubator.forceCompletion();
+
+    QVERIFY(incubator.isReady());
+    QVERIFY(incubator.object() != 0);
+    QCOMPARE(incubator.object()->property("testValue").toInt(), 3499);
+
+    delete incubator.object();
+    }
+
+    {
+    // forceCompletion during creation completes it
+    SelfRegisteringType::clearMe();
+
+    QDeclarativeIncubator incubator;
+    QVERIFY(incubator.isNull());
+    component.create(incubator);
+    QVERIFY(incubator.isLoading());
+
+    while (SelfRegisteringType::me() == 0 && incubator.isLoading()) {
+        bool b = false;
+        controller.incubateWhile(&b);
+    }
+
+    QVERIFY(SelfRegisteringType::me() != 0);
+    QVERIFY(incubator.isLoading());
+
+    incubator.forceCompletion();
+
+    QVERIFY(incubator.isReady());
+    QVERIFY(incubator.object() != 0);
+    QCOMPARE(incubator.object()->property("testValue").toInt(), 3499);
+
+    delete incubator.object();
+    }
+
+    {
+    // forceCompletion on a ready incubator has no effect
+    QDeclarativeIncubator incubator;
+    QVERIFY(incubator.isNull());
+    component.create(incubator);
+    QVERIFY(incubator.isLoading());
+
+    incubator.forceCompletion();
+
+    QVERIFY(incubator.isReady());
+    QVERIFY(incubator.object() != 0);
+    QCOMPARE(incubator.object()->property("testValue").toInt(), 3499);
+
+    incubator.forceCompletion();
+
+    QVERIFY(incubator.isReady());
+    QVERIFY(incubator.object() != 0);
+    QCOMPARE(incubator.object()->property("testValue").toInt(), 3499);
+
+    delete incubator.object();
+    }
+}
+
+void tst_qdeclarativeincubator::setInitialState()
+{
+    QDeclarativeComponent component(&engine, TEST_FILE("setInitialState.qml"));
+    QVERIFY(component.isReady());
+
+    struct MyIncubator : public QDeclarativeIncubator
+    {
+        MyIncubator(QDeclarativeIncubator::IncubationMode mode)
+        : QDeclarativeIncubator(mode) {}
+
+        virtual void setInitialState(QObject *o) {
+            QDeclarativeProperty::write(o, "test2", 19);
+            QDeclarativeProperty::write(o, "testData1", 201);
+        }
+    };
+
+    {
+    MyIncubator incubator(QDeclarativeIncubator::Asynchronous);
+    component.create(incubator);
+    QVERIFY(incubator.isLoading());
+    bool b = true;
+    controller.incubateWhile(&b);
+    QVERIFY(incubator.isReady());
+    QVERIFY(incubator.object());
+    QCOMPARE(incubator.object()->property("myValueFunctionCalled").toBool(), false);
+    QCOMPARE(incubator.object()->property("test1").toInt(), 502);
+    QCOMPARE(incubator.object()->property("test2").toInt(), 19);
+    delete incubator.object();
+    }
+
+    {
+    MyIncubator incubator(QDeclarativeIncubator::Synchronous);
+    component.create(incubator);
+    QVERIFY(incubator.isReady());
+    QVERIFY(incubator.object());
+    QCOMPARE(incubator.object()->property("myValueFunctionCalled").toBool(), false);
+    QCOMPARE(incubator.object()->property("test1").toInt(), 502);
+    QCOMPARE(incubator.object()->property("test2").toInt(), 19);
+    delete incubator.object();
+    }
+}
+
 QTEST_MAIN(tst_qdeclarativeincubator)
 
 #include "tst_qdeclarativeincubator.moc"