diff options
author | Martin Jones <martin.jones@nokia.com> | 2011-11-01 10:05:47 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-11-01 13:09:31 +0100 |
commit | f75bd7eb78759a2b708771517b5fc64fd7a75e8a (patch) | |
tree | 3e71ed39482f9272afbc6feea2d6cf94b5555e48 /tests/auto/declarative/qdeclarativeincubator | |
parent | c29b3c0974383dfe5e2b4890b5d6377d5aa4264e (diff) |
Ensure that chained incubation works from componentCompleted.
Make chained AsynchronousIfNested initiated from componentComplete
work correctly, i.e. asynchronous incubator is not Ready until
all chained creation is Ready.
Change-Id: I286cc10e2f09e36dcc6034f3f23681e833d7e6e8
Reviewed-by: Aaron Kennedy <aaron.kennedy@nokia.com>
Diffstat (limited to 'tests/auto/declarative/qdeclarativeincubator')
4 files changed, 180 insertions, 0 deletions
diff --git a/tests/auto/declarative/qdeclarativeincubator/data/chainInCompletion.qml b/tests/auto/declarative/qdeclarativeincubator/data/chainInCompletion.qml new file mode 100644 index 0000000000..e79fed356a --- /dev/null +++ b/tests/auto/declarative/qdeclarativeincubator/data/chainInCompletion.qml @@ -0,0 +1,5 @@ +import Qt.test 1.0 + +SelfRegistering { + property variant a: CompletionCallback {} +} diff --git a/tests/auto/declarative/qdeclarativeincubator/testtypes.cpp b/tests/auto/declarative/qdeclarativeincubator/testtypes.cpp index 99d2cb1005..6d6fb38daf 100644 --- a/tests/auto/declarative/qdeclarativeincubator/testtypes.cpp +++ b/tests/auto/declarative/qdeclarativeincubator/testtypes.cpp @@ -101,9 +101,37 @@ void CallbackRegisteringType::registerCallback(callback c, void *d) m_data = d; } +CompletionCallbackType::callback CompletionCallbackType::m_callback = 0; +void *CompletionCallbackType::m_data = 0; +CompletionCallbackType::CompletionCallbackType() +{ +} + +void CompletionCallbackType::classBegin() +{ +} + +void CompletionCallbackType::componentComplete() +{ + if (m_callback) m_callback(this, m_data); +} + +void CompletionCallbackType::clearCallback() +{ + m_callback = 0; + m_data = 0; +} + +void CompletionCallbackType::registerCallback(callback c, void *d) +{ + m_callback = c; + m_data = d; +} + void registerTypes() { qmlRegisterType<SelfRegisteringType>("Qt.test", 1,0, "SelfRegistering"); qmlRegisterType<CompletionRegisteringType>("Qt.test", 1,0, "CompletionRegistering"); qmlRegisterType<CallbackRegisteringType>("Qt.test", 1,0, "CallbackRegistering"); + qmlRegisterType<CompletionCallbackType>("Qt.test", 1,0, "CompletionCallback"); } diff --git a/tests/auto/declarative/qdeclarativeincubator/testtypes.h b/tests/auto/declarative/qdeclarativeincubator/testtypes.h index 6e732548b2..8d9968de3c 100644 --- a/tests/auto/declarative/qdeclarativeincubator/testtypes.h +++ b/tests/auto/declarative/qdeclarativeincubator/testtypes.h @@ -100,6 +100,24 @@ private: static CompletionRegisteringType *m_me; }; +class CompletionCallbackType : public QObject, public QDeclarativeParserStatus +{ +Q_OBJECT +public: + CompletionCallbackType(); + + virtual void classBegin(); + virtual void componentComplete(); + + typedef void (*callback)(CompletionCallbackType *, void *); + static void clearCallback(); + static void registerCallback(callback, void *); + +private: + static callback m_callback; + static void *m_data; +}; + void registerTypes(); #endif // TESTTYPES_H diff --git a/tests/auto/declarative/qdeclarativeincubator/tst_qdeclarativeincubator.cpp b/tests/auto/declarative/qdeclarativeincubator/tst_qdeclarativeincubator.cpp index 684cd35613..54ca622753 100644 --- a/tests/auto/declarative/qdeclarativeincubator/tst_qdeclarativeincubator.cpp +++ b/tests/auto/declarative/qdeclarativeincubator/tst_qdeclarativeincubator.cpp @@ -83,6 +83,7 @@ private slots: void asynchronousIfNested(); void nestedComponent(); void chainedAsynchronousIfNested(); + void chainedAsynchronousIfNestedOnCompleted(); void selfDelete(); private: @@ -773,6 +774,134 @@ void tst_qdeclarativeincubator::chainedAsynchronousIfNested() QVERIFY(incubator2.isReady()); } +// Checks that new AsynchronousIfNested incubators can be correctly chained if started in +// componentCompleted(). +void tst_qdeclarativeincubator::chainedAsynchronousIfNestedOnCompleted() +{ + SelfRegisteringType::clearMe(); + + QDeclarativeComponent component(&engine, TEST_FILE("chainInCompletion.qml")); + QVERIFY(component.isReady()); + + QDeclarativeComponent c1(&engine, TEST_FILE("chainedAsynchronousIfNested.qml")); + QVERIFY(c1.isReady()); + + struct MyIncubator : public QDeclarativeIncubator { + MyIncubator(MyIncubator *next, QDeclarativeComponent *component, QDeclarativeContext *ctxt) + : QDeclarativeIncubator(AsynchronousIfNested), next(next), component(component), ctxt(ctxt) {} + + protected: + virtual void statusChanged(Status s) { + if (s == Ready && next) { + component->create(*next, 0, ctxt); + } + } + + private: + MyIncubator *next; + QDeclarativeComponent *component; + QDeclarativeContext *ctxt; + }; + + struct CallbackData { + CallbackData(QDeclarativeComponent *c, MyIncubator *i, QDeclarativeContext *ct) + : component(c), incubator(i), ctxt(ct) {} + QDeclarativeComponent *component; + MyIncubator *incubator; + QDeclarativeContext *ctxt; + static void callback(CompletionCallbackType *o, void *data) { + CallbackData *d = (CallbackData *)data; + d->component->create(*d->incubator, 0, d->ctxt); + } + }; + + QDeclarativeIncubator incubator(QDeclarativeIncubator::Asynchronous); + component.create(incubator); + + QVERIFY(incubator.isLoading()); + QVERIFY(SelfRegisteringType::me() == 0); + + while (SelfRegisteringType::me() == 0 && incubator.isLoading()) { + bool b = false; + controller.incubateWhile(&b); + } + + QVERIFY(SelfRegisteringType::me() != 0); + QVERIFY(incubator.isLoading()); + + MyIncubator incubator3(0, &c1, qmlContext(SelfRegisteringType::me())); + MyIncubator incubator2(&incubator3, &c1, qmlContext(SelfRegisteringType::me())); + MyIncubator incubator1(&incubator2, &c1, qmlContext(SelfRegisteringType::me())); + + // start incubator1 in componentComplete + CallbackData cd(&c1, &incubator1, qmlContext(SelfRegisteringType::me())); + CompletionCallbackType::registerCallback(&CallbackData::callback, &cd); + + while (!incubator1.isLoading()) { + QVERIFY(incubator.isLoading()); + QVERIFY(incubator2.isNull()); + QVERIFY(incubator3.isNull()); + + bool b = false; + controller.incubateWhile(&b); + } + + QVERIFY(incubator.isLoading()); + QVERIFY(incubator1.isLoading()); + QVERIFY(incubator2.isNull()); + QVERIFY(incubator3.isNull()); + + while (incubator1.isLoading()) { + QVERIFY(incubator.isLoading()); + QVERIFY(incubator1.isLoading()); + QVERIFY(incubator2.isNull()); + QVERIFY(incubator3.isNull()); + + bool b = false; + controller.incubateWhile(&b); + } + + QVERIFY(incubator.isLoading()); + QVERIFY(incubator1.isReady()); + QVERIFY(incubator2.isLoading()); + QVERIFY(incubator3.isNull()); + + while (incubator2.isLoading()) { + QVERIFY(incubator.isLoading()); + QVERIFY(incubator1.isReady()); + QVERIFY(incubator2.isLoading()); + QVERIFY(incubator3.isNull()); + + bool b = false; + controller.incubateWhile(&b); + } + + QVERIFY(incubator.isLoading()); + QVERIFY(incubator1.isReady()); + QVERIFY(incubator2.isReady()); + QVERIFY(incubator3.isLoading()); + + while (incubator3.isLoading()) { + QVERIFY(incubator.isLoading()); + QVERIFY(incubator1.isReady()); + QVERIFY(incubator2.isReady()); + QVERIFY(incubator3.isLoading()); + + bool b = false; + controller.incubateWhile(&b); + } + + { + bool b = true; + controller.incubateWhile(&b); + } + + QVERIFY(incubator.isReady()); + QVERIFY(incubator1.isReady()); + QVERIFY(incubator2.isReady()); + QVERIFY(incubator3.isReady()); +} + void tst_qdeclarativeincubator::selfDelete() { struct MyIncubator : public QDeclarativeIncubator { |