From 0cf34bc8a232220a33932efda748cea8917a855d Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Tue, 4 Oct 2011 10:42:37 +1000 Subject: [PATCH] QDeclarativeIncubator autotests Change-Id: Ib1b70903c5aa82fc1112c17db1b676b4740ea685 Task-number: QTBUG-21151 Reviewed-on: http://codereview.qt-project.org/5940 Reviewed-by: Qt Sanity Bot Reviewed-by: Martin Jones --- src/declarative/qml/qdeclarativeincubator.cpp | 29 +++- .../qdeclarativeincubator/data/forceCompletion.qml | 9 ++ .../data/noIncubationController.qml | 5 + .../qdeclarativeincubator/data/setInitialState.qml | 17 +++ .../tst_qdeclarativeincubator.cpp | 161 +++++++++++++++++++++ 5 files changed, 219 insertions(+), 2 deletions(-) create mode 100644 tests/auto/declarative/qdeclarativeincubator/data/forceCompletion.qml create mode 100644 tests/auto/declarative/qdeclarativeincubator/data/noIncubationController.qml create mode 100644 tests/auto/declarative/qdeclarativeincubator/data/setInitialState.qml diff --git a/src/declarative/qml/qdeclarativeincubator.cpp b/src/declarative/qml/qdeclarativeincubator.cpp index b6eb4e4..ff0712d 100644 --- a/src/declarative/qml/qdeclarativeincubator.cpp +++ b/src/declarative/qml/qdeclarativeincubator.cpp @@ -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 index 0000000..9b76701 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeincubator/data/forceCompletion.qml @@ -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 index 0000000..7d93e85 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeincubator/data/noIncubationController.qml @@ -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 index 0000000..0fd61ab --- /dev/null +++ b/tests/auto/declarative/qdeclarativeincubator/data/setInitialState.qml @@ -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; + } +} + diff --git a/tests/auto/declarative/qdeclarativeincubator/tst_qdeclarativeincubator.cpp b/tests/auto/declarative/qdeclarativeincubator/tst_qdeclarativeincubator.cpp index 25e6c6e..e7fc777 100644 --- a/tests/auto/declarative/qdeclarativeincubator/tst_qdeclarativeincubator.cpp +++ b/tests/auto/declarative/qdeclarativeincubator/tst_qdeclarativeincubator.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -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" -- 2.7.4