diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2009-11-16 08:30:04 (GMT) |
---|---|---|
committer | Aaron Kennedy <aaron.kennedy@nokia.com> | 2009-11-16 08:30:04 (GMT) |
commit | 7db99f103981b6b45cb70a5837eb6b439d33e207 (patch) | |
tree | ca9163d9bc8336a83e2f2ff364aefed5c38f204f | |
parent | d51de46fe6d52126c57623156a5c7e4ed61a51a7 (diff) | |
download | Qt-7db99f103981b6b45cb70a5837eb6b439d33e207.zip Qt-7db99f103981b6b45cb70a5837eb6b439d33e207.tar.gz Qt-7db99f103981b6b45cb70a5837eb6b439d33e207.tar.bz2 |
Tests
-rw-r--r-- | src/declarative/qml/qmlcompiler.cpp | 4 | ||||
-rw-r--r-- | src/declarative/qml/qmlcomponent.h | 3 | ||||
-rw-r--r-- | src/declarative/qml/qmlengine.cpp | 75 | ||||
-rw-r--r-- | tests/auto/declarative/qmlengine/tst_qmlengine.cpp | 53 | ||||
-rw-r--r-- | tests/auto/declarative/qmlqt/data/createComponent.qml | 23 | ||||
-rw-r--r-- | tests/auto/declarative/qmlqt/data/createComponentData.qml | 5 | ||||
-rw-r--r-- | tests/auto/declarative/qmlqt/data/createQmlObject.qml | 31 | ||||
-rw-r--r-- | tests/auto/declarative/qmlqt/tst_qmlqt.cpp | 53 |
8 files changed, 211 insertions, 36 deletions
diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp index 2cb44a3..9000339 100644 --- a/src/declarative/qml/qmlcompiler.cpp +++ b/src/declarative/qml/qmlcompiler.cpp @@ -2044,12 +2044,12 @@ bool QmlCompiler::checkDynamicMeta(QmlParser::Object *obj) if (prop.isDefaultProperty) { if (seenDefaultProperty) - COMPILE_EXCEPTION(obj, qApp->translate("QmlCompiler","Duplicate default property")); + COMPILE_EXCEPTION(&prop, qApp->translate("QmlCompiler","Duplicate default property")); seenDefaultProperty = true; } if (propNames.contains(prop.name)) - COMPILE_EXCEPTION(obj, qApp->translate("QmlCompiler","Duplicate property name")); + COMPILE_EXCEPTION(&prop, qApp->translate("QmlCompiler","Duplicate property name")); propNames.insert(prop.name); } diff --git a/src/declarative/qml/qmlcomponent.h b/src/declarative/qml/qmlcomponent.h index 835bdc5..0abb58f 100644 --- a/src/declarative/qml/qmlcomponent.h +++ b/src/declarative/qml/qmlcomponent.h @@ -67,6 +67,9 @@ class Q_DECLARATIVE_EXPORT QmlComponent : public QObject Q_PROPERTY(bool isReady READ isReady NOTIFY statusChanged) Q_PROPERTY(bool isError READ isError NOTIFY statusChanged) Q_PROPERTY(bool isLoading READ isLoading NOTIFY statusChanged) + Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged) + Q_PROPERTY(Status status READ status NOTIFY statusChanged) + Q_PROPERTY(QUrl url READ url CONSTANT) public: QmlComponent(QObject *parent = 0); diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp index 1483c8c..9abd216 100644 --- a/src/declarative/qml/qmlengine.cpp +++ b/src/declarative/qml/qmlengine.cpp @@ -572,23 +572,23 @@ QmlContext *QmlEnginePrivate::getContext(QScriptContext *ctxt) QScriptValue QmlEnginePrivate::createComponent(QScriptContext *ctxt, QScriptEngine *engine) { - QmlComponent* c; - QmlEnginePrivate *activeEnginePriv = static_cast<QmlScriptEngine*>(engine)->p; QmlEngine* activeEngine = activeEnginePriv->q_func(); QmlContext* context = activeEnginePriv->getContext(ctxt); + Q_ASSERT(context); if(ctxt->argumentCount() != 1) { - c = new QmlComponent(activeEngine); + return engine->nullValue(); }else{ - QUrl url = QUrl(context->resolvedUrl(ctxt->argument(0).toString())); - if(!url.isValid()) - url = QUrl(ctxt->argument(0).toString()); - c = new QmlComponent(activeEngine, url, activeEngine); + QString arg = ctxt->argument(0).toString(); + if (arg.isEmpty()) + return engine->nullValue(); + QUrl url = QUrl(context->resolvedUrl(arg)); + QmlComponent *c = new QmlComponent(activeEngine, url, activeEngine); + c->setCreationContext(context); + return activeEnginePriv->objectClass->newQObject(c, qMetaTypeId<QmlComponent*>()); } - c->setCreationContext(context); - return engine->newQObject(c); } QScriptValue QmlEnginePrivate::createQmlObject(QScriptContext *ctxt, QScriptEngine *engine) @@ -597,57 +597,64 @@ QScriptValue QmlEnginePrivate::createQmlObject(QScriptContext *ctxt, QScriptEngi static_cast<QmlScriptEngine*>(engine)->p; QmlEngine* activeEngine = activeEnginePriv->q_func(); - if(ctxt->argumentCount() < 2) + if(ctxt->argumentCount() < 2 || ctxt->argumentCount() > 3) return engine->nullValue(); + QmlContext* context = activeEnginePriv->getContext(ctxt); + Q_ASSERT(context); + QString qml = ctxt->argument(0).toString(); + if (qml.isEmpty()) + return engine->nullValue(); + QUrl url; if(ctxt->argumentCount() > 2) url = QUrl(ctxt->argument(2).toString()); + + if (url.isValid() && url.isRelative()) + url = context->resolvedUrl(url); + QObject *parentArg = activeEnginePriv->objectClass->toQObject(ctxt->argument(1)); - QmlContext *qmlCtxt = qmlContext(parentArg); - if(!parentArg || !qmlCtxt){ - //TODO: Could use a qmlInfo() like function for script functions - qWarning() << "createQmlObject called with invalid parent object"; + if(!parentArg) return engine->nullValue(); - } - if (url.isEmpty()) { - url = qmlCtxt->resolvedUrl(QUrl(QLatin1String("<Unknown File>"))); - } else { - url = qmlCtxt->resolvedUrl(url); - } QmlComponent component(activeEngine, qml.toUtf8(), url); if(component.isError()) { QList<QmlError> errors = component.errors(); - qWarning() <<"QmlEngine::createQmlObject():"; + qWarning().nospace() << "QmlEngine::createQmlObject():"; foreach (const QmlError &error, errors) - qWarning() << " " << error; + qWarning().nospace() << " " << error; + + return engine->nullValue(); + } + + if (!component.isReady()) { + qWarning().nospace() << "QmlEngine::createQmlObject(): Component is not ready"; return engine->nullValue(); } - QObject *obj = component.create(qmlCtxt); + QObject *obj = component.create(context); if(component.isError()) { QList<QmlError> errors = component.errors(); - qWarning() <<"QmlEngine::createQmlObject():"; + qWarning().nospace() << "QmlEngine::createQmlObject():"; foreach (const QmlError &error, errors) - qWarning() << " " << error; + qWarning().nospace() << " " << error; return engine->nullValue(); } - if(obj) { - obj->setParent(parentArg); - QGraphicsObject* gobj = qobject_cast<QGraphicsObject*>(obj); - QGraphicsObject* gparent = qobject_cast<QGraphicsObject*>(parentArg); - if(gobj && gparent) - gobj->setParentItem(gparent); - return qmlScriptObject(obj, activeEngine); - } - return engine->nullValue(); + Q_ASSERT(obj); + + obj->setParent(parentArg); + QGraphicsObject* gobj = qobject_cast<QGraphicsObject*>(obj); + QGraphicsObject* gparent = qobject_cast<QGraphicsObject*>(parentArg); + if(gobj && gparent) + gobj->setParentItem(gparent); + + return qmlScriptObject(obj, activeEngine); } QScriptValue QmlEnginePrivate::vector(QScriptContext *ctxt, QScriptEngine *engine) diff --git a/tests/auto/declarative/qmlengine/tst_qmlengine.cpp b/tests/auto/declarative/qmlengine/tst_qmlengine.cpp index ef1eee5..54f916f 100644 --- a/tests/auto/declarative/qmlengine/tst_qmlengine.cpp +++ b/tests/auto/declarative/qmlengine/tst_qmlengine.cpp @@ -47,6 +47,7 @@ #include <QDir> #include <QDesktopServices> #include <QDebug> +#include <QmlComponent> class tst_qmlengine : public QObject { @@ -60,6 +61,7 @@ private slots: void baseUrl(); void contextForObject(); void offlineStoragePath(); + void clearComponentCache(); }; void tst_qmlengine::rootContext() @@ -171,6 +173,57 @@ void tst_qmlengine::offlineStoragePath() QCOMPARE(engine.offlineStoragePath(), QDir::homePath()); } +void tst_qmlengine::clearComponentCache() +{ + QmlEngine engine; + + // Create original qml file + { + QFile file("temp.qml"); + QVERIFY(file.open(QIODevice::WriteOnly)); + file.write("import Qt 4.6\nObject {\nproperty int test: 10\n}\n"); + file.close(); + } + + // Test "test" property + { + QmlComponent component(&engine, "temp.qml"); + QObject *obj = component.create(); + QVERIFY(obj != 0); + QCOMPARE(obj->property("test").toInt(), 10); + delete obj; + } + + // Modify qml file + { + QFile file("temp.qml"); + QVERIFY(file.open(QIODevice::WriteOnly)); + file.write("import Qt 4.6\nObject {\nproperty int test: 11\n}\n"); + file.close(); + } + + // Test cache hit + { + QmlComponent component(&engine, "temp.qml"); + QObject *obj = component.create(); + QVERIFY(obj != 0); + QCOMPARE(obj->property("test").toInt(), 10); + delete obj; + } + + // Clear cache + engine.clearComponentCache(); + + // Test cache refresh + { + QmlComponent component(&engine, "temp.qml"); + QObject *obj = component.create(); + QVERIFY(obj != 0); + QCOMPARE(obj->property("test").toInt(), 11); + delete obj; + } +} + QTEST_MAIN(tst_qmlengine) #include "tst_qmlengine.moc" diff --git a/tests/auto/declarative/qmlqt/data/createComponent.qml b/tests/auto/declarative/qmlqt/data/createComponent.qml new file mode 100644 index 0000000..57f50d8 --- /dev/null +++ b/tests/auto/declarative/qmlqt/data/createComponent.qml @@ -0,0 +1,23 @@ +import Qt 4.6 + +Object { + property bool incorrectArgCount1: false + property bool incorrectArgCount2: false + property bool emptyArg: false + + property string relativeUrl + property string absoluteUrl + + Component.onCompleted: { + // Test that using incorrect argument count returns a null object + incorrectArgCount1 = (createComponent() == null); + incorrectArgCount2 = (createComponent("main.qml", 10) == null); + emptyArg = (createComponent("") == null); + + var r = createComponent("createComponentData.qml"); + relativeUrl = r.url; + + var a = createComponent("http://www.example.com/test.qml"); + absoluteUrl = a.url; + } +} diff --git a/tests/auto/declarative/qmlqt/data/createComponentData.qml b/tests/auto/declarative/qmlqt/data/createComponentData.qml new file mode 100644 index 0000000..145fe78 --- /dev/null +++ b/tests/auto/declarative/qmlqt/data/createComponentData.qml @@ -0,0 +1,5 @@ +import Qt 4.6 + +Object { + property int test: 1913 +} diff --git a/tests/auto/declarative/qmlqt/data/createQmlObject.qml b/tests/auto/declarative/qmlqt/data/createQmlObject.qml new file mode 100644 index 0000000..8e8919a --- /dev/null +++ b/tests/auto/declarative/qmlqt/data/createQmlObject.qml @@ -0,0 +1,31 @@ +import Qt 4.6 + +Item { + id: root + + property bool incorrectArgCount1: false + property bool incorrectArgCount2: false + property bool emptyArg: false + property bool noParent: false + property bool notReady: false + property bool runtimeError: false + property bool errors: false + + property bool success: false + + Component.onCompleted: { + // errors + incorrectArgCount1 = (createQmlObject() == null); + incorrectArgCount2 = (createQmlObject("import Qt 4.6\nObject{}", root, "main.qml", 10) == null); + emptyArg = (createQmlObject("", root) == null); + errors = (createQmlObject("import Qt 4.6\nObject{\nproperty int test: 13\nproperty int test: 13\n}", root, "main.qml") == null); + noParent = (createQmlObject("import Qt 4.6\nObject{\nproperty int test: 13}", 0) == null); + notReady = (createQmlObject("import Qt 4.6\nObject{\nBlah{}\n}", root, "http://www.example.com/main.qml") == null); + runtimeError = (createQmlObject("import Qt 4.6\nObject{property int test\nonTestChanged: Object{}\n}", root) == null); + + var o = createQmlObject("import Qt 4.6\nObject{\nproperty int test: 13\n}", root); + success = (o.test == 13); + + createQmlObject("import Qt 4.6\nItem {}\n", root); + } +} diff --git a/tests/auto/declarative/qmlqt/tst_qmlqt.cpp b/tests/auto/declarative/qmlqt/tst_qmlqt.cpp index 4d09aee..292102a 100644 --- a/tests/auto/declarative/qmlqt/tst_qmlqt.cpp +++ b/tests/auto/declarative/qmlqt/tst_qmlqt.cpp @@ -47,6 +47,7 @@ #include <QDir> #include <QVector3D> #include <QCryptographicHash> +#include <QmlGraphicsItem> class tst_qmlqt : public QObject { @@ -69,6 +70,8 @@ private slots: void playSound(); void openUrlExternally(); void md5(); + void createComponent(); + void createQmlObject(); private: QmlEngine engine; @@ -299,6 +302,56 @@ void tst_qmlqt::md5() delete object; } +void tst_qmlqt::createComponent() +{ + QmlComponent component(&engine, TEST_FILE("createComponent.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(object->property("incorrectArgCount1").toBool(), true); + QCOMPARE(object->property("incorrectArgCount2").toBool(), true); + QCOMPARE(object->property("emptyArg").toBool(), true); + + QCOMPARE(object->property("absoluteUrl").toString(), QString("http://www.example.com/test.qml")); + QCOMPARE(object->property("relativeUrl").toString(), TEST_FILE("createComponentData.qml").toString()); + + delete object; +} + +void tst_qmlqt::createQmlObject() +{ + QmlComponent component(&engine, TEST_FILE("createQmlObject.qml")); + + QString warning1 = "QmlEngine::createQmlObject():"; + QString warning2 = " " + TEST_FILE("main.qml").toString() + ":4:1: Duplicate property name"; + QString warning3 = "QmlEngine::createQmlObject(): Component is not ready"; + QString warning4 = "QmlEngine::createQmlObject():"; + QString warning5 = " :3: Cannot assign object type QObject with no default method"; + + QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1)); + QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2)); + QTest::ignoreMessage(QtWarningMsg, qPrintable(warning3)); + QTest::ignoreMessage(QtWarningMsg, qPrintable(warning4)); + QTest::ignoreMessage(QtWarningMsg, qPrintable(warning5)); + + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(object->property("incorrectArgCount1").toBool(), true); + QCOMPARE(object->property("incorrectArgCount2").toBool(), true); + QCOMPARE(object->property("emptyArg").toBool(), true); + QCOMPARE(object->property("errors").toBool(), true); + QCOMPARE(object->property("noParent").toBool(), true); + QCOMPARE(object->property("notReady").toBool(), true); + QCOMPARE(object->property("runtimeError").toBool(), true); + QCOMPARE(object->property("success").toBool(), true); + + QmlGraphicsItem *item = qobject_cast<QmlGraphicsItem *>(object); + QVERIFY(item != 0); + QVERIFY(item->childItems().count() == 1); + + delete object; +} QTEST_MAIN(tst_qmlqt) |